add info to ProvResult & rename addProvResult to addResult
This commit is contained in:
parent
75f1521814
commit
f33ce834f9
8 changed files with 107 additions and 58 deletions
.run
doc
src
main/kotlin/org/domaindrivenarchitecture/provs
desktop/infrastructure
framework
test/kotlin/org/domaindrivenarchitecture/provs/framework/core
|
@ -1,6 +1,6 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="test_incl_extensive_container_tests" type="JUnit" factoryName="JUnit">
|
||||
<module name="org.domaindrivenarchitecture.provs.provs.test" />
|
||||
<module name="provs.test" />
|
||||
<option name="PACKAGE_NAME" value="org" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
|
|
|
@ -16,13 +16,14 @@ The success or failure is computed automatically in the following way:
|
|||
|
||||
### Recommended way
|
||||
|
||||
A task can be declared by
|
||||
A task can be declared by
|
||||
|
||||
```kotlin
|
||||
fun Prov.myCustomTask() = task { /* ... code and subtasks come here ... */ }
|
||||
|
||||
// e.g.
|
||||
fun Prov.myEchoTask() = task {
|
||||
cmd("echo hello world!")
|
||||
fun Prov.myEchoTask() = task {
|
||||
cmd("echo hello world!")
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -56,17 +57,18 @@ fun Prov.myCustomTask() {{ task { /* ... code and subtasks come here ... */ } }}
|
|||
|
||||
### Add custom results
|
||||
|
||||
If you want to add a result explicitly, you can use method `addResultToEval`.
|
||||
This maxy be used e.g. to add explicitly an error line, like in:
|
||||
If you want to add a result explicitly, you can use method `addResult`.
|
||||
This may be used e.g. to add explicitly an error line or with additional info, like in:
|
||||
|
||||
```kotlin
|
||||
fun Prov.myCustomTask() = task {
|
||||
/* some other code ... */
|
||||
addResultToEval(ProvResult(false, err = "my error msg"))
|
||||
addResult(false, err = "my error msg")
|
||||
/* some other code ... */
|
||||
addResult(true, info = "package was already installed")
|
||||
}
|
||||
```
|
||||
or alternatively you can use `taskWithResult`.
|
||||
or alternatively you can use `taskWithResult` and `return@taskWithResult ProvResult(false, err = "my error msg")`.
|
||||
|
||||
#### TaskWithResult
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import org.domaindrivenarchitecture.provs.framework.core.ProvResult
|
|||
fun Prov.installShadowCljs(): ProvResult = task {
|
||||
|
||||
if (!chk(". .nvm/nvm.sh")) {
|
||||
addProvResult(false, err = "nvm not installed!")
|
||||
addResult(false, err = "nvm not installed!")
|
||||
} else {
|
||||
if (!chk("npm list -g --depth=0 | grep shadow-cljs")) {
|
||||
cmd(". .nvm/nvm.sh && npm install -g shadow-cljs")
|
||||
|
|
|
@ -217,12 +217,12 @@ open class Prov protected constructor(
|
|||
fun getSecret(command: String, removeNewlineSuffix: Boolean = false): Secret? {
|
||||
val result = cmdNoLog(command)
|
||||
return if (result.success && result.out != null) {
|
||||
addProvResult(true, getCallingMethodName())
|
||||
addResult(true, getCallingMethodName())
|
||||
val plainSecret =
|
||||
if (removeNewlineSuffix && result.out.takeLast(1) == "\n") result.out.dropLast(1) else result.out
|
||||
Secret(plainSecret)
|
||||
} else {
|
||||
addProvResult(false, getCallingMethodName(), err = result.err, exception = result.exception)
|
||||
addResult(false, getCallingMethodName(), err = result.err, exception = result.exception)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ open class Prov protected constructor(
|
|||
* Adds a ProvResult to the overall success evaluation.
|
||||
* Intended for use in methods which do not automatically add results.
|
||||
*/
|
||||
@Deprecated("since 0.39.7", replaceWith = ReplaceWith("addProvResult", ))
|
||||
@Deprecated("since 0.39.7", replaceWith = ReplaceWith("addResult", ))
|
||||
fun addResultToEval(result: ProvResult) = taskWithResult {
|
||||
result
|
||||
}
|
||||
|
@ -241,15 +241,16 @@ open class Prov protected constructor(
|
|||
* Adds a ProvResult to the overall success evaluation.
|
||||
* Intended for use in methods which do not automatically add results.
|
||||
*/
|
||||
fun addProvResult(
|
||||
fun addResult(
|
||||
success: Boolean,
|
||||
cmd: String? = null,
|
||||
out: String? = null,
|
||||
err: String? = null,
|
||||
exception: Exception? = null,
|
||||
exit: String? = null
|
||||
exit: String? = null,
|
||||
info: String? = null,
|
||||
) = taskWithResult {
|
||||
ProvResult(success, cmd, out, err, exception, exit)
|
||||
ProvResult(success, cmd, out, err, exception, exit, info)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -272,6 +273,9 @@ open class Prov protected constructor(
|
|||
ProvResult(success)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given text, which will be printed at the very end, after all tasks were executed.
|
||||
*/
|
||||
fun addInfoText(text: String) {
|
||||
infoTexts.add(text)
|
||||
}
|
||||
|
@ -492,14 +496,17 @@ open class Prov protected constructor(
|
|||
|
||||
internal data class ResultLine(val level: Int, val method: String?, var provResult: ProvResult?) {
|
||||
override fun toString(): String {
|
||||
val provResult = provResult
|
||||
return if (provResult != null) {
|
||||
prefix(level) + (if (provResult.success) "Success -- " else "FAILED -- ") +
|
||||
method + " " + (provResult.cmd ?: "") +
|
||||
(if (!provResult.success && provResult.err != null) " -- Error: " + provResult.err.escapeControlChars() else "")
|
||||
} else
|
||||
prefix(level) + method + " " + "... in progress ... "
|
||||
val result = provResult
|
||||
if (result != null) {
|
||||
val status = if (result.success) "Success -- " else "FAILED -- "
|
||||
val taskName = method + " " + (result.cmd ?: "")
|
||||
val infoText = if (result.info != null) "-- Info: " + result.info.escapeControlChars() + " " else ""
|
||||
val errorText = if (!result.success && result.err != null) "-- Error: " + result.err.escapeControlChars() else ""
|
||||
|
||||
return prefix(level) + status + taskName + infoText + errorText
|
||||
} else {
|
||||
return prefix(level) + method + " " + "... in progress ... "
|
||||
}
|
||||
}
|
||||
|
||||
fun inProgress(): String {
|
||||
|
|
|
@ -1,28 +1,26 @@
|
|||
package org.domaindrivenarchitecture.provs.framework.core
|
||||
|
||||
|
||||
data class ProvResult(val success: Boolean,
|
||||
val cmd: String? = null,
|
||||
val out: String? = null,
|
||||
val err: String? = null,
|
||||
val exception: Exception? = null,
|
||||
val exit: String? = null) {
|
||||
data class ProvResult(
|
||||
val success: Boolean,
|
||||
val cmd: String? = null,
|
||||
val out: String? = null,
|
||||
val err: String? = null,
|
||||
val exception: Exception? = null,
|
||||
val exit: String? = null,
|
||||
val info: String? = null,
|
||||
) {
|
||||
|
||||
val outTrimmed: String? = out?.trim()
|
||||
|
||||
constructor(returnCode : Int) : this(returnCode == 0)
|
||||
constructor(returnCode: Int) : this(returnCode == 0)
|
||||
|
||||
override fun toString(): String {
|
||||
return "ProvResult:: ${if (success) "Succeeded" else "FAILED"} -- ${if (!cmd.isNullOrEmpty()) "Name: " +
|
||||
cmd.escapeNewline() + ", " else ""}${if (!out.isNullOrEmpty()) "Details: $out" else ""}" +
|
||||
|
||||
return "ProvResult:: ${if (success) "Succeeded" else "FAILED"} -- ${
|
||||
if (!cmd.isNullOrEmpty()) "Name: " +
|
||||
cmd.escapeNewline() + ", " else ""
|
||||
}${if (!out.isNullOrEmpty()) "Details: $out" else ""}" +
|
||||
(exception?.run { " Exception: " + toString() } ?: "")
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun toShortString() : String {
|
||||
return "ProvResult:: ${if (success) "Succeeded" else "FAILED"} -- " +
|
||||
if (!success)
|
||||
(if (out != null) "Details: $out " else "" +
|
||||
if (err != null) " Error: " + err else "") else ""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.domaindrivenarchitecture.provs.framework.ubuntu.scheduledjobs.infrastructure
|
||||
|
||||
import org.domaindrivenarchitecture.provs.framework.core.Prov
|
||||
import org.domaindrivenarchitecture.provs.framework.core.ProvResult
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.checkFile
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createDirs
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createFile
|
||||
|
@ -24,6 +23,6 @@ fun Prov.createCronJob(cronFilename: String, schedule: String, command: String,
|
|||
createDirs("/etc/cron.d/", sudo = true)
|
||||
createFile("/etc/cron.d/$cronFilename", cronLine, "644", sudo = true, overwriteIfExisting = true)
|
||||
} else {
|
||||
addResultToEval(ProvResult(false, err = "$command not found."))
|
||||
addResult(false, err = "$command not found.")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -316,7 +316,7 @@ internal class ProvTest {
|
|||
"============================================== SUMMARY (test instance with no progress info) =============================================\n" +
|
||||
"> \u001B[92mSuccess\u001B[0m -- session \n" +
|
||||
"---> \u001B[92mSuccess\u001B[0m -- testMethodForOutputTest_with_mode_requireLast (requireLast) \n" +
|
||||
"------> \u001B[93mFAILED\u001B[0m -- checkPrereq_evaluateToFailure (requireLast) -- Error: This is a test error.\n" +
|
||||
"------> \u001B[93mFAILED\u001B[0m -- checkPrereq_evaluateToFailure (requireLast) -- Error: This is a test error.\n" +
|
||||
"------> \u001B[92mSuccess\u001B[0m -- sh \n" +
|
||||
"---------> \u001B[92mSuccess\u001B[0m -- cmd [echo -Start test-]\n" +
|
||||
"---------> \u001B[92mSuccess\u001B[0m -- cmd [echo Some output]\n" +
|
||||
|
@ -362,7 +362,7 @@ internal class ProvTest {
|
|||
"---> \u001B[91mFAILED\u001B[0m -- testMethodForOutputTest_nested_with_failure \n" +
|
||||
"------> \u001B[91mFAILED\u001B[0m -- sub1 \n" +
|
||||
"---------> \u001B[92mSuccess\u001B[0m -- testMethodForOutputTest_nested_with_failure \n" +
|
||||
"---------> \u001B[91mFAILED\u001B[0m -- sub1 (returned result) -- Error: Iamanerrormessage\n" +
|
||||
"---------> \u001B[91mFAILED\u001B[0m -- sub1 (returned result) -- Error: Iamanerrormessage\n" +
|
||||
"------> \u001B[92mSuccess\u001B[0m -- cmd [echo -End test-]\n" +
|
||||
"----------------------------------------------------------------------------------------------------\n" +
|
||||
"Overall > \u001B[91mFAILED\u001B[0m \n" +
|
||||
|
@ -418,6 +418,51 @@ internal class ProvTest {
|
|||
assertEquals(expectedOutput, outContent.toString().replace("\r", ""))
|
||||
}
|
||||
|
||||
@Test
|
||||
@NonCi
|
||||
fun prov_prints_info_text_correctly() {
|
||||
|
||||
// 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).task("taskA") {
|
||||
taskWithResult("taskB") {
|
||||
addResult(true, info = "Package A always was already installed.")
|
||||
addResult(true, info = "Package B always was already installed.")
|
||||
}
|
||||
addResult(false, err = "Package C was missing", info = "Pls install package C.")
|
||||
}
|
||||
|
||||
// then
|
||||
System.setOut(originalOut)
|
||||
System.setErr(originalErr)
|
||||
|
||||
println(outContent.toString())
|
||||
|
||||
val expectedOutput =
|
||||
"============================================== SUMMARY (test instance with no progress info) =============================================\n" +
|
||||
"> \u001B[91mFAILED\u001B[0m -- taskA \n" +
|
||||
"---> \u001B[92mSuccess\u001B[0m -- taskB \n" +
|
||||
"------> \u001B[92mSuccess\u001B[0m -- addResult -- Info: Package A always was already installed. \n" +
|
||||
"------> \u001B[92mSuccess\u001B[0m -- addResult -- Info: Package B always was already installed. \n" +
|
||||
"---> \u001B[91mFAILED\u001B[0m -- addResult -- Info: Pls install package C. -- Error: Package C was missing\n" +
|
||||
"----------------------------------------------------------------------------------------------------\n" +
|
||||
"Overall > \u001B[91mFAILED\u001B[0m \n" +
|
||||
"============================================ SUMMARY END ===========================================\n" +
|
||||
"\n"
|
||||
|
||||
assertEquals(expectedOutput, outContent.toString().replace("\r", ""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun chk_returnsTrue() {
|
||||
// when
|
||||
|
@ -490,7 +535,7 @@ internal class ProvTest {
|
|||
fun addResultToEval_success() {
|
||||
// given
|
||||
fun Prov.inner() {
|
||||
addResultToEval(ProvResult(true))
|
||||
addResult(true)
|
||||
}
|
||||
|
||||
fun Prov.outer() = task {
|
||||
|
@ -509,7 +554,7 @@ internal class ProvTest {
|
|||
fun task_with_subtask_and_failed_result_fails() {
|
||||
// given
|
||||
fun Prov.inner() {
|
||||
addResultToEval(ProvResult(true))
|
||||
addResult(true)
|
||||
}
|
||||
|
||||
fun Prov.outer() = taskWithResult {
|
||||
|
@ -547,7 +592,7 @@ internal class ProvTest {
|
|||
fun addResultToEval_failure() {
|
||||
// given
|
||||
fun Prov.inner() {
|
||||
addResultToEval(ProvResult(false))
|
||||
addResult(false)
|
||||
}
|
||||
|
||||
fun Prov.outer() = taskWithResult {
|
||||
|
@ -665,11 +710,9 @@ internal class ProvTest {
|
|||
}
|
||||
optional("sub2c-optional") {
|
||||
taskWithResult("sub3a-taskWithResult") {
|
||||
addResultToEval(
|
||||
ProvResult(
|
||||
false,
|
||||
err = "returned-result - error msg B should be once in output - in addResultToEval"
|
||||
)
|
||||
addResult(
|
||||
false,
|
||||
err = "returned-result - error msg B should be once in output - in addResult"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -679,7 +722,7 @@ internal class ProvTest {
|
|||
}
|
||||
}
|
||||
task("sub2e-task") {
|
||||
addResultToEval(ProvResult(true))
|
||||
addResult(true)
|
||||
ProvResult(
|
||||
false,
|
||||
err = "error should NOT be in output as results of task (not taskWithResult) are ignored"
|
||||
|
@ -725,16 +768,16 @@ internal class ProvTest {
|
|||
"> \u001B[91mFAILED\u001B[0m -- testMethodForOutputTest_with_returned_results \n" +
|
||||
"---> \u001B[91mFAILED\u001B[0m -- sub1 \n" +
|
||||
"------> \u001B[92mSuccess\u001B[0m -- sub2a \n" +
|
||||
"------> \u001B[91mFAILED\u001B[0m -- sub2b -- Error: error msg A for sub2b should be shown as result of sub2b\n" +
|
||||
"------> \u001B[91mFAILED\u001B[0m -- sub2b -- Error: error msg A for sub2b should be shown as result of sub2b\n" +
|
||||
"------> \u001B[92mSuccess\u001B[0m -- sub2c-optional \n" +
|
||||
"---------> \u001B[93mFAILED\u001B[0m -- sub3a-taskWithResult \n" +
|
||||
"------------> \u001B[93mFAILED\u001B[0m -- addResultToEval -- Error: returned-result - error msg B should be once in output - in addResultToEval\n" +
|
||||
"------------> \u001B[93mFAILED\u001B[0m -- addResult -- Error: returned-result - error msg B should be once in output - in addResult\n" +
|
||||
"------> \u001B[91mFAILED\u001B[0m -- sub2d-requireLast \n" +
|
||||
"---------> \u001B[91mFAILED\u001B[0m -- sub3b-taskWithResult without error message \n" +
|
||||
"------> \u001B[92mSuccess\u001B[0m -- sub2e-task \n" +
|
||||
"---------> \u001B[92mSuccess\u001B[0m -- addResultToEval \n" +
|
||||
"------> \u001B[91mFAILED\u001B[0m -- sub2f-taskWithResult -- Error: returned-result - error msg C should be once in output - at the end of sub3taskWithResult \n" +
|
||||
"------> \u001B[91mFAILED\u001B[0m -- sub1 (returned result) -- Error: returned-result - error msg D should be once in output - at the end of sub1 \n" +
|
||||
"---------> \u001B[92mSuccess\u001B[0m -- addResult \n" +
|
||||
"------> \u001B[91mFAILED\u001B[0m -- sub2f-taskWithResult -- Error: returned-result - error msg C should be once in output - at the end of sub3taskWithResult \n" +
|
||||
"------> \u001B[91mFAILED\u001B[0m -- sub1 (returned result) -- Error: returned-result - error msg D should be once in output - at the end of sub1 \n" +
|
||||
"----------------------------------------------------------------------------------------------------\n" +
|
||||
"Overall > \u001B[91mFAILED\u001B[0m \n" +
|
||||
"============================================ SUMMARY END ===========================================\n" +
|
||||
|
|
|
@ -18,7 +18,7 @@ internal class UbuntuHostDockerKtTest {
|
|||
val containerName = "testContainer"
|
||||
val result = testLocal().task {
|
||||
runContainer(containerName)
|
||||
addResultToEval(ProvResult(containerRuns(containerName)))
|
||||
addResult(containerRuns(containerName))
|
||||
|
||||
exitAndRmContainer(containerName)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue