INFRA-433 Rebuild node config parsing tests (#6423)

Replace node configuration parsing tests with lighter weight equivalents which just parse the configuration rather than starting a full node.
This commit is contained in:
Ross Nicoll 2020-07-01 21:47:09 +00:00 committed by GitHub
parent 5499e2c050
commit 9f12e6bbc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 147 additions and 119 deletions

View File

@ -1,110 +0,0 @@
package net.corda.node
import net.corda.core.utilities.getOrThrow
import net.corda.node.logging.logFile
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.NodeParameters
import net.corda.testing.driver.driver
import net.corda.testing.driver.internal.incrementalPortAllocation
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Test
import org.junit.Assert.assertTrue
class NodeConfigParsingTests {
@Test(timeout=300_000)
fun `config is overriden by underscore variable`() {
val portAllocator = incrementalPortAllocation()
val sshPort = portAllocator.nextPort()
driver(DriverParameters(
environmentVariables = mapOf("corda_sshd_port" to sshPort.toString()),
startNodesInProcess = false,
portAllocation = portAllocator)) {
val hasSsh = startNode().get()
.logFile()
.readLines()
.filter { it.contains("SSH server listening on port") }
.any { it.contains(sshPort.toString()) }
assertTrue(hasSsh)
}
}
@Test(timeout=300_000)
fun `config is overriden by case insensitive underscore variable`() {
val portAllocator = incrementalPortAllocation()
val sshPort = portAllocator.nextPort()
driver(DriverParameters(
environmentVariables = mapOf("CORDA_sshd_port" to sshPort.toString()),
startNodesInProcess = false,
portAllocation = portAllocator)) {
val hasSsh = startNode().get()
.logFile()
.readLines()
.filter { it.contains("SSH server listening on port") }
.any { it.contains(sshPort.toString()) }
assertTrue(hasSsh)
}
}
@Test(timeout=300_000)
fun `config is overriden by case insensitive dot variable`() {
val portAllocator = incrementalPortAllocation()
val sshPort = portAllocator.nextPort()
driver(DriverParameters(
environmentVariables = mapOf("CORDA.sshd.port" to sshPort.toString(),
"corda.devMode" to true.toString()),
startNodesInProcess = false,
portAllocation = portAllocator)) {
val hasSsh = startNode(NodeParameters()).get()
.logFile()
.readLines()
.filter { it.contains("SSH server listening on port") }
.any { it.contains(sshPort.toString()) }
assertTrue(hasSsh)
}
}
@Test(timeout=300_000)
fun `shadowing is forbidden`() {
val portAllocator = incrementalPortAllocation()
val sshPort = portAllocator.nextPort()
driver(DriverParameters(
environmentVariables = mapOf(
"CORDA_sshd_port" to sshPort.toString(),
"corda.sshd.port" to sshPort.toString()),
startNodesInProcess = false,
portAllocation = portAllocator,
notarySpecs = emptyList())) {
assertThatThrownBy {
startNode().getOrThrow()
}
}
}
@Test(timeout=300_000)
fun `bad keys are ignored and warned for`() {
val portAllocator = incrementalPortAllocation()
driver(DriverParameters(
environmentVariables = mapOf(
"corda_bad_key" to "2077"),
startNodesInProcess = false,
portAllocation = portAllocator,
notarySpecs = emptyList())) {
val hasWarning = startNode()
.getOrThrow()
.logFile()
.readLines()
.any {
it.contains("(property or environment variable) cannot be mapped to an existing Corda")
}
assertTrue(hasWarning)
}
}
}

View File

@ -0,0 +1,32 @@
package net.corda.node.services.config
import net.corda.core.utilities.getOrThrow
import net.corda.node.logging.logFile
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.driver.internal.incrementalPortAllocation
import org.junit.Assert.assertTrue
import org.junit.Test
class NodeConfigParsingTests {
@Test(timeout = 300_000)
fun `bad keys are ignored and warned for`() {
val portAllocator = incrementalPortAllocation()
driver(DriverParameters(
environmentVariables = mapOf(
"corda_bad_key" to "2077"),
startNodesInProcess = false,
portAllocation = portAllocator,
notarySpecs = emptyList())) {
val hasWarning = startNode()
.getOrThrow()
.logFile()
.readLines()
.any {
it.contains("(property or environment variable) cannot be mapped to an existing Corda")
}
assertTrue(hasWarning)
}
}
}

View File

@ -6,6 +6,7 @@ import com.typesafe.config.ConfigParseOptions
import net.corda.cliutils.CordaSystemUtils import net.corda.cliutils.CordaSystemUtils
import net.corda.common.configuration.parsing.internal.Configuration import net.corda.common.configuration.parsing.internal.Configuration
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.VisibleForTesting
import net.corda.core.internal.createDirectories import net.corda.core.internal.createDirectories
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.exists import net.corda.core.internal.exists
@ -36,11 +37,34 @@ object ConfigHelper {
private const val UPPERCASE_PROPERTY_PREFIX = "CORDA." private const val UPPERCASE_PROPERTY_PREFIX = "CORDA."
private val log = LoggerFactory.getLogger(javaClass) private val log = LoggerFactory.getLogger(javaClass)
val DEFAULT_CONFIG_FILENAME = "node.conf"
@Suppress("LongParameterList") @Suppress("LongParameterList")
fun loadConfig(baseDirectory: Path, fun loadConfig(baseDirectory: Path,
configFile: Path = baseDirectory / "node.conf", configFile: Path = baseDirectory / DEFAULT_CONFIG_FILENAME,
allowMissingConfig: Boolean = false, allowMissingConfig: Boolean = false,
configOverrides: Config = ConfigFactory.empty()): Config { configOverrides: Config = ConfigFactory.empty()): Config
= loadConfig(baseDirectory,
configFile = configFile,
allowMissingConfig = allowMissingConfig,
configOverrides = configOverrides,
rawSystemOverrides = ConfigFactory.systemProperties(),
rawEnvironmentOverrides = ConfigFactory.systemEnvironment())
/**
* Internal equivalent of [loadConfig] which allows the system and environment
* overrides to be provided from a test.
*/
@Suppress("LongParameterList")
@VisibleForTesting
internal fun loadConfig(baseDirectory: Path,
configFile: Path,
allowMissingConfig: Boolean,
configOverrides: Config,
rawSystemOverrides: Config,
rawEnvironmentOverrides: Config
): Config {
val parseOptions = ConfigParseOptions.defaults() val parseOptions = ConfigParseOptions.defaults()
val defaultConfig = ConfigFactory.parseResources("corda-reference.conf", parseOptions.setAllowMissing(false)) val defaultConfig = ConfigFactory.parseResources("corda-reference.conf", parseOptions.setAllowMissing(false))
val appConfig = ConfigFactory.parseFile(configFile.toFile(), parseOptions.setAllowMissing(allowMissingConfig)) val appConfig = ConfigFactory.parseFile(configFile.toFile(), parseOptions.setAllowMissing(allowMissingConfig))
@ -55,8 +79,8 @@ object ConfigHelper {
"flowExternalOperationThreadPoolSize" to min(coreCount, FLOW_EXTERNAL_OPERATION_THREAD_POOL_SIZE_MAX).toString() "flowExternalOperationThreadPoolSize" to min(coreCount, FLOW_EXTERNAL_OPERATION_THREAD_POOL_SIZE_MAX).toString()
) )
val systemOverrides = ConfigFactory.systemProperties().cordaEntriesOnly() val systemOverrides = rawSystemOverrides.cordaEntriesOnly()
val environmentOverrides = ConfigFactory.systemEnvironment().cordaEntriesOnly() val environmentOverrides = rawEnvironmentOverrides.cordaEntriesOnly()
val finalConfig = configOf( val finalConfig = configOf(
// Add substitution values here // Add substitution values here
"baseDirectory" to baseDirectory.toString()) "baseDirectory" to baseDirectory.toString())
@ -91,8 +115,8 @@ object ConfigHelper {
.mapKeys { .mapKeys {
val original = it.key as String val original = it.key as String
// Reject environment variable that are in all caps // Reject environment variable that are in all caps
// since these cannot be properties. // since these cannot be properties.
if (original == original.toUpperCase()){ if (original == original.toUpperCase()){
return@mapKeys original return@mapKeys original
} }

View File

@ -1,9 +1,9 @@
package net.corda.node.internal package net.corda.node.internal
import com.google.common.io.Files
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.Test import org.junit.Test
import java.nio.channels.OverlappingFileLockException import java.nio.channels.OverlappingFileLockException
import java.nio.file.Files
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
import kotlin.concurrent.thread import kotlin.concurrent.thread
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
@ -11,8 +11,7 @@ import kotlin.test.assertFailsWith
class NodeStartupTest { class NodeStartupTest {
@Test(timeout=300_000) @Test(timeout=300_000)
fun `test that you cant start two nodes in the same directory`() { fun `test that you cant start two nodes in the same directory`() {
val dir = Files.createTempDir().toPath() val dir = Files.createTempDirectory("node_startup_test")
val latch = CountDownLatch(1) val latch = CountDownLatch(1)
thread(start = true) { thread(start = true) {

View File

@ -0,0 +1,83 @@
package net.corda.node.services.config
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import net.corda.core.internal.delete
import net.corda.core.internal.div
import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import java.nio.file.Files
import java.nio.file.Path
class ConfigHelperTests {
private var baseDir: Path? = null
@Before
fun setup() {
baseDir = Files.createTempDirectory("corda_config")
}
@After
fun cleanup() {
baseDir?.delete()
}
@Test(timeout = 300_000)
fun `config is overridden by underscore variable`() {
val sshPort: Long = 9000
// Verify the port isn't set when not provided
var config = loadConfig()
Assert.assertFalse("SSH port should not be configured when not provided", config!!.hasPath("sshd.port"))
config = loadConfig("corda_sshd_port" to sshPort)
Assert.assertEquals(sshPort, config?.getLong("sshd.port"))
}
@Test(timeout = 300_000)
fun `config is overridden by case insensitive underscore variable`() {
val sshPort: Long = 10000
val config = loadConfig("CORDA_sshd_port" to sshPort)
Assert.assertEquals(sshPort, config?.getLong("sshd.port"))
}
@Test(timeout = 300_000)
fun `config is overridden by case insensitive dot variable`() {
val sshPort: Long = 11000
val config = loadConfig("CORDA.sshd.port" to sshPort,
"corda.devMode" to true.toString())
Assert.assertEquals(sshPort, config?.getLong("sshd.port"))
}
@Test(timeout = 300_000, expected = ShadowingException::class)
fun `shadowing is forbidden`() {
val sshPort: Long = 12000
loadConfig("CORDA_sshd_port" to sshPort.toString(),
"corda.sshd.port" to sshPort.toString())
}
/**
* Load the node configuration with the given environment variable
* overrides.
*
* @param environmentVariables pairs of keys and values for environment variables
* to simulate when loading the configuration.
*/
@Suppress("SpreadOperator")
private fun loadConfig(vararg environmentVariables: Pair<String, Any>): Config? {
return baseDir?.let {
ConfigHelper.loadConfig(
baseDirectory = it,
configFile = it / ConfigHelper.DEFAULT_CONFIG_FILENAME,
allowMissingConfig = true,
configOverrides = ConfigFactory.empty(),
rawSystemOverrides = ConfigFactory.empty(),
rawEnvironmentOverrides = ConfigFactory.empty().plus(
mapOf(*environmentVariables)
)
)
}
}
}