add ConfigRepositoryKtTest.kt & improve error messages for missing config file resp. wrong config format
This commit is contained in:
parent
f3f3121395
commit
cb23a563e8
6 changed files with 155 additions and 16 deletions
|
@ -1,7 +1,9 @@
|
||||||
package org.domaindrivenarchitecture.provs.workplace.application
|
package org.domaindrivenarchitecture.provs.workplace.application
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerializationException
|
||||||
import org.domaindrivenarchitecture.provs.core.cli.createProvInstance
|
import org.domaindrivenarchitecture.provs.core.cli.createProvInstance
|
||||||
import org.domaindrivenarchitecture.provs.workplace.infrastructure.getConfig
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.getConfig
|
||||||
|
import java.io.FileNotFoundException
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,7 +27,11 @@ fun main(args: Array<String>) {
|
||||||
val prov = createProvInstance(cmd.target, remoteHostSetSudoWithoutPasswordRequired = true)
|
val prov = createProvInstance(cmd.target, remoteHostSetSudoWithoutPasswordRequired = true)
|
||||||
provision(prov, conf)
|
provision(prov, conf)
|
||||||
|
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: SerializationException) {
|
||||||
|
println(
|
||||||
|
"Error: File \"${cmd.configFile}\" has an invalid format and or invalid data.\n"
|
||||||
|
)
|
||||||
|
} catch (e: FileNotFoundException) {
|
||||||
println(
|
println(
|
||||||
"Error: File\u001b[31m ${cmd.configFile} \u001b[0m was not found.\n" +
|
"Error: File\u001b[31m ${cmd.configFile} \u001b[0m was not found.\n" +
|
||||||
"Pls copy file \u001B[31m WorkplaceConfigExample.yaml \u001B[0m to file \u001B[31m ${cmd.configFile} \u001B[0m " +
|
"Pls copy file \u001B[31m WorkplaceConfigExample.yaml \u001B[0m to file \u001B[31m ${cmd.configFile} \u001B[0m " +
|
||||||
|
|
|
@ -4,27 +4,27 @@ import com.charleskorn.kaml.Yaml
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import org.domaindrivenarchitecture.provs.core.tags.Api
|
import org.domaindrivenarchitecture.provs.core.tags.Api
|
||||||
import org.domaindrivenarchitecture.provs.workplace.domain.WorkplaceConfig
|
import org.domaindrivenarchitecture.provs.workplace.domain.WorkplaceConfig
|
||||||
import java.io.*
|
import java.io.BufferedReader
|
||||||
|
import java.io.FileReader
|
||||||
|
import java.io.FileWriter
|
||||||
|
|
||||||
|
|
||||||
internal fun getConfig(filename: String = "WorkplaceConfig.json"): WorkplaceConfig {
|
/**
|
||||||
val file = File(filename)
|
* Returns WorkplaceConfig; data for config is read from specified file.
|
||||||
require(file.exists(), { "File not found: " + filename })
|
* Throws exceptions FileNotFoundException, SerializationException if file is not found resp. cannot be parsed.
|
||||||
|
*/
|
||||||
|
internal fun getConfig(filename: String = "WorkplaceConfig.yaml"): WorkplaceConfig {
|
||||||
|
|
||||||
|
// read file
|
||||||
|
val inputAsString = BufferedReader(FileReader(filename)).use { it.readText() }
|
||||||
|
|
||||||
|
// serializing objects
|
||||||
val config =
|
val config =
|
||||||
try {
|
|
||||||
// read from file
|
|
||||||
val inputAsString = BufferedReader(FileReader(filename)).use { it.readText() }
|
|
||||||
|
|
||||||
// serializing objects
|
|
||||||
if (filename.lowercase().endsWith(".yaml")) {
|
if (filename.lowercase().endsWith(".yaml")) {
|
||||||
Yaml.default.decodeFromString(WorkplaceConfig.serializer(), inputAsString)
|
Yaml.default.decodeFromString(WorkplaceConfig.serializer(), inputAsString)
|
||||||
} else {
|
} else {
|
||||||
Json.decodeFromString(WorkplaceConfig.serializer(), inputAsString)
|
Json.decodeFromString(WorkplaceConfig.serializer(), inputAsString)
|
||||||
}
|
}
|
||||||
} catch (e: FileNotFoundException) {
|
|
||||||
throw IllegalArgumentException("File not found: " + filename, e)
|
|
||||||
}
|
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,11 @@ import org.domaindrivenarchitecture.provs.workplace.domain.WorkplaceType
|
||||||
import org.domaindrivenarchitecture.provs.workplace.domain.provisionWorkplace
|
import org.domaindrivenarchitecture.provs.workplace.domain.provisionWorkplace
|
||||||
import org.domaindrivenarchitecture.provs.workplace.infrastructure.getConfig
|
import org.domaindrivenarchitecture.provs.workplace.infrastructure.getConfig
|
||||||
import org.junit.jupiter.api.AfterAll
|
import org.junit.jupiter.api.AfterAll
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.BeforeAll
|
import org.junit.jupiter.api.BeforeAll
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.io.PrintStream
|
||||||
|
|
||||||
internal class CliWorkplaceKtTest {
|
internal class CliWorkplaceKtTest {
|
||||||
|
|
||||||
|
@ -35,7 +38,10 @@ internal class CliWorkplaceKtTest {
|
||||||
every { getConfig("testconfig.yaml") } returns testConfig
|
every { getConfig("testconfig.yaml") } returns testConfig
|
||||||
|
|
||||||
mockkStatic(Prov::provisionWorkplace)
|
mockkStatic(Prov::provisionWorkplace)
|
||||||
every { any<Prov>().provisionWorkplace(any(), any(), any(), any(), any()) } returns ProvResult(true, cmd = "mocked command")
|
every { any<Prov>().provisionWorkplace(any(), any(), any(), any(), any()) } returns ProvResult(
|
||||||
|
true,
|
||||||
|
cmd = "mocked command"
|
||||||
|
)
|
||||||
|
|
||||||
mockkStatic(::retrievePassword)
|
mockkStatic(::retrievePassword)
|
||||||
every { retrievePassword(any()) } returns Secret("sec")
|
every { retrievePassword(any()) } returns Secret("sec")
|
||||||
|
@ -58,7 +64,15 @@ internal class CliWorkplaceKtTest {
|
||||||
main(arrayOf("-l", "testconfig.yaml"))
|
main(arrayOf("-l", "testconfig.yaml"))
|
||||||
|
|
||||||
// then
|
// then
|
||||||
verify { any<Prov>().provisionWorkplace(WorkplaceType.MINIMAL, null, null, testConfig.gitUserName, testConfig.gitEmail) }
|
verify {
|
||||||
|
any<Prov>().provisionWorkplace(
|
||||||
|
WorkplaceType.MINIMAL,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
testConfig.gitUserName,
|
||||||
|
testConfig.gitEmail
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -69,6 +83,62 @@ internal class CliWorkplaceKtTest {
|
||||||
|
|
||||||
// then
|
// then
|
||||||
verify { remote("host123", "user123", Secret("sec"), any()) }
|
verify { remote("host123", "user123", Secret("sec"), any()) }
|
||||||
verify { any<Prov>().provisionWorkplace(WorkplaceType.MINIMAL, null, null, testConfig.gitUserName, testConfig.gitEmail) }
|
verify {
|
||||||
|
any<Prov>().provisionWorkplace(
|
||||||
|
WorkplaceType.MINIMAL,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
testConfig.gitUserName,
|
||||||
|
testConfig.gitEmail
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun prints_error_message_if_config_not_found() {
|
||||||
|
// given
|
||||||
|
val outContent = ByteArrayOutputStream()
|
||||||
|
val errContent = ByteArrayOutputStream()
|
||||||
|
val originalOut = System.out
|
||||||
|
val originalErr = System.err
|
||||||
|
|
||||||
|
System.setOut(PrintStream(outContent))
|
||||||
|
System.setErr(PrintStream(errContent))
|
||||||
|
|
||||||
|
// when
|
||||||
|
main(arrayOf("-l", "idontexist.yaml"))
|
||||||
|
|
||||||
|
// then
|
||||||
|
System.setOut(originalOut)
|
||||||
|
System.setErr(originalErr)
|
||||||
|
|
||||||
|
val expectedOutput = "Error: File\u001B[31m idontexist.yaml \u001B[0m was not found.Pls copy file \u001B[31m WorkplaceConfigExample.yaml \u001B[0m to file \u001B[31m idontexist.yaml \u001B[0m and change the content according to your needs."
|
||||||
|
assertEquals(expectedOutput, outContent.toString().replace("\r", "").replace("\n", ""))
|
||||||
|
|
||||||
|
verify(exactly = 0) { any<Prov>().provisionWorkplace(any()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun prints_error_message_if_config_not_parsable() {
|
||||||
|
// given
|
||||||
|
val outContent = ByteArrayOutputStream()
|
||||||
|
val errContent = ByteArrayOutputStream()
|
||||||
|
val originalOut = System.out
|
||||||
|
val originalErr = System.err
|
||||||
|
|
||||||
|
System.setOut(PrintStream(outContent))
|
||||||
|
System.setErr(PrintStream(errContent))
|
||||||
|
|
||||||
|
// when
|
||||||
|
main(arrayOf("-l", "src/test/resources/InvalidWorkplaceConfig.yaml"))
|
||||||
|
|
||||||
|
// then
|
||||||
|
System.setOut(originalOut)
|
||||||
|
System.setErr(originalErr)
|
||||||
|
|
||||||
|
val expectedOutput = "Error: File \"src/test/resources/InvalidWorkplaceConfig.yaml\" has an invalid format and or invalid data."
|
||||||
|
assertEquals(expectedOutput, outContent.toString().replace("\r", "").replace("\n", ""))
|
||||||
|
|
||||||
|
verify(exactly = 0) { any<Prov>().provisionWorkplace(any()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package org.domaindrivenarchitecture.provs.workplace.infrastructure
|
||||||
|
|
||||||
|
import com.charleskorn.kaml.InvalidPropertyValueException
|
||||||
|
import org.domaindrivenarchitecture.provs.ubuntu.secret.SecretSourceType
|
||||||
|
import org.domaindrivenarchitecture.provs.workplace.domain.WorkplaceType
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.assertThrows
|
||||||
|
import java.io.FileNotFoundException
|
||||||
|
|
||||||
|
internal class ConfigRepositoryKtTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getConfig_successful() {
|
||||||
|
// when
|
||||||
|
val config = getConfig("src/test/resources/TestWorkplaceConfig.yaml")
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(WorkplaceType.OFFICE, config.type)
|
||||||
|
assertEquals("username", config.gitUserName)
|
||||||
|
assertEquals("for@git.email", config.gitEmail)
|
||||||
|
|
||||||
|
assertEquals(SecretSourceType.FILE, config.ssh?.sourceType)
|
||||||
|
assertEquals("~/.ssh/id_rsa.pub", config.ssh?.publicKey)
|
||||||
|
assertEquals("~/.ssh/id_rsa", config.ssh?.privateKey)
|
||||||
|
|
||||||
|
assertEquals(SecretSourceType.GOPASS, config.gpg?.sourceType)
|
||||||
|
assertEquals("path/to/pub.key", config.gpg?.publicKey)
|
||||||
|
assertEquals("path/to/priv.key", config.gpg?.privateKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getConfig_fails_due_to_invalidProperty() {
|
||||||
|
assertThrows<InvalidPropertyValueException> {
|
||||||
|
getConfig("src/test/resources/InvalidWorkplaceConfig.yaml")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getConfig_fails_due_to_non_existing_file() {
|
||||||
|
assertThrows<FileNotFoundException> {
|
||||||
|
getConfig("src/test/resources/Idonotexist.yaml")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
2
src/test/resources/InvalidWorkplaceConfig.yaml
Normal file
2
src/test/resources/InvalidWorkplaceConfig.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
type: WRONGTYPE # IDE, OFFICE or MINIMAL
|
||||||
|
nonexistingkey: foo
|
14
src/test/resources/TestWorkplaceConfig.yaml
Normal file
14
src/test/resources/TestWorkplaceConfig.yaml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# type is required
|
||||||
|
type: OFFICE # IDE, OFFICE or MINIMAL
|
||||||
|
|
||||||
|
# fields below are optional, either remove them or update them with your data
|
||||||
|
ssh:
|
||||||
|
sourceType: FILE # FILE or GOPASS
|
||||||
|
publicKey: ~/.ssh/id_rsa.pub # file path resp. gopass path to public key
|
||||||
|
privateKey: ~/.ssh/id_rsa # file path resp. gopass path to private key
|
||||||
|
gpg:
|
||||||
|
sourceType: GOPASS # FILE or GOPASS
|
||||||
|
publicKey: path/to/pub.key # file path resp. gopass path to public key
|
||||||
|
privateKey: path/to/priv.key # file path resp. gopass path to private key
|
||||||
|
gitUserName: username # global git user name
|
||||||
|
gitEmail: for@git.email # global git email
|
Loading…
Reference in a new issue