diff --git a/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt b/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt index f8f5c58dcf..e033dc2b75 100644 --- a/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt +++ b/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt @@ -75,7 +75,7 @@ class NodeMonitorModelTest { vaultUpdates = monitor.vaultUpdates.bufferUntilSubscribed() networkMapUpdates = monitor.networkMap.bufferUntilSubscribed() - monitor.register(aliceNodeHandle.configuration.rpcOptions.address!!, cashUser.username, cashUser.password) + monitor.register(aliceNodeHandle.rpcAddress, cashUser.username, cashUser.password) rpc = monitor.proxyObservable.value!! notaryParty = defaultNotaryIdentity @@ -83,7 +83,7 @@ class NodeMonitorModelTest { bobNode = bobNodeHandle.nodeInfo val monitorBob = NodeMonitorModel() stateMachineUpdatesBob = monitorBob.stateMachineUpdates.bufferUntilSubscribed() - monitorBob.register(bobNodeHandle.configuration.rpcOptions.address!!, cashUser.username, cashUser.password) + monitorBob.register(bobNodeHandle.rpcAddress, cashUser.username, cashUser.password) rpcBob = monitorBob.proxyObservable.value!! runTest() } diff --git a/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java b/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java index b5b8371959..d7a1d863d7 100644 --- a/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java +++ b/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java @@ -3,9 +3,9 @@ package net.corda.core.flows; import co.paralleluniverse.fibers.Suspendable; import com.google.common.primitives.Primitives; import net.corda.core.identity.Party; -import net.corda.node.internal.StartedNode; import net.corda.testing.core.TestConstants; import net.corda.testing.node.MockNetwork; +import net.corda.testing.node.StartedMockNode; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -21,8 +21,8 @@ import static net.corda.testing.node.NodeTestUtils.startFlow; public class FlowsInJavaTest { private final MockNetwork mockNet = new MockNetwork(emptyList()); - private StartedNode aliceNode; - private StartedNode bobNode; + private StartedMockNode aliceNode; + private StartedMockNode bobNode; private Party bob; @Before 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 5499040845..6c31273511 100644 --- a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt @@ -15,6 +15,7 @@ import net.corda.testing.core.BOB_NAME import net.corda.testing.core.singleIdentity import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNodeParameters +import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.startFlow import org.junit.After import org.junit.Before @@ -27,11 +28,11 @@ import kotlin.test.assertEquals import kotlin.test.assertFailsWith class AttachmentTests { - lateinit var mockNet: MockNetwork + lateinit var mockNet: InternalMockNetwork @Before fun setUp() { - mockNet = MockNetwork(emptyList()) + mockNet = InternalMockNetwork(emptyList()) } @After @@ -100,7 +101,7 @@ class AttachmentTests { fun maliciousResponse() { // Make a node that doesn't do sanity checking at load time. val aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME), nodeFactory = { args -> - object : MockNetwork.MockNode(args) { + object : InternalMockNetwork.MockNode(args) { override fun start() = super.start().apply { attachments.checkAttachmentsOnLoad = false } } }) diff --git a/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt index d3bbcd9dc8..2dfbb59352 100644 --- a/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt @@ -11,11 +11,11 @@ import net.corda.core.identity.groupAbstractPartyByWellKnownParty import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.getOrThrow -import net.corda.node.internal.StartedNode import net.corda.testing.contracts.DummyContract import net.corda.testing.core.* import net.corda.testing.internal.rigorousMock import net.corda.testing.node.MockNetwork +import net.corda.testing.node.StartedMockNode import net.corda.testing.node.MockServices import net.corda.testing.node.startFlow import org.junit.After @@ -30,9 +30,9 @@ class CollectSignaturesFlowTests { } private lateinit var mockNet: MockNetwork - private lateinit var aliceNode: StartedNode - private lateinit var bobNode: StartedNode - private lateinit var charlieNode: StartedNode + private lateinit var aliceNode: StartedMockNode + private lateinit var bobNode: StartedMockNode + private lateinit var charlieNode: StartedMockNode private lateinit var alice: Party private lateinit var bob: Party private lateinit var charlie: Party diff --git a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt index 61f50c1e05..efcc570ac4 100644 --- a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt +++ b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt @@ -19,17 +19,14 @@ import net.corda.finance.flows.CashIssueFlow import net.corda.node.internal.SecureCordaRPCOps import net.corda.node.internal.StartedNode import net.corda.node.services.Permissions.Companion.startFlow -import net.corda.testing.core.ALICE_NAME -import net.corda.testing.core.BOB_NAME -import net.corda.testing.node.User import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContractV2 -import net.corda.testing.node.internal.RPCDriverDSL -import net.corda.testing.node.internal.rpcDriver -import net.corda.testing.node.internal.rpcTestUser -import net.corda.testing.node.internal.startRpcClient -import net.corda.testing.node.MockNetwork +import net.corda.testing.core.ALICE_NAME +import net.corda.testing.core.BOB_NAME import net.corda.testing.core.singleIdentity +import net.corda.testing.node.User +import net.corda.testing.node.internal.* +import net.corda.testing.node.internal.InternalMockNetwork.MockNode import net.corda.testing.node.startFlow import org.junit.After import org.junit.Before @@ -40,16 +37,16 @@ import kotlin.test.assertFailsWith import kotlin.test.assertTrue class ContractUpgradeFlowTest { - private lateinit var mockNet: MockNetwork - private lateinit var aliceNode: StartedNode - private lateinit var bobNode: StartedNode + private lateinit var mockNet: InternalMockNetwork + private lateinit var aliceNode: StartedNode + private lateinit var bobNode: StartedNode private lateinit var notary: Party private lateinit var alice: Party private lateinit var bob: Party @Before fun setup() { - mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset", "net.corda.core.flows")) + mockNet = InternalMockNetwork(cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset", "net.corda.core.flows")) aliceNode = mockNet.createPartyNode(ALICE_NAME) bobNode = mockNet.createPartyNode(BOB_NAME) notary = mockNet.defaultNotaryIdentity @@ -103,7 +100,7 @@ class ContractUpgradeFlowTest { val result = resultFuture.getOrThrow() - fun check(node: StartedNode<*>) { + fun check(node: StartedNode) { val nodeStx = node.database.transaction { node.services.validatedTransactions.getTransaction(result.ref.txhash) } @@ -123,7 +120,7 @@ class ContractUpgradeFlowTest { check(bobNode) } - private fun RPCDriverDSL.startProxy(node: StartedNode<*>, user: User): CordaRPCOps { + private fun RPCDriverDSL.startProxy(node: StartedNode, user: User): CordaRPCOps { return startRpcClient( rpcAddress = startRpcServer( rpcUser = user, diff --git a/core/src/test/kotlin/net/corda/core/flows/FlowTestsUtils.kt b/core/src/test/kotlin/net/corda/core/flows/FlowTestsUtils.kt index 4d2d12335d..9ea4d254f1 100644 --- a/core/src/test/kotlin/net/corda/core/flows/FlowTestsUtils.kt +++ b/core/src/test/kotlin/net/corda/core/flows/FlowTestsUtils.kt @@ -5,6 +5,8 @@ import net.corda.core.utilities.UntrustworthyData import net.corda.core.utilities.unwrap import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.StartedNode +import net.corda.testing.node.StartedMockNode +import net.corda.testing.node.internal.InternalMockNetwork import kotlin.reflect.KClass /** @@ -37,14 +39,14 @@ class NoAnswer(private val closure: () -> Unit = {}) : FlowLogic() { /** * Allows to register a flow of type [R] against an initiating flow of type [I]. */ -inline fun , reified R : FlowLogic<*>> StartedNode<*>.registerInitiatedFlow(initiatingFlowType: KClass, crossinline construct: (session: FlowSession) -> R) { +inline fun , reified R : FlowLogic<*>> StartedNode.registerInitiatedFlow(initiatingFlowType: KClass, crossinline construct: (session: FlowSession) -> R) { internalRegisterFlowFactory(initiatingFlowType.java, InitiatedFlowFactory.Core { session -> construct(session) }, R::class.javaObjectType, true) } /** * Allows to register a flow of type [Answer] against an initiating flow of type [I], returning a valure of type [R]. */ -inline fun , reified R : Any> StartedNode<*>.registerAnswer(initiatingFlowType: KClass, value: R) { +inline fun , reified R : Any> StartedNode.registerAnswer(initiatingFlowType: KClass, value: R) { internalRegisterFlowFactory(initiatingFlowType.java, InitiatedFlowFactory.Core { session -> Answer(session, value) }, Answer::class.javaObjectType, true) } diff --git a/core/src/test/kotlin/net/corda/core/flows/ReceiveAllFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/ReceiveAllFlowTests.kt index 1893e3607e..18fdf82f64 100644 --- a/core/src/test/kotlin/net/corda/core/flows/ReceiveAllFlowTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/ReceiveAllFlowTests.kt @@ -5,15 +5,15 @@ import net.corda.core.identity.Party import net.corda.core.utilities.UntrustworthyData import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.unwrap -import net.corda.testing.node.MockNetwork import net.corda.testing.core.singleIdentity +import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.startFlow import org.assertj.core.api.Assertions.assertThat import org.junit.After import org.junit.Test class ReceiveMultipleFlowTests { - private val mockNet = MockNetwork(emptyList()) + private val mockNet = InternalMockNetwork(emptyList()) private val nodes = (0..2).map { mockNet.createPartyNode() } @After fun stopNodes() { diff --git a/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt b/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt index 9038232355..fa6ab2b0ff 100644 --- a/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt +++ b/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt @@ -8,10 +8,10 @@ import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.sequence -import net.corda.node.internal.StartedNode import net.corda.testing.contracts.DummyContract import net.corda.testing.node.MockNetwork import net.corda.testing.core.singleIdentity +import net.corda.testing.node.StartedMockNode import net.corda.testing.node.startFlow import org.junit.After import org.junit.Before @@ -28,9 +28,9 @@ import kotlin.test.assertNull // DOCSTART 3 class ResolveTransactionsFlowTest { private lateinit var mockNet: MockNetwork - private lateinit var notaryNode: StartedNode - private lateinit var megaCorpNode: StartedNode - private lateinit var miniCorpNode: StartedNode + private lateinit var notaryNode: StartedMockNode + private lateinit var megaCorpNode: StartedMockNode + private lateinit var miniCorpNode: StartedMockNode private lateinit var megaCorp: Party private lateinit var miniCorp: Party private lateinit var notary: Party 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 56959a0cec..8551845849 100644 --- a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt +++ b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt @@ -21,6 +21,7 @@ import net.corda.testing.core.BOB_NAME import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNodeParameters import net.corda.testing.core.singleIdentity +import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.startFlow import org.junit.After import org.junit.Before @@ -63,14 +64,14 @@ private fun updateAttachment(attachmentId: SecureHash, data: ByteArray) { } class AttachmentSerializationTest { - private lateinit var mockNet: MockNetwork - private lateinit var server: StartedNode - private lateinit var client: StartedNode + private lateinit var mockNet: InternalMockNetwork + private lateinit var server: StartedNode + private lateinit var client: StartedNode private lateinit var serverIdentity: Party @Before fun setUp() { - mockNet = MockNetwork(emptyList()) + mockNet = InternalMockNetwork(emptyList()) server = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME)) client = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME)) client.internals.disableDBCloseOnStop() // Otherwise the in-memory database may disappear (taking the checkpoint with it) while we reboot the client. @@ -161,7 +162,7 @@ class AttachmentSerializationTest { private fun rebootClientAndGetAttachmentContent(checkAttachmentsOnLoad: Boolean = true): String { client.dispose() client = mockNet.createNode(MockNodeParameters(client.internals.id, client.internals.configuration.myLegalName), { args -> - object : MockNetwork.MockNode(args) { + object : InternalMockNetwork.MockNode(args) { override fun start() = super.start().apply { attachments.checkAttachmentsOnLoad = checkAttachmentsOnLoad } } }) diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index bccaf5c085..556a6ba917 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -181,6 +181,9 @@ UNRELEASED * Marked ``stateMachine`` on ``FlowLogic`` as ``CordaInternal`` to make clear that is it not part of the public api and is only for internal use +* Created new ``StartedMockNode`` and ``UnstartedMockNode`` classes which are wrappers around our MockNode implementation + that expose relevant methods for testing without exposing internals, create these using a ``MockNetwork``. + .. _changelog_v1: Release 1.0 diff --git a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt index 99eb5df37f..164e6f08f8 100644 --- a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt +++ b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt @@ -1,5 +1,6 @@ package net.corda.docs +import net.corda.client.rpc.CordaRPCClient import net.corda.core.internal.concurrent.transpose import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.startFlow @@ -45,10 +46,10 @@ class IntegrationTestingTutorial { // END 1 // START 2 - val aliceClient = alice.rpcClientToNode() + val aliceClient = CordaRPCClient(alice.rpcAddress) val aliceProxy = aliceClient.start("aliceUser", "testPassword1").proxy - val bobClient = bob.rpcClientToNode() + val bobClient = CordaRPCClient(bob.rpcAddress) val bobProxy = bobClient.start("bobUser", "testPassword2").proxy // END 2 diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt index 896152398d..255caf2271 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt @@ -2,6 +2,7 @@ package net.corda.docs +import net.corda.client.rpc.CordaRPCClient import net.corda.core.contracts.Amount import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.startFlow @@ -53,7 +54,7 @@ fun main(args: Array) { // END 1 // START 2 - val client = node.rpcClientToNode() + val client = CordaRPCClient(node.rpcAddress) val proxy = client.start("user", "password").proxy thread { diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/tutorial/mocknetwork/TutorialMockNetwork.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/tutorial/mocknetwork/TutorialMockNetwork.kt index 1ab3513656..520304ee2f 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/tutorial/mocknetwork/TutorialMockNetwork.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/tutorial/mocknetwork/TutorialMockNetwork.kt @@ -13,15 +13,10 @@ import net.corda.core.serialization.serialize import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.unwrap -import net.corda.node.internal.StartedNode import net.corda.node.services.messaging.Message import net.corda.node.services.statemachine.DataSessionMessage import net.corda.node.services.statemachine.ExistingSessionMessage -import net.corda.testing.node.InMemoryMessagingNetwork -import net.corda.testing.node.MessagingServiceSpy -import net.corda.testing.node.MockNetwork -import net.corda.testing.node.setMessagingServiceSpy -import net.corda.testing.node.startFlow +import net.corda.testing.node.* import org.junit.After import org.junit.Before import org.junit.Rule @@ -58,8 +53,8 @@ class TutorialMockNetwork { } lateinit private var mockNet: MockNetwork - lateinit private var nodeA: StartedNode - lateinit private var nodeB: StartedNode + lateinit private var nodeA: StartedMockNode + lateinit private var nodeB: StartedMockNode @Rule @JvmField diff --git a/docs/source/example-code/src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt b/docs/source/example-code/src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt index efd1935059..2b194b1e94 100644 --- a/docs/source/example-code/src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt +++ b/docs/source/example-code/src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt @@ -7,9 +7,9 @@ import net.corda.core.utilities.getOrThrow import net.corda.finance.* import net.corda.finance.contracts.getCashBalances import net.corda.finance.flows.CashIssueFlow -import net.corda.node.internal.StartedNode import net.corda.testing.core.chooseIdentity import net.corda.testing.node.MockNetwork +import net.corda.testing.node.StartedMockNode import net.corda.testing.node.startFlow import org.junit.After import org.junit.Assert @@ -19,8 +19,8 @@ import java.util.* class CustomVaultQueryTest { private lateinit var mockNet: MockNetwork - private lateinit var nodeA: StartedNode - private lateinit var nodeB: StartedNode + private lateinit var nodeA: StartedMockNode + private lateinit var nodeB: StartedMockNode private lateinit var notary: Party @Before diff --git a/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt b/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt index 8ecfb2c453..0805565e03 100644 --- a/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt +++ b/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt @@ -7,9 +7,9 @@ import net.corda.core.utilities.getOrThrow import net.corda.finance.* import net.corda.finance.contracts.getCashBalances import net.corda.finance.flows.CashIssueFlow -import net.corda.node.internal.StartedNode import net.corda.testing.core.chooseIdentity import net.corda.testing.node.MockNetwork +import net.corda.testing.node.StartedMockNode import net.corda.testing.node.startFlow import org.junit.After import org.junit.Before @@ -18,8 +18,8 @@ import kotlin.test.assertEquals class FxTransactionBuildTutorialTest { private lateinit var mockNet: MockNetwork - private lateinit var nodeA: StartedNode - private lateinit var nodeB: StartedNode + private lateinit var nodeA: StartedMockNode + private lateinit var nodeB: StartedMockNode private lateinit var notary: Party @Before diff --git a/finance/src/test/kotlin/net/corda/finance/flows/CashExitFlowTests.kt b/finance/src/test/kotlin/net/corda/finance/flows/CashExitFlowTests.kt index 9c70c96316..40ba1deffc 100644 --- a/finance/src/test/kotlin/net/corda/finance/flows/CashExitFlowTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/flows/CashExitFlowTests.kt @@ -6,11 +6,10 @@ import net.corda.core.utilities.getOrThrow import net.corda.finance.DOLLARS import net.corda.finance.`issued by` import net.corda.finance.contracts.asset.Cash -import net.corda.node.internal.StartedNode import net.corda.testing.core.BOC_NAME import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.MockNetwork -import net.corda.testing.node.MockNetwork.MockNode +import net.corda.testing.node.StartedMockNode import net.corda.testing.node.startFlow import org.junit.After import org.junit.Before @@ -22,7 +21,7 @@ class CashExitFlowTests { private lateinit var mockNet: MockNetwork private val initialBalance = 2000.DOLLARS private val ref = OpaqueBytes.of(0x01) - private lateinit var bankOfCordaNode: StartedNode + private lateinit var bankOfCordaNode: StartedMockNode private lateinit var bankOfCorda: Party private lateinit var notary: Party diff --git a/finance/src/test/kotlin/net/corda/finance/flows/CashIssueFlowTests.kt b/finance/src/test/kotlin/net/corda/finance/flows/CashIssueFlowTests.kt index 95c283415e..cd6522d901 100644 --- a/finance/src/test/kotlin/net/corda/finance/flows/CashIssueFlowTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/flows/CashIssueFlowTests.kt @@ -6,11 +6,10 @@ import net.corda.core.utilities.getOrThrow import net.corda.finance.DOLLARS import net.corda.finance.`issued by` import net.corda.finance.contracts.asset.Cash -import net.corda.node.internal.StartedNode import net.corda.testing.core.BOC_NAME import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.MockNetwork -import net.corda.testing.node.MockNetwork.MockNode +import net.corda.testing.node.StartedMockNode import net.corda.testing.node.startFlow import org.junit.After import org.junit.Before @@ -20,7 +19,7 @@ import kotlin.test.assertFailsWith class CashIssueFlowTests { private lateinit var mockNet: MockNetwork - private lateinit var bankOfCordaNode: StartedNode + private lateinit var bankOfCordaNode: StartedMockNode private lateinit var bankOfCorda: Party private lateinit var notary: Party diff --git a/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt b/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt index 6380a4b9a6..2d3b901f9a 100644 --- a/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt @@ -9,11 +9,10 @@ import net.corda.core.utilities.getOrThrow import net.corda.finance.DOLLARS import net.corda.finance.`issued by` import net.corda.finance.contracts.asset.Cash -import net.corda.node.internal.StartedNode import net.corda.testing.core.* import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.MockNetwork -import net.corda.testing.node.MockNetwork.MockNode +import net.corda.testing.node.StartedMockNode import net.corda.testing.node.startFlow import org.junit.After import org.junit.Before @@ -25,9 +24,9 @@ class CashPaymentFlowTests { private lateinit var mockNet: MockNetwork private val initialBalance = 2000.DOLLARS private val ref = OpaqueBytes.of(0x01) - private lateinit var bankOfCordaNode: StartedNode + private lateinit var bankOfCordaNode: StartedMockNode private lateinit var bankOfCorda: Party - private lateinit var aliceNode: StartedNode + private lateinit var aliceNode: StartedMockNode @Before fun start() { diff --git a/node/src/integration-test/kotlin/net/corda/node/BootTests.kt b/node/src/integration-test/kotlin/net/corda/node/BootTests.kt index 7bb503d744..11016c4bef 100644 --- a/node/src/integration-test/kotlin/net/corda/node/BootTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/BootTests.kt @@ -1,6 +1,7 @@ package net.corda.node import co.paralleluniverse.fibers.Suspendable +import net.corda.client.rpc.CordaRPCClient import net.corda.core.flows.FlowLogic import net.corda.core.flows.StartableByRPC import net.corda.core.internal.div @@ -25,7 +26,7 @@ class BootTests { fun `java deserialization is disabled`() { driver { val user = User("u", "p", setOf(startFlow())) - val future = startNode(rpcUsers = listOf(user)).getOrThrow().rpcClientToNode(). + val future = CordaRPCClient(startNode(rpcUsers = listOf(user)).getOrThrow().rpcAddress). start(user.username, user.password).proxy.startFlow(::ObjectInputStreamFlow).returnValue assertThatThrownBy { future.getOrThrow() }.isInstanceOf(InvalidClassException::class.java).hasMessage("filter status: REJECTED") } @@ -37,7 +38,7 @@ class BootTests { assertThat(logConfigFile).isRegularFile() driver(isDebug = true, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString())) { val alice = startNode(providedName = ALICE_NAME).get() - val logFolder = alice.configuration.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME + val logFolder = alice.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME val logFile = logFolder.toFile().listFiles { _, name -> name.endsWith(".log") }.single() // Start second Alice, should fail assertThatThrownBy { diff --git a/node/src/integration-test/kotlin/net/corda/node/CordappScanningDriverTest.kt b/node/src/integration-test/kotlin/net/corda/node/CordappScanningDriverTest.kt index 94f0034278..fad710317b 100644 --- a/node/src/integration-test/kotlin/net/corda/node/CordappScanningDriverTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/CordappScanningDriverTest.kt @@ -1,6 +1,7 @@ package net.corda.node import co.paralleluniverse.fibers.Suspendable +import net.corda.client.rpc.CordaRPCClient import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.internal.concurrent.transpose @@ -25,7 +26,7 @@ class CordappScanningDriverTest { val (alice, bob) = listOf( startNode(providedName = ALICE_NAME, rpcUsers = listOf(user)), startNode(providedName = BOB_NAME)).transpose().getOrThrow() - val initiatedFlowClass = alice.rpcClientToNode() + val initiatedFlowClass = CordaRPCClient(alice.rpcAddress) .start(user.username, user.password) .proxy .startFlow(::ReceiveFlow, bob.nodeInfo.chooseIdentity()) diff --git a/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt b/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt index 594c402ba2..51604c1ea2 100644 --- a/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt @@ -2,6 +2,7 @@ package net.corda.node import co.paralleluniverse.fibers.Suspendable import com.google.common.base.Stopwatch +import net.corda.client.rpc.CordaRPCClient import net.corda.core.flows.FlowLogic import net.corda.core.flows.StartableByRPC import net.corda.core.internal.concurrent.transpose @@ -14,19 +15,18 @@ import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.Permissions.Companion.startFlow import net.corda.testing.core.DUMMY_NOTARY_NAME +import net.corda.testing.driver.InProcess import net.corda.testing.node.User -import net.corda.testing.driver.NodeHandle import net.corda.testing.driver.driver import net.corda.testing.internal.performance.div import net.corda.testing.node.NotarySpec import net.corda.testing.node.internal.InternalDriverDSL +import net.corda.testing.node.internal.internalDriver import net.corda.testing.node.internal.performance.startPublishingFixedRateInjector import net.corda.testing.node.internal.performance.startReporter import net.corda.testing.node.internal.performance.startTightLoopInjector -import org.junit.Before import org.junit.Ignore import org.junit.Test -import java.lang.management.ManagementFactory import java.util.* import java.util.concurrent.TimeUnit import kotlin.streams.toList @@ -50,7 +50,7 @@ class NodePerformanceTests { driver(startNodesInProcess = true) { val a = startNode(rpcUsers = listOf(User("A", "A", setOf(startFlow())))).get() - a.rpcClientToNode().use("A", "A") { connection -> + CordaRPCClient(a.rpcAddress).use("A", "A") { connection -> val timings = Collections.synchronizedList(ArrayList()) val N = 10000 val overallTiming = Stopwatch.createStarted().apply { @@ -77,11 +77,11 @@ class NodePerformanceTests { @Test fun `empty flow rate`() { - driver(startNodesInProcess = true) { + internalDriver(startNodesInProcess = true) { val a = startNode(rpcUsers = listOf(User("A", "A", setOf(startFlow())))).get() - a as NodeHandle.InProcess - val metricRegistry = startReporter((this as InternalDriverDSL).shutdownManager, a.node.services.monitoringService.metrics) - a.rpcClientToNode().use("A", "A") { connection -> + a as InProcess + val metricRegistry = startReporter(this.shutdownManager, a.services.monitoringService.metrics) + CordaRPCClient(a.rpcAddress).use("A", "A") { connection -> startPublishingFixedRateInjector(metricRegistry, 8, 5.minutes, 2000L / TimeUnit.SECONDS) { connection.proxy.startFlow(::EmptyFlow).returnValue.get() } @@ -92,14 +92,14 @@ class NodePerformanceTests { @Test fun `self pay rate`() { val user = User("A", "A", setOf(startFlow(), startFlow())) - driver( + internalDriver( notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, rpcUsers = listOf(user))), startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.finance") ) { - val notary = defaultNotaryNode.getOrThrow() as NodeHandle.InProcess - val metricRegistry = startReporter((this as InternalDriverDSL).shutdownManager, notary.node.services.monitoringService.metrics) - notary.rpcClientToNode().use("A", "A") { connection -> + val notary = defaultNotaryNode.getOrThrow() as InProcess + val metricRegistry = startReporter(this.shutdownManager, notary.services.monitoringService.metrics) + CordaRPCClient(notary.rpcAddress).use("A", "A") { connection -> println("ISSUING") val doneFutures = (1..100).toList().parallelStream().map { connection.proxy.startFlow(::CashIssueFlow, 1.DOLLARS, OpaqueBytes.of(0), defaultNotaryIdentity).returnValue diff --git a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt index c5a036f09f..e972d71468 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt @@ -18,7 +18,6 @@ import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.Try import net.corda.core.utilities.getOrThrow -import net.corda.node.internal.StartedNode import net.corda.node.services.config.BFTSMaRtConfiguration import net.corda.node.services.config.NotaryConfig import net.corda.node.services.transactions.minClusterSize @@ -31,7 +30,7 @@ import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.contracts.DummyContract import net.corda.testing.core.dummyCommand import net.corda.testing.node.MockNetwork -import net.corda.testing.node.MockNetwork.MockNode +import net.corda.testing.node.StartedMockNode import net.corda.testing.node.MockNodeParameters import net.corda.testing.node.startFlow import org.junit.After @@ -44,7 +43,7 @@ import kotlin.test.assertTrue class BFTNotaryServiceTests { private lateinit var mockNet: MockNetwork private lateinit var notary: Party - private lateinit var node: StartedNode + private lateinit var node: StartedMockNode @Before fun before() { @@ -154,7 +153,7 @@ class BFTNotaryServiceTests { } } - private fun StartedNode<*>.signInitialTransaction(notary: Party, block: TransactionBuilder.() -> Any?): SignedTransaction { + private fun StartedMockNode.signInitialTransaction(notary: Party, block: TransactionBuilder.() -> Any?): SignedTransaction { return services.signInitialTransaction( TransactionBuilder(notary).apply { addCommand(dummyCommand(services.myInfo.chooseIdentity().owningKey)) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt index aca792c913..639cce9aa9 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt @@ -1,5 +1,6 @@ package net.corda.node.services +import net.corda.client.rpc.CordaRPCClient import net.corda.core.contracts.Amount import net.corda.core.identity.Party import net.corda.core.internal.bufferUntilSubscribed @@ -15,6 +16,7 @@ import net.corda.node.services.Permissions.Companion.invokeRpc import net.corda.node.services.Permissions.Companion.startFlow import net.corda.testing.core.* import net.corda.testing.driver.NodeHandle +import net.corda.testing.driver.OutOfProcess import net.corda.testing.driver.driver import net.corda.testing.node.NotarySpec import net.corda.testing.node.User @@ -26,7 +28,7 @@ import java.util.* class DistributedServiceTests { private lateinit var alice: NodeHandle - private lateinit var notaryNodes: List + private lateinit var notaryNodes: List private lateinit var aliceProxy: CordaRPCOps private lateinit var raftNotaryIdentity: Party private lateinit var notaryStateMachines: Observable> @@ -49,7 +51,7 @@ class DistributedServiceTests { ) { alice = startNode(providedName = ALICE_NAME, rpcUsers = listOf(testUser)).getOrThrow() raftNotaryIdentity = defaultNotaryIdentity - notaryNodes = defaultNotaryHandle.nodeHandles.getOrThrow().map { it as NodeHandle.OutOfProcess } + notaryNodes = defaultNotaryHandle.nodeHandles.getOrThrow().map { it as OutOfProcess } assertThat(notaryNodes).hasSize(3) @@ -62,7 +64,7 @@ class DistributedServiceTests { // Connect to Alice and the notaries fun connectRpc(node: NodeHandle): CordaRPCOps { - val client = node.rpcClientToNode() + val client = CordaRPCClient(node.rpcAddress) return client.start("test", "test").proxy } aliceProxy = connectRpc(alice) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/RaftNotaryServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/RaftNotaryServiceTests.kt index 6e56ee45d3..b7d3a046fa 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/RaftNotaryServiceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/RaftNotaryServiceTests.kt @@ -10,13 +10,12 @@ import net.corda.core.identity.Party import net.corda.core.internal.concurrent.map import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.getOrThrow -import net.corda.node.internal.StartedNode import net.corda.testing.core.DUMMY_BANK_A_NAME import net.corda.testing.core.chooseIdentity import net.corda.testing.contracts.DummyContract -import net.corda.testing.driver.NodeHandle import net.corda.testing.driver.driver import net.corda.testing.core.dummyCommand +import net.corda.testing.driver.InProcess import net.corda.testing.node.ClusterSpec import net.corda.testing.node.NotarySpec import net.corda.testing.node.startFlow @@ -35,7 +34,7 @@ class RaftNotaryServiceTests { extraCordappPackagesToScan = listOf("net.corda.testing.contracts"), notarySpecs = listOf(NotarySpec(notaryName, cluster = ClusterSpec.Raft(clusterSize = 3))) ) { - val bankA = startNode(providedName = DUMMY_BANK_A_NAME).map { (it as NodeHandle.InProcess).node }.getOrThrow() + val bankA = startNode(providedName = DUMMY_BANK_A_NAME).map { (it as InProcess) }.getOrThrow() val inputState = issueState(bankA, defaultNotaryIdentity) val firstTxBuilder = TransactionBuilder(defaultNotaryIdentity) @@ -47,7 +46,7 @@ class RaftNotaryServiceTests { firstSpend.getOrThrow() val secondSpendBuilder = TransactionBuilder(defaultNotaryIdentity).withItems(inputState).run { - val dummyState = DummyContract.SingleOwnerState(0, bankA.info.chooseIdentity()) + val dummyState = DummyContract.SingleOwnerState(0, bankA.services.myInfo.chooseIdentity()) addOutputState(dummyState, DummyContract.PROGRAM_ID) addCommand(dummyCommand(bankA.services.myInfo.chooseIdentity().owningKey)) this @@ -61,11 +60,12 @@ class RaftNotaryServiceTests { } } - private fun issueState(node: StartedNode<*>, notary: Party): StateAndRef<*> { - return node.database.transaction { - val builder = DummyContract.generateInitial(Random().nextInt(), notary, node.info.chooseIdentity().ref(0)) - val stx = node.services.signInitialTransaction(builder) - node.services.recordTransactions(stx) + private fun issueState(nodeHandle: InProcess, notary: Party): StateAndRef<*> { + return nodeHandle.database.transaction { + + val builder = DummyContract.generateInitial(Random().nextInt(), notary, nodeHandle.services.myInfo.chooseIdentity().ref(0)) + val stx = nodeHandle.services.signInitialTransaction(builder) + nodeHandle.services.recordTransactions(stx) StateAndRef(builder.outputStates().first(), StateRef(stx.id, 0)) } } diff --git a/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt index 53713ee6d2..a8c0f5d99b 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt @@ -63,7 +63,7 @@ class NetworkMapTest { notarySpecs = emptyList() ) { val alice = startNode(providedName = ALICE_NAME).getOrThrow() - val networkParameters = (alice.configuration.baseDirectory / NETWORK_PARAMS_FILE_NAME) + val networkParameters = (alice.baseDirectory / NETWORK_PARAMS_FILE_NAME) .readAll() .deserialize>() .verified() @@ -147,7 +147,7 @@ class NetworkMapTest { private fun NodeHandle.onlySees(vararg nodes: NodeInfo) { // Make sure the nodes aren't getting the node infos from their additional directories - val nodeInfosDir = configuration.baseDirectory / CordformNode.NODE_INFO_DIRECTORY + val nodeInfosDir = baseDirectory / CordformNode.NODE_INFO_DIRECTORY if (nodeInfosDir.exists()) { assertThat(nodeInfosDir.list { it.toList() }).isEmpty() } diff --git a/node/src/integration-test/kotlin/net/corda/node/services/rpc/RpcSslTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/rpc/RpcSslTest.kt index 03387d9a13..bbe96ed7a7 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/rpc/RpcSslTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/rpc/RpcSslTest.kt @@ -1,5 +1,6 @@ package net.corda.node.services.rpc +import net.corda.client.rpc.CordaRPCClient import net.corda.core.identity.CordaX500Name import net.corda.core.utilities.getOrThrow import net.corda.node.services.Permissions.Companion.all @@ -32,7 +33,7 @@ class RpcSslTest { var successful = false driver(isDebug = true, startNodesInProcess = true, portAllocation = PortAllocation.RandomFree) { startNode(rpcUsers = listOf(user), customOverrides = nodeSslOptions.useSslRpcOverrides()).getOrThrow().use { node -> - node.rpcClientToNode(clientSslOptions).start(user.username, user.password).use { connection -> + CordaRPCClient(node.rpcAddress, sslConfiguration = clientSslOptions).start(user.username, user.password).use { connection -> connection.proxy.apply { nodeInfo() successful = true @@ -51,7 +52,7 @@ class RpcSslTest { var successful = false driver(isDebug = true, startNodesInProcess = true, portAllocation = PortAllocation.RandomFree) { startNode(rpcUsers = listOf(user)).getOrThrow().use { node -> - node.rpcClientToNode().start(user.username, user.password).use { connection -> + CordaRPCClient(node.rpcAddress).start(user.username, user.password).use { connection -> connection.proxy.apply { nodeInfo() successful = true diff --git a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt index 23c3a987c3..ec2fd513e6 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt @@ -1,6 +1,7 @@ package net.corda.node.services.statemachine import co.paralleluniverse.fibers.Suspendable +import net.corda.client.rpc.CordaRPCClient import net.corda.core.crypto.SecureHash import net.corda.core.flows.* import net.corda.core.internal.InputStreamAndHash @@ -73,7 +74,7 @@ class LargeTransactionsTest { driver(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.testing.contracts"), portAllocation = PortAllocation.RandomFree) { val rpcUser = User("admin", "admin", setOf("ALL")) val (alice, _) = listOf(ALICE_NAME, BOB_NAME).map { startNode(providedName = it, rpcUsers = listOf(rpcUser)) }.transpose().getOrThrow() - alice.rpcClientToNode().use(rpcUser.username, rpcUser.password) { + CordaRPCClient(alice.rpcAddress).use(rpcUser.username, rpcUser.password) { val hash1 = it.proxy.uploadAttachment(bigFile1.inputStream) val hash2 = it.proxy.uploadAttachment(bigFile2.inputStream) val hash3 = it.proxy.uploadAttachment(bigFile3.inputStream) diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt index 3cea7b31e6..be183c8e3b 100644 --- a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt +++ b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt @@ -12,15 +12,13 @@ import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.seconds -import net.corda.node.internal.Node -import net.corda.node.internal.StartedNode import net.corda.node.services.messaging.MessagingService import net.corda.node.services.messaging.ReceivedMessage import net.corda.node.services.messaging.send import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.chooseIdentity import net.corda.testing.driver.DriverDSL -import net.corda.testing.driver.NodeHandle +import net.corda.testing.driver.InProcess import net.corda.testing.driver.driver import net.corda.testing.node.ClusterSpec import net.corda.testing.node.NotarySpec @@ -44,13 +42,14 @@ class P2PMessagingTest { } } + @Test fun `distributed service requests are retried if one of the nodes in the cluster goes down without sending a response`() { startDriverWithDistributedService { distributedServiceNodes -> val alice = startAlice() val serviceAddress = alice.services.networkMapCache.run { val notaryParty = notaryIdentities.randomOrNull()!! - alice.network.getAddressOfParty(getPartyInfo(notaryParty)!!) + alice.services.networkService.getAddressOfParty(getPartyInfo(notaryParty)!!) } val responseMessage = "response" @@ -76,7 +75,7 @@ class P2PMessagingTest { val alice = startAlice() val serviceAddress = alice.services.networkMapCache.run { val notaryParty = notaryIdentities.randomOrNull()!! - alice.network.getAddressOfParty(getPartyInfo(notaryParty)!!) + alice.services.networkService.getAddressOfParty(getPartyInfo(notaryParty)!!) } val responseMessage = "response" @@ -89,7 +88,7 @@ class P2PMessagingTest { // Wait until the first request is received crashingNodes.firstRequestReceived.await() // Stop alice's node after we ensured that the first request was delivered and ignored. - alice.dispose() + alice.stop() val numberOfRequestsReceived = crashingNodes.requestsReceived.get() assertThat(numberOfRequestsReceived).isGreaterThanOrEqualTo(1) @@ -99,7 +98,7 @@ class P2PMessagingTest { val aliceRestarted = startAlice() val responseFuture = openFuture() - aliceRestarted.network.runOnNextMessage("test.response") { + aliceRestarted.services.networkService.runOnNextMessage("test.response") { responseFuture.set(it.data.deserialize()) } val response = responseFuture.getOrThrow() @@ -109,15 +108,16 @@ class P2PMessagingTest { } } - private fun startDriverWithDistributedService(dsl: DriverDSL.(List>) -> Unit) { + + private fun startDriverWithDistributedService(dsl: DriverDSL.(List) -> Unit) { driver(startNodesInProcess = true, notarySpecs = listOf(NotarySpec(DISTRIBUTED_SERVICE_NAME, cluster = ClusterSpec.Raft(clusterSize = 2)))) { - dsl(defaultNotaryHandle.nodeHandles.getOrThrow().map { (it as NodeHandle.InProcess).node }) + dsl(defaultNotaryHandle.nodeHandles.getOrThrow().map { (it as InProcess) }) } } - private fun DriverDSL.startAlice(): StartedNode { + private fun DriverDSL.startAlice(): InProcess { return startNode(providedName = ALICE_NAME, customOverrides = mapOf("messageRedeliveryDelaySeconds" to 1)) - .map { (it as NodeHandle.InProcess).node } + .map { (it as InProcess) } .getOrThrow() } @@ -133,7 +133,7 @@ class P2PMessagingTest { * initially set to true. This may be used to simulate scenarios where nodes receive request messages but crash * before sending back a response. */ - private fun simulateCrashingNodes(distributedServiceNodes: List>, responseMessage: String): CrashingNodes { + private fun simulateCrashingNodes(distributedServiceNodes: List, responseMessage: String): CrashingNodes { val crashingNodes = CrashingNodes( requestsReceived = AtomicInteger(0), firstRequestReceived = CountDownLatch(1), @@ -141,8 +141,8 @@ class P2PMessagingTest { ) distributedServiceNodes.forEach { - val nodeName = it.info.chooseIdentity().name - it.network.addMessageHandler("test.request") { netMessage, _ -> + val nodeName = it.services.myInfo.chooseIdentity().name + it.services.networkService.addMessageHandler("test.request") { netMessage, _ -> crashingNodes.requestsReceived.incrementAndGet() crashingNodes.firstRequestReceived.countDown() // The node which receives the first request will ignore all requests @@ -154,21 +154,21 @@ class P2PMessagingTest { } else { println("sending response") val request = netMessage.data.deserialize() - val response = it.network.createMessage("test.response", responseMessage.serialize().bytes) - it.network.send(response, request.replyTo) + val response = it.services.networkService.createMessage("test.response", responseMessage.serialize().bytes) + it.services.networkService.send(response, request.replyTo) } } } return crashingNodes } - private fun assertAllNodesAreUsed(participatingServiceNodes: List>, serviceName: CordaX500Name, originatingNode: StartedNode<*>) { + private fun assertAllNodesAreUsed(participatingServiceNodes: List, serviceName: CordaX500Name, originatingNode: InProcess) { // Setup each node in the distributed service to return back it's NodeInfo so that we can know which node is being used participatingServiceNodes.forEach { node -> - node.respondWith(node.info) + node.respondWith(node.services.myInfo) } val serviceAddress = originatingNode.services.networkMapCache.run { - originatingNode.network.getAddressOfParty(getPartyInfo(getNotary(serviceName)!!)!!) + originatingNode.services.networkService.getAddressOfParty(getPartyInfo(getNotary(serviceName)!!)!!) } val participatingNodes = HashSet() // Try several times so that we can be fairly sure that any node not participating is not due to Artemis' selection @@ -180,23 +180,23 @@ class P2PMessagingTest { break } } - assertThat(participatingNodes).containsOnlyElementsOf(participatingServiceNodes.map(StartedNode<*>::info)) + assertThat(participatingNodes).containsOnlyElementsOf(participatingServiceNodes.map { it.services.myInfo }) } - - private fun StartedNode<*>.respondWith(message: Any) { - network.addMessageHandler("test.request") { netMessage, _ -> + + private fun InProcess.respondWith(message: Any) { + services.networkService.addMessageHandler("test.request") { netMessage, _ -> val request = netMessage.data.deserialize() - val response = network.createMessage("test.response", message.serialize().bytes) - network.send(response, request.replyTo) + val response = services.networkService.createMessage("test.response", message.serialize().bytes) + services.networkService.send(response, request.replyTo) } } - private fun StartedNode<*>.receiveFrom(target: MessageRecipients, retryId: Long? = null): CordaFuture { + private fun InProcess.receiveFrom(target: MessageRecipients, retryId: Long? = null): CordaFuture { val response = openFuture() - network.runOnNextMessage("test.response") { netMessage -> + services.networkService.runOnNextMessage("test.response") { netMessage -> response.set(netMessage.data.deserialize()) } - network.send("test.request", TestRequest(replyTo = network.myAddress), target, retryId = retryId) + services.networkService.send("test.request", TestRequest(replyTo = services.networkService.myAddress), target, retryId = retryId) return response } diff --git a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt index d711b59ebc..1df94d02d7 100644 --- a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt @@ -1,6 +1,7 @@ package net.corda.test.node import co.paralleluniverse.fibers.Suspendable +import net.corda.client.rpc.CordaRPCClient import net.corda.core.contracts.* import net.corda.core.flows.FinalityFlow import net.corda.core.flows.FlowLogic @@ -47,7 +48,7 @@ class NodeStatePersistenceTests { val nodeName = nodeHandle.nodeInfo.chooseIdentity().name // Ensure the notary node has finished starting up, before starting a flow that needs a notary defaultNotaryNode.getOrThrow() - nodeHandle.rpcClientToNode().start(user.username, user.password).use { + CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use { it.proxy.startFlow(::SendMessageFlow, message, defaultNotaryIdentity).returnValue.getOrThrow() } nodeHandle.stop() @@ -55,7 +56,7 @@ class NodeStatePersistenceTests { }() val nodeHandle = startNode(providedName = nodeName, rpcUsers = listOf(user)).getOrThrow() - val result = nodeHandle.rpcClientToNode().start(user.username, user.password).use { + val result = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use { val page = it.proxy.vaultQuery(MessageState::class.java) page.states.singleOrNull() } @@ -81,7 +82,7 @@ class NodeStatePersistenceTests { val nodeName = nodeHandle.nodeInfo.chooseIdentity().name // Ensure the notary node has finished starting up, before starting a flow that needs a notary defaultNotaryNode.getOrThrow() - nodeHandle.rpcClientToNode().start(user.username, user.password).use { + CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use { it.proxy.startFlow(::SendMessageFlow, message, defaultNotaryIdentity).returnValue.getOrThrow() } nodeHandle.stop() @@ -89,7 +90,7 @@ class NodeStatePersistenceTests { }() val nodeHandle = startNode(providedName = nodeName, rpcUsers = listOf(user), customOverrides = mapOf("devMode" to "false")).getOrThrow() - val result = nodeHandle.rpcClientToNode().start(user.username, user.password).use { + val result = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use { val page = it.proxy.vaultQuery(MessageState::class.java) page.states.singleOrNull() } diff --git a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt index 0214d551f9..75ce1850d3 100644 --- a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt +++ b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt @@ -37,9 +37,9 @@ import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.expect import net.corda.testing.core.expectEvents import net.corda.testing.core.sequence -import net.corda.testing.node.MockNetwork -import net.corda.testing.node.MockNetwork.MockNode import net.corda.testing.node.MockNodeParameters +import net.corda.testing.node.internal.InternalMockNetwork +import net.corda.testing.node.internal.InternalMockNetwork.MockNode import net.corda.testing.node.testActor import org.apache.commons.io.IOUtils import org.assertj.core.api.Assertions.assertThatExceptionOfType @@ -68,7 +68,7 @@ class CordaRPCOpsImplTest { val testJar = "net/corda/node/testing/test.jar" } - private lateinit var mockNet: MockNetwork + private lateinit var mockNet: InternalMockNetwork private lateinit var aliceNode: StartedNode private lateinit var alice: Party private lateinit var notary: Party @@ -79,7 +79,7 @@ class CordaRPCOpsImplTest { @Before fun setup() { - mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset")) + mockNet = InternalMockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset")) aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME)) rpc = SecureCordaRPCOps(aliceNode.services, aliceNode.smm, aliceNode.database, aliceNode.services) CURRENT_RPC_CONTEXT.set(RpcAuthContext(InvocationContext.rpc(testActor()), buildSubject("TEST_USER", emptySet()))) diff --git a/node/src/test/kotlin/net/corda/node/internal/CordaServiceTest.kt b/node/src/test/kotlin/net/corda/node/internal/CordaServiceTest.kt index b7b47d9165..a8dccd47ba 100644 --- a/node/src/test/kotlin/net/corda/node/internal/CordaServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/internal/CordaServiceTest.kt @@ -15,6 +15,7 @@ import net.corda.finance.DOLLARS import net.corda.finance.flows.CashIssueFlow import net.corda.node.internal.cordapp.DummyRPCFlow import net.corda.testing.node.MockNetwork +import net.corda.testing.node.StartedMockNode import org.junit.After import org.junit.Before import org.junit.Test @@ -75,7 +76,7 @@ class LegacyCordaService(@Suppress("UNUSED_PARAMETER") simpleServiceHub: Service class CordaServiceTest { private lateinit var mockNet: MockNetwork - private lateinit var nodeA: StartedNode + private lateinit var nodeA: StartedMockNode @Before fun start() { diff --git a/node/src/test/kotlin/net/corda/node/internal/NetworkParametersTest.kt b/node/src/test/kotlin/net/corda/node/internal/NetworkParametersTest.kt index 0ece39f948..5ee95ed7e7 100644 --- a/node/src/test/kotlin/net/corda/node/internal/NetworkParametersTest.kt +++ b/node/src/test/kotlin/net/corda/node/internal/NetworkParametersTest.kt @@ -27,7 +27,7 @@ class NetworkParametersTest { private val mockNet = MockNetwork( emptyList(), MockNetworkParameters(networkSendManuallyPumped = true), - notarySpecs = listOf(MockNetwork.NotarySpec(DUMMY_NOTARY_NAME))) + notarySpecs = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME))) @After fun tearDown() { 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 e17201cf46..d9d2051e7e 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -48,6 +48,8 @@ import net.corda.testing.dsl.TestTransactionDSLInterpreter import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.vault.VaultFiller import net.corda.testing.node.* +import net.corda.testing.node.internal.InternalMockNetwork +import net.corda.testing.node.internal.pumpReceive import org.assertj.core.api.Assertions.assertThat import org.junit.After import org.junit.Before @@ -83,7 +85,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { private val DUMMY_NOTARY get() = dummyNotary.party } - private lateinit var mockNet: MockNetwork + private lateinit var mockNet: InternalMockNetwork @Before fun before() { @@ -101,7 +103,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { // We run this in parallel threads to help catch any race conditions that may exist. The other tests // we run in the unit test thread exclusively to speed things up, ensure deterministic results and // allow interruption half way through. - mockNet = MockNetwork(threadPerNode = true, cordappPackages = cordappPackages) + mockNet = InternalMockNetwork(threadPerNode = true, cordappPackages = cordappPackages) val ledgerIdentityService = rigorousMock() MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) { val notaryNode = mockNet.defaultNotaryNode @@ -153,7 +155,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { @Test(expected = InsufficientBalanceException::class) fun `trade cash for commercial paper fails using soft locking`() { - mockNet = MockNetwork(threadPerNode = true, cordappPackages = cordappPackages) + mockNet = InternalMockNetwork(threadPerNode = true, cordappPackages = cordappPackages) val ledgerIdentityService = rigorousMock() MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) { val notaryNode = mockNet.defaultNotaryNode @@ -211,7 +213,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { @Test fun `shutdown and restore`() { - mockNet = MockNetwork(cordappPackages = cordappPackages) + mockNet = InternalMockNetwork(cordappPackages = cordappPackages) val ledgerIdentityService = rigorousMock() MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) { val notaryNode = mockNet.defaultNotaryNode @@ -308,11 +310,10 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { // Creates a mock node with an overridden storage service that uses a RecordingMap, that lets us test the order // of gets and puts. - private fun makeNodeWithTracking( - name: CordaX500Name): StartedNode { + private fun makeNodeWithTracking(name: CordaX500Name): StartedNode { // Create a node in the mock network ... return mockNet.createNode(MockNodeParameters(legalName = name), nodeFactory = { args -> - object : MockNetwork.MockNode(args) { + object : InternalMockNetwork.MockNode(args) { // That constructs a recording tx storage override fun makeTransactionStorage(database: CordaPersistence, transactionCacheSizeBytes: Long): WritableTransactionStorage { return RecordingTransactionStorage(database, super.makeTransactionStorage(database, transactionCacheSizeBytes)) @@ -323,7 +324,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { @Test fun `check dependencies of sale asset are resolved`() { - mockNet = MockNetwork(cordappPackages = cordappPackages) + mockNet = InternalMockNetwork(cordappPackages = cordappPackages) val notaryNode = mockNet.defaultNotaryNode val aliceNode = makeNodeWithTracking(ALICE_NAME) val bobNode = makeNodeWithTracking(BOB_NAME) @@ -427,7 +428,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { @Test fun `track works`() { - mockNet = MockNetwork(cordappPackages = cordappPackages) + mockNet = InternalMockNetwork(cordappPackages = cordappPackages) val notaryNode = mockNet.defaultNotaryNode val aliceNode = makeNodeWithTracking(ALICE_NAME) val bobNode = makeNodeWithTracking(BOB_NAME) @@ -505,7 +506,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { @Test fun `dependency with error on buyer side`() { - mockNet = MockNetwork(cordappPackages = cordappPackages) + mockNet = InternalMockNetwork(cordappPackages = cordappPackages) val ledgerIdentityService = rigorousMock() MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) { runWithError(ledgerIdentityService, true, false, "at least one cash input") @@ -514,7 +515,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { @Test fun `dependency with error on seller side`() { - mockNet = MockNetwork(cordappPackages = cordappPackages) + mockNet = InternalMockNetwork(cordappPackages = cordappPackages) val ledgerIdentityService = rigorousMock() MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) { runWithError(ledgerIdentityService, false, true, "Issuances have a time-window") @@ -530,8 +531,8 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) { private fun runBuyerAndSeller(notary: Party, buyer: Party, - sellerNode: StartedNode, - buyerNode: StartedNode, + sellerNode: StartedNode, + buyerNode: StartedNode, assetToSell: StateAndRef): RunResult { val buyerFlows: Observable> = buyerNode.registerInitiatedFlow(BuyerAcceptor::class.java) val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine } diff --git a/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt b/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt index bdb1381f57..9851246573 100644 --- a/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt @@ -12,13 +12,9 @@ import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.WireTransaction import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.seconds -import net.corda.node.internal.StartedNode import net.corda.testing.contracts.DummyContract import net.corda.testing.core.* -import net.corda.testing.node.MockNetwork -import net.corda.testing.node.MockNetwork.NotarySpec -import net.corda.testing.node.MockNodeParameters -import net.corda.testing.node.startFlow +import net.corda.testing.node.* import org.assertj.core.api.Assertions.assertThatExceptionOfType import org.junit.After import org.junit.Before @@ -30,9 +26,9 @@ import kotlin.test.assertTrue class NotaryChangeTests { private lateinit var mockNet: MockNetwork - private lateinit var oldNotaryNode: StartedNode - private lateinit var clientNodeA: StartedNode - private lateinit var clientNodeB: StartedNode + private lateinit var oldNotaryNode: StartedMockNode + private lateinit var clientNodeA: StartedMockNode + private lateinit var clientNodeB: StartedMockNode private lateinit var newNotaryParty: Party private lateinit var oldNotaryParty: Party private lateinit var clientA: Party @@ -41,7 +37,7 @@ class NotaryChangeTests { fun setUp() { val oldNotaryName = CordaX500Name("Regulator A", "Paris", "FR") mockNet = MockNetwork( - notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME), NotarySpec(oldNotaryName)), + notarySpecs = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME), MockNetworkNotarySpec(oldNotaryName)), cordappPackages = listOf("net.corda.testing.contracts") ) clientNodeA = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME)) @@ -145,7 +141,7 @@ class NotaryChangeTests { assertEquals(issued.state, changedNotaryBack.state) } - private fun changeNotary(movedState: StateAndRef, node: StartedNode<*>, newNotary: Party): StateAndRef { + private fun changeNotary(movedState: StateAndRef, node: StartedMockNode, newNotary: Party): StateAndRef { val flow = NotaryChangeFlow(movedState, newNotary) val future = node.services.startFlow(flow) mockNet.runNetwork() @@ -153,7 +149,7 @@ class NotaryChangeTests { return future.getOrThrow() } - private fun moveState(state: StateAndRef, fromNode: StartedNode<*>, toNode: StartedNode<*>): StateAndRef { + private fun moveState(state: StateAndRef, fromNode: StartedMockNode, toNode: StartedMockNode): StateAndRef { val tx = DummyContract.move(state, toNode.info.chooseIdentity()) val stx = fromNode.services.signInitialTransaction(tx) @@ -203,7 +199,7 @@ fun issueState(services: ServiceHub, nodeIdentity: Party, notaryIdentity: Party) return stx.tx.outRef(0) } -fun issueMultiPartyState(nodeA: StartedNode<*>, nodeB: StartedNode<*>, notaryNode: StartedNode<*>, notaryIdentity: Party): StateAndRef { +fun issueMultiPartyState(nodeA: StartedMockNode, nodeB: StartedMockNode, notaryNode: StartedMockNode, notaryIdentity: Party): StateAndRef { val participants = listOf(nodeA.info.chooseIdentity(), nodeB.info.chooseIdentity()) val state = TransactionState( DummyContract.MultiOwnerState(0, participants), diff --git a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt index 45a34c7a00..b98c4d5c34 100644 --- a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt @@ -25,8 +25,9 @@ import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.BOB_NAME import net.corda.testing.core.dummyCommand import net.corda.testing.core.singleIdentity -import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNodeParameters +import net.corda.testing.node.internal.InternalMockNetwork +import net.corda.testing.node.internal.InternalMockNetwork.MockNode import net.corda.testing.node.startFlow import org.junit.After import org.junit.Assert.* @@ -42,9 +43,9 @@ class ScheduledFlowTests { val SORTING = Sort(listOf(Sort.SortColumn(SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF_TXN_ID), Sort.Direction.DESC))) } - private lateinit var mockNet: MockNetwork - private lateinit var aliceNode: StartedNode - private lateinit var bobNode: StartedNode + private lateinit var mockNet: InternalMockNetwork + private lateinit var aliceNode: StartedNode + private lateinit var bobNode: StartedNode private lateinit var notary: Party private lateinit var alice: Party private lateinit var bob: Party @@ -102,7 +103,7 @@ class ScheduledFlowTests { @Before fun setup() { - mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.testing.contracts")) + mockNet = InternalMockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.testing.contracts")) aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME)) bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME)) notary = mockNet.defaultNotaryIdentity diff --git a/node/src/test/kotlin/net/corda/node/services/schema/NodeSchemaServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/schema/NodeSchemaServiceTest.kt index 45bd2e5c7d..a7bd4a9b15 100644 --- a/node/src/test/kotlin/net/corda/node/services/schema/NodeSchemaServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/schema/NodeSchemaServiceTest.kt @@ -11,7 +11,7 @@ import net.corda.core.utilities.getOrThrow import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.schema.NodeSchemaService.NodeCoreV1 import net.corda.node.services.schema.NodeSchemaService.NodeNotaryV1 -import net.corda.testing.driver.NodeHandle +import net.corda.testing.driver.InProcess import net.corda.testing.driver.driver import net.corda.testing.internal.vault.DummyLinearStateSchemaV1 import net.corda.testing.node.MockNetwork @@ -26,7 +26,7 @@ import kotlin.test.assertTrue class NodeSchemaServiceTest { /** - * Note: this test requires explicitly registering custom contract schemas with a MockNode + * Note: this test requires explicitly registering custom contract schemas with a StartedMockNode */ @Test fun `registering custom schemas for testing with MockNode`() { @@ -79,7 +79,7 @@ class NodeSchemaServiceTest { fun `custom schemas are loaded eagerly`() { val expected = setOf("PARENTS", "CHILDREN") val tables = driver(startNodesInProcess = true) { - (defaultNotaryNode.getOrThrow() as NodeHandle.InProcess).node.database.transaction { + (defaultNotaryNode.getOrThrow() as InProcess).database.transaction { session.createNativeQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES").list() } } diff --git a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt index e16037795a..da80ff4b2e 100644 --- a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt @@ -34,11 +34,11 @@ import net.corda.testing.core.* import net.corda.testing.internal.LogHelper import net.corda.testing.node.InMemoryMessagingNetwork.MessageTransfer import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin -import net.corda.testing.node.MockNetwork -import net.corda.testing.node.MockNetwork.MockNode import net.corda.testing.node.MockNodeParameters +import net.corda.testing.node.internal.InternalMockNetwork +import net.corda.testing.node.internal.InternalMockNetwork.MockNode +import net.corda.testing.node.internal.pumpReceive import net.corda.testing.node.internal.startFlow -import net.corda.testing.node.pumpReceive import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType @@ -62,7 +62,7 @@ class FlowFrameworkTests { } } - private lateinit var mockNet: MockNetwork + private lateinit var mockNet: InternalMockNetwork private val receivedSessionMessages = ArrayList() private lateinit var aliceNode: StartedNode private lateinit var bobNode: StartedNode @@ -76,7 +76,7 @@ class FlowFrameworkTests { @Before fun start() { - mockNet = MockNetwork( + mockNet = InternalMockNetwork( servicePeerAllocationStrategy = RoundRobin(), cordappPackages = listOf("net.corda.finance.contracts", "net.corda.testing.contracts") ) @@ -145,7 +145,7 @@ class FlowFrameworkTests { val restoredFlow = bobNode.restartAndGetRestoredFlow() assertThat(restoredFlow.receivedPayloads[0]).isEqualTo("Hello") } - + @Test fun `flow loaded from checkpoint will respond to messages from before start`() { aliceNode.registerFlowFactory(ReceiveFlow::class) { InitiatedSendFlow("Hello", it) } 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 c165ab7ef9..02e5e1c1dd 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 @@ -30,6 +30,7 @@ import net.corda.testing.core.chooseIdentity import net.corda.testing.node.MockNetwork import net.corda.testing.internal.rigorousMock import net.corda.testing.node.MockNodeParameters +import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.startFlow import org.junit.After import org.junit.Test @@ -38,7 +39,7 @@ import java.util.concurrent.atomic.AtomicBoolean import kotlin.reflect.jvm.jvmName import kotlin.test.assertEquals -class NodePair(private val mockNet: MockNetwork) { +class NodePair(private val mockNet: InternalMockNetwork) { private class ServerLogic(private val session: FlowSession, private val running: AtomicBoolean) : FlowLogic() { @Suspendable override fun call() { @@ -81,8 +82,8 @@ class VaultSoftLockManagerTest { private val mockVault = rigorousMock().also { doNothing().whenever(it).softLockRelease(any(), anyOrNull()) } - private val mockNet = MockNetwork(cordappPackages = listOf(ContractImpl::class.packageName), defaultFactory = { args -> - object : MockNetwork.MockNode(args) { + private val mockNet = InternalMockNetwork(cordappPackages = listOf(ContractImpl::class.packageName), defaultFactory = { args -> + object : InternalMockNetwork.MockNode(args) { override fun makeVaultService(keyManagementService: KeyManagementService, stateLoader: StateLoader, hibernateConfig: HibernateConfiguration): VaultServiceInternal { val realVault = super.makeVaultService(keyManagementService, stateLoader, hibernateConfig) return object : VaultServiceInternal by realVault { diff --git a/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt b/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt index 637efa9d55..e480657b6d 100644 --- a/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt +++ b/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt @@ -1,5 +1,6 @@ package net.corda.attachmentdemo +import net.corda.client.rpc.CordaRPCClient import net.corda.core.messaging.CordaRPCOps import net.corda.core.utilities.getOrThrow import net.corda.node.services.Permissions.Companion.invokeRpc @@ -9,6 +10,7 @@ import net.corda.testing.core.DUMMY_BANK_B_NAME import net.corda.testing.node.User import net.corda.testing.driver.PortAllocation import net.corda.testing.driver.driver +import net.corda.testing.driver.internal.NodeHandleInternal import org.junit.Test import java.util.concurrent.CompletableFuture.supplyAsync @@ -30,17 +32,17 @@ class AttachmentDemoTest { startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = demoUser, maximumHeapSize = "1g"), startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = demoUser, maximumHeapSize = "1g") ).map { it.getOrThrow() } - startWebserver(nodeB).getOrThrow() + val webserverHandle = startWebserver(nodeB).getOrThrow() val senderThread = supplyAsync { - nodeA.rpcClientToNode().start(demoUser[0].username, demoUser[0].password).use { + CordaRPCClient(nodeA.rpcAddress).start(demoUser[0].username, demoUser[0].password).use { sender(it.proxy, numOfExpectedBytes) } } val recipientThread = supplyAsync { - nodeB.rpcClientToNode().start(demoUser[0].username, demoUser[0].password).use { - recipient(it.proxy, nodeB.webAddress.port) + CordaRPCClient(nodeB.rpcAddress).start(demoUser[0].username, demoUser[0].password).use { + recipient(it.proxy, webserverHandle.listenAddress.port) } } diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt index dfa5199b13..c10a266934 100644 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt +++ b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt @@ -1,5 +1,6 @@ package net.corda.bank +import net.corda.client.rpc.CordaRPCClient import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.startFlow import net.corda.core.node.services.Vault @@ -37,11 +38,11 @@ class BankOfCordaRPCClientTest { ).map { it.getOrThrow() } // Bank of Corda RPC Client - val bocClient = nodeBankOfCorda.rpcClientToNode() + val bocClient = CordaRPCClient(nodeBankOfCorda.rpcAddress) val bocProxy = bocClient.start("bocManager", "password1").proxy // Big Corporation RPC Client - val bigCorpClient = nodeBigCorporation.rpcClientToNode() + val bigCorpClient = CordaRPCClient(nodeBigCorporation.rpcAddress) val bigCorpProxy = bigCorpClient.start("bigCorpCFO", "password2").proxy // Register for Bank of Corda Vault updates diff --git a/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt b/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt index 9a4c73a772..02e258e1e8 100644 --- a/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt +++ b/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt @@ -15,6 +15,7 @@ import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.messaging.vaultTrackBy import net.corda.core.toFuture +import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.contextLogger import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.seconds @@ -78,7 +79,7 @@ class IRSDemoTest { registerIRSModule(mapper) HttpApi.fromHostAndPort(it.second, "api/irs", mapper = mapper) } - val nextFixingDates = getFixingDateObservable(nodeA.configuration) + val nextFixingDates = getFixingDateObservable(nodeA.rpcAddress) val numADeals = getTradeCount(nodeAApi) val numBDeals = getTradeCount(nodeBApi) @@ -102,8 +103,8 @@ class IRSDemoTest { return getTrades(nodeApi)[0].calculation.floatingLegPaymentSchedule.count { it.value.rate.ratioUnit != null } } - private fun getFixingDateObservable(config: NodeConfiguration): Observable { - val client = CordaRPCClient(config.rpcOptions.address!!) + private fun getFixingDateObservable(address: NetworkHostAndPort): Observable { + val client = CordaRPCClient(address) val proxy = client.start("user", "password").proxy val vaultUpdates = proxy.vaultTrackBy().updates diff --git a/samples/irs-demo/src/integration-test/kotlin/net/corda/test/spring/SpringDriver.kt b/samples/irs-demo/src/integration-test/kotlin/net/corda/test/spring/SpringDriver.kt index 4d05a61d85..f425688c59 100644 --- a/samples/irs-demo/src/integration-test/kotlin/net/corda/test/spring/SpringDriver.kt +++ b/samples/irs-demo/src/integration-test/kotlin/net/corda/test/spring/SpringDriver.kt @@ -7,6 +7,7 @@ import net.corda.testing.driver.DriverParameters import net.corda.testing.driver.NodeHandle import net.corda.testing.driver.PortAllocation import net.corda.testing.driver.WebserverHandle +import net.corda.testing.driver.internal.NodeHandleInternal import net.corda.testing.node.NotarySpec import net.corda.testing.node.internal.* import okhttp3.OkHttpClient @@ -68,12 +69,12 @@ data class SpringBootDriverDSL(private val driverDSL: DriverDSLImpl) : InternalD val debugPort = if (driverDSL.isDebug) driverDSL.debugPortAllocation.nextPort() else null val process = startApplication(handle, debugPort, clazz) driverDSL.shutdownManager.registerProcessShutdown(process) - val webReadyFuture = addressMustBeBoundFuture(driverDSL.executorService, handle.webAddress, process) + val webReadyFuture = addressMustBeBoundFuture(driverDSL.executorService, (handle as NodeHandleInternal).webAddress, process) return webReadyFuture.map { queryWebserver(handle, process, checkUrl) } } private fun queryWebserver(handle: NodeHandle, process: Process, checkUrl: String): WebserverHandle { - val protocol = if (handle.useHTTPS) "https://" else "http://" + val protocol = if ((handle as NodeHandleInternal).useHTTPS) "https://" else "http://" val url = URL(URL("$protocol${handle.webAddress}"), checkUrl) val client = OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).build() @@ -102,19 +103,19 @@ data class SpringBootDriverDSL(private val driverDSL: DriverDSLImpl) : InternalD className = className, // cannot directly get class for this, so just use string jdwpPort = debugPort, extraJvmArguments = listOf( - "-Dname=node-${handle.configuration.p2pAddress}-webserver", + "-Dname=node-${handle.p2pAddress}-webserver", "-Djava.io.tmpdir=${System.getProperty("java.io.tmpdir")}" // Inherit from parent process ), classpath = ProcessUtilities.defaultClassPath, - workingDirectory = handle.configuration.baseDirectory, + workingDirectory = handle.baseDirectory, errorLogPath = Paths.get("error.$className.log"), arguments = listOf( - "--base-directory", handle.configuration.baseDirectory.toString(), - "--server.port=${handle.webAddress.port}", - "--corda.host=${handle.configuration.rpcOptions.address}", - "--corda.user=${handle.configuration.rpcUsers.first().username}", - "--corda.password=${handle.configuration.rpcUsers.first().password}" + "--base-directory", handle.baseDirectory.toString(), + "--server.port=${(handle as NodeHandleInternal).webAddress.port}", + "--corda.host=${handle.rpcAddress}", + "--corda.user=${handle.rpcUsers.first().username}", + "--corda.password=${handle.rpcUsers.first().password}" ), maximumHeapSize = null ) diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/NetworkMapVisualiser.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/NetworkMapVisualiser.kt index bbf21b1ece..9d370c22f6 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/NetworkMapVisualiser.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/NetworkMapVisualiser.kt @@ -19,6 +19,7 @@ import net.corda.node.services.statemachine.* import net.corda.testing.core.chooseIdentity import net.corda.testing.node.InMemoryMessagingNetwork import net.corda.testing.node.MockNetwork +import net.corda.testing.node.internal.InternalMockNetwork import rx.Scheduler import rx.schedulers.Schedulers import java.time.format.DateTimeFormatter @@ -105,8 +106,8 @@ class NetworkMapVisualiser : Application() { } // Fire the message bullets between nodes. simulation.mockNet.messagingNetwork.sentMessages.observeOn(uiThread).subscribe { msg: InMemoryMessagingNetwork.MessageTransfer -> - val senderNode: MockNetwork.MockNode = simulation.mockNet.addressToNode(msg.sender) - val destNode: MockNetwork.MockNode = simulation.mockNet.addressToNode(msg.recipients) + val senderNode: InternalMockNetwork.MockNode = simulation.mockNet.addressToNode(msg.sender) + val destNode: InternalMockNetwork.MockNode = simulation.mockNet.addressToNode(msg.recipients) if (transferIsInteresting(msg)) { viewModel.nodesToWidgets[senderNode]!!.pulseAnim.play() @@ -114,7 +115,7 @@ class NetworkMapVisualiser : Application() { } } // Pulse all parties in a trade when the trade completes - simulation.doneSteps.observeOn(uiThread).subscribe { nodes: Collection -> + simulation.doneSteps.observeOn(uiThread).subscribe { nodes: Collection -> nodes.forEach { viewModel.nodesToWidgets[it]!!.longPulseAnim.play() } } diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt index cb4fa0c488..5ba0385023 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt @@ -13,7 +13,7 @@ import net.corda.finance.utils.ScreenCoordinate import net.corda.netmap.simulation.IRSSimulation import net.corda.netmap.simulation.place import net.corda.testing.core.chooseIdentity -import net.corda.testing.node.MockNetwork +import net.corda.testing.node.internal.InternalMockNetwork import java.util.* class VisualiserViewModel { @@ -25,10 +25,10 @@ class VisualiserViewModel { } } - inner class NodeWidget(val node: MockNetwork.MockNode, val innerDot: Circle, val outerDot: Circle, val longPulseDot: Circle, + inner class NodeWidget(val node: InternalMockNetwork.MockNode, val innerDot: Circle, val outerDot: Circle, val longPulseDot: Circle, val pulseAnim: Animation, val longPulseAnim: Animation, val nameLabel: Label, val statusLabel: Label) { - fun position(nodeCoords: (node: MockNetwork.MockNode) -> ScreenCoordinate) { + fun position(nodeCoords: (node: InternalMockNetwork.MockNode) -> ScreenCoordinate) { val (x, y) = nodeCoords(node) innerDot.centerX = x innerDot.centerY = y @@ -47,7 +47,7 @@ class VisualiserViewModel { val trackerBoxes = HashMap() val doneTrackers = ArrayList() - val nodesToWidgets = HashMap() + val nodesToWidgets = HashMap() var bankCount: Int = 0 var serviceCount: Int = 0 @@ -78,7 +78,7 @@ class VisualiserViewModel { } } - fun nodeMapCoords(node: MockNetwork.MockNode): ScreenCoordinate { + fun nodeMapCoords(node: InternalMockNetwork.MockNode): ScreenCoordinate { // For an image of the whole world, we use: // return node.place.coordinate.project(mapImage.fitWidth, mapImage.fitHeight, 85.0511, -85.0511, -180.0, 180.0) @@ -128,7 +128,7 @@ class VisualiserViewModel { } } - fun makeNodeWidget(forNode: MockNetwork.MockNode, type: String, label: CordaX500Name = CordaX500Name(organisation = "Bank of Bologna", locality = "Bologna", country = "IT"), + fun makeNodeWidget(forNode: InternalMockNetwork.MockNode, type: String, label: CordaX500Name = CordaX500Name(organisation = "Bank of Bologna", locality = "Bologna", country = "IT"), nodeType: NetworkMapVisualiser.NodeType, index: Int): NodeWidget { fun emitRadarPulse(initialRadius: Double, targetRadius: Double, duration: Double): Pair { val pulse = Circle(initialRadius).apply { @@ -180,7 +180,7 @@ class VisualiserViewModel { return widget } - fun fireBulletBetweenNodes(senderNode: MockNetwork.MockNode, destNode: MockNetwork.MockNode, startType: String, endType: String) { + fun fireBulletBetweenNodes(senderNode: InternalMockNetwork.MockNode, destNode: InternalMockNetwork.MockNode, startType: String, endType: String) { val sx = nodesToWidgets[senderNode]!!.innerDot.centerX val sy = nodesToWidgets[senderNode]!!.innerDot.centerY val dx = nodesToWidgets[destNode]!!.innerDot.centerX 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 8fafa86192..66ba4e7cbd 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 @@ -10,9 +10,12 @@ import net.corda.irs.api.NodeInterestRates import net.corda.node.internal.StartedNode import net.corda.node.services.statemachine.StateMachineManager import net.corda.testing.core.TestIdentity -import net.corda.testing.node.* -import net.corda.testing.node.MockNetwork.MockNode +import net.corda.testing.node.InMemoryMessagingNetwork +import net.corda.testing.node.MockNodeParameters import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties +import net.corda.testing.node.TestClock +import net.corda.testing.node.internal.InternalMockNetwork +import net.corda.testing.node.internal.MockNodeArgs import rx.Observable import rx.subjects.PublishSubject import java.math.BigInteger @@ -24,7 +27,7 @@ import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletableFuture.allOf import java.util.concurrent.Future -internal val MockNode.place get() = configuration.myLegalName.locality.let { CityDatabase[it] }!! +internal val InternalMockNetwork.MockNode.place get() = configuration.myLegalName.locality.let { CityDatabase[it] }!! /** * Base class for network simulations that are based on the unit test / mock environment. @@ -50,7 +53,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, val bankLocations = listOf(Pair("London", "GB"), Pair("Frankfurt", "DE"), Pair("Rome", "IT")) - class RatesOracleNode(args: MockNodeArgs) : MockNode(args) { + class RatesOracleNode(args: MockNodeArgs) : InternalMockNetwork.MockNode(args) { companion object { // TODO: Make a more realistic legal name val RATES_SERVICE_NAME = CordaX500Name(organisation = "Rates Service Provider", locality = "Madrid", country = "ES") @@ -67,7 +70,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, } } - val mockNet = MockNetwork( + val mockNet = InternalMockNetwork( networkSendManuallyPumped = networkSendManuallyPumped, threadPerNode = runAsync, cordappPackages = listOf("net.corda.finance.contract", "net.corda.irs")) @@ -77,8 +80,8 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, val regulators = listOf(mockNet.createUnstartedNode(defaultParams.copy(legalName = DUMMY_REGULATOR.name))) 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(mockNet.defaultNotaryNode.internals, ratesOracle) - val banks: List = bankLocations.mapIndexed { i, (city, country) -> + val serviceProviders: List = listOf(mockNet.defaultNotaryNode.internals, ratesOracle) + val banks: List = bankLocations.mapIndexed { i, (city, country) -> val legalName = CordaX500Name(organisation = "Bank ${'A' + i}", locality = city, country = country) // Use deterministic seeds so the simulation is stable. Needed so that party owning keys are stable. mockNet.createUnstartedNode(defaultParams.copy(legalName = legalName, entropyRoot = BigInteger.valueOf(i.toLong()))) @@ -86,12 +89,12 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, val clocks = (serviceProviders + regulators + banks).map { it.platformClock as TestClock } // These are used from the network visualiser tool. - private val _allFlowSteps = PublishSubject.create>() - private val _doneSteps = PublishSubject.create>() + private val _allFlowSteps = PublishSubject.create>() + private val _doneSteps = PublishSubject.create>() @Suppress("unused") - val allFlowSteps: Observable> = _allFlowSteps + val allFlowSteps: Observable> = _allFlowSteps @Suppress("unused") - val doneSteps: Observable> = _doneSteps + val doneSteps: Observable> = _doneSteps private var pumpCursor = 0 @@ -120,7 +123,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, * A place for simulations to stash human meaningful text about what the node is "thinking", which might appear * in the UI somewhere. */ - val extraNodeLabels: MutableMap = Collections.synchronizedMap(HashMap()) + val extraNodeLabels: MutableMap = Collections.synchronizedMap(HashMap()) /** * Iterates the simulation by one step. @@ -151,7 +154,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, return null } - protected fun showProgressFor(nodes: List>) { + protected fun showProgressFor(nodes: List>) { nodes.forEach { node -> node.smm.changes.filter { it is StateMachineManager.Change.Add }.subscribe { linkFlowProgress(node.internals, it.logic) @@ -159,7 +162,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, } } - private fun linkFlowProgress(node: MockNode, flow: FlowLogic<*>) { + private fun linkFlowProgress(node: InternalMockNetwork.MockNode, flow: FlowLogic<*>) { val pt = flow.progressTracker ?: return pt.changes.subscribe { change: ProgressTracker.Change -> // Runs on node thread. @@ -168,14 +171,14 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, } - protected fun showConsensusFor(nodes: List) { + protected fun showConsensusFor(nodes: List) { val node = nodes.first() node.started!!.smm.changes.filter { it is StateMachineManager.Change.Add }.first().subscribe { linkConsensus(nodes, it.logic) } } - private fun linkConsensus(nodes: Collection, flow: FlowLogic<*>) { + private fun linkConsensus(nodes: Collection, flow: FlowLogic<*>) { flow.progressTracker?.changes?.subscribe { _: ProgressTracker.Change -> // Runs on node thread. if (flow.progressTracker!!.currentStep == ProgressTracker.DONE) { diff --git a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt index 10e20e070c..f76f400ef3 100644 --- a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt +++ b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt @@ -12,7 +12,7 @@ import net.corda.testing.core.BOC_NAME import net.corda.testing.core.DUMMY_BANK_A_NAME import net.corda.testing.core.DUMMY_BANK_B_NAME import net.corda.testing.core.chooseIdentity -import net.corda.testing.driver.NodeHandle +import net.corda.testing.driver.InProcess import net.corda.testing.driver.driver import net.corda.testing.node.User import net.corda.testing.node.internal.poll @@ -37,14 +37,14 @@ class TraderDemoTest { startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser)), startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser)), startNode(providedName = BOC_NAME, rpcUsers = listOf(bankUser)) - ).map { (it.getOrThrow() as NodeHandle.InProcess).node } + ).map { (it.getOrThrow() as InProcess) } nodeA.registerInitiatedFlow(BuyerFlow::class.java) val (nodeARpc, nodeBRpc) = listOf(nodeA, nodeB).map { - val client = CordaRPCClient(it.internals.configuration.rpcOptions.address!!) + val client = CordaRPCClient(it.rpcAddress) client.start(demoUser.username, demoUser.password).proxy } val nodeBankRpc = let { - val client = CordaRPCClient(bankNode.internals.configuration.rpcOptions.address!!) + val client = CordaRPCClient(bankNode.rpcAddress) client.start(bankUser.username, bankUser.password).proxy } @@ -56,8 +56,8 @@ class TraderDemoTest { val expectedBCash = clientB.cashCount + 1 val expectedPaper = listOf(clientA.commercialPaperCount + 1, clientB.commercialPaperCount) - clientBank.runIssuer(amount = 100.DOLLARS, buyerName = nodeA.info.chooseIdentity().name, sellerName = nodeB.info.chooseIdentity().name) - clientB.runSeller(buyerName = nodeA.info.chooseIdentity().name, amount = 5.DOLLARS) + clientBank.runIssuer(amount = 100.DOLLARS, buyerName = nodeA.services.myInfo.chooseIdentity().name, sellerName = nodeB.services.myInfo.chooseIdentity().name) + clientB.runSeller(buyerName = nodeA.services.myInfo.chooseIdentity().name, amount = 5.DOLLARS) assertThat(clientA.cashCount).isGreaterThan(originalACash) assertThat(clientB.cashCount).isEqualTo(expectedBCash) diff --git a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/driver/DriverTests.kt b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/driver/DriverTests.kt index 9778fbd44e..bf3bdf648e 100644 --- a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/driver/DriverTests.kt +++ b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/driver/DriverTests.kt @@ -15,6 +15,7 @@ import net.corda.testing.node.internal.addressMustNotBeBound import net.corda.testing.node.internal.internalDriver import net.corda.testing.core.DUMMY_BANK_A_NAME import net.corda.testing.core.DUMMY_NOTARY_NAME +import net.corda.testing.driver.internal.NodeHandleInternal import net.corda.testing.http.HttpApi import net.corda.testing.node.NotarySpec import org.assertj.core.api.Assertions.assertThat @@ -27,10 +28,11 @@ class DriverTests { private companion object { val DUMMY_REGULATOR_NAME = CordaX500Name("Regulator A", "Paris", "FR") val executorService: ScheduledExecutorService = Executors.newScheduledThreadPool(2) + fun nodeMustBeUp(handleFuture: CordaFuture) = handleFuture.getOrThrow().apply { val hostAndPort = nodeInfo.addresses.single() // Check that the port is bound - addressMustBeBound(executorService, hostAndPort, (this as? NodeHandle.OutOfProcess)?.process) + addressMustBeBound(executorService, hostAndPort, (this as? OutOfProcess)?.process) } fun nodeMustBeDown(handle: NodeHandle) { @@ -80,7 +82,7 @@ class DriverTests { val logConfigFile = projectRootDir / "config" / "dev" / "log4j2.xml" assertThat(logConfigFile).isRegularFile() driver(isDebug = true, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString())) { - val baseDirectory = startNode(providedName = DUMMY_BANK_A_NAME).getOrThrow().configuration.baseDirectory + val baseDirectory = startNode(providedName = DUMMY_BANK_A_NAME).getOrThrow().baseDirectory val logFile = (baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME).list { it.sorted().findFirst().get() } val debugLinesPresent = logFile.readLines { lines -> lines.anyMatch { line -> line.startsWith("[DEBUG]") } } assertThat(debugLinesPresent).isTrue() @@ -105,7 +107,7 @@ class DriverTests { // First check that the process-id file is created by the node on startup, so that we can be sure our check that // it's deleted on shutdown isn't a false-positive. driver { - val baseDirectory = defaultNotaryNode.getOrThrow().configuration.baseDirectory + val baseDirectory = defaultNotaryNode.getOrThrow().baseDirectory assertThat(baseDirectory / "process-id").exists() } diff --git a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/FlowStackSnapshotTest.kt b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/FlowStackSnapshotTest.kt index e2c03d66a1..423b14c014 100644 --- a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/FlowStackSnapshotTest.kt +++ b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/FlowStackSnapshotTest.kt @@ -2,6 +2,7 @@ package net.corda.testing.node import co.paralleluniverse.fibers.Suspendable import net.corda.client.jackson.JacksonSupport +import net.corda.client.rpc.CordaRPCClient import net.corda.core.flows.* import net.corda.core.internal.div import net.corda.core.internal.list @@ -228,7 +229,7 @@ class FlowStackSnapshotTest { fun `flowStackSnapshot contains full frames when methods with side effects are called`() { driver(startNodesInProcess = true) { val a = startNode(rpcUsers = listOf(User(Constants.USER, Constants.PASSWORD, setOf(startFlow())))).get() - a.rpcClientToNode().use(Constants.USER, Constants.PASSWORD) { connection -> + CordaRPCClient(a.rpcAddress).use(Constants.USER, Constants.PASSWORD) { connection -> val stackSnapshotFrames = connection.proxy.startFlow(::SideEffectFlow).returnValue.get() val iterator = stackSnapshotFrames.listIterator() assertFrame("run", false, iterator.next()) @@ -243,7 +244,7 @@ class FlowStackSnapshotTest { fun `flowStackSnapshot contains empty frames when methods with no side effects are called`() { driver(startNodesInProcess = true) { val a = startNode(rpcUsers = listOf(User(Constants.USER, Constants.PASSWORD, setOf(startFlow())))).get() - a.rpcClientToNode().use(Constants.USER, Constants.PASSWORD) { connection -> + CordaRPCClient(a.rpcAddress).use(Constants.USER, Constants.PASSWORD) { connection -> val stackSnapshotFrames = connection.proxy.startFlow(::NoSideEffectFlow).returnValue.get() val iterator = stackSnapshotFrames.listIterator() assertFrame("run", false, iterator.next()) @@ -258,10 +259,9 @@ class FlowStackSnapshotTest { fun `persistFlowStackSnapshot persists empty frames to a file when methods with no side effects are called`() { driver(startNodesInProcess = true) { val a = startNode(rpcUsers = listOf(User(Constants.USER, Constants.PASSWORD, setOf(startFlow())))).get() - - a.rpcClientToNode().use(Constants.USER, Constants.PASSWORD) { connection -> + CordaRPCClient(a.rpcAddress).use(Constants.USER, Constants.PASSWORD) { connection -> val flowId = connection.proxy.startFlow(::PersistingNoSideEffectFlow).returnValue.get() - val snapshotFromFile = readFlowStackSnapshotFromDir(a.configuration.baseDirectory, flowId) + val snapshotFromFile = readFlowStackSnapshotFromDir(a.baseDirectory, flowId) val stackSnapshotFrames = convertToStackSnapshotFrames(snapshotFromFile) val iterator = stackSnapshotFrames.listIterator() assertFrame("call", true, iterator.next()) @@ -276,10 +276,10 @@ class FlowStackSnapshotTest { driver(startNodesInProcess = true) { val a = startNode(rpcUsers = listOf(User(Constants.USER, Constants.PASSWORD, setOf(startFlow())))).get() - a.rpcClientToNode().use(Constants.USER, Constants.PASSWORD) { connection -> + CordaRPCClient(a.rpcAddress).use(Constants.USER, Constants.PASSWORD) { connection -> val numberOfFlowSnapshots = 5 val flowId = connection.proxy.startFlow(::MultiplePersistingSideEffectFlow, 5).returnValue.get() - val fileCount = countFilesInDir(a.configuration.baseDirectory, flowId) + val fileCount = countFilesInDir(a.baseDirectory, flowId) assertEquals(numberOfFlowSnapshots, fileCount) } } @@ -307,9 +307,9 @@ class FlowStackSnapshotTest { driver(startNodesInProcess = true) { val a = startNode(rpcUsers = listOf(User(Constants.USER, Constants.PASSWORD, setOf(startFlow())))).get() - a.rpcClientToNode().use(Constants.USER, Constants.PASSWORD) { connection -> + CordaRPCClient(a.rpcAddress).use(Constants.USER, Constants.PASSWORD) { connection -> val flowId = connection.proxy.startFlow(::PersistingSideEffectFlow).returnValue.get() - val snapshotFromFile = readFlowStackSnapshotFromDir(a.configuration.baseDirectory, flowId) + val snapshotFromFile = readFlowStackSnapshotFromDir(a.baseDirectory, flowId) var inCallCount = 0 var inPersistCount = 0 snapshotFromFile.stackFrames.forEach { diff --git a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/MockNetworkIntegrationTests.kt b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/MockNetworkIntegrationTests.kt index cf82aec871..eee030d580 100644 --- a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/MockNetworkIntegrationTests.kt +++ b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/MockNetworkIntegrationTests.kt @@ -2,6 +2,7 @@ package net.corda.testing.node import net.corda.core.internal.div import net.corda.testing.common.internal.ProjectStructure.projectRootDir +import net.corda.testing.node.internal.InternalMockNetwork import net.corda.testing.node.internal.ProcessUtilities.startJavaProcess import org.junit.Test import kotlin.test.assertEquals diff --git a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/internal/InternalMockNetworkIntegrationTests.kt b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/internal/InternalMockNetworkIntegrationTests.kt new file mode 100644 index 0000000000..b630143a71 --- /dev/null +++ b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/internal/InternalMockNetworkIntegrationTests.kt @@ -0,0 +1,26 @@ +package net.corda.testing.node.internal + +import net.corda.core.internal.div +import net.corda.testing.common.internal.ProjectStructure.projectRootDir +import net.corda.testing.node.internal.ProcessUtilities.startJavaProcess +import org.junit.Test +import kotlin.test.assertEquals + +class InternalMockNetworkIntegrationTests { + companion object { + @JvmStatic + fun main(args: Array) { + InternalMockNetwork(emptyList()).run { + repeat(2) { createNode() } + runNetwork() + stopNodes() + } + } + } + + @Test + fun `does not leak non-daemon threads`() { + val quasar = projectRootDir / "lib" / "quasar.jar" + assertEquals(0, startJavaProcess(emptyList(), extraJvmArguments = listOf("-javaagent:$quasar")).waitFor()) + } +} diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt index 826a49f16c..6a74e2d673 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt @@ -2,9 +2,9 @@ package net.corda.testing.driver -import net.corda.client.rpc.CordaRPCClient import net.corda.core.DoNotImplement import net.corda.core.concurrent.CordaFuture +import net.corda.core.flows.FlowLogic import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.messaging.CordaRPCOps @@ -12,15 +12,17 @@ import net.corda.core.node.NodeInfo import net.corda.core.utilities.NetworkHostAndPort import net.corda.node.internal.Node import net.corda.node.internal.StartedNode +import net.corda.node.services.api.StartedNodeServices import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.VerifierType -import net.corda.nodeapi.internal.config.SSLConfiguration +import net.corda.nodeapi.internal.persistence.CordaPersistence import net.corda.testing.core.DUMMY_NOTARY_NAME import net.corda.testing.node.NotarySpec import net.corda.testing.node.User import net.corda.testing.node.internal.DriverDSLImpl import net.corda.testing.node.internal.genericDriver import net.corda.testing.node.internal.getTimestampAsDirectoryName +import rx.Observable import java.net.InetSocketAddress import java.net.ServerSocket import java.nio.file.Path @@ -33,73 +35,37 @@ import java.util.concurrent.atomic.AtomicInteger data class NotaryHandle(val identity: Party, val validating: Boolean, val nodeHandles: CordaFuture>) @DoNotImplement -sealed class NodeHandle : AutoCloseable { - abstract val nodeInfo: NodeInfo +interface NodeHandle : AutoCloseable { + val nodeInfo: NodeInfo /** * Interface to the node's RPC system. The first RPC user will be used to login if are any, otherwise a default one * will be added and that will be used. */ - abstract val rpc: CordaRPCOps - abstract val configuration: NodeConfiguration - abstract val webAddress: NetworkHostAndPort - abstract val useHTTPS: Boolean - + val rpc: CordaRPCOps + val p2pAddress: NetworkHostAndPort + val rpcAddress: NetworkHostAndPort + val rpcUsers: List + val baseDirectory: Path /** * Stops the referenced node. */ - abstract fun stop() + fun stop() +} + +@DoNotImplement +interface OutOfProcess : NodeHandle { + val process: Process +} + +@DoNotImplement +interface InProcess : NodeHandle { + val database: CordaPersistence + val services: StartedNodeServices /** - * Closes and stops the node. + * Register a flow that is initiated by another flow */ - override fun close() = stop() - - data class OutOfProcess( - override val nodeInfo: NodeInfo, - override val rpc: CordaRPCOps, - override val configuration: NodeConfiguration, - override val webAddress: NetworkHostAndPort, - override val useHTTPS: Boolean, - val debugPort: Int?, - val process: Process, - private val onStopCallback: () -> Unit - ) : NodeHandle() { - override fun stop() { - with(process) { - destroy() - waitFor() - } - onStopCallback() - } - } - - data class InProcess( - override val nodeInfo: NodeInfo, - override val rpc: CordaRPCOps, - override val configuration: NodeConfiguration, - override val webAddress: NetworkHostAndPort, - override val useHTTPS: Boolean, - val node: StartedNode, - val nodeThread: Thread, - private val onStopCallback: () -> Unit - ) : NodeHandle() { - override fun stop() { - node.dispose() - with(nodeThread) { - interrupt() - join() - } - onStopCallback() - } - } - - /** - * Connects to node through RPC. - * - * @param sslConfiguration specifies SSL options. - */ - @JvmOverloads - fun rpcClientToNode(sslConfiguration: SSLConfiguration? = null): CordaRPCClient = CordaRPCClient(configuration.rpcOptions.address!!, sslConfiguration = sslConfiguration) + fun > registerInitiatedFlow(initiatedFlowClass: Class): Observable } data class WebserverHandle( @@ -137,12 +103,12 @@ data class NodeParameters( val startInSameProcess: Boolean? = null, val maximumHeapSize: String = "200m" ) { - fun setProvidedName(providedName: CordaX500Name?) = copy(providedName = providedName) - fun setRpcUsers(rpcUsers: List) = copy(rpcUsers = rpcUsers) - fun setVerifierType(verifierType: VerifierType) = copy(verifierType = verifierType) - fun setCustomerOverrides(customOverrides: Map) = copy(customOverrides = customOverrides) - fun setStartInSameProcess(startInSameProcess: Boolean?) = copy(startInSameProcess = startInSameProcess) - fun setMaximumHeapSize(maximumHeapSize: String) = copy(maximumHeapSize = maximumHeapSize) + fun setProvidedName(providedName: CordaX500Name?): NodeParameters = copy(providedName = providedName) + fun setRpcUsers(rpcUsers: List): NodeParameters = copy(rpcUsers = rpcUsers) + fun setVerifierType(verifierType: VerifierType): NodeParameters = copy(verifierType = verifierType) + fun setCustomerOverrides(customOverrides: Map): NodeParameters = copy(customOverrides = customOverrides) + fun setStartInSameProcess(startInSameProcess: Boolean?): NodeParameters = copy(startInSameProcess = startInSameProcess) + fun setMaximumHeapSize(maximumHeapSize: String): NodeParameters = copy(maximumHeapSize = maximumHeapSize) } data class JmxPolicy(val startJmxHttpServer: Boolean = false, diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/internal/DriverInternal.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/internal/DriverInternal.kt new file mode 100644 index 0000000000..3f658d6086 --- /dev/null +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/internal/DriverInternal.kt @@ -0,0 +1,74 @@ +package net.corda.testing.driver.internal + +import net.corda.core.flows.FlowLogic +import net.corda.core.messaging.CordaRPCOps +import net.corda.core.node.NodeInfo +import net.corda.core.utilities.NetworkHostAndPort +import net.corda.node.internal.Node +import net.corda.node.internal.StartedNode +import net.corda.node.services.api.StartedNodeServices +import net.corda.node.services.config.NodeConfiguration +import net.corda.nodeapi.internal.persistence.CordaPersistence +import net.corda.testing.driver.InProcess +import net.corda.testing.driver.NodeHandle +import net.corda.testing.driver.OutOfProcess +import net.corda.testing.node.User +import rx.Observable +import java.nio.file.Path + +interface NodeHandleInternal : NodeHandle { + val configuration: NodeConfiguration + val useHTTPS: Boolean + val webAddress: NetworkHostAndPort + override val p2pAddress: NetworkHostAndPort get() = configuration.p2pAddress + override val rpcAddress: NetworkHostAndPort get() = configuration.rpcOptions.address!! + override val baseDirectory: Path get() = configuration.baseDirectory +} + +data class OutOfProcessImpl( + override val nodeInfo: NodeInfo, + override val rpc: CordaRPCOps, + override val configuration: NodeConfiguration, + override val webAddress: NetworkHostAndPort, + override val useHTTPS: Boolean, + val debugPort: Int?, + override val process: Process, + private val onStopCallback: () -> Unit +) : OutOfProcess, NodeHandleInternal { + override val rpcUsers: List = configuration.rpcUsers.map { User(it.username, it.password, it.permissions) } + override fun stop() { + with(process) { + destroy() + waitFor() + } + onStopCallback() + } + + override fun close() = stop() +} + +data class InProcessImpl( + override val nodeInfo: NodeInfo, + override val rpc: CordaRPCOps, + override val configuration: NodeConfiguration, + override val webAddress: NetworkHostAndPort, + override val useHTTPS: Boolean, + private val nodeThread: Thread, + private val onStopCallback: () -> Unit, + private val node: StartedNode +) : InProcess, NodeHandleInternal { + override val database: CordaPersistence get() = node.database + override val services: StartedNodeServices get() = node.services + override val rpcUsers: List = configuration.rpcUsers.map { User(it.username, it.password, it.permissions) } + override fun stop() { + node.dispose() + with(nodeThread) { + interrupt() + join() + } + onStopCallback() + } + + override fun close() = stop() + override fun > registerInitiatedFlow(initiatedFlowClass: Class): Observable = node.registerInitiatedFlow(initiatedFlowClass) +} diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt index f1d45b1028..42e5793d75 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt @@ -304,7 +304,7 @@ class InMemoryMessagingNetwork internal constructor( override fun getAddressOfParty(partyInfo: PartyInfo): MessageRecipients { return when (partyInfo) { - is PartyInfo.SingleNode -> peersMapping[partyInfo.party.name] ?: throw IllegalArgumentException("No MockNode for party ${partyInfo.party.name}") + is PartyInfo.SingleNode -> peersMapping[partyInfo.party.name] ?: throw IllegalArgumentException("No StartedMockNode for party ${partyInfo.party.name}") is PartyInfo.DistributedNode -> ServiceHandle(partyInfo.party) } } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNetwork.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNetwork.kt new file mode 100644 index 0000000000..070fec8ef9 --- /dev/null +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNetwork.kt @@ -0,0 +1,178 @@ +package net.corda.testing.node + +import com.google.common.jimfs.Jimfs +import net.corda.core.concurrent.CordaFuture +import net.corda.core.crypto.random63BitValue +import net.corda.core.flows.FlowLogic +import net.corda.core.identity.CordaX500Name +import net.corda.core.identity.Party +import net.corda.core.node.NodeInfo +import net.corda.node.VersionInfo +import net.corda.node.internal.StartedNode +import net.corda.node.services.api.StartedNodeServices +import net.corda.node.services.config.NodeConfiguration +import net.corda.node.services.messaging.MessagingService +import net.corda.nodeapi.internal.persistence.CordaPersistence +import net.corda.testing.core.DUMMY_NOTARY_NAME +import net.corda.testing.node.internal.InternalMockNetwork +import net.corda.testing.node.internal.setMessagingServiceSpy +import rx.Observable +import java.math.BigInteger +import java.nio.file.Path + +/** + * Extend this class in order to intercept and modify messages passing through the [MessagingService] when using the [InMemoryMessagingNetwork]. + */ +open class MessagingServiceSpy(val messagingService: MessagingService) : MessagingService by messagingService + +/** + * @param entropyRoot the initial entropy value to use when generating keys. Defaults to an (insecure) random value, + * but can be overridden to cause nodes to have stable or colliding identity/service keys. + * @param configOverrides add/override behaviour of the [NodeConfiguration] mock object. + */ +@Suppress("unused") +data class MockNodeParameters( + val forcedID: Int? = null, + val legalName: CordaX500Name? = null, + val entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), + val configOverrides: (NodeConfiguration) -> Any? = {}, + val version: VersionInfo = MockServices.MOCK_VERSION_INFO) { + fun setForcedID(forcedID: Int?): MockNodeParameters = copy(forcedID = forcedID) + fun setLegalName(legalName: CordaX500Name?): MockNodeParameters = copy(legalName = legalName) + fun setEntropyRoot(entropyRoot: BigInteger): MockNodeParameters = copy(entropyRoot = entropyRoot) + fun setConfigOverrides(configOverrides: (NodeConfiguration) -> Any?): MockNodeParameters = copy(configOverrides = configOverrides) +} + +/** Helper builder for configuring a [InternalMockNetwork] from Java. */ +@Suppress("unused") +data class MockNetworkParameters( + val networkSendManuallyPumped: Boolean = false, + val threadPerNode: Boolean = false, + val servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = InMemoryMessagingNetwork.ServicePeerAllocationStrategy.Random(), + val initialiseSerialization: Boolean = true, + val notarySpecs: List = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME)), + val maxTransactionSize: Int = Int.MAX_VALUE) { + fun setNetworkSendManuallyPumped(networkSendManuallyPumped: Boolean): MockNetworkParameters = copy(networkSendManuallyPumped = networkSendManuallyPumped) + fun setThreadPerNode(threadPerNode: Boolean): MockNetworkParameters = copy(threadPerNode = threadPerNode) + fun setServicePeerAllocationStrategy(servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy): MockNetworkParameters = copy(servicePeerAllocationStrategy = servicePeerAllocationStrategy) + fun setInitialiseSerialization(initialiseSerialization: Boolean): MockNetworkParameters = copy(initialiseSerialization = initialiseSerialization) + fun setNotarySpecs(notarySpecs: List): MockNetworkParameters = copy(notarySpecs = notarySpecs) + fun setMaxTransactionSize(maxTransactionSize: Int): MockNetworkParameters = copy(maxTransactionSize = maxTransactionSize) +} + +/** Represents a node configuration for injection via [MockNetworkParameters] **/ +data class MockNetworkNotarySpec(val name: CordaX500Name, val validating: Boolean = true) { + constructor(name: CordaX500Name) : this(name, validating = true) +} + +/** A class that represents an unstarted mock node for testing. **/ +class UnstartedMockNode private constructor(private val node: InternalMockNetwork.MockNode) { + companion object { + internal fun create(node: InternalMockNetwork.MockNode): UnstartedMockNode { + return UnstartedMockNode(node) + } + } + + val id get() : Int = node.id + /** Start the node **/ + fun start() = StartedMockNode.create(node.start()) +} + +/** A class that represents a started mock node for testing. **/ +class StartedMockNode private constructor(private val node: StartedNode) { + companion object { + internal fun create(node: StartedNode): StartedMockNode { + return StartedMockNode(node) + } + } + + val services get() : StartedNodeServices = node.services + val database get() : CordaPersistence = node.database + val id get() : Int = node.internals.id + val info get() : NodeInfo = node.services.myInfo + val network get() : MessagingService = node.network + /** Register a flow that is initiated by another flow **/ + fun > registerInitiatedFlow(initiatedFlowClass: Class): Observable = node.registerInitiatedFlow(initiatedFlowClass) + + /** + * Attach a [MessagingServiceSpy] to the [InternalMockNetwork.MockNode] allowing + * interception and modification of messages. + */ + fun setMessagingServiceSpy(messagingServiceSpy: MessagingServiceSpy) = node.setMessagingServiceSpy(messagingServiceSpy) + + /** Stop the node **/ + fun stop() = node.internals.stop() + + /** Receive a message from the queue. */ + fun pumpReceive(block: Boolean = false): InMemoryMessagingNetwork.MessageTransfer? { + return (services.networkService as InMemoryMessagingNetwork.TestMessagingService).pumpReceive(block) + } + + /** Returns the currently live flows of type [flowClass], and their corresponding result future. */ + fun > findStateMachines(flowClass: Class): List>> = node.smm.findStateMachines(flowClass) +} + +/** + * A mock node brings up a suite of in-memory services in a fast manner suitable for unit testing. + * Components that do IO are either swapped out for mocks, or pointed to a [Jimfs] in memory filesystem or an in + * memory H2 database instance. + * + * Mock network nodes require manual pumping by default: they will not run asynchronous. This means that + * for message exchanges to take place (and associated handlers to run), you must call the [runNetwork] + * method. + * + * You can get a printout of every message sent by using code like: + * + * LogHelper.setLevel("+messages") + * + * By default a single notary node is automatically started, which forms part of the network parameters for all the nodes. + * This node is available by calling [defaultNotaryNode]. + */ +open class MockNetwork( + val cordappPackages: List, + val defaultParameters: MockNetworkParameters = MockNetworkParameters(), + val networkSendManuallyPumped: Boolean = defaultParameters.networkSendManuallyPumped, + val threadPerNode: Boolean = defaultParameters.threadPerNode, + val servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy, + val initialiseSerialization: Boolean = defaultParameters.initialiseSerialization, + val notarySpecs: List = defaultParameters.notarySpecs, + val maxTransactionSize: Int = defaultParameters.maxTransactionSize) { + @JvmOverloads + constructor(cordappPackages: List, parameters: MockNetworkParameters = MockNetworkParameters()) : this(cordappPackages, defaultParameters = parameters) + + private val internalMockNetwork: InternalMockNetwork = InternalMockNetwork(cordappPackages, defaultParameters, networkSendManuallyPumped, threadPerNode, servicePeerAllocationStrategy, initialiseSerialization, notarySpecs, maxTransactionSize) + val defaultNotaryNode get() : StartedMockNode = StartedMockNode.create(internalMockNetwork.defaultNotaryNode) + val defaultNotaryIdentity get() : Party = internalMockNetwork.defaultNotaryIdentity + val notaryNodes get() : List = internalMockNetwork.notaryNodes.map { StartedMockNode.create(it) } + val nextNodeId get() : Int = internalMockNetwork.nextNodeId + + /** Create a started node with the given identity. **/ + fun createPartyNode(legalName: CordaX500Name? = null): StartedMockNode = StartedMockNode.create(internalMockNetwork.createPartyNode(legalName)) + + /** Create a started node with the given parameters. **/ + fun createNode(parameters: MockNodeParameters = MockNodeParameters()): StartedMockNode = StartedMockNode.create(internalMockNetwork.createNode(parameters)) + + /** Create an unstarted node with the given parameters. **/ + fun createUnstartedNode(parameters: MockNodeParameters = MockNodeParameters()): UnstartedMockNode = UnstartedMockNode.create(internalMockNetwork.createUnstartedNode(parameters)) + + /** Start all nodes that aren't already started. **/ + fun startNodes() = internalMockNetwork.startNodes() + + /** Stop all nodes. **/ + fun stopNodes() = internalMockNetwork.stopNodes() + + /** Block until all scheduled activity, active flows and network activity has ceased. **/ + fun waitQuiescent() = internalMockNetwork.waitQuiescent() + + /** + * Asks every node in order to process any queued up inbound messages. This may in turn result in nodes + * sending more messages to each other, thus, a typical usage is to call runNetwork with the [rounds] + * parameter set to -1 (the default) which simply runs as many rounds as necessary to result in network + * stability (no nodes sent any messages in the last round). + */ + @JvmOverloads + fun runNetwork(rounds: Int = -1) = internalMockNetwork.runNetwork(rounds) + + /** Get the base directory for the given node id. **/ + fun baseDirectory(nodeId: Int): Path = internalMockNetwork.baseDirectory(nodeId) +} \ No newline at end of file diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt index bdd40ada5a..3f7bc3d6b5 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt @@ -44,6 +44,9 @@ import net.corda.testing.core.BOB_NAME import net.corda.testing.core.DUMMY_BANK_A_NAME import net.corda.testing.core.setGlobalSerialization import net.corda.testing.driver.* +import net.corda.testing.driver.internal.InProcessImpl +import net.corda.testing.driver.internal.NodeHandleInternal +import net.corda.testing.driver.internal.OutOfProcessImpl import net.corda.testing.node.ClusterSpec import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO import net.corda.testing.node.NotarySpec @@ -355,7 +358,7 @@ class DriverDSLImpl( } private fun queryWebserver(handle: NodeHandle, process: Process): WebserverHandle { - val protocol = if (handle.useHTTPS) "https://" else "http://" + val protocol = if ((handle as NodeHandleInternal).useHTTPS) "https://" else "http://" val url = URL("$protocol${handle.webAddress}/api/status") val client = OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build() @@ -375,7 +378,7 @@ class DriverDSLImpl( val debugPort = if (isDebug) debugPortAllocation.nextPort() else null val process = startWebserver(handle, debugPort, maximumHeapSize) shutdownManager.registerProcessShutdown(process) - val webReadyFuture = addressMustBeBoundFuture(executorService, handle.webAddress, process) + val webReadyFuture = addressMustBeBoundFuture(executorService, (handle as NodeHandleInternal).webAddress, process) return webReadyFuture.map { queryWebserver(handle, process) } } @@ -654,7 +657,7 @@ class DriverDSLImpl( return nodeAndThreadFuture.flatMap { (node, thread) -> establishRpc(config, openFuture()).flatMap { rpc -> allNodesConnected(rpc).map { - NodeHandle.InProcess(rpc.nodeInfo(), rpc, config.corda, webAddress, useHTTPS, node, thread, onNodeExit) + InProcessImpl(rpc.nodeInfo(), rpc, config.corda, webAddress, useHTTPS, thread, onNodeExit, node) } } } @@ -683,7 +686,7 @@ class DriverDSLImpl( } processDeathFuture.cancel(false) log.info("Node handle is ready. NodeInfo: ${rpc.nodeInfo()}, WebAddress: $webAddress") - NodeHandle.OutOfProcess(rpc.nodeInfo(), rpc, config.corda, webAddress, useHTTPS, debugPort, process, onNodeExit) + OutOfProcessImpl(rpc.nodeInfo(), rpc, config.corda, webAddress, useHTTPS, debugPort, process, onNodeExit) } } } @@ -833,10 +836,10 @@ class DriverDSLImpl( val className = "net.corda.webserver.WebServer" return ProcessUtilities.startCordaProcess( className = className, // cannot directly get class for this, so just use string - arguments = listOf("--base-directory", handle.configuration.baseDirectory.toString()), + arguments = listOf("--base-directory", handle.baseDirectory.toString()), jdwpPort = debugPort, extraJvmArguments = listOf( - "-Dname=node-${handle.configuration.p2pAddress}-webserver", + "-Dname=node-${handle.p2pAddress}-webserver", "-Djava.io.tmpdir=${System.getProperty("java.io.tmpdir")}" // Inherit from parent process ), errorLogPath = Paths.get("error.$className.log"), 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/internal/InternalMockNetwork.kt similarity index 80% rename from testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt rename to testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/InternalMockNetwork.kt index 5db5bb6fcd..a60dc7d13d 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/internal/InternalMockNetwork.kt @@ -1,4 +1,4 @@ -package net.corda.testing.node +package net.corda.testing.node.internal import com.google.common.jimfs.Configuration.unix import com.google.common.jimfs.Jimfs @@ -7,6 +7,7 @@ import com.nhaarman.mockito_kotlin.whenever import net.corda.core.DoNotImplement import net.corda.core.crypto.Crypto import net.corda.core.crypto.random63BitValue +import net.corda.core.flows.FlowLogic import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate @@ -28,6 +29,7 @@ import net.corda.core.utilities.contextLogger import net.corda.core.utilities.seconds import net.corda.node.VersionInfo import net.corda.node.internal.AbstractNode +import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.StartedNode import net.corda.node.internal.cordapp.CordappLoader import net.corda.node.services.api.IdentityServiceInternal @@ -52,8 +54,11 @@ import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.testThreadFactory import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties +import net.corda.testing.core.setGlobalSerialization +import net.corda.testing.node.* import org.apache.activemq.artemis.utils.ReusableLatch import org.apache.sshd.common.util.security.SecurityUtils +import rx.Observable import rx.internal.schedulers.CachedThreadScheduler import java.math.BigInteger import java.nio.file.Path @@ -63,48 +68,13 @@ import java.time.Clock import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicInteger -fun StartedNode.pumpReceive(block: Boolean = false): InMemoryMessagingNetwork.MessageTransfer? { +fun StartedNode.pumpReceive(block: Boolean = false): InMemoryMessagingNetwork.MessageTransfer? { return (network as InMemoryMessagingNetwork.TestMessagingService).pumpReceive(block) } -/** Helper builder for configuring a [MockNetwork] from Java. */ -@Suppress("unused") -data class MockNetworkParameters( - val networkSendManuallyPumped: Boolean = false, - val threadPerNode: Boolean = false, - val servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = InMemoryMessagingNetwork.ServicePeerAllocationStrategy.Random(), - val defaultFactory: (MockNodeArgs) -> MockNetwork.MockNode = MockNetwork::MockNode, - val initialiseSerialization: Boolean = true, - val notarySpecs: List = listOf(MockNetwork.NotarySpec(DUMMY_NOTARY_NAME))) { - 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: (MockNodeArgs) -> MockNetwork.MockNode) = copy(defaultFactory = defaultFactory) - fun setInitialiseSerialization(initialiseSerialization: Boolean) = copy(initialiseSerialization = initialiseSerialization) - fun setNotarySpecs(notarySpecs: List) = copy(notarySpecs = notarySpecs) -} - -/** - * @param entropyRoot the initial entropy value to use when generating keys. Defaults to an (insecure) random value, - * but can be overridden to cause nodes to have stable or colliding identity/service keys. - * @param configOverrides add/override behaviour of the [NodeConfiguration] mock object. - */ -@Suppress("unused") -data class MockNodeParameters( - val forcedID: Int? = null, - val legalName: CordaX500Name? = null, - val entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), - val configOverrides: (NodeConfiguration) -> Any? = {}, - val version: VersionInfo = MOCK_VERSION_INFO) { - fun setForcedID(forcedID: Int?) = copy(forcedID = forcedID) - fun setLegalName(legalName: CordaX500Name?) = copy(legalName = legalName) - fun setEntropyRoot(entropyRoot: BigInteger) = copy(entropyRoot = entropyRoot) - fun setConfigOverrides(configOverrides: (NodeConfiguration) -> Any?) = copy(configOverrides = configOverrides) -} - data class MockNodeArgs( val config: NodeConfiguration, - val network: MockNetwork, + val network: InternalMockNetwork, val id: Int, val entropyRoot: BigInteger, val version: VersionInfo = MOCK_VERSION_INFO @@ -126,19 +96,15 @@ data class MockNodeArgs( * By default a single notary node is automatically started, which forms part of the network parameters for all the nodes. * This node is available by calling [defaultNotaryNode]. */ -open class MockNetwork(private val cordappPackages: List, - defaultParameters: MockNetworkParameters = MockNetworkParameters(), - private val networkSendManuallyPumped: Boolean = defaultParameters.networkSendManuallyPumped, - private val threadPerNode: Boolean = defaultParameters.threadPerNode, - servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy, - private val defaultFactory: (MockNodeArgs) -> MockNode = defaultParameters.defaultFactory, - initialiseSerialization: Boolean = defaultParameters.initialiseSerialization, - private val notarySpecs: List = defaultParameters.notarySpecs, - maxTransactionSize: Int = Int.MAX_VALUE) { - /** Helper constructor for creating a [MockNetwork] with custom parameters from Java. */ - @JvmOverloads - constructor(cordappPackages: List, parameters: MockNetworkParameters = MockNetworkParameters()) : this(cordappPackages, defaultParameters = parameters) - +open class InternalMockNetwork(private val cordappPackages: List, + defaultParameters: MockNetworkParameters = MockNetworkParameters(), + val networkSendManuallyPumped: Boolean = defaultParameters.networkSendManuallyPumped, + val threadPerNode: Boolean = defaultParameters.threadPerNode, + servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy, + initialiseSerialization: Boolean = defaultParameters.initialiseSerialization, + val notarySpecs: List = defaultParameters.notarySpecs, + maxTransactionSize: Int = Int.MAX_VALUE, + val defaultFactory: (MockNodeArgs) -> MockNode = InternalMockNetwork::MockNode) { init { // Apache SSHD for whatever reason registers a SFTP FileSystemProvider - which gets loaded by JimFS. // This SFTP support loads BouncyCastle, which we want to avoid. @@ -158,7 +124,7 @@ open class MockNetwork(private val cordappPackages: List, private val serializationEnv = try { setGlobalSerialization(initialiseSerialization) } catch (e: IllegalStateException) { - throw IllegalStateException("Using more than one MockNetwork simultaneously is not supported.", e) + throw IllegalStateException("Using more than one InternalMockNetwork simultaneously is not supported.", e) } private val sharedUserCount = AtomicInteger(0) @@ -329,12 +295,12 @@ open class MockNetwork(private val cordappPackages: List, // This is not thread safe, but node construction is done on a single thread, so that should always be fine override fun generateKeyPair(): KeyPair { counter = counter.add(BigInteger.ONE) - // The MockNode specifically uses EdDSA keys as they are fixed and stored in json files for some tests (e.g IRSSimulation). + // The StartedMockNode specifically uses EdDSA keys as they are fixed and stored in json files for some tests (e.g IRSSimulation). return Crypto.deriveKeyPairFromEntropy(Crypto.EDDSA_ED25519_SHA512, counter) } /** - * MockNetwork will ensure nodes are connected to each other. The nodes themselves + * InternalMockNetwork will ensure nodes are connected to each other. The nodes themselves * won't be able to tell if that happened already or not. */ override fun checkNetworkMapIsInitialized() = Unit @@ -478,20 +444,12 @@ open class MockNetwork(private val cordappPackages: List, busyLatch.await() } - data class NotarySpec(val name: CordaX500Name, val validating: Boolean = true) { - constructor(name: CordaX500Name) : this(name, validating = true) - } } /** - * Extend this class in order to intercept and modify messages passing through the [MessagingService] when using the [InMemoryMessagingNetwork]. + * Attach a [MessagingServiceSpy] to the [InternalMockNetwork.MockNode] allowing interception and modification of messages. */ -open class MessagingServiceSpy(val messagingService: MessagingService) : MessagingService by messagingService - -/** - * Attach a [MessagingServiceSpy] to the [MockNetwork.MockNode] allowing interception and modification of messages. - */ -fun StartedNode.setMessagingServiceSpy(messagingServiceSpy: MessagingServiceSpy) { +fun StartedNode.setMessagingServiceSpy(messagingServiceSpy: MessagingServiceSpy) { internals.setMessagingServiceSpy(messagingServiceSpy) } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/ProcessUtilities.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/ProcessUtilities.kt index 8d2a8d5486..6354cde0d0 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/ProcessUtilities.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/ProcessUtilities.kt @@ -60,4 +60,4 @@ object ProcessUtilities { } val defaultClassPath: String get() = System.getProperty("java.class.path") -} +} \ No newline at end of file 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 index b6b336ec7b..fbf6bb01f4 100644 --- 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 @@ -6,22 +6,15 @@ import static java.util.Collections.emptyList; @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(emptyList(), new MockNetworkParameters().setDefaultFactory(args -> new CustomNode(args))); - new MockNetwork(emptyList(), new MockNetworkParameters().setDefaultFactory(CustomNode::new)); + new MockNetwork(emptyList()); + new MockNetwork(emptyList(), new MockNetworkParameters().setInitialiseSerialization(false)); //noinspection Convert2MethodRef - new MockNetwork(emptyList()).createNode(new MockNodeParameters(), args -> new CustomNode(args)); - new MockNetwork(emptyList()).createNode(new MockNodeParameters(), CustomNode::new); + new MockNetwork(emptyList()).createNode(new MockNodeParameters()); } } diff --git a/testing/node-driver/src/test/kotlin/net/corda/testing/node/MockNetworkTests.kt b/testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/InternalMockNetworkTests.kt similarity index 75% rename from testing/node-driver/src/test/kotlin/net/corda/testing/node/MockNetworkTests.kt rename to testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/InternalMockNetworkTests.kt index 10d9358243..478585af17 100644 --- a/testing/node-driver/src/test/kotlin/net/corda/testing/node/MockNetworkTests.kt +++ b/testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/InternalMockNetworkTests.kt @@ -1,18 +1,18 @@ -package net.corda.testing.node +package net.corda.testing.node.internal import net.corda.core.serialization.internal.effectiveSerializationEnv import org.assertj.core.api.Assertions.assertThatThrownBy import org.junit.Test -class MockNetworkTests { +class InternalMockNetworkTests { @Test fun `does not leak serialization env if init fails`() { val e = Exception("didn't work") assertThatThrownBy { - object : MockNetwork(emptyList(), initialiseSerialization = true) { + object : InternalMockNetwork(emptyList(), initialiseSerialization = true) { override fun createNotaries() = throw e } }.isSameAs(e) assertThatThrownBy { effectiveSerializationEnv }.isInstanceOf(IllegalStateException::class.java) } -} +} \ No newline at end of file diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt index 9480d13b6b..62d9fc9dca 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt @@ -4,6 +4,7 @@ import joptsimple.OptionSet import net.corda.client.mock.ErrorFlowsEventGenerator import net.corda.client.mock.EventGenerator import net.corda.client.mock.Generator +import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCConnection import net.corda.core.contracts.Amount import net.corda.core.identity.CordaX500Name @@ -83,7 +84,7 @@ class ExplorerSimulation(private val options: OptionSet) { issuerNodeUSD = issuerUSD.get() arrayOf(notaryNode, aliceNode, bobNode, issuerNodeGBP, issuerNodeUSD).forEach { - println("${it.nodeInfo.legalIdentities.first()} started on ${it.configuration.rpcOptions.address}") + println("${it.nodeInfo.legalIdentities.first()} started on ${it.rpcAddress}") } when { @@ -95,19 +96,19 @@ class ExplorerSimulation(private val options: OptionSet) { private fun setUpRPC() { // Register with alice to use alice's RPC proxy to create random events. - val aliceClient = aliceNode.rpcClientToNode() + val aliceClient = CordaRPCClient(aliceNode.rpcAddress) val aliceConnection = aliceClient.start(user.username, user.password) val aliceRPC = aliceConnection.proxy - val bobClient = bobNode.rpcClientToNode() + val bobClient = CordaRPCClient(bobNode.rpcAddress) val bobConnection = bobClient.start(user.username, user.password) val bobRPC = bobConnection.proxy - val issuerClientGBP = issuerNodeGBP.rpcClientToNode() + val issuerClientGBP = CordaRPCClient(issuerNodeGBP.rpcAddress) val issuerGBPConnection = issuerClientGBP.start(manager.username, manager.password) val issuerRPCGBP = issuerGBPConnection.proxy - val issuerClientUSD = issuerNodeUSD.rpcClientToNode() + val issuerClientUSD = CordaRPCClient(issuerNodeUSD.rpcAddress) val issuerUSDConnection = issuerClientUSD.start(manager.username, manager.password) val issuerRPCUSD = issuerUSDConnection.proxy diff --git a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierDriver.kt b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierDriver.kt index ad436e30d6..70de05b28e 100644 --- a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierDriver.kt +++ b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierDriver.kt @@ -28,6 +28,7 @@ import net.corda.testing.driver.JmxPolicy import net.corda.testing.driver.NodeHandle import net.corda.testing.driver.PortAllocation import net.corda.testing.driver.driver +import net.corda.testing.driver.internal.NodeHandleInternal import net.corda.testing.node.NotarySpec import net.corda.testing.node.internal.* import org.apache.activemq.artemis.api.core.SimpleString @@ -255,7 +256,7 @@ data class VerifierDriverDSL(private val driverDSL: DriverDSLImpl) : InternalDri /** Starts a verifier connecting to the specified node */ fun startVerifier(nodeHandle: NodeHandle): CordaFuture { - return startVerifier(nodeHandle.configuration.p2pAddress) + return startVerifier(nodeHandle.p2pAddress) } /** Starts a verifier connecting to the specified requestor */ @@ -263,8 +264,8 @@ data class VerifierDriverDSL(private val driverDSL: DriverDSLImpl) : InternalDri return startVerifier(verificationRequestorHandle.p2pAddress) } - private fun NodeHandle.connectToNode(closure: (ClientSession) -> A): A { - val transport = ArtemisTcpTransport.tcpTransport(ConnectionDirection.Outbound(), configuration.p2pAddress, configuration) + private fun NodeHandleInternal.connectToNode(closure: (ClientSession) -> A): A { + val transport = ArtemisTcpTransport.tcpTransport(ConnectionDirection.Outbound(), p2pAddress, configuration) val locator = ActiveMQClient.createServerLocatorWithoutHA(transport) val sessionFactory = locator.createSessionFactory() val session = sessionFactory.createSession(NODE_USER, NODE_USER, false, true, true, locator.isPreAcknowledge, locator.ackBatchSize) @@ -277,7 +278,7 @@ data class VerifierDriverDSL(private val driverDSL: DriverDSLImpl) : InternalDri * Waits until [number] verifiers are listening for verification requests coming from the Node. Check * [VerificationRequestorHandle.waitUntilNumberOfVerifiers] for an equivalent for requestors. */ - fun NodeHandle.waitUntilNumberOfVerifiers(number: Int) { + fun NodeHandleInternal.waitUntilNumberOfVerifiers(number: Int) { connectToNode { session -> poll(driverDSL.executorService, "$number verifiers to come online") { if (session.queueQuery(SimpleString(VerifierApi.VERIFICATION_REQUESTS_QUEUE_NAME)).consumerCount >= number) { diff --git a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt index 2138b1876f..6de9c38700 100644 --- a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt +++ b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt @@ -15,6 +15,7 @@ import net.corda.node.services.config.VerifierType import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.DUMMY_NOTARY_NAME import net.corda.testing.core.SerializationEnvironmentRule +import net.corda.testing.driver.internal.NodeHandleInternal import net.corda.testing.node.NotarySpec import org.junit.Rule import org.junit.Test @@ -139,7 +140,7 @@ class VerifierTests { notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, verifierType = VerifierType.OutOfProcess)) ) { val aliceNode = startNode(providedName = ALICE_NAME).getOrThrow() - val notaryNode = defaultNotaryNode.getOrThrow() + val notaryNode = defaultNotaryNode.getOrThrow() as NodeHandleInternal val alice = aliceNode.rpc.wellKnownPartyFromX500Name(ALICE_NAME)!! startVerifier(notaryNode) aliceNode.rpc.startFlow(::CashIssueFlow, 10.DOLLARS, OpaqueBytes.of(0), defaultNotaryIdentity).returnValue.get()