From 122fa68850d3bf3994ef6c6f8a66cc25f6cbcc2f Mon Sep 17 00:00:00 2001 From: ansgarz Date: Sat, 15 May 2021 19:33:56 +0200 Subject: [PATCH] make progress info level configurable --- build.gradle | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- src/main/kotlin/io/provs/Prov.kt | 211 ++++++++++++------ .../io/provs/{Results.kt => ProvResult.kt} | 8 - .../docker/platforms/UbuntuHostDocker.kt | 11 +- .../kotlin/io/provs/platforms/UbuntuProv.kt | 6 +- src/main/kotlin/io/provs/platforms/WinProv.kt | 4 +- .../ContainerUbuntuHostProcessor.kt | 3 +- .../io/provs/processors/PrintOnlyProcessor.kt | 1 + src/main/resources/logback.xml | 16 +- src/test/kotlin/io/provs/ProvTest.kt | 44 ++-- .../platforms/UbuntuHostDockerKtTest.kt | 4 +- src/test/kotlin/io/provs/entry/EntryTest.kt | 4 +- .../io/provs/platformTest/UbuntuProvTests.kt | 17 +- .../io/provs/platformTest/WinProvTests.kt | 11 +- .../ContainerUbuntuHostProcessorTest.kt | 12 +- .../kotlin/io/provs/test/TestSetup.kt | 11 +- 17 files changed, 236 insertions(+), 133 deletions(-) rename src/main/kotlin/io/provs/{Results.kt => ProvResult.kt} (75%) diff --git a/build.gradle b/build.gradle index 7944d8b..8e70e04 100644 --- a/build.gradle +++ b/build.gradle @@ -10,11 +10,12 @@ buildscript { } apply plugin: 'org.jetbrains.kotlin.jvm' +apply plugin: 'java-library' apply plugin: 'java-test-fixtures' apply plugin: 'maven-publish' group = 'io.provs' -version = '0.8.10-SNAPSHOT' +version = '0.8.11-SNAPSHOT' repositories { mavenCentral() @@ -38,6 +39,7 @@ test { } compileJava.options.debugOptions.debugLevel = "source,lines,vars" +compileTestFixturesJava.options.debugOptions.debugLevel = "source,lines,vars" compileTestJava.options.debugOptions.debugLevel = "source,lines,vars" sourceCompatibility = 1.11 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2a56324..0f80bbf 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/kotlin/io/provs/Prov.kt b/src/main/kotlin/io/provs/Prov.kt index cbfe113..e5e19aa 100644 --- a/src/main/kotlin/io/provs/Prov.kt +++ b/src/main/kotlin/io/provs/Prov.kt @@ -5,68 +5,103 @@ import io.provs.platforms.UbuntuProv import io.provs.platforms.WinProv import io.provs.processors.LocalProcessor import io.provs.processors.Processor +import org.slf4j.LoggerFactory + +enum class ProgressType { NONE, DOTS, BASIC, FULL_LOG } enum class ResultMode { NONE, LAST, ALL, FAILEXIT } enum class OS { WINDOWS, LINUX } /** - * This main class offers methods to execute shell commands either locally or remotely (via ssh) or in a docker + * This main class offers methods to execute shell commands. + * The commands are executed locally, remotely (via ssh) or in a docker container * depending on the processor which is passed to the constructor. */ -open class Prov protected constructor(private val processor: Processor, val name: String? = null) { +open class Prov protected constructor( + private val processor: Processor, + val name: String? = null, + private val progressType: ProgressType = ProgressType.BASIC +) { + init { + if (progressType == ProgressType.FULL_LOG) { + val log = LoggerFactory.getILoggerFactory() + .getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME) as (ch.qos.logback.classic.Logger) + log.level = ch.qos.logback.classic.Level.INFO + } + } companion object Factory { - lateinit var prov: Prov + private lateinit var defaultProvInstance: Prov fun defaultInstance(platform: String? = null): Prov { - return if (::prov.isInitialized) { - prov + return if (::defaultProvInstance.isInitialized) { + defaultProvInstance } else { - prov = newInstance(platform = platform, name = "default instance") - prov + defaultProvInstance = newInstance(platform = platform, name = "default instance") + defaultProvInstance } } - fun newInstance(processor: Processor = LocalProcessor(), platform: String? = null, name: String? = null): Prov { + fun newInstance( + processor: Processor = LocalProcessor(), + platform: String? = null, + name: String? = null, + progressType: ProgressType = ProgressType.BASIC + ): Prov { val os = platform ?: System.getProperty("os.name") return when { - os.toUpperCase().contains(OS.LINUX.name) -> UbuntuProv(processor, name) - os.toUpperCase().contains(OS.WINDOWS.name) -> WinProv(processor, name) + os.toUpperCase().contains(OS.LINUX.name) -> UbuntuProv(processor, name, progressType) + os.toUpperCase().contains(OS.WINDOWS.name) -> WinProv(processor, name, progressType) else -> throw Exception("OS not supported") } } } - private val internalResults = arrayListOf() + + private val internalResults = arrayListOf() private var level = 0 private var previousLevel = 0 private var exit = false private var runInContainerWithName: String? = null - - // task defining functions + /** + * defines a task with default success behavior, i.e. returns success if all subtasks finished with success. + * Same as requireAll. + */ fun def(a: Prov.() -> ProvResult): ProvResult { return handle(ResultMode.ALL) { a() } } + /** + * defines a task, which returns success if the the last subtasks or last value returns success + */ fun requireLast(a: Prov.() -> ProvResult): ProvResult { return handle(ResultMode.LAST) { a() } } + /** + * defines a task, which always returns success + */ fun optional(a: Prov.() -> ProvResult): ProvResult { return handle(ResultMode.NONE) { a() } } + /** + * defines a task, which returns success if all subtasks finished with success + */ fun requireAll(a: Prov.() -> ProvResult): ProvResult { return handle(ResultMode.ALL) { a() } } + /** + * defines a task, which exits the overall execution on failure + */ fun exitOnFailure(a: Prov.() -> ProvResult): ProvResult { return handle(ResultMode.FAILEXIT) { a() } } @@ -80,7 +115,9 @@ open class Prov protected constructor(private val processor: Processor, val name } - // execute programs + /** + * execute program with parameters + */ fun xec(vararg s: String): ProvResult { val cmd = runInContainerWithName?.let { cmdInContainer(it, *s) } ?: s val result = processor.x(*cmd) @@ -92,6 +129,9 @@ open class Prov protected constructor(private val processor: Processor, val name ) } + /** + * execute program with parameters without logging (to be used if secrets are involved) + */ fun xecNoLog(vararg s: String): ProvResult { val cmd = runInContainerWithName?.let { cmdInContainer(it, *s) } ?: s val result = processor.xNoLog(*cmd) @@ -103,19 +143,6 @@ open class Prov protected constructor(private val processor: Processor, val name ) } - private fun cmdInContainer(containerName: String, vararg args: String): Array { - return arrayOf(SHELL, "-c", "sudo docker exec $containerName " + buildCommand(*args)) - } - private fun buildCommand(vararg args: String) : String { - return if (args.size == 1) - args[0].escapeAndEncloseByDoubleQuoteForShell() - else - if (args.size == 3 && SHELL.equals(args[0]) && "-c".equals(args[1])) - SHELL + " -c " + args[2].escapeAndEncloseByDoubleQuoteForShell() - else - args.joinToString(separator = " ") - } - /** * Executes a command by using the shell. @@ -172,7 +199,7 @@ open class Prov protected constructor(private val processor: Processor, val name /** - * Adds an ProvResult to the overall success evaluation. + * Adds a ProvResult to the overall success evaluation. * Intended for use in methods which do not automatically add results. */ fun addResultToEval(result: ProvResult) = requireAll { @@ -200,6 +227,22 @@ open class Prov protected constructor(private val processor: Processor, val name } + // todo: put logic in subclasses, such as UbuntuProv + private fun cmdInContainer(containerName: String, vararg args: String): Array { + return arrayOf(SHELL, "-c", "sudo docker exec $containerName " + buildCommand(*args)) + } + + private fun buildCommand(vararg args: String): String { + return if (args.size == 1) + args[0].escapeAndEncloseByDoubleQuoteForShell() + else + if (args.size == 3 && SHELL.equals(args[0]) && "-c".equals(args[1])) + SHELL + " -c " + args[2].escapeAndEncloseByDoubleQuoteForShell() + else + args.joinToString(separator = " ") + } + + /** * Provides result handling, e.g. gather results for result summary */ @@ -210,13 +253,14 @@ open class Prov protected constructor(private val processor: Processor, val name internalResults.clear() previousLevel = -1 exit = false - ProgressBar.init() + initProgress() } // pre-handling val resultIndex = internalResults.size val method = getCallingMethodName() - internalResults.add(InternalResult(level, method, null)) + val internalResult = ResultLine(level, method, null) + internalResults.add(internalResult) previousLevel = level @@ -224,7 +268,7 @@ open class Prov protected constructor(private val processor: Processor, val name // call the actual function val res = if (!exit) { - ProgressBar.progress() + progress(internalResult) @Suppress("UNUSED_EXPRESSION") // false positive a() } else { @@ -261,7 +305,7 @@ open class Prov protected constructor(private val processor: Processor, val name internalResults[resultIndex].provResult = returnValue if (level == 0) { - ProgressBar.end() + endProgress() processor.close() printResults() } @@ -270,16 +314,16 @@ open class Prov protected constructor(private val processor: Processor, val name } - private fun internalResultIsLeaf(resultIndex: Int) : Boolean { + private fun internalResultIsLeaf(resultIndex: Int): Boolean { return !(resultIndex < internalResults.size - 1 && internalResults[resultIndex + 1].level > internalResults[resultIndex].level) } - private fun cumulativeSuccessSublevel(resultIndex: Int) : Boolean? { + private fun cumulativeSuccessSublevel(resultIndex: Int): Boolean? { val currentLevel = internalResults[resultIndex].level - var res : Boolean? = null + var res: Boolean? = null var i = resultIndex + 1 - while ( i < internalResults.size && internalResults[i].level > currentLevel) { + while (i < internalResults.size && internalResults[i].level > currentLevel) { if (internalResults[i].level == currentLevel + 1) { res = if (res == null) internalResults[i].provResult?.success else res && (internalResults[i].provResult?.success @@ -291,23 +335,6 @@ open class Prov protected constructor(private val processor: Processor, val name } - private data class InternalResult(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.escapeNewline() else "") - } else - prefix(level) + " " + method + " " + "... in progress ... " - - } - - private fun prefix(level: Int): String { - return "---".repeat(level) + "> " - } - } - private val ANSI_RESET = "\u001B[0m" private val ANSI_BRIGHT_RED = "\u001B[91m" private val ANSI_BRIGHT_GREEN = "\u001B[92m" @@ -320,15 +347,17 @@ open class Prov protected constructor(private val processor: Processor, val name // val ANSI_PURPLE = "\u001B[35m" // val ANSI_CYAN = "\u001B[36m" // val ANSI_WHITE = "\u001B[37m" - // val ANSI_GRAY = "\u001B[90m" + val ANSI_GRAY = "\u001B[90m" private fun printResults() { - println("============================================== SUMMARY " + (if (name != null) "(" + name + ") " else "") + - "============================================== ") + println( + "============================================== SUMMARY " + (if (name != null) "(" + name + ") " else "") + + "============================================== " + ) for (result in internalResults) { println( - result.toString().escapeNewline(). - replace("Success --", ANSI_BRIGHT_GREEN + "Success" + ANSI_RESET + " --") + result.toString().escapeNewline() + .replace("Success --", ANSI_BRIGHT_GREEN + "Success" + ANSI_RESET + " --") .replace("FAILED --", ANSI_BRIGHT_RED + "FAILED" + ANSI_RESET + " --") ) } @@ -342,20 +371,70 @@ open class Prov protected constructor(private val processor: Processor, val name } println("============================================ SUMMARY END ============================================ " + newline()) } + + private fun String.formattedAsResultLine(): String = this + .replace("Success", ANSI_BRIGHT_GREEN + "Success" + ANSI_RESET) + .replace("FAILED", ANSI_BRIGHT_RED + "FAILED" + ANSI_RESET) + .replace("executing...", ANSI_GRAY + "executing..." + ANSI_RESET) + + + private fun initProgress() { + if ((progressType == ProgressType.DOTS) || (progressType == ProgressType.BASIC)) { + println("---------- Processing started ----------") + System.out.flush() + } + } + + private fun progress(line: ResultLine) { + if (progressType == ProgressType.DOTS) { + print(".") + System.out.flush() + } else if (progressType == ProgressType.BASIC) { + val shortLine = line.inProgress() + if (!shortLine.endsWith("cmd") && !shortLine.endsWith("sh")) { + println(shortLine.formattedAsResultLine()) + System.out.flush() + } + } + } + + private fun endProgress() { + if ((progressType == ProgressType.DOTS) || (progressType == ProgressType.BASIC)) { + println("---------- Processing completed ----------") + } + } + } -private object ProgressBar { - fun init() { - print("Processing started ...\n") +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.escapeNewline() else "") + } else + prefix(level) + method + " " + "... in progress ... " + + } + + fun inProgress(): String { + return prefix(level) + "executing... -- " + method } - fun progress() { - print(".") - System.out.flush() + private fun prefix(level: Int): String { + return "---".repeat(level) + "> " } +} + +fun Prov.myfu() = def { + cmd("echo asdf222") +} +fun main() { - fun end() { - println("processing completed.") + local().def { + cmd("echo asdfasdf") + myfu() } } \ No newline at end of file diff --git a/src/main/kotlin/io/provs/Results.kt b/src/main/kotlin/io/provs/ProvResult.kt similarity index 75% rename from src/main/kotlin/io/provs/Results.kt rename to src/main/kotlin/io/provs/ProvResult.kt index ebc9e7a..56837b3 100644 --- a/src/main/kotlin/io/provs/Results.kt +++ b/src/main/kotlin/io/provs/ProvResult.kt @@ -23,11 +23,3 @@ data class ProvResult(val success: Boolean, if (err != null) " Error: " + err else "") else "" } } - - -@Suppress("unused") // might be used by custom methods -data class TypedResult(val success: Boolean, val resultObject: T? = null) { - override fun toString(): String { - return "TypedResult:: ${if (success) "Succeeded" else "FAILED"} -- Result object: " + resultObject?.run { toString().escapeNewline() } - } -} diff --git a/src/main/kotlin/io/provs/docker/platforms/UbuntuHostDocker.kt b/src/main/kotlin/io/provs/docker/platforms/UbuntuHostDocker.kt index 7c206e2..53ef4f3 100644 --- a/src/main/kotlin/io/provs/docker/platforms/UbuntuHostDocker.kt +++ b/src/main/kotlin/io/provs/docker/platforms/UbuntuHostDocker.kt @@ -28,10 +28,11 @@ fun UbuntuProv.provideContainerPlatform( throw RuntimeException("could not start docker") } } else if (startMode == ContainerStartMode.USE_RUNNING_ELSE_CREATE) { - val r = - cmd(dockerCmd + "inspect -f '{{.State.Running}}' $containerName") - if (!r.success || "false\n" == r.out) { - cmd(dockerCmd + "rm -f $containerName") + val runCheckResult = cmdNoEval(dockerCmd + "inspect -f '{{.State.Running}}' $containerName") + + // if either container not found or container found but not running + if (!runCheckResult.success || "false\n" == runCheckResult.out) { + cmdNoEval(dockerCmd + "rm -f $containerName") cmd(dockerCmd + "run -dit --name=$containerName $imageName") } } @@ -83,7 +84,7 @@ fun UbuntuProv.dockerProvideImagePlatform(image: DockerImage, skipIfExisting: Bo fun UbuntuProv.dockerImageExistsPlatform(imageName: String, sudo: Boolean): Boolean { val dockerCmd = if (sudo) "sudo docker " else "docker " - return (cmd(dockerCmd + "images $imageName -q").out != "") + return (cmdNoEval(dockerCmd + "images $imageName -q").out != "") } diff --git a/src/main/kotlin/io/provs/platforms/UbuntuProv.kt b/src/main/kotlin/io/provs/platforms/UbuntuProv.kt index 1b3dddf..514afbc 100644 --- a/src/main/kotlin/io/provs/platforms/UbuntuProv.kt +++ b/src/main/kotlin/io/provs/platforms/UbuntuProv.kt @@ -1,15 +1,17 @@ package io.provs.platforms +import io.provs.ProgressType import io.provs.Prov import io.provs.ProvResult import io.provs.escapeAndEncloseByDoubleQuoteForShell import io.provs.processors.LocalProcessor import io.provs.processors.Processor -const val SHELL = "/bin/bash" // could be changed to another shell like "sh", "/bin/csh" if required +const val SHELL = "/bin/bash" -class UbuntuProv internal constructor(processor : Processor = LocalProcessor(), name: String? = null) : Prov (processor, name) { +class UbuntuProv internal constructor(processor : Processor = LocalProcessor(), name: String? = null, progressType: ProgressType) + : Prov (processor, name, progressType) { override fun cmd(cmd: String, dir: String?, sudo: Boolean) : ProvResult = def { xec(SHELL, "-c", commandWithDirAndSudo(cmd, dir, sudo)) diff --git a/src/main/kotlin/io/provs/platforms/WinProv.kt b/src/main/kotlin/io/provs/platforms/WinProv.kt index 628cf66..7a87201 100644 --- a/src/main/kotlin/io/provs/platforms/WinProv.kt +++ b/src/main/kotlin/io/provs/platforms/WinProv.kt @@ -1,12 +1,14 @@ package io.provs.platforms +import io.provs.ProgressType import io.provs.Prov import io.provs.ProvResult import io.provs.processors.LocalProcessor import io.provs.processors.Processor -class WinProv internal constructor(processor : Processor = LocalProcessor(), name: String? = null) : Prov (processor, name) { +class WinProv internal constructor(processor : Processor = LocalProcessor(), name: String? = null, progressType: ProgressType) + : Prov (processor, name, progressType) { private val SHELL = "cmd.exe" diff --git a/src/main/kotlin/io/provs/processors/ContainerUbuntuHostProcessor.kt b/src/main/kotlin/io/provs/processors/ContainerUbuntuHostProcessor.kt index 8d39005..425fc97 100644 --- a/src/main/kotlin/io/provs/processors/ContainerUbuntuHostProcessor.kt +++ b/src/main/kotlin/io/provs/processors/ContainerUbuntuHostProcessor.kt @@ -1,5 +1,6 @@ package io.provs.processors +import io.provs.ProgressType import io.provs.Prov import io.provs.docker.provideContainer import io.provs.escapeAndEncloseByDoubleQuoteForShell @@ -28,7 +29,7 @@ open class ContainerUbuntuHostProcessor( ) : Processor { private val dockerCmd = if (sudo) "sudo docker " else "docker " private var localExecution = LocalProcessor() - private var a = Prov.newInstance(name = "LocalProcessor for Docker operations") + private var a = Prov.newInstance(name = "LocalProcessor for Docker operations", progressType = ProgressType.NONE) init { val r = a.provideContainer(containerName, dockerImage, startMode, sudo) diff --git a/src/main/kotlin/io/provs/processors/PrintOnlyProcessor.kt b/src/main/kotlin/io/provs/processors/PrintOnlyProcessor.kt index 4a6fb2c..27638d6 100644 --- a/src/main/kotlin/io/provs/processors/PrintOnlyProcessor.kt +++ b/src/main/kotlin/io/provs/processors/PrintOnlyProcessor.kt @@ -1,6 +1,7 @@ package io.provs.processors +@Suppress("unused") // used externally class PrintOnlyProcessor : Processor { override fun x(vararg args: String): ProcessResult diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index eed0f3f..2dd0fdb 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -12,6 +12,16 @@ + + System.out + + DEBUG + + + %d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{35}) - %msg %n + + + ./logs/provs-${byTime}.log @@ -31,9 +41,13 @@ - + + + + + \ No newline at end of file diff --git a/src/test/kotlin/io/provs/ProvTest.kt b/src/test/kotlin/io/provs/ProvTest.kt index 8a79536..4f3c748 100644 --- a/src/test/kotlin/io/provs/ProvTest.kt +++ b/src/test/kotlin/io/provs/ProvTest.kt @@ -3,6 +3,7 @@ package io.provs import io.provs.docker.provideContainer import io.provs.test.tags.ContainerTest import io.provs.test.tags.NonCi +import io.provs.test.testLocal import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test @@ -115,7 +116,7 @@ internal class ProvTest { } // when - val res = Prov.defaultInstance().tst_def().success + val res = testLocal().tst_def().success // then assert(res) @@ -130,7 +131,7 @@ internal class ProvTest { } // when - val res = Prov.defaultInstance().tst_def().success + val res = testLocal().tst_def().success // then assert(res) @@ -145,7 +146,7 @@ internal class ProvTest { } // when - val res = Prov.defaultInstance().tst_def().success + val res = testLocal().tst_def().success // then assert(!res) @@ -160,7 +161,7 @@ internal class ProvTest { } // when - val res = Prov.defaultInstance().tst_def_all_true_mode_ALL().success + val res = testLocal().tst_def_all_true_mode_ALL().success // then assert(res) @@ -176,7 +177,7 @@ internal class ProvTest { @Test fun def_modeALL_resultFalse() { // when - val res = Prov.defaultInstance().tst_def_one_false_mode_ALL().success + val res = testLocal().tst_def_one_false_mode_ALL().success // then assert(!res) @@ -198,7 +199,7 @@ internal class ProvTest { @Test fun def_modeALLnested_resultFalse() { // when - val res = Prov.defaultInstance().tst_def_one_false_mode_ALL_nested().success + val res = testLocal().tst_def_one_false_mode_ALL_nested().success // then assert(!res) @@ -218,7 +219,7 @@ internal class ProvTest { } // when - val res = Prov.defaultInstance().tst_def_one_false_mode_ALL().success + val res = testLocal().tst_def_one_false_mode_ALL().success // then assert(!res) @@ -238,7 +239,7 @@ internal class ProvTest { } // when - val res = Prov.defaultInstance().tst_def_failexit_outer().success + val res = testLocal().tst_def_failexit_outer().success // then assert(!res) @@ -258,7 +259,7 @@ internal class ProvTest { } // when - val res = Prov.defaultInstance().tst_def_failexit_outer().success + val res = testLocal().tst_def_failexit_outer().success // then assert(res) @@ -283,7 +284,7 @@ internal class ProvTest { } // when - val res = Prov.defaultInstance().tst_nested().success + val res = testLocal().tst_nested().success // then assert(!res) @@ -322,7 +323,7 @@ internal class ProvTest { System.setErr(PrintStream(errContent)) // when - local().methodThatProvidesSomeOutput() + Prov.newInstance(name = "test instance", progressType = ProgressType.NONE).methodThatProvidesSomeOutput() // then System.setOut(originalOut) @@ -330,9 +331,8 @@ internal class ProvTest { println(outContent.toString()) - // todo : simplify next lines val expectedOutput = if (OS.WINDOWS.isCurrentOs) "\n" + - "============================================== SUMMARY (default Instance) ============================================== \n" + + "============================================== SUMMARY (test Instance) ============================================== \n" + "> Success -- methodThatProvidesSomeOutput (requireLast) \n" + "---> FAILED -- checkPrereq_evaluateToFailure (requireLast) -- Error: This is a test error.\n" + "---> Success -- sh \n" + @@ -342,9 +342,7 @@ internal class ProvTest { "------> Success -- cmd [cmd.exe, /c, echo -End test-]\n" + "============================================ SUMMARY END ============================================ \n" else if (OS.LINUX.isCurrentOs()) { - "Processing started ...\n" + - ".......processing completed.\n" + - "============================================== SUMMARY (default instance) ============================================== \n" + + "============================================== SUMMARY (test instance) ============================================== \n" + "> \u001B[92mSuccess\u001B[0m -- methodThatProvidesSomeOutput (requireLast) \n" + "---> \u001B[91mFAILED\u001B[0m -- checkPrereq_evaluateToFailure (requireLast) -- Error: This is a test error.\n" + "---> \u001B[92mSuccess\u001B[0m -- sh \n" + @@ -366,7 +364,7 @@ internal class ProvTest { @Test fun check_returnsTrue() { // when - val res = local().chk("echo 123") + val res = testLocal().chk("echo 123") // then assertTrue(res) @@ -375,7 +373,7 @@ internal class ProvTest { @Test fun check_returnsFalse() { // when - val res = local().chk("cmddoesnotexist") + val res = testLocal().chk("cmddoesnotexist") // then assertFalse(res) @@ -384,7 +382,7 @@ internal class ProvTest { @Test fun getSecret_returnsSecret() { // when - val res = local().getSecret("echo 123") + val res = testLocal().getSecret("echo 123") // then assertEquals("123", res?.plain()?.trim()) @@ -403,7 +401,7 @@ internal class ProvTest { } // when - val res = local().outer() + val res = testLocal().outer() //then assertEquals(ProvResult(true), res) @@ -422,7 +420,7 @@ internal class ProvTest { } // when - val res = local().outer() + val res = testLocal().outer() //then assertEquals(ProvResult(false), res) @@ -434,7 +432,7 @@ internal class ProvTest { fun inContainer_locally() { // given val containerName = "provs_test" - local().provideContainer(containerName, "ubuntu") + testLocal().provideContainer(containerName, "ubuntu") fun Prov.inner() = def { cmd("echo in container") @@ -448,7 +446,7 @@ internal class ProvTest { } } - val res = local().def { outer() } + val res = testLocal().def { outer() } // then assertEquals(true, res.success) diff --git a/src/test/kotlin/io/provs/docker/platforms/UbuntuHostDockerKtTest.kt b/src/test/kotlin/io/provs/docker/platforms/UbuntuHostDockerKtTest.kt index 8ce3d33..4fec1ed 100644 --- a/src/test/kotlin/io/provs/docker/platforms/UbuntuHostDockerKtTest.kt +++ b/src/test/kotlin/io/provs/docker/platforms/UbuntuHostDockerKtTest.kt @@ -4,8 +4,8 @@ import io.provs.ProvResult import io.provs.docker.containerRuns import io.provs.docker.exitAndRmContainer import io.provs.docker.runContainer -import io.provs.local import io.provs.test.tags.NonCi +import io.provs.test.testLocal import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.junit.jupiter.api.condition.EnabledOnOs @@ -19,7 +19,7 @@ internal class UbuntuHostDockerKtTest { fun runAndCheckAndExitContainer() { // when val containerName = "testContainer" - val result = local().requireAll { + val result = testLocal().requireAll { runContainer(containerName) addResultToEval(ProvResult(containerRuns(containerName))) diff --git a/src/test/kotlin/io/provs/entry/EntryTest.kt b/src/test/kotlin/io/provs/entry/EntryTest.kt index 68dc6e8..25cc628 100644 --- a/src/test/kotlin/io/provs/entry/EntryTest.kt +++ b/src/test/kotlin/io/provs/entry/EntryTest.kt @@ -4,7 +4,7 @@ import org.junit.jupiter.api.Test @Suppress("unused") -fun test() { +fun testfun() { println("test is fun") } @@ -13,6 +13,6 @@ internal class EntryKtTest { @Test fun test_main_no_arg() { - main("io.provs.entry.EntryTestKt", "test") + main("io.provs.entry.EntryTestKt", "testfun") } } diff --git a/src/test/kotlin/io/provs/platformTest/UbuntuProvTests.kt b/src/test/kotlin/io/provs/platformTest/UbuntuProvTests.kt index 48c3fed..d41ad16 100644 --- a/src/test/kotlin/io/provs/platformTest/UbuntuProvTests.kt +++ b/src/test/kotlin/io/provs/platformTest/UbuntuProvTests.kt @@ -2,19 +2,18 @@ package io.provs.platformTest import io.provs.Prov import io.provs.test.tags.NonCi +import io.provs.test.testLocal import org.junit.jupiter.api.Test import org.junit.jupiter.api.condition.EnabledOnOs import org.junit.jupiter.api.condition.OS internal class UbuntuProvTests { - private val prov = Prov.defaultInstance() - - private fun ping(url: String) = prov.def { + private fun Prov.ping(url: String) = def { xec("ping", "-c", "4", url) } - private fun outerPing() = prov.def { + private fun Prov.outerPing() = def { ping("gitlab.com") } @@ -22,7 +21,7 @@ internal class UbuntuProvTests { @EnabledOnOs(OS.LINUX) fun that_ping_works() { // when - val res = outerPing() + val res = testLocal().outerPing() // then assert(res.success) @@ -32,7 +31,7 @@ internal class UbuntuProvTests { @EnabledOnOs(OS.LINUX) fun that_cmd_works() { // given - val a = Prov.defaultInstance() + val a = testLocal() // when val res1 = a.cmd("pwd") @@ -50,7 +49,7 @@ internal class UbuntuProvTests { @NonCi fun that_cmd_works_with_sudo() { // given - val a = Prov.defaultInstance() + val a = testLocal() // when val res1 = a.cmd("echo abc", "/root", sudo = true) @@ -64,7 +63,7 @@ internal class UbuntuProvTests { @EnabledOnOs(OS.LINUX) fun that_nested_shells_work() { // given - val a = Prov.defaultInstance() + val a = testLocal() // when val res1 = a.cmd("pwd") @@ -81,7 +80,7 @@ internal class UbuntuProvTests { @EnabledOnOs(OS.LINUX) fun that_xec_works() { // given - val a = Prov.defaultInstance() + val a = testLocal() // when val res1 = a.xec("/usr/bin/printf", "hi") diff --git a/src/test/kotlin/io/provs/platformTest/WinProvTests.kt b/src/test/kotlin/io/provs/platformTest/WinProvTests.kt index 1e10248..54e9487 100644 --- a/src/test/kotlin/io/provs/platformTest/WinProvTests.kt +++ b/src/test/kotlin/io/provs/platformTest/WinProvTests.kt @@ -1,6 +1,7 @@ package io.provs.platformTest import io.provs.Prov +import io.provs.test.testLocal import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.junit.jupiter.api.condition.EnabledOnOs @@ -8,19 +9,17 @@ import org.junit.jupiter.api.condition.OS internal class WinProvTests { - private val prov = Prov.defaultInstance() - - private fun ping(url: String) = prov.def { + private fun Prov.ping(url: String) = def { cmd("ping $url") } - private fun outerPing() = prov.def { ping("nu.nl") } + private fun Prov.outerPing() = def { ping("nu.nl") } @Test @EnabledOnOs(OS.WINDOWS) fun def_definesPing_function() { // when - val res = outerPing() + val res = testLocal().outerPing() // then assert(res.success) @@ -30,7 +29,7 @@ internal class WinProvTests { @EnabledOnOs(OS.WINDOWS) fun cmd_executesCommand() { // given - val a = Prov.defaultInstance() + val a = testLocal() // when val res1 = a.cmd("echo %cd%") diff --git a/src/test/kotlin/io/provs/processors/ContainerUbuntuHostProcessorTest.kt b/src/test/kotlin/io/provs/processors/ContainerUbuntuHostProcessorTest.kt index 96ab8ea..fe270da 100644 --- a/src/test/kotlin/io/provs/processors/ContainerUbuntuHostProcessorTest.kt +++ b/src/test/kotlin/io/provs/processors/ContainerUbuntuHostProcessorTest.kt @@ -4,6 +4,7 @@ import io.provs.platforms.SHELL import io.provs.test.DEFAULT_START_MODE_TEST_CONTAINER import io.provs.test.tags.ContainerTest import io.provs.test.testDockerWithSudo +import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.junit.jupiter.api.condition.EnabledOnOs import org.junit.jupiter.api.condition.OS.LINUX @@ -14,9 +15,16 @@ class ContainerUbuntuHostProcessorTest { @Test @EnabledOnOs(LINUX) @ContainerTest - fun test() { + fun test_execution() { + // given val processor = ContainerUbuntuHostProcessor("provs_ubuntuhost_test", "ubuntu", DEFAULT_START_MODE_TEST_CONTAINER, sudo = testDockerWithSudo) - processor.x(SHELL, "-c", "'cd /home && mkdir blabla'") + + // when + val res = processor.x(SHELL, "-c", "echo -n abc") + + // then + assertEquals(0, res.exitCode) + assertEquals("abc", res.out) } } \ No newline at end of file diff --git a/src/testFixtures/kotlin/io/provs/test/TestSetup.kt b/src/testFixtures/kotlin/io/provs/test/TestSetup.kt index 6e86654..0df8081 100644 --- a/src/testFixtures/kotlin/io/provs/test/TestSetup.kt +++ b/src/testFixtures/kotlin/io/provs/test/TestSetup.kt @@ -1,10 +1,10 @@ package io.provs.test +import io.provs.ProgressType import io.provs.Prov import io.provs.docker.dockerImageExists import io.provs.docker.dockerProvideImage import io.provs.docker.images.UbuntuPlusUser -import io.provs.local import io.provs.processors.ContainerStartMode import io.provs.processors.ContainerUbuntuHostProcessor @@ -16,7 +16,7 @@ const val defaultTestContainerName = "provs_test" fun defaultTestContainer(): Prov { val image = UbuntuPlusUser() - val prov = local() + val prov = testLocal() if (!prov.dockerImageExists(image.imageName(), testDockerWithSudo)) { prov.dockerProvideImage(image, sudo = testDockerWithSudo) } @@ -27,6 +27,11 @@ fun defaultTestContainer(): Prov { startMode = DEFAULT_START_MODE_TEST_CONTAINER, sudo = testDockerWithSudo, dockerImage = image.imageName() - ) + ), + progressType = ProgressType.NONE ) } + +fun testLocal(): Prov { + return Prov.newInstance(name = "testing", progressType = ProgressType.NONE) +} \ No newline at end of file