From 8668f4aa3b11d775b9b04dddac12d30dad11f872 Mon Sep 17 00:00:00 2001 From: Maksymilian Pawlak Date: Fri, 8 Jun 2018 18:17:39 +0100 Subject: [PATCH] [CORDA-1494] Enable TimeFlow test integration tests to run properly with external DBs (#962) --- .../net/corda/node/services/TimedFlowTests.kt | 139 ++++++++++-------- 1 file changed, 76 insertions(+), 63 deletions(-) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/TimedFlowTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/TimedFlowTests.kt index 7ac0f1a59e..f0ffec54ec 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/TimedFlowTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/TimedFlowTests.kt @@ -34,98 +34,111 @@ import net.corda.node.internal.StartedNode import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NotaryConfig import net.corda.node.services.config.P2PMessagingRetryConfiguration +import net.corda.node.services.vault.VaultQueryIntegrationTests import net.corda.nodeapi.internal.DevIdentityGenerator import net.corda.nodeapi.internal.network.NetworkParametersCopier import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.contracts.DummyContract import net.corda.testing.core.dummyCommand import net.corda.testing.core.singleIdentity +import net.corda.testing.internal.GlobalDatabaseRule import net.corda.testing.internal.LogHelper +import net.corda.testing.internal.toDatabaseSchemaName import net.corda.testing.node.InMemoryMessagingNetwork import net.corda.testing.node.MockNetworkParameters import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.internal.InternalMockNodeParameters import net.corda.testing.node.internal.startFlow -import org.junit.AfterClass -import org.junit.Before -import org.junit.BeforeClass -import org.junit.Test +import org.junit.* +import org.junit.rules.ExternalResource +import org.junit.rules.RuleChain import org.slf4j.MDC import java.security.PublicKey import java.util.concurrent.atomic.AtomicInteger +class TimedFlowTestRule(val clusterSize: Int) : ExternalResource() { + + lateinit var mockNet: InternalMockNetwork + lateinit var notary: Party + lateinit var node: StartedNode + + private fun startClusterAndNode(mockNet: InternalMockNetwork): Pair> { + val replicaIds = (0 until clusterSize) + val notaryIdentity = DevIdentityGenerator.generateDistributedNotaryCompositeIdentity( + replicaIds.map { mockNet.baseDirectory(mockNet.nextNodeId + it) }, + CordaX500Name("Custom Notary", "Zurich", "CH")) + + val networkParameters = NetworkParametersCopier(testNetworkParameters(listOf(NotaryInfo(notaryIdentity, true)))) + val notaryConfig = mock { + whenever(it.custom).thenReturn(true) + whenever(it.isClusterConfig).thenReturn(true) + whenever(it.validating).thenReturn(true) + } + + val notaryNodes = (0 until clusterSize).map { + mockNet.createUnstartedNode(InternalMockNodeParameters(configOverrides = { + doReturn(notaryConfig).whenever(it).notary + })) + } + + val aliceNode = mockNet.createUnstartedNode( + InternalMockNodeParameters( + legalName = CordaX500Name("Alice", "AliceCorp", "GB"), + configOverrides = { conf: NodeConfiguration -> + val retryConfig = P2PMessagingRetryConfiguration(10.seconds, 3, 1.0) + doReturn(retryConfig).whenever(conf).p2pMessagingRetry + } + ) + ) + + // MockNetwork doesn't support notary clusters, so we create all the nodes we need unstarted, and then install the + // network-parameters in their directories before they're started. + val node = (notaryNodes + aliceNode).map { node -> + networkParameters.install(mockNet.baseDirectory(node.id)) + node.start() + }.last() + + return Pair(notaryIdentity, node) + } + + + override fun before() { + mockNet = InternalMockNetwork( + listOf("net.corda.testing.contracts", "net.corda.node.services"), + MockNetworkParameters().withServicePeerAllocationStrategy(InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin()), + threadPerNode = true + ) + val started = startClusterAndNode(mockNet) + notary = started.first + node = started.second + } + + override fun after() { + mockNet.stopNodes() + } +} + class TimedFlowTests { companion object { - /** The notary nodes don't run any consensus protocol, so 2 nodes are sufficient for the purpose of this test. */ - private const val CLUSTER_SIZE = 2 /** A shared counter across all notary service nodes. */ var requestsReceived: AtomicInteger = AtomicInteger(0) - private lateinit var mockNet: InternalMockNetwork - private lateinit var notary: Party - private lateinit var node: StartedNode + private val notary by lazy { globalRule.notary } + private val node by lazy { globalRule.node } init { LogHelper.setLevel("+net.corda.flow", "+net.corda.testing.node", "+net.corda.node.services.messaging") } - @BeforeClass - @JvmStatic - fun setup() { - mockNet = InternalMockNetwork( - listOf("net.corda.testing.contracts", "net.corda.node.services"), - MockNetworkParameters().withServicePeerAllocationStrategy(InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin()), - threadPerNode = true - ) - val started = startClusterAndNode(mockNet) - notary = started.first - node = started.second - } + /** node_0 for default notary created by mock network + alice + cluster size = 5 */ + private val globalDatabaseRule = GlobalDatabaseRule(listOf("node_0", "node_1", "node_2", "node_3")) - @AfterClass - @JvmStatic - fun stopNodes() { - mockNet.stopNodes() - } + /** The notary nodes don't run any consensus protocol, so 2 nodes are sufficient for the purpose of this test. */ + private val globalRule = TimedFlowTestRule(2) - private fun startClusterAndNode(mockNet: InternalMockNetwork): Pair> { - val replicaIds = (0 until CLUSTER_SIZE) - val notaryIdentity = DevIdentityGenerator.generateDistributedNotaryCompositeIdentity( - replicaIds.map { mockNet.baseDirectory(mockNet.nextNodeId + it) }, - CordaX500Name("Custom Notary", "Zurich", "CH")) + @ClassRule @JvmField + val ruleChain = RuleChain.outerRule(globalDatabaseRule).around(globalRule) - val networkParameters = NetworkParametersCopier(testNetworkParameters(listOf(NotaryInfo(notaryIdentity, true)))) - val notaryConfig = mock { - whenever(it.custom).thenReturn(true) - whenever(it.isClusterConfig).thenReturn(true) - whenever(it.validating).thenReturn(true) - } - - val notaryNodes = (0 until CLUSTER_SIZE).map { - mockNet.createUnstartedNode(InternalMockNodeParameters(configOverrides = { - doReturn(notaryConfig).whenever(it).notary - })) - } - - val aliceNode = mockNet.createUnstartedNode( - InternalMockNodeParameters( - legalName = CordaX500Name("Alice", "AliceCorp", "GB"), - configOverrides = { conf: NodeConfiguration -> - val retryConfig = P2PMessagingRetryConfiguration(1.seconds, 3, 1.0) - doReturn(retryConfig).whenever(conf).p2pMessagingRetry - } - ) - ) - - // MockNetwork doesn't support notary clusters, so we create all the nodes we need unstarted, and then install the - // network-parameters in their directories before they're started. - val node = (notaryNodes + aliceNode).map { node -> - networkParameters.install(mockNet.baseDirectory(node.id)) - node.start() - }.last() - - return Pair(notaryIdentity, node) - } } @Before