make progress info level configurable

This commit is contained in:
ansgarz 2021-05-15 19:33:56 +02:00
parent 2d4607964f
commit 122fa68850
17 changed files with 236 additions and 133 deletions

View file

@ -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

View file

@ -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

View file

@ -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<InternalResult>()
private val internalResults = arrayListOf<ResultLine>()
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<String> {
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<String> {
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 object ProgressBar {
fun init() {
print("Processing started ...\n")
}
fun progress() {
print(".")
private fun initProgress() {
if ((progressType == ProgressType.DOTS) || (progressType == ProgressType.BASIC)) {
println("---------- Processing started ----------")
System.out.flush()
}
}
fun end() {
println("processing completed.")
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 ----------")
}
}
}
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
}
private fun prefix(level: Int): String {
return "---".repeat(level) + "> "
}
}
fun Prov.myfu() = def {
cmd("echo asdf222")
}
fun main() {
local().def {
cmd("echo asdfasdf")
myfu()
}
}

View file

@ -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<T>(val success: Boolean, val resultObject: T? = null) {
override fun toString(): String {
return "TypedResult:: ${if (success) "Succeeded" else "FAILED"} -- Result object: " + resultObject?.run { toString().escapeNewline() }
}
}

View file

@ -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 != "")
}

View file

@ -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))

View file

@ -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"

View file

@ -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)

View file

@ -1,6 +1,7 @@
package io.provs.processors
@Suppress("unused") // used externally
class PrintOnlyProcessor : Processor {
override fun x(vararg args: String): ProcessResult

View file

@ -12,6 +12,16 @@
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<target>System.out</target>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{35}) - %msg %n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/provs-${byTime}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
@ -31,9 +41,13 @@
<appender-ref ref="FILE" />
</logger>
<root level="DEBUG">
<root level="INFO">
<appender-ref ref="STDERR" />
<appender-ref ref="FILE" />
</root>
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View file

@ -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)

View file

@ -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)))

View file

@ -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")
}
}

View file

@ -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")

View file

@ -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%")

View file

@ -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)
}
}

View file

@ -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)
}