add warning if not session (but e.g. task) used on top-level

This commit is contained in:
az 2023-04-28 13:53:19 +02:00
parent 99c02e8a48
commit f4156fd9ec
2 changed files with 95 additions and 24 deletions

View file

@ -72,11 +72,11 @@ open class Prov protected constructor(
* A session is the top-level execution unit in provs. A session can contain tasks. * A session is the top-level execution unit in provs. A session can contain tasks.
* Returns success if no sub-tasks are called or if all subtasks finish with success. * Returns success if no sub-tasks are called or if all subtasks finish with success.
*/ */
fun session(taskLambda: Prov.() -> Unit) = task("session") { fun session(taskLambda: Prov.() -> ProvResult): ProvResult {
if (level > 1) { if (level > 0) {
throw IllegalStateException("A session can only be created on the top-level and may not be included in another session or task.") throw IllegalStateException("A session can only be created on the top-level and may not be included in another session or task.")
} }
taskLambda() return evaluate(ResultMode.ALL, "session") { taskLambda() }
} }
/** /**
@ -84,6 +84,7 @@ open class Prov protected constructor(
* Returns success if no sub-tasks are called or if all subtasks finish with success. * Returns success if no sub-tasks are called or if all subtasks finish with success.
*/ */
fun task(name: String? = null, taskLambda: Prov.() -> Unit): ProvResult { fun task(name: String? = null, taskLambda: Prov.() -> Unit): ProvResult {
printDeprecationWarningIfLevel0("task")
return evaluate(ResultMode.ALL, name) { taskLambda(); ProvResult(true) } return evaluate(ResultMode.ALL, name) { taskLambda(); ProvResult(true) }
} }
@ -92,6 +93,7 @@ open class Prov protected constructor(
* The returned result is included in the evaluation. * The returned result is included in the evaluation.
*/ */
fun taskWithResult(name: String? = null, taskLambda: Prov.() -> ProvResult): ProvResult { fun taskWithResult(name: String? = null, taskLambda: Prov.() -> ProvResult): ProvResult {
printDeprecationWarningIfLevel0("taskWithResult")
return evaluate(ResultMode.ALL, name) { taskLambda() } return evaluate(ResultMode.ALL, name) { taskLambda() }
} }
@ -99,6 +101,7 @@ open class Prov protected constructor(
* defines a task, which returns the returned result, the results of sub-tasks are not considered * defines a task, which returns the returned result, the results of sub-tasks are not considered
*/ */
fun requireLast(name: String? = null, a: Prov.() -> ProvResult): ProvResult { fun requireLast(name: String? = null, a: Prov.() -> ProvResult): ProvResult {
printDeprecationWarningIfLevel0("requireLast")
return evaluate(ResultMode.LAST, name) { a() } return evaluate(ResultMode.LAST, name) { a() }
} }
@ -106,6 +109,7 @@ open class Prov protected constructor(
* defines a task, which always returns success * defines a task, which always returns success
*/ */
fun optional(name: String? = null, a: Prov.() -> ProvResult): ProvResult { fun optional(name: String? = null, a: Prov.() -> ProvResult): ProvResult {
printDeprecationWarningIfLevel0("optional")
return evaluate(ResultMode.OPTIONAL, name) { a() } return evaluate(ResultMode.OPTIONAL, name) { a() }
} }
@ -113,6 +117,7 @@ open class Prov protected constructor(
* defines a task, which exits the overall execution on failure * defines a task, which exits the overall execution on failure
*/ */
fun exitOnFailure(a: Prov.() -> ProvResult): ProvResult { fun exitOnFailure(a: Prov.() -> ProvResult): ProvResult {
printDeprecationWarningIfLevel0("exitOnFailure")
return evaluate(ResultMode.FAILEXIT) { a() } return evaluate(ResultMode.FAILEXIT) { a() }
} }
@ -120,6 +125,7 @@ open class Prov protected constructor(
* Runs the provided task in the specified (running) container * Runs the provided task in the specified (running) container
*/ */
fun taskInContainer(containerName: String, taskLambda: Prov.() -> ProvResult): ProvResult { fun taskInContainer(containerName: String, taskLambda: Prov.() -> ProvResult): ProvResult {
printDeprecationWarningIfLevel0("taskInContainer")
runInContainerWithName = containerName runInContainerWithName = containerName
val res = evaluate(ResultMode.ALL) { taskLambda() } val res = evaluate(ResultMode.ALL) { taskLambda() }
runInContainerWithName = null runInContainerWithName = null
@ -456,6 +462,11 @@ open class Prov protected constructor(
} }
} }
fun printDeprecationWarningIfLevel0(methodName: String) {
if (level == 0) {
println("WARNING: method $methodName should not be used at top-level, use method <session> instead.")
}
}
} }

View file

@ -301,7 +301,9 @@ internal class ProvTest {
// when // when
Prov.newInstance(name = "test instance with no progress info", progressType = ProgressType.NONE) Prov.newInstance(name = "test instance with no progress info", progressType = ProgressType.NONE)
.testMethodForOutputTest_with_mode_requireLast() .session {
testMethodForOutputTest_with_mode_requireLast()
}
// then // then
System.setOut(originalOut) System.setOut(originalOut)
@ -311,13 +313,14 @@ internal class ProvTest {
val expectedOutput = val expectedOutput =
"============================================== SUMMARY (test instance with no progress info) =============================================\n" + "============================================== SUMMARY (test instance with no progress info) =============================================\n" +
"> \u001B[92mSuccess\u001B[0m -- testMethodForOutputTest_with_mode_requireLast (requireLast) \n" + "> \u001B[92mSuccess\u001B[0m -- session \n" +
"---> \u001B[93mFAILED\u001B[0m -- checkPrereq_evaluateToFailure (requireLast) -- Error: This is a test error.\n" + "---> \u001B[92mSuccess\u001B[0m -- testMethodForOutputTest_with_mode_requireLast (requireLast) \n" +
"---> \u001B[92mSuccess\u001B[0m -- sh \n" + "------> \u001B[93mFAILED\u001B[0m -- checkPrereq_evaluateToFailure (requireLast) -- Error: This is a test error.\n" +
"------> \u001B[92mSuccess\u001B[0m -- cmd [/bin/bash, -c, echo -Start test-]\n" + "------> \u001B[92mSuccess\u001B[0m -- sh \n" +
"------> \u001B[92mSuccess\u001B[0m -- cmd [/bin/bash, -c, echo Some output]\n" + "---------> \u001B[92mSuccess\u001B[0m -- cmd [/bin/bash, -c, echo -Start test-]\n" +
"---> \u001B[92mSuccess\u001B[0m -- sh \n" + "---------> \u001B[92mSuccess\u001B[0m -- cmd [/bin/bash, -c, echo Some output]\n" +
"------> \u001B[92mSuccess\u001B[0m -- cmd [/bin/bash, -c, echo -End test-]\n" + "------> \u001B[92mSuccess\u001B[0m -- sh \n" +
"---------> \u001B[92mSuccess\u001B[0m -- cmd [/bin/bash, -c, echo -End test-]\n" +
"----------------------------------------------------------------------------------------------------\n" + "----------------------------------------------------------------------------------------------------\n" +
"Overall > \u001B[92mSuccess\u001B[0m\n" + "Overall > \u001B[92mSuccess\u001B[0m\n" +
"============================================ SUMMARY END ===========================================\n" + "============================================ SUMMARY END ===========================================\n" +
@ -342,8 +345,9 @@ internal class ProvTest {
System.setErr(PrintStream(errContent)) System.setErr(PrintStream(errContent))
// when // when
Prov.newInstance(name = "test instance with no progress info", progressType = ProgressType.NONE) Prov.newInstance(name = "test instance with no progress info", progressType = ProgressType.NONE).session {
.testMethodForOutputTest_nested_with_failure() testMethodForOutputTest_nested_with_failure()
}
// then // then
System.setOut(originalOut) System.setOut(originalOut)
@ -353,11 +357,12 @@ internal class ProvTest {
val expectedOutput = val expectedOutput =
"============================================== SUMMARY (test instance with no progress info) =============================================\n" + "============================================== SUMMARY (test instance with no progress info) =============================================\n" +
"> \u001B[91mFAILED\u001B[0m -- testMethodForOutputTest_nested_with_failure \n" + "> \u001B[91mFAILED\u001B[0m -- session \n" +
"---> \u001B[91mFAILED\u001B[0m -- sub1 \n" + "---> \u001B[91mFAILED\u001B[0m -- testMethodForOutputTest_nested_with_failure \n" +
"------> \u001B[92mSuccess\u001B[0m -- testMethodForOutputTest_nested_with_failure \n" + "------> \u001B[91mFAILED\u001B[0m -- sub1 \n" +
"------> \u001B[91mFAILED\u001B[0m -- <<returned result>> -- Error: Iamanerrormessage\n" + "---------> \u001B[92mSuccess\u001B[0m -- testMethodForOutputTest_nested_with_failure \n" +
"---> \u001B[92mSuccess\u001B[0m -- cmd [/bin/bash, -c, echo -End test-]\n" + "---------> \u001B[91mFAILED\u001B[0m -- <<returned result>> -- Error: Iamanerrormessage\n" +
"------> \u001B[92mSuccess\u001B[0m -- cmd [/bin/bash, -c, echo -End test-]\n" +
"----------------------------------------------------------------------------------------------------\n" + "----------------------------------------------------------------------------------------------------\n" +
"Overall > \u001B[91mFAILED\u001B[0m \n" + "Overall > \u001B[91mFAILED\u001B[0m \n" +
"============================================ SUMMARY END ===========================================\n" + "============================================ SUMMARY END ===========================================\n" +
@ -399,7 +404,8 @@ internal class ProvTest {
println(outContent.toString()) println(outContent.toString())
val expectedOutput = val expectedOutput =
"============================================== SUMMARY (test instance with no progress info) =============================================\n" + "WARNING: method task should not be used at top-level, use method <session> instead.\n" +
"============================================== SUMMARY (test instance with no progress info) =============================================\n" +
"> \u001B[92mSuccess\u001B[0m -- taskA \n" + "> \u001B[92mSuccess\u001B[0m -- taskA \n" +
"---> \u001B[92mSuccess\u001B[0m -- prov_marks_failed_output_yellow_if_optional (optional) \n" + "---> \u001B[92mSuccess\u001B[0m -- prov_marks_failed_output_yellow_if_optional (optional) \n" +
"------> \u001B[93mFAILED\u001B[0m -- taskB \n" + "------> \u001B[93mFAILED\u001B[0m -- taskB \n" +
@ -469,7 +475,8 @@ internal class ProvTest {
println(outContent.toString()) println(outContent.toString())
val expectedOutput = val expectedOutput =
"============================================== SUMMARY (test instance) =============================================\n" + "WARNING: method task should not be used at top-level, use method <session> instead.\n" +
"============================================== SUMMARY (test instance) =============================================\n" +
"> \u001B[92mSuccess\u001B[0m -- TaskB \n" + "> \u001B[92mSuccess\u001B[0m -- TaskB \n" +
"---> \u001B[92mSuccess\u001B[0m -- taskC \n" + "---> \u001B[92mSuccess\u001B[0m -- taskC \n" +
"----------------------------------------------------------------------------------------------------\n" + "----------------------------------------------------------------------------------------------------\n" +
@ -621,9 +628,10 @@ internal class ProvTest {
val prov = Prov.newInstance(name = "test instance with no progress info", progressType = ProgressType.NONE) val prov = Prov.newInstance(name = "test instance with no progress info", progressType = ProgressType.NONE)
// when // when
prov.task { prov.session {
addInfoText("Text1") addInfoText("Text1")
addInfoText("Text2\nwith newline") addInfoText("Text2\nwith newline")
ProvResult(true)
} }
// then // then
@ -634,7 +642,7 @@ internal class ProvTest {
val expectedOutput = val expectedOutput =
"============================================== SUMMARY (test instance with no progress info) =============================================\n" + "============================================== SUMMARY (test instance with no progress info) =============================================\n" +
"> \u001B[92mSuccess\u001B[0m -- infoText_is_printed_correctly \n" + "> \u001B[92mSuccess\u001B[0m -- session \n" +
"+++++++++++++++++++++++++++++++++++ \u001B[94mAdditional information\u001B[0m +++++++++++++++++++++++++++++++++++++++\n" + "+++++++++++++++++++++++++++++++++++ \u001B[94mAdditional information\u001B[0m +++++++++++++++++++++++++++++++++++++++\n" +
"Text1\n" + "Text1\n" +
"Text2\n" + "Text2\n" +
@ -714,7 +722,8 @@ internal class ProvTest {
println(outContent.toString()) println(outContent.toString())
val expectedOutput = val expectedOutput =
"============================================== SUMMARY (test instance with no progress info) =============================================\n" + "WARNING: method taskWithResult should not be used at top-level, use method <session> instead.\n" +
"============================================== SUMMARY (test instance with no progress info) =============================================\n" +
"> \u001B[91mFAILED\u001B[0m -- testMethodForOutputTest_with_returned_results \n" + "> \u001B[91mFAILED\u001B[0m -- testMethodForOutputTest_with_returned_results \n" +
"---> \u001B[91mFAILED\u001B[0m -- sub1 \n" + "---> \u001B[91mFAILED\u001B[0m -- sub1 \n" +
"------> \u001B[92mSuccess\u001B[0m -- sub2a \n" + "------> \u001B[92mSuccess\u001B[0m -- sub2a \n" +
@ -755,6 +764,57 @@ internal class ProvTest {
} }
} }
// then // then
assertEquals("A session can only be created on the top-level and may not be included in another session or task.", exception.message) assertEquals(
"A session can only be created on the top-level and may not be included in another session or task.",
exception.message
)
}
// method for task_warning_for_task_on_top_level_is_in_output
// must be declared outside test task_warning_for_task_on_top_level_is_in_output in order to avoid strange naming in result output
fun Prov.tst_task() = task {
task_returningTrue()
task_returningFalse()
}
@Test
fun task_warning_for_task_on_top_level_is_in_output() {
// given
setRootLoggingLevel(Level.OFF)
val outContent = ByteArrayOutputStream()
val errContent = ByteArrayOutputStream()
val originalOut = System.out
val originalErr = System.err
System.setOut(PrintStream(outContent))
System.setErr(PrintStream(errContent))
// when
Prov.newInstance(name = "test instance with no progress info", progressType = ProgressType.NONE)
.tst_task().success
Prov.newInstance(name = "test instance with no progress info", progressType = ProgressType.NONE)
.tst_task().success // test that also second run gets warning
// then
System.setOut(originalOut)
System.setErr(originalErr)
println(outContent.toString())
val expectedOutputOneRun =
"WARNING: method task should not be used at top-level, use method <session> instead.\n" +
"============================================== SUMMARY (test instance with no progress info) =============================================\n" +
"> \u001B[91mFAILED\u001B[0m -- tst_task \n" +
"---> \u001B[92mSuccess\u001B[0m -- task_returningTrue \n" +
"---> \u001B[91mFAILED\u001B[0m -- task_returningFalse \n" +
"----------------------------------------------------------------------------------------------------\n" +
"Overall > \u001B[91mFAILED\u001B[0m \n" +
"============================================ SUMMARY END ===========================================\n" +
"\n"
val expectedOutputDoubleRun = expectedOutputOneRun + expectedOutputOneRun
assertEquals(expectedOutputDoubleRun, outContent.toString().replace("\r", ""))
} }
} }