NOTICK fix smoke tests and slow integration tests (#6422)

* Add schema migration to smoke tests
* Fix driver to work correctly for out-of-proc node with persistent database.
Co-authored-by: Ross Nicoll <ross.nicoll@r3.com>
This commit is contained in:
Christian Sailer 2020-07-09 15:13:20 +01:00 committed by GitHub
parent 4091fdc8b1
commit 057a8d8ae9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 10 deletions

View File

@ -80,7 +80,8 @@ constructor(private val initSerEnv: Boolean,
"-jar", "-jar",
"corda.jar", "corda.jar",
"run-migration-scripts", "run-migration-scripts",
"--core-schemas" "--core-schemas",
"--app-schemas"
) )
private const val LOGS_DIR_NAME = "logs" private const val LOGS_DIR_NAME = "logs"

View File

@ -84,7 +84,8 @@ class NodeRegistrationTest {
portAllocation = portAllocation, portAllocation = portAllocation,
compatibilityZone = compatibilityZone, compatibilityZone = compatibilityZone,
notarySpecs = listOf(NotarySpec(notaryName)), notarySpecs = listOf(NotarySpec(notaryName)),
notaryCustomOverrides = mapOf("devMode" to false) notaryCustomOverrides = mapOf("devMode" to false),
allowHibernateToManageAppSchema = false
) { ) {
startNode(providedName = aliceName, customOverrides = mapOf("devMode" to false)).getOrThrow() startNode(providedName = aliceName, customOverrides = mapOf("devMode" to false)).getOrThrow()

View File

@ -15,7 +15,6 @@ import net.corda.core.concurrent.firstOf
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.PLATFORM_VERSION import net.corda.core.internal.PLATFORM_VERSION
import net.corda.core.internal.ThreadBox import net.corda.core.internal.ThreadBox
import net.corda.core.internal.concurrent.doOnComplete
import net.corda.core.internal.concurrent.doOnError import net.corda.core.internal.concurrent.doOnError
import net.corda.core.internal.concurrent.doneFuture import net.corda.core.internal.concurrent.doneFuture
import net.corda.core.internal.concurrent.flatMap import net.corda.core.internal.concurrent.flatMap
@ -260,7 +259,7 @@ class DriverDSLImpl(
val config = createConfig(name, parameters, p2pAddress) val config = createConfig(name, parameters, p2pAddress)
val registrationFuture = if (compatibilityZone?.rootCert != null) { val registrationFuture = if (compatibilityZone?.rootCert != null) {
// We don't need the network map to be available to be able to register the node // We don't need the network map to be available to be able to register the node
createSchema(config, false).doOnComplete { startNodeRegistration(it, compatibilityZone.rootCert, compatibilityZone.config()) } createSchema(config, false).flatMap { startNodeRegistration(it, compatibilityZone.rootCert, compatibilityZone.config()) }
} else { } else {
doneFuture(config) doneFuture(config)
} }
@ -536,7 +535,7 @@ class DriverDSLImpl(
): CordaFuture<Pair<NodeConfig,NotaryInfo>> { ): CordaFuture<Pair<NodeConfig,NotaryInfo>> {
val notaryConfig = mapOf("notary" to mapOf("validating" to spec.validating)) val notaryConfig = mapOf("notary" to mapOf("validating" to spec.validating))
val parameters = NodeParameters(rpcUsers = spec.rpcUsers, verifierType = spec.verifierType, customOverrides = notaryConfig + notaryCustomOverrides, maximumHeapSize = spec.maximumHeapSize) val parameters = NodeParameters(rpcUsers = spec.rpcUsers, verifierType = spec.verifierType, customOverrides = notaryConfig + notaryCustomOverrides, maximumHeapSize = spec.maximumHeapSize)
return createSchema(createConfig(spec.name, parameters), false).doOnComplete { config -> return createSchema(createConfig(spec.name, parameters), false).flatMap { config ->
startNodeRegistration(config, rootCert, compatibilityZone.config())}.flatMap { config -> startNodeRegistration(config, rootCert, compatibilityZone.config())}.flatMap { config ->
// Node registration only gives us the node CA cert, not the identity cert. That is only created on first // Node registration only gives us the node CA cert, not the identity cert. That is only created on first
// startup or when the node is told to just generate its node info file. We do that here. // startup or when the node is told to just generate its node info file. We do that here.

View File

@ -2,19 +2,22 @@ package net.corda.smoketesting
import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCClient
import net.corda.client.rpc.CordaRPCConnection import net.corda.client.rpc.CordaRPCConnection
import net.corda.nodeapi.internal.rpc.client.AMQPClientSerializationScheme
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.* import net.corda.core.internal.createDirectories
import net.corda.core.internal.deleteRecursively
import net.corda.core.internal.div
import net.corda.core.internal.toPath
import net.corda.core.internal.writeText
import net.corda.core.node.NotaryInfo import net.corda.core.node.NotaryInfo
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.nodeapi.internal.DevIdentityGenerator import net.corda.nodeapi.internal.DevIdentityGenerator
import net.corda.nodeapi.internal.config.User import net.corda.nodeapi.internal.config.User
import net.corda.nodeapi.internal.network.NetworkParametersCopier import net.corda.nodeapi.internal.network.NetworkParametersCopier
import net.corda.nodeapi.internal.rpc.client.AMQPClientSerializationScheme
import net.corda.testing.common.internal.asContextEnv import net.corda.testing.common.internal.asContextEnv
import net.corda.testing.common.internal.checkNotOnClasspath import net.corda.testing.common.internal.checkNotOnClasspath
import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.common.internal.testNetworkParameters
import java.lang.IllegalStateException
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import java.time.Instant import java.time.Instant
@ -32,6 +35,7 @@ class NodeProcess(
companion object { companion object {
const val CORDAPPS_DIR_NAME = "cordapps" const val CORDAPPS_DIR_NAME = "cordapps"
private val log = contextLogger() private val log = contextLogger()
private const val schemaCreationTimeOutSeconds: Long = 180
} }
fun connect(user: User): CordaRPCConnection { fun connect(user: User): CordaRPCConnection {
@ -103,6 +107,7 @@ class NodeProcess(
(nodeDir / "node.conf").writeText(config.toText()) (nodeDir / "node.conf").writeText(config.toText())
createNetworkParameters(NotaryInfo(notaryParty!!, true), nodeDir) createNetworkParameters(NotaryInfo(notaryParty!!, true), nodeDir)
createSchema(nodeDir)
val process = startNode(nodeDir) val process = startNode(nodeDir)
val client = CordaRPCClient(NetworkHostAndPort("localhost", config.rpcPort)) val client = CordaRPCClient(NetworkHostAndPort("localhost", config.rpcPort))
waitForNode(process, config, client) waitForNode(process, config, client)
@ -138,9 +143,25 @@ class NodeProcess(
} }
} }
private fun startNode(nodeDir: Path): Process { class SchemaCreationTimedOutError(nodeDir: Path) : Exception("Creating node schema timed out for $nodeDir")
class SchemaCreationFailedError(nodeDir: Path) : Exception("Creating node schema failed for $nodeDir")
private fun createSchema(nodeDir: Path){
val process = startNode(nodeDir, arrayOf("run-migration-scripts", "--core-schemas", "--app-schemas"))
if (!process.waitFor(schemaCreationTimeOutSeconds, SECONDS)) {
process.destroy()
throw SchemaCreationTimedOutError(nodeDir)
}
if (process.exitValue() != 0){
throw SchemaCreationFailedError(nodeDir)
}
}
@Suppress("SpreadOperator")
private fun startNode(nodeDir: Path, extraArgs: Array<String> = emptyArray()): Process {
val builder = ProcessBuilder() val builder = ProcessBuilder()
.command(javaPath.toString(), "-Dcapsule.log=verbose", "-jar", cordaJar.toString()) .command(javaPath.toString(), "-Dcapsule.log=verbose", "-jar", cordaJar.toString(), *extraArgs)
.directory(nodeDir.toFile()) .directory(nodeDir.toFile())
.redirectError(ProcessBuilder.Redirect.INHERIT) .redirectError(ProcessBuilder.Redirect.INHERIT)
.redirectOutput(ProcessBuilder.Redirect.INHERIT) .redirectOutput(ProcessBuilder.Redirect.INHERIT)