CORDA-1959 - Enforce backwards compatibility of new CLI's (#3939)

* enforce backwards compatibility of new CLI's

* move Shell yml
This commit is contained in:
Stefano Franz 2018-09-14 14:37:52 +01:00 committed by GitHub
parent 3c9619b169
commit 5be7d5c4f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 349 additions and 7 deletions

View File

@ -189,6 +189,8 @@ dependencies {
compile "org.jolokia:jolokia-jvm:${jolokia_version}:agent"
// Optional New Relic JVM reporter, used to push metrics to the configured account associated with a newrelic.yml configuration. See https://mvnrepository.com/artifact/com.palominolabs.metrics/metrics-new-relic
compile "com.palominolabs.metrics:metrics-new-relic:${metrics_new_relic_version}"
testCompile(project(':test-cli'))
}
tasks.withType(JavaCompile) {

View File

@ -0,0 +1,141 @@
- commandName: "<main class>"
positionalParams: []
params:
- parameterName: "--base-directory"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "--bootstrap-raft-cluster"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--clear-network-map-cache"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--config-file"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "--dev-mode"
parameterType: "java.lang.Boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--initial-registration"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--install-shell-extensions"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--just-generate-node-info"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--just-generate-rpc-ssl-settings"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--log-to-console"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--logging-level"
parameterType: "org.slf4j.event.Level"
required: false
multiParam: false
acceptableValues:
- "ERROR"
- "WARN"
- "INFO"
- "DEBUG"
- "TRACE"
- parameterName: "--network-root-truststore"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "--network-root-truststore-password"
parameterType: "java.lang.String"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--no-local-shell"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--on-unknown-config-keys"
parameterType: "net.corda.nodeapi.internal.config.UnknownConfigKeysPolicy"
required: false
multiParam: false
acceptableValues:
- "FAIL"
- "WARN"
- "IGNORE"
- parameterName: "--sshd"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--sshd-port"
parameterType: "int"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--verbose"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "-b"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "-c"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "-d"
parameterType: "java.lang.Boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "-f"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "-n"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "-p"
parameterType: "java.lang.String"
required: false
multiParam: false
acceptableValues: []
- parameterName: "-t"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "-v"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []

View File

@ -0,0 +1,5 @@
package net.corda.node.internal
import net.corda.testing.CliBackwardsCompatibleTest
class NodeStartupCompatibilityTest : CliBackwardsCompatibleTest(NodeStartup::class.java)

View File

@ -1,16 +1,21 @@
package net.corda.testing
import junit.framework.AssertionFailedError
import org.junit.Test
open class CliBackwardsCompatibleTest {
open class CliBackwardsCompatibleTest(val clazz: Class<*>) {
@Test
fun `should always be backwards compatible`() {
checkBackwardsCompatibility(clazz)
}
fun checkBackwardsCompatibility(clazz: Class<*>) {
val checker = CommandLineCompatibilityChecker()
val checkResults = checker.checkCommandLineIsBackwardsCompatible(clazz)
if (checkResults.isNotEmpty()) {
val exceptionMessage= checkResults.map { it.message }.joinToString(separator = "\n")
val exceptionMessage = checkResults.map { it.message }.joinToString(separator = "\n")
throw AssertionFailedError("Command line is not backwards compatible:\n$exceptionMessage")
}
}

View File

@ -11,6 +11,11 @@ import kotlin.collections.ArrayList
class CommandLineCompatibilityChecker {
companion object {
fun printCommandLineYAML(clazz: Class<*>) {
CommandLineCompatibilityChecker().printCommandDescription(CommandLine(clazz.newInstance()))
}
}
fun topoSort(commandLine: CommandLine): List<CommandDescription> {
val toVisit = Stack<CommandLine>()
@ -62,6 +67,7 @@ class CommandLineCompatibilityChecker {
return Iterable::class.java.isAssignableFrom(clazz) || Array<Any>::class.java.isAssignableFrom(clazz)
}
fun printCommandDescription(commandLine: CommandLine) {
val objectMapper = ObjectMapper(YAMLFactory()).registerKotlinModule()
val results = topoSort(commandLine)
@ -109,7 +115,7 @@ class CommandLineCompatibilityChecker {
throw IllegalArgumentException("Commands must match (${old.commandName} != ${new.commandName})")
}
val oldSet = old.positionalParams.sortedBy { it.parameterName }.toSet()
val newSet = new.positionalParams.sortedBy { it.parameterName}.toSet()
val newSet = new.positionalParams.sortedBy { it.parameterName }.toSet()
val newIsSuperSetOfOld = newSet.containsAll(oldSet)
return if (!newIsSuperSetOfOld) {
oldSet.filterNot { newSet.contains(it) }.map {
@ -150,7 +156,9 @@ class CommandLineCompatibilityChecker {
val commandLineToCheckName = commandLineToCheck.canonicalName
val instance = commandLineToCheck.newInstance()
val resourceAsStream = this.javaClass.classLoader.getResourceAsStream("$commandLineToCheckName.yml")
?: throw IllegalStateException("no Descriptor for $commandLineToCheckName found on classpath")
?: throw IllegalStateException("$commandLineToCheckName.yml not found on classpath").also {
printCommandLineYAML(commandLineToCheck)
}
val old = readCommandDescription(resourceAsStream)
val new = topoSort(CommandLine(instance))
return checkCommandLineIsBackwardsCompatible(old, new)
@ -158,8 +166,8 @@ class CommandLineCompatibilityChecker {
fun checkBackwardsCompatibility(old: CommandLine, new: CommandLine): List<CliBackwardsCompatibilityValidationCheck> {
val topoSortOld= topoSort(old)
val topoSortNew= topoSort(new)
val topoSortOld = topoSort(old)
val topoSortNew = topoSort(new)
return checkCommandLineIsBackwardsCompatible(topoSortOld, topoSortNew)
}

View File

@ -8,6 +8,12 @@ dependencies {
compile project(':node-api')
compile project(':tools:cliutils')
compile "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
testCompile(project(':test-utils')) {
exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl'
}
testCompile(project(':test-cli'))
}
processResources {

View File

@ -0,0 +1,5 @@
package net.corda.bootstrapper
import net.corda.testing.CliBackwardsCompatibleTest
class NetworkBootstrapperRunnerTest : CliBackwardsCompatibleTest(NetworkBootstrapperRunner::class.java)

View File

@ -0,0 +1,43 @@
- commandName: "<main class>"
positionalParams: []
params:
- parameterName: "--dir"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "--install-shell-extensions"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--log-to-console"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--logging-level"
parameterType: "org.slf4j.event.Level"
required: false
multiParam: false
acceptableValues:
- "ERROR"
- "WARN"
- "INFO"
- "DEBUG"
- "TRACE"
- parameterName: "--no-copy"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--verbose"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "-v"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []

View File

@ -17,13 +17,15 @@ dependencies {
testCompile(project(':test-utils')) {
exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl'
}
testCompile(project(':test-cli'))
}
processResources {
from file("$rootDir/config/dev/log4j2.xml")
}
shadowJar {
shadowJar {
mergeServiceFiles()
}

View File

@ -0,0 +1,6 @@
package net.corda.tools.shell
import net.corda.testing.CliBackwardsCompatibleTest
class StandaloneShellCompatibilityTest : CliBackwardsCompatibleTest(StandaloneShell::class.java)

View File

@ -0,0 +1,119 @@
- commandName: "<main class>"
positionalParams: []
params:
- parameterName: "--commands-directory"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "--config-file"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "--cordapp-directory"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "--host"
parameterType: "java.lang.String"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--install-shell-extensions"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--log-to-console"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--logging-level"
parameterType: "org.slf4j.event.Level"
required: false
multiParam: false
acceptableValues:
- "ERROR"
- "WARN"
- "INFO"
- "DEBUG"
- "TRACE"
- parameterName: "--password"
parameterType: "java.lang.String"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--port"
parameterType: "java.lang.String"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--sshd-hostkey-directory"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "--sshd-port"
parameterType: "java.lang.String"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--truststore-file"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "--truststore-password"
parameterType: "java.lang.String"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--truststore-type"
parameterType: "java.lang.String"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--user"
parameterType: "java.lang.String"
required: false
multiParam: false
acceptableValues: []
- parameterName: "--verbose"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []
- parameterName: "-a"
parameterType: "java.lang.String"
required: false
multiParam: false
acceptableValues: []
- parameterName: "-c"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "-f"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "-o"
parameterType: "java.nio.file.Path"
required: false
multiParam: true
acceptableValues: []
- parameterName: "-p"
parameterType: "java.lang.String"
required: false
multiParam: false
acceptableValues: []
- parameterName: "-v"
parameterType: "boolean"
required: false
multiParam: false
acceptableValues: []