From 6b2b663ab3b47792941422389aa348206136d8cc Mon Sep 17 00:00:00 2001 From: Andrzej Cichocki Date: Tue, 31 Oct 2017 17:10:37 +0000 Subject: [PATCH] CORDA-716 Retire MockNetwork.Factory (#1937) --- .../net/corda/core/flows/AttachmentTests.kt | 11 +++----- .../AttachmentSerializationTest.kt | 9 +++---- .../node/messaging/TwoPartyTradeFlowTests.kt | 12 ++++----- .../vault/VaultSoftLockManagerTest.kt | 17 +++++------- .../corda/netmap/simulation/IRSSimulation.kt | 2 +- .../net/corda/netmap/simulation/Simulation.kt | 26 +++++++++--------- .../kotlin/net/corda/testing/node/MockNode.kt | 27 +++++++------------ .../node/MockNodeFactoryInJavaTest.java | 25 +++++++++++++++++ 8 files changed, 66 insertions(+), 63 deletions(-) create mode 100644 testing/node-driver/src/test/java/net/corda/testing/node/MockNodeFactoryInJavaTest.java diff --git a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt index 81e67b3b6e..1824be00a9 100644 --- a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt @@ -14,7 +14,6 @@ import net.corda.testing.ALICE import net.corda.testing.ALICE_NAME import net.corda.testing.BOB import net.corda.testing.node.MockNetwork -import net.corda.testing.node.MockNodeArgs import net.corda.testing.node.MockNodeParameters import net.corda.testing.singleIdentity import org.junit.After @@ -109,13 +108,11 @@ class AttachmentTests { } @Test - fun `malicious response`() { + fun maliciousResponse() { // Make a node that doesn't do sanity checking at load time. - val aliceNode = mockNet.createNotaryNode(MockNodeParameters(legalName = ALICE.name), nodeFactory = object : MockNetwork.Factory { - override fun create(args: MockNodeArgs): MockNetwork.MockNode { - return object : MockNetwork.MockNode(args) { - override fun start() = super.start().apply { attachments.checkAttachmentsOnLoad = false } - } + val aliceNode = mockNet.createNotaryNode(MockNodeParameters(legalName = ALICE.name), nodeFactory = { args -> + object : MockNetwork.MockNode(args) { + override fun start() = super.start().apply { attachments.checkAttachmentsOnLoad = false } } }, validating = false) val bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB.name)) diff --git a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt index 8057164bcf..2828bb31b9 100644 --- a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt +++ b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt @@ -17,7 +17,6 @@ import net.corda.node.services.persistence.NodeAttachmentService import net.corda.node.utilities.currentDBSession import net.corda.testing.chooseIdentity import net.corda.testing.node.MockNetwork -import net.corda.testing.node.MockNodeArgs import net.corda.testing.node.MockNodeParameters import org.junit.After import org.junit.Before @@ -156,11 +155,9 @@ class AttachmentSerializationTest { private fun rebootClientAndGetAttachmentContent(checkAttachmentsOnLoad: Boolean = true): String { client.dispose() - client = mockNet.createNode(MockNodeParameters(client.internals.id), object : MockNetwork.Factory { - override fun create(args: MockNodeArgs): MockNetwork.MockNode { - return object : MockNetwork.MockNode(args) { - override fun start() = super.start().apply { attachments.checkAttachmentsOnLoad = checkAttachmentsOnLoad } - } + client = mockNet.createNode(MockNodeParameters(client.internals.id), { args -> + object : MockNetwork.MockNode(args) { + override fun start() = super.start().apply { attachments.checkAttachmentsOnLoad = checkAttachmentsOnLoad } } }) return (client.smm.allStateMachines[0].stateMachine.resultFuture.apply { mockNet.runNetwork() }.getOrThrow() as ClientResult).attachmentContent diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt index c5f893965e..451b1c2d9c 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -294,13 +294,11 @@ class TwoPartyTradeFlowTests(val anonymous: Boolean) { // of gets and puts. private fun makeNodeWithTracking(name: CordaX500Name): StartedNode { // Create a node in the mock network ... - return mockNet.createNode(MockNodeParameters(legalName = name), nodeFactory = object : MockNetwork.Factory { - override fun create(args: MockNodeArgs): MockNetwork.MockNode { - return object : MockNetwork.MockNode(args) { - // That constructs a recording tx storage - override fun makeTransactionStorage(): WritableTransactionStorage { - return RecordingTransactionStorage(database, super.makeTransactionStorage()) - } + return mockNet.createNode(MockNodeParameters(legalName = name), nodeFactory = { args -> + object : MockNetwork.MockNode(args) { + // That constructs a recording tx storage + override fun makeTransactionStorage(): WritableTransactionStorage { + return RecordingTransactionStorage(database, super.makeTransactionStorage()) } } }) diff --git a/node/src/test/kotlin/net/corda/node/services/vault/VaultSoftLockManagerTest.kt b/node/src/test/kotlin/net/corda/node/services/vault/VaultSoftLockManagerTest.kt index ae1ac4da8f..16aa63254d 100644 --- a/node/src/test/kotlin/net/corda/node/services/vault/VaultSoftLockManagerTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/vault/VaultSoftLockManagerTest.kt @@ -28,7 +28,6 @@ import net.corda.node.services.api.VaultServiceInternal import net.corda.testing.chooseIdentity import net.corda.testing.node.MockNetwork import net.corda.testing.rigorousMock -import net.corda.testing.node.MockNodeArgs import net.corda.testing.node.MockNodeParameters import org.junit.After import org.junit.Test @@ -80,15 +79,13 @@ class VaultSoftLockManagerTest { private val mockVault = rigorousMock().also { doNothing().whenever(it).softLockRelease(any(), anyOrNull()) } - private val mockNet = MockNetwork(cordappPackages = listOf(ContractImpl::class.packageName), defaultFactory = object : MockNetwork.Factory { - override fun create(args: MockNodeArgs): MockNetwork.MockNode { - return object : MockNetwork.MockNode(args) { - override fun makeVaultService(keyManagementService: KeyManagementService, stateLoader: StateLoader): VaultServiceInternal { - val realVault = super.makeVaultService(keyManagementService, stateLoader) - return object : VaultServiceInternal by realVault { - override fun softLockRelease(lockId: UUID, stateRefs: NonEmptySet?) { - mockVault.softLockRelease(lockId, stateRefs) // No need to also call the real one for these tests. - } + private val mockNet = MockNetwork(cordappPackages = listOf(ContractImpl::class.packageName), defaultFactory = { args -> + object : MockNetwork.MockNode(args) { + override fun makeVaultService(keyManagementService: KeyManagementService, stateLoader: StateLoader): VaultServiceInternal { + val realVault = super.makeVaultService(keyManagementService, stateLoader) + return object : VaultServiceInternal by realVault { + override fun softLockRelease(lockId: UUID, stateRefs: NonEmptySet?) { + mockVault.softLockRelease(lockId, stateRefs) // No need to also call the real one for these tests. } } } diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt index 5b73073155..ae34b399da 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt @@ -133,7 +133,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten val irs = om.readValue(javaClass.classLoader.getResourceAsStream("net/corda/irs/web/simulation/trade.json") .reader() .readText() - .replace("oracleXXX", RatesOracleFactory.RATES_SERVICE_NAME.toString())) + .replace("oracleXXX", RatesOracleNode.RATES_SERVICE_NAME.toString())) irs.fixedLeg.fixedRatePayer = node1.info.chooseIdentity() irs.floatingLeg.floatingRatePayer = node2.info.chooseIdentity() diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt index d186a74484..4e774cc191 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt @@ -50,20 +50,18 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, val bankLocations = listOf(Pair("London", "GB"), Pair("Frankfurt", "DE"), Pair("Rome", "IT")) - object RatesOracleFactory : MockNetwork.Factory { - // TODO: Make a more realistic legal name - val RATES_SERVICE_NAME = CordaX500Name(organisation = "Rates Service Provider", locality = "Madrid", country = "ES") + class RatesOracleNode(args: MockNodeArgs) : MockNode(args) { + companion object { + // TODO: Make a more realistic legal name + val RATES_SERVICE_NAME = CordaX500Name(organisation = "Rates Service Provider", locality = "Madrid", country = "ES") + } - override fun create(args: MockNodeArgs): MockNode { - return object : MockNode(args) { - override fun start() = super.start().apply { - registerInitiatedFlow(NodeInterestRates.FixQueryHandler::class.java) - registerInitiatedFlow(NodeInterestRates.FixSignHandler::class.java) - javaClass.classLoader.getResourceAsStream("net/corda/irs/simulation/example.rates.txt").use { - database.transaction { - findTokenizableService(NodeInterestRates.Oracle::class.java)!!.uploadFixes(it.reader().readText()) - } - } + override fun start() = super.start().apply { + registerInitiatedFlow(NodeInterestRates.FixQueryHandler::class.java) + registerInitiatedFlow(NodeInterestRates.FixSignHandler::class.java) + javaClass.classLoader.getResourceAsStream("net/corda/irs/simulation/example.rates.txt").use { + database.transaction { + findTokenizableService(NodeInterestRates.Oracle::class.java)!!.uploadFixes(it.reader().readText()) } } } @@ -78,7 +76,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, // So we just fire a message at a node that doesn't know how to handle it, and it'll ignore it. // But that's fine for visualisation purposes. val regulators = listOf(mockNet.createUnstartedNode(defaultParams.copy(legalName = DUMMY_REGULATOR.name))) - val ratesOracle = mockNet.createUnstartedNode(defaultParams.copy(legalName = RatesOracleFactory.RATES_SERVICE_NAME), RatesOracleFactory) + val ratesOracle = mockNet.createUnstartedNode(defaultParams.copy(legalName = RatesOracleNode.RATES_SERVICE_NAME), ::RatesOracleNode) // All nodes must be in one of these two lists for the purposes of the visualiser tool. val serviceProviders: List = listOf(notary.internals, ratesOracle) val banks: List = bankLocations.mapIndexed { i, (city, country) -> diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt index 5f008e40d0..0dd7089795 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt @@ -63,13 +63,13 @@ data class MockNetworkParameters( val networkSendManuallyPumped: Boolean = false, val threadPerNode: Boolean = false, val servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = InMemoryMessagingNetwork.ServicePeerAllocationStrategy.Random(), - val defaultFactory: MockNetwork.Factory<*> = MockNetwork.DefaultFactory, + val defaultFactory: (MockNodeArgs) -> MockNetwork.MockNode = MockNetwork::MockNode, val initialiseSerialization: Boolean = true, val cordappPackages: List = emptyList()) { fun setNetworkSendManuallyPumped(networkSendManuallyPumped: Boolean) = copy(networkSendManuallyPumped = networkSendManuallyPumped) fun setThreadPerNode(threadPerNode: Boolean) = copy(threadPerNode = threadPerNode) fun setServicePeerAllocationStrategy(servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy) = copy(servicePeerAllocationStrategy = servicePeerAllocationStrategy) - fun setDefaultFactory(defaultFactory: MockNetwork.Factory<*>) = copy(defaultFactory = defaultFactory) + fun setDefaultFactory(defaultFactory: (MockNodeArgs) -> MockNetwork.MockNode) = copy(defaultFactory = defaultFactory) fun setInitialiseSerialization(initialiseSerialization: Boolean) = copy(initialiseSerialization = initialiseSerialization) fun setCordappPackages(cordappPackages: List) = copy(cordappPackages = cordappPackages) } @@ -119,7 +119,7 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete private val networkSendManuallyPumped: Boolean = defaultParameters.networkSendManuallyPumped, private val threadPerNode: Boolean = defaultParameters.threadPerNode, servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy, - private val defaultFactory: Factory<*> = defaultParameters.defaultFactory, + private val defaultFactory: (MockNodeArgs) -> MockNode = defaultParameters.defaultFactory, initialiseSerialization: Boolean = defaultParameters.initialiseSerialization, private val cordappPackages: List = defaultParameters.cordappPackages) : Closeable { /** Helper constructor for creating a [MockNetwork] with custom parameters from Java. */ @@ -141,15 +141,6 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete filesystem.getPath("/nodes").createDirectory() } - /** Allows customisation of how nodes are created. */ - interface Factory { - fun create(args: MockNodeArgs): N - } - - object DefaultFactory : Factory { - override fun create(args: MockNodeArgs) = MockNode(args) - } - /** * Because this executor is shared, we need to be careful about nodes shutting it down. */ @@ -286,19 +277,19 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete } fun createUnstartedNode(parameters: MockNodeParameters = MockNodeParameters()) = createUnstartedNode(parameters, defaultFactory) - fun createUnstartedNode(parameters: MockNodeParameters = MockNodeParameters(), nodeFactory: Factory): N { + fun createUnstartedNode(parameters: MockNodeParameters = MockNodeParameters(), nodeFactory: (MockNodeArgs) -> N): N { return createNodeImpl(parameters, nodeFactory, false) } fun createNode(parameters: MockNodeParameters = MockNodeParameters()): StartedNode = createNode(parameters, defaultFactory) - /** Like the other [createNode] but takes a [Factory] and propagates its [MockNode] subtype. */ - fun createNode(parameters: MockNodeParameters = MockNodeParameters(), nodeFactory: Factory): StartedNode { + /** Like the other [createNode] but takes a [nodeFactory] and propagates its [MockNode] subtype. */ + fun createNode(parameters: MockNodeParameters = MockNodeParameters(), nodeFactory: (MockNodeArgs) -> N): StartedNode { val node: StartedNode = uncheckedCast(createNodeImpl(parameters, nodeFactory, true).started)!! ensureAllNetworkMapCachesHaveAllNodeInfos() return node } - private fun createNodeImpl(parameters: MockNodeParameters, nodeFactory: Factory, start: Boolean): N { + private fun createNodeImpl(parameters: MockNodeParameters, nodeFactory: (MockNodeArgs) -> N, start: Boolean): N { val id = parameters.forcedID ?: nextNodeId++ val config = testNodeConfiguration( baseDirectory = baseDirectory(id).createDirectories(), @@ -306,7 +297,7 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete doReturn(makeTestDataSourceProperties("node_${id}_net_$networkId")).whenever(it).dataSourceProperties parameters.configOverrides(it) } - return nodeFactory.create(MockNodeArgs(config, this, id, parameters.notaryIdentity, parameters.entropyRoot)).apply { + return nodeFactory(MockNodeArgs(config, this, id, parameters.notaryIdentity, parameters.entropyRoot)).apply { if (start) { start() if (threadPerNode) nodeReadyFuture.getOrThrow() // XXX: What about manually-started nodes? @@ -347,7 +338,7 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete fun createNotaryNode(parameters: MockNodeParameters = MockNodeParameters(legalName = DUMMY_NOTARY.name), validating: Boolean = true, - nodeFactory: Factory): StartedNode { + nodeFactory: (MockNodeArgs) -> N): StartedNode { return createNode(parameters.copy(configOverrides = { doReturn(NotaryConfig(validating)).whenever(it).notary parameters.configOverrides(it) diff --git a/testing/node-driver/src/test/java/net/corda/testing/node/MockNodeFactoryInJavaTest.java b/testing/node-driver/src/test/java/net/corda/testing/node/MockNodeFactoryInJavaTest.java new file mode 100644 index 0000000000..4e6b9215ca --- /dev/null +++ b/testing/node-driver/src/test/java/net/corda/testing/node/MockNodeFactoryInJavaTest.java @@ -0,0 +1,25 @@ +package net.corda.testing.node; + +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("unused") +public class MockNodeFactoryInJavaTest { + private static class CustomNode extends MockNetwork.MockNode { + private CustomNode(@NotNull MockNodeArgs args) { + super(args); + } + } + + /** + * Does not need to run, only compile. + */ + @SuppressWarnings("unused") + private static void factoryIsEasyToPassInUsingJava() { + //noinspection Convert2MethodRef + new MockNetwork(new MockNetworkParameters().setDefaultFactory(args -> new CustomNode(args))); + new MockNetwork(new MockNetworkParameters().setDefaultFactory(CustomNode::new)); + //noinspection Convert2MethodRef + new MockNetwork().createNode(new MockNodeParameters(), args -> new CustomNode(args)); + new MockNetwork().createNode(new MockNodeParameters(), CustomNode::new); + } +}