Use in-memory H2 for integration test (#2508)

* Default integration tests running with in-memory H2
This commit is contained in:
Maksymilian Pawlak 2018-07-05 14:58:51 +01:00 committed by GitHub
parent 02978fc174
commit f7dd4f7880
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 51 additions and 21 deletions

View File

@ -30,7 +30,7 @@ class FlowsExecutionModeRpcTest {
assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win"))
val user = User("mark", "dadada", setOf(invokeRpc("setFlowsDrainingModeEnabled"), invokeRpc("isFlowsDrainingModeEnabled"))) val user = User("mark", "dadada", setOf(invokeRpc("setFlowsDrainingModeEnabled"), invokeRpc("isFlowsDrainingModeEnabled")))
driver(DriverParameters(isDebug = true, startNodesInProcess = true)) { driver(DriverParameters(isDebug = true, inMemoryDB = false, startNodesInProcess = true)) {
val nodeName = { val nodeName = {
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow() val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
val nodeName = nodeHandle.nodeInfo.chooseIdentity().name val nodeName = nodeHandle.nodeInfo.chooseIdentity().name

View File

@ -37,7 +37,7 @@ class NodeStatePersistenceTests {
fun `persistent state survives node restart`() { fun `persistent state survives node restart`() {
val user = User("mark", "dadada", setOf(startFlow<SendMessageFlow>(), invokeRpc("vaultQuery"))) val user = User("mark", "dadada", setOf(startFlow<SendMessageFlow>(), invokeRpc("vaultQuery")))
val message = Message("Hello world!") val message = Message("Hello world!")
val stateAndRef: StateAndRef<MessageState>? = driver(DriverParameters(isDebug = true, startNodesInProcess = isQuasarAgentSpecified(), val stateAndRef: StateAndRef<MessageState>? = driver(DriverParameters(isDebug = true, inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(),
portAllocation = RandomFree, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) { portAllocation = RandomFree, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) {
val nodeName = { val nodeName = {
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow() val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
@ -70,7 +70,7 @@ class NodeStatePersistenceTests {
val user = User("mark", "dadada", setOf(startFlow<SendMessageFlow>(), invokeRpc("vaultQuery"))) val user = User("mark", "dadada", setOf(startFlow<SendMessageFlow>(), invokeRpc("vaultQuery")))
val message = Message("Hello world!") val message = Message("Hello world!")
val stateAndRef: StateAndRef<MessageState>? = driver(DriverParameters(isDebug = true, startNodesInProcess = isQuasarAgentSpecified(), portAllocation = RandomFree, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) { val stateAndRef: StateAndRef<MessageState>? = driver(DriverParameters(isDebug = true, inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(), portAllocation = RandomFree, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) {
val nodeName = { val nodeName = {
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow() val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
val nodeName = nodeHandle.nodeInfo.singleIdentity().name val nodeName = nodeHandle.nodeInfo.singleIdentity().name

View File

@ -61,7 +61,7 @@ class HardRestartTest {
@Test @Test
fun restartShortPingPongFlowRandomly() { fun restartShortPingPongFlowRandomly() {
val demoUser = User("demo", "demo", setOf(Permissions.startFlow<Ping>(), Permissions.all())) val demoUser = User("demo", "demo", setOf(Permissions.startFlow<Ping>(), Permissions.all()))
driver(DriverParameters(isDebug = true, startNodesInProcess = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
val (a, b) = listOf( val (a, b) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")), startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000")) startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000"))
@ -93,7 +93,7 @@ class HardRestartTest {
@Test @Test
fun restartLongPingPongFlowRandomly() { fun restartLongPingPongFlowRandomly() {
val demoUser = User("demo", "demo", setOf(Permissions.startFlow<Ping>(), Permissions.all())) val demoUser = User("demo", "demo", setOf(Permissions.startFlow<Ping>(), Permissions.all()))
driver(DriverParameters(isDebug = true, startNodesInProcess = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
val (a, b) = listOf( val (a, b) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")), startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000")) startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000"))
@ -125,7 +125,7 @@ class HardRestartTest {
@Test @Test
fun softRestartLongPingPongFlowRandomly() { fun softRestartLongPingPongFlowRandomly() {
val demoUser = User("demo", "demo", setOf(Permissions.startFlow<Ping>(), Permissions.all())) val demoUser = User("demo", "demo", setOf(Permissions.startFlow<Ping>(), Permissions.all()))
driver(DriverParameters(isDebug = true, startNodesInProcess = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
val (a, b) = listOf( val (a, b) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")), startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000")) startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000"))
@ -201,7 +201,7 @@ class HardRestartTest {
@Test @Test
fun restartRecursiveFlowRandomly() { fun restartRecursiveFlowRandomly() {
val demoUser = User("demo", "demo", setOf(Permissions.startFlow<RecursiveA>(), Permissions.all())) val demoUser = User("demo", "demo", setOf(Permissions.startFlow<RecursiveA>(), Permissions.all()))
driver(DriverParameters(isDebug = true, startNodesInProcess = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
val (a, b) = listOf( val (a, b) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")), startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000")) startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000"))

View File

@ -63,7 +63,7 @@ class P2PMessagingTest {
} }
assertThat(participatingNodes).containsOnlyElementsOf(participatingServiceNodes.map { it.services.myInfo }) assertThat(participatingNodes).containsOnlyElementsOf(participatingServiceNodes.map { it.services.myInfo })
} }
private fun InProcess.respondWith(message: Any) { private fun InProcess.respondWith(message: Any) {
internalServices.networkService.addMessageHandler("test.request") { netMessage, _, handler -> internalServices.networkService.addMessageHandler("test.request") { netMessage, _, handler ->
val request = netMessage.data.deserialize<TestRequest>() val request = netMessage.data.deserialize<TestRequest>()

View File

@ -34,7 +34,7 @@ class TraderDemoTest {
startFlow<CashPaymentFlow>(), startFlow<CashPaymentFlow>(),
startFlow<CommercialPaperIssueFlow>(), startFlow<CommercialPaperIssueFlow>(),
all())) all()))
driver(DriverParameters(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.finance"))) { driver(DriverParameters(startNodesInProcess = true, inMemoryDB = false, extraCordappPackagesToScan = listOf("net.corda.finance"))) {
val (nodeA, nodeB, bankNode) = listOf( val (nodeA, nodeB, bankNode) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser)), startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser)),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser)), startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser)),
@ -76,7 +76,7 @@ class TraderDemoTest {
@Test @Test
fun `Tudor test`() { fun `Tudor test`() {
driver(DriverParameters(isDebug = true, startNodesInProcess = false, extraCordappPackagesToScan = listOf("net.corda.finance"))) { driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, extraCordappPackagesToScan = listOf("net.corda.finance"))) {
val demoUser = User("demo", "demo", setOf(startFlow<SellerFlow>(), all())) val demoUser = User("demo", "demo", setOf(startFlow<SellerFlow>(), all()))
val bankUser = User("user1", "test", permissions = setOf(all())) val bankUser = User("user1", "test", permissions = setOf(all()))
val (nodeA, nodeB, bankNode) = listOf( val (nodeA, nodeB, bankNode) = listOf(

View File

@ -234,7 +234,8 @@ fun <A> driver(defaultParameters: DriverParameters = DriverParameters(), dsl: Dr
jmxPolicy = defaultParameters.jmxPolicy, jmxPolicy = defaultParameters.jmxPolicy,
compatibilityZone = null, compatibilityZone = null,
networkParameters = defaultParameters.networkParameters, networkParameters = defaultParameters.networkParameters,
notaryCustomOverrides = defaultParameters.notaryCustomOverrides notaryCustomOverrides = defaultParameters.notaryCustomOverrides,
inMemoryDB = defaultParameters.inMemoryDB
), ),
coerce = { it }, coerce = { it },
dsl = dsl, dsl = dsl,
@ -267,6 +268,10 @@ fun <A> driver(defaultParameters: DriverParameters = DriverParameters(), dsl: Dr
* @property networkParameters The network parameters to be used by all the nodes. [NetworkParameters.notaries] must be * @property networkParameters The network parameters to be used by all the nodes. [NetworkParameters.notaries] must be
* empty as notaries are defined by [notarySpecs]. * empty as notaries are defined by [notarySpecs].
* @property notaryCustomOverrides Extra settings that need to be passed to the notary. * @property notaryCustomOverrides Extra settings that need to be passed to the notary.
* @property initialiseSerialization Indicates whether to initialized the serialization subsystem.
* @property inMemoryDB Whether to use in-memory H2 for new nodes rather then on-disk (the node starts quicker, however
* the data is not persisted between node restarts). Has no effect if node is configured
* in any way to use database other than H2.
*/ */
@Suppress("unused") @Suppress("unused")
data class DriverParameters( data class DriverParameters(
@ -283,7 +288,8 @@ data class DriverParameters(
val jmxPolicy: JmxPolicy = JmxPolicy(), val jmxPolicy: JmxPolicy = JmxPolicy(),
val networkParameters: NetworkParameters = testNetworkParameters(notaries = emptyList()), val networkParameters: NetworkParameters = testNetworkParameters(notaries = emptyList()),
val notaryCustomOverrides: Map<String, Any?> = emptyMap(), val notaryCustomOverrides: Map<String, Any?> = emptyMap(),
val initialiseSerialization: Boolean = true val initialiseSerialization: Boolean = true,
val inMemoryDB: Boolean = true
) { ) {
constructor( constructor(
isDebug: Boolean, isDebug: Boolean,
@ -312,6 +318,7 @@ data class DriverParameters(
jmxPolicy, jmxPolicy,
networkParameters, networkParameters,
emptyMap(), emptyMap(),
true,
true true
) )
@ -328,7 +335,8 @@ data class DriverParameters(
extraCordappPackagesToScan: List<String>, extraCordappPackagesToScan: List<String>,
jmxPolicy: JmxPolicy, jmxPolicy: JmxPolicy,
networkParameters: NetworkParameters, networkParameters: NetworkParameters,
initialiseSerialization: Boolean initialiseSerialization: Boolean,
inMemoryDB: Boolean
) : this( ) : this(
isDebug, isDebug,
driverDirectory, driverDirectory,
@ -343,7 +351,8 @@ data class DriverParameters(
jmxPolicy, jmxPolicy,
networkParameters, networkParameters,
emptyMap(), emptyMap(),
initialiseSerialization initialiseSerialization,
inMemoryDB
) )
fun withIsDebug(isDebug: Boolean): DriverParameters = copy(isDebug = isDebug) fun withIsDebug(isDebug: Boolean): DriverParameters = copy(isDebug = isDebug)
@ -360,6 +369,7 @@ data class DriverParameters(
fun withJmxPolicy(jmxPolicy: JmxPolicy): DriverParameters = copy(jmxPolicy = jmxPolicy) fun withJmxPolicy(jmxPolicy: JmxPolicy): DriverParameters = copy(jmxPolicy = jmxPolicy)
fun withNetworkParameters(networkParameters: NetworkParameters): DriverParameters = copy(networkParameters = networkParameters) fun withNetworkParameters(networkParameters: NetworkParameters): DriverParameters = copy(networkParameters = networkParameters)
fun withNotaryCustomOverrides(notaryCustomOverrides: Map<String, Any?>): DriverParameters = copy(notaryCustomOverrides = notaryCustomOverrides) fun withNotaryCustomOverrides(notaryCustomOverrides: Map<String, Any?>): DriverParameters = copy(notaryCustomOverrides = notaryCustomOverrides)
fun withInMemoryDB(inMemoryDB: Boolean): DriverParameters = copy(inMemoryDB = inMemoryDB)
fun copy( fun copy(
isDebug: Boolean, isDebug: Boolean,

View File

@ -73,6 +73,7 @@ import java.util.*
import java.util.concurrent.Executors import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.collections.HashMap import kotlin.collections.HashMap
import kotlin.concurrent.thread import kotlin.concurrent.thread
@ -92,7 +93,8 @@ class DriverDSLImpl(
val notarySpecs: List<NotarySpec>, val notarySpecs: List<NotarySpec>,
val compatibilityZone: CompatibilityZoneParams?, val compatibilityZone: CompatibilityZoneParams?,
val networkParameters: NetworkParameters, val networkParameters: NetworkParameters,
val notaryCustomOverrides: Map<String, Any?> val notaryCustomOverrides: Map<String, Any?>,
val inMemoryDB: Boolean
) : InternalDriverDSL { ) : InternalDriverDSL {
private var _executorService: ScheduledExecutorService? = null private var _executorService: ScheduledExecutorService? = null
@ -111,6 +113,9 @@ class DriverDSLImpl(
private lateinit var _notaries: CordaFuture<List<NotaryHandle>> private lateinit var _notaries: CordaFuture<List<NotaryHandle>>
override val notaryHandles: List<NotaryHandle> get() = _notaries.getOrThrow() override val notaryHandles: List<NotaryHandle> get() = _notaries.getOrThrow()
// While starting with inProcess mode, we need to have different names to avoid clashes
private val inMemoryCounter = AtomicInteger()
interface Waitable { interface Waitable {
@Throws(InterruptedException::class) @Throws(InterruptedException::class)
fun waitFor() fun waitFor()
@ -127,6 +132,16 @@ class DriverDSLImpl(
private val jolokiaJarPath: String by lazy { resolveJar(".*jolokia-jvm-.*-agent\\.jar$") } private val jolokiaJarPath: String by lazy { resolveJar(".*jolokia-jvm-.*-agent\\.jar$") }
private fun NodeConfig.checkAndOverrideForInMemoryDB(): NodeConfig = this.run {
if (inMemoryDB && corda.dataSourceProperties.getProperty("dataSource.url").startsWith("jdbc:h2:")) {
val jdbcUrl = "jdbc:h2:mem:persistence${inMemoryCounter.getAndIncrement()};DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=10000;WRITE_DELAY=100"
corda.dataSourceProperties.setProperty("dataSource.url", jdbcUrl)
NodeConfig(typesafe = typesafe + mapOf("dataSourceProperties" to mapOf("dataSource.url" to jdbcUrl)), corda = corda)
} else {
this
}
}
private fun resolveJar(jarNamePattern: String): String { private fun resolveJar(jarNamePattern: String): String {
return try { return try {
val cl = ClassLoader.getSystemClassLoader() val cl = ClassLoader.getSystemClassLoader()
@ -234,7 +249,7 @@ class DriverDSLImpl(
baseDirectory = baseDirectory(name), baseDirectory = baseDirectory(name),
allowMissingConfig = true, allowMissingConfig = true,
configOverrides = if (overrides.hasPath("devMode")) overrides else overrides + mapOf("devMode" to true) configOverrides = if (overrides.hasPath("devMode")) overrides else overrides + mapOf("devMode" to true)
)) )).checkAndOverrideForInMemoryDB()
return startNodeInternal(config, webAddress, startInSameProcess, maximumHeapSize, localNetworkMap) return startNodeInternal(config, webAddress, startInSameProcess, maximumHeapSize, localNetworkMap)
} }
@ -252,7 +267,7 @@ class DriverDSLImpl(
"adminAddress" to portAllocation.nextHostAndPort().toString() "adminAddress" to portAllocation.nextHostAndPort().toString()
), ),
"devMode" to false) "devMode" to false)
)) )).checkAndOverrideForInMemoryDB()
val versionInfo = VersionInfo(1, "1", "1", "1") val versionInfo = VersionInfo(1, "1", "1", "1")
config.corda.certificatesDirectory.createDirectories() config.corda.certificatesDirectory.createDirectories()
@ -375,7 +390,7 @@ class DriverDSLImpl(
configOverrides = rawConfig.toNodeOnly() configOverrides = rawConfig.toNodeOnly()
) )
val cordaConfig = typesafe.parseAsNodeConfiguration() val cordaConfig = typesafe.parseAsNodeConfiguration()
val config = NodeConfig(rawConfig, cordaConfig) val config = NodeConfig(rawConfig, cordaConfig).checkAndOverrideForInMemoryDB()
return startNodeInternal(config, webAddress, null, "512m", localNetworkMap) return startNodeInternal(config, webAddress, null, "512m", localNetworkMap)
} }
@ -1056,7 +1071,8 @@ fun <DI : DriverDSL, D : InternalDriverDSL, A> genericDriver(
notarySpecs = defaultParameters.notarySpecs, notarySpecs = defaultParameters.notarySpecs,
compatibilityZone = null, compatibilityZone = null,
networkParameters = defaultParameters.networkParameters, networkParameters = defaultParameters.networkParameters,
notaryCustomOverrides = defaultParameters.notaryCustomOverrides notaryCustomOverrides = defaultParameters.notaryCustomOverrides,
inMemoryDB = defaultParameters.inMemoryDB
) )
) )
val shutdownHook = addShutdownHook(driverDsl::shutdown) val shutdownHook = addShutdownHook(driverDsl::shutdown)
@ -1135,6 +1151,7 @@ fun <A> internalDriver(
networkParameters: NetworkParameters = DriverParameters().networkParameters, networkParameters: NetworkParameters = DriverParameters().networkParameters,
compatibilityZone: CompatibilityZoneParams? = null, compatibilityZone: CompatibilityZoneParams? = null,
notaryCustomOverrides: Map<String, Any?> = DriverParameters().notaryCustomOverrides, notaryCustomOverrides: Map<String, Any?> = DriverParameters().notaryCustomOverrides,
inMemoryDB: Boolean = DriverParameters().inMemoryDB,
dsl: DriverDSLImpl.() -> A dsl: DriverDSLImpl.() -> A
): A { ): A {
return genericDriver( return genericDriver(
@ -1152,7 +1169,8 @@ fun <A> internalDriver(
jmxPolicy = jmxPolicy, jmxPolicy = jmxPolicy,
compatibilityZone = compatibilityZone, compatibilityZone = compatibilityZone,
networkParameters = networkParameters, networkParameters = networkParameters,
notaryCustomOverrides = notaryCustomOverrides notaryCustomOverrides = notaryCustomOverrides,
inMemoryDB = inMemoryDB
), ),
coerce = { it }, coerce = { it },
dsl = dsl, dsl = dsl,

View File

@ -115,6 +115,7 @@ fun <A> rpcDriver(
jmxPolicy: JmxPolicy = JmxPolicy(), jmxPolicy: JmxPolicy = JmxPolicy(),
networkParameters: NetworkParameters = testNetworkParameters(), networkParameters: NetworkParameters = testNetworkParameters(),
notaryCustomOverrides: Map<String, Any?> = emptyMap(), notaryCustomOverrides: Map<String, Any?> = emptyMap(),
inMemoryDB: Boolean = true,
dsl: RPCDriverDSL.() -> A dsl: RPCDriverDSL.() -> A
): A { ): A {
return genericDriver( return genericDriver(
@ -133,7 +134,8 @@ fun <A> rpcDriver(
jmxPolicy = jmxPolicy, jmxPolicy = jmxPolicy,
compatibilityZone = null, compatibilityZone = null,
networkParameters = networkParameters, networkParameters = networkParameters,
notaryCustomOverrides = notaryCustomOverrides notaryCustomOverrides = notaryCustomOverrides,
inMemoryDB = inMemoryDB
), externalTrace ), externalTrace
), ),
coerce = { it }, coerce = { it },