Skip to content

Commit

Permalink
[CORDA-1035] Testing api KDoc Updates (corda#2584)
Browse files Browse the repository at this point in the history
* Testing api KDoc Updates

* Update after code review

* Update api-current

* Revert changes to compiler.xml

* Made comment changes from review

* Fixing merge conflict

* Don't expose net.corda.node through test API (first pass)

* Fixing merge conflicts

* Update api-current

* Addressing review commits

* Fix exposure of internal implementation of MessageHandlerRegistration

* Make InProcess expose ServiceHub instead of internal StartedNodeServices

* Move InternalMockMessaginService interface to internal namespace

* Move MOCK_VERSION_INFO to internal namespace to avoid exposing VersionInfo

* Don't expose WritableTransactionStorage via testing api

* Create public VerifierType enum

* Update api-current and modify check-api-changes to check for net.corda.node exposures

* Fix merge conflicts

* Fixing another merge conflict

* Fix accidentally broken unit tests

* Make getInternalServices a property

* Fix failing unit tests

* Add todo to check-api-changes

* Fix rpc sender thread busy looping

* Fix tests

* Fixing tests

* Address mike's comments

* Fixing tests

* Make random port allocation internal

* Update api
  • Loading branch information
anthonykeenan authored Feb 28, 2018
1 parent b7d48b2 commit 5770334
Show file tree
Hide file tree
Showing 115 changed files with 1,162 additions and 833 deletions.
252 changes: 127 additions & 125 deletions .ci/api-current.txt

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions .ci/check-api-changes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,20 @@ EOF

#Get a list of any methods that expose classes in .internal. namespaces, and any classes which extend/implement
#an internal class
#TODO: check that only classes in a whitelist are part of the API rather than look for specific invalid cases going forward
newInternalExposures=$(echo "$userDiffContents" | grep "^+" | grep "\.internal\." )
newNodeExposures=$(echo "$userDiffContents" | grep "^+" | grep "net.corda.node" )

internalCount=`grep -v "^$" <<EOF | wc -l
$newInternalExposures
$newNodeExposures
EOF
`

echo "Number of new internal class exposures: "$internalCount
if [ $internalCount -gt 0 ]; then
echo "$newInternalExposures"
echo "$newNodeExposures"
echo
fi

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.core.*
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.internal.chooseIdentity
import net.corda.testing.node.User
import org.junit.Test
import rx.Observable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import net.corda.finance.schemas.CashSchemaV1;
import net.corda.node.internal.Node;
import net.corda.node.internal.StartedNode;
import net.corda.testing.core.TestUtils;
import net.corda.testing.internal.InternalTestUtilsKt;
import net.corda.testing.node.User;
import net.corda.testing.node.internal.NodeBasedTest;
import org.junit.After;
Expand Down Expand Up @@ -76,7 +76,7 @@ public void testCashBalances() throws ExecutionException, InterruptedException {

FlowHandle<AbstractCashFlow.Result> flowHandle = rpcProxy.startFlowDynamic(CashIssueFlow.class,
DOLLARS(123), OpaqueBytes.of((byte)0),
TestUtils.chooseIdentity(node.getInfo()));
InternalTestUtilsKt.chooseIdentity(node.getInfo()));
System.out.println("Started issuing cash, waiting on result");
flowHandle.getReturnValue().get();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import net.corda.node.internal.Node
import net.corda.node.internal.StartedNode
import net.corda.node.services.Permissions
import net.corda.node.services.Permissions.Companion.invokeRpc
import net.corda.testing.core.*
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.driver
import net.corda.testing.internal.chooseIdentity
import net.corda.testing.node.User
import net.corda.testing.node.internal.NodeBasedTest
import org.assertj.core.api.Assertions.assertThat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.CHARLIE_NAME
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.startFlow
import net.corda.testing.node.internal.startFlow
import org.junit.After
import org.junit.Before
import org.junit.Test
Expand Down Expand Up @@ -57,13 +57,13 @@ class IdentitySyncFlowTests {
// Alice issues then pays some cash to a new confidential identity that Bob doesn't know about
val anonymous = true
val ref = OpaqueBytes.of(0x01)
val issueFlow = aliceNode.services.startFlow(CashIssueAndPaymentFlow(1000.DOLLARS, ref, alice, anonymous, notary))
val issueFlow = aliceNode.services.startFlow(CashIssueAndPaymentFlow(1000.DOLLARS, ref, alice, anonymous, notary)).resultFuture
val issueTx = issueFlow.getOrThrow().stx
val confidentialIdentity = issueTx.tx.outputs.map { it.data }.filterIsInstance<Cash.State>().single().owner
assertNull(bobNode.database.transaction { bobNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity) })

// Run the flow to sync up the identities
aliceNode.services.startFlow(Initiator(bob, issueTx.tx)).getOrThrow()
aliceNode.services.startFlow(Initiator(bob, issueTx.tx)).resultFuture.getOrThrow()
val expected = aliceNode.database.transaction {
aliceNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity)
}
Expand All @@ -88,7 +88,7 @@ class IdentitySyncFlowTests {
val anonymous = true
val ref = OpaqueBytes.of(0x01)
val issueFlow = charlieNode.services.startFlow(CashIssueAndPaymentFlow(1000.DOLLARS, ref, charlie, anonymous, notary))
val issueTx = issueFlow.getOrThrow().stx
val issueTx = issueFlow.resultFuture.getOrThrow().stx
val confidentialIdentity = issueTx.tx.outputs.map { it.data }.filterIsInstance<Cash.State>().single().owner
val confidentialIdentCert = charlieNode.services.identityService.certificateFromKey(confidentialIdentity.owningKey)!!

Expand All @@ -97,11 +97,11 @@ class IdentitySyncFlowTests {
assertNotNull(aliceNode.database.transaction { aliceNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity) })

// Generate a payment from Charlie to Alice, including the confidential state
val payTx = charlieNode.services.startFlow(CashPaymentFlow(1000.DOLLARS, alice, anonymous)).getOrThrow().stx
val payTx = charlieNode.services.startFlow(CashPaymentFlow(1000.DOLLARS, alice, anonymous)).resultFuture.getOrThrow().stx

// Run the flow to sync up the identities, and confirm Charlie's confidential identity doesn't leak
assertNull(bobNode.database.transaction { bobNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity) })
aliceNode.services.startFlow(Initiator(bob, payTx.tx)).getOrThrow()
aliceNode.services.startFlow(Initiator(bob, payTx.tx)).resultFuture.getOrThrow()
assertNull(bobNode.database.transaction { bobNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity) })
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import net.corda.core.identity.*
import net.corda.core.utilities.getOrThrow
import net.corda.testing.core.*
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.startFlow
import org.junit.Before
import net.corda.testing.node.startFlow
import org.junit.Test
import kotlin.test.*

Expand All @@ -27,7 +27,7 @@ class SwapIdentitiesFlowTests {
val bob = bobNode.services.myInfo.singleIdentity()

// Run the flows
val requesterFlow = aliceNode.services.startFlow(SwapIdentitiesFlow(bob))
val requesterFlow = aliceNode.services.startFlow(SwapIdentitiesFlow(bob)).resultFuture

// Get the results
val actual: Map<Party, AnonymousParty> = requesterFlow.getOrThrow().toMap()
Expand Down Expand Up @@ -62,7 +62,7 @@ class SwapIdentitiesFlowTests {
val charlieNode = mockNet.createPartyNode(CHARLIE_NAME)
val bob: Party = bobNode.services.myInfo.singleIdentity()
val notBob = charlieNode.database.transaction {
charlieNode.services.keyManagementService.freshKeyAndCert(charlieNode.services.myInfo.chooseIdentityAndCert(), false)
charlieNode.services.keyManagementService.freshKeyAndCert(charlieNode.services.myInfo.singleIdentityAndCert(), false)
}
val sigData = SwapIdentitiesFlow.buildDataToSign(notBob)
val signature = charlieNode.services.keyManagementService.sign(sigData, notBob.owningKey)
Expand Down
5 changes: 2 additions & 3 deletions core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import static net.corda.testing.core.TestUtils.singleIdentity;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.Assert.fail;
import static net.corda.testing.node.NodeTestUtils.startFlow;

public class FlowsInJavaTest {
private final MockNetwork mockNet = new MockNetwork(emptyList());
Expand All @@ -40,7 +39,7 @@ public void cleanUp() {
@Test
public void suspendableActionInsideUnwrap() throws Exception {
bobNode.registerInitiatedFlow(SendHelloAndThenReceive.class);
Future<String> result = startFlow(aliceNode.getServices(), new SendInUnwrapFlow(bob));
Future<String> result = aliceNode.startFlow(new SendInUnwrapFlow(bob));
mockNet.runNetwork();
assertThat(result.get()).isEqualTo("Hello");
}
Expand All @@ -56,7 +55,7 @@ public void primitiveClassForReceiveType() throws InterruptedException {

private void primitiveReceiveTypeTest(Class<?> receiveType) throws InterruptedException {
PrimitiveReceiveFlow flow = new PrimitiveReceiveFlow(bob, receiveType);
Future<?> result = startFlow(aliceNode.getServices(), flow);
Future<?> result = aliceNode.startFlow(flow);
mockNet.runNetwork();
try {
result.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import net.corda.finance.contracts.asset.Cash
import net.corda.node.services.api.IdentityServiceInternal
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.TEST_TX_TIME
import net.corda.testing.core.TestIdentity
import net.corda.testing.dsl.LedgerDSL
import net.corda.testing.dsl.TestLedgerDSLInterpreter
import net.corda.testing.dsl.TestTransactionDSLInterpreter
import net.corda.testing.internal.TEST_TX_TIME
import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockServices
import net.corda.testing.node.ledger
Expand Down
16 changes: 8 additions & 8 deletions core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import net.corda.node.services.persistence.NodeAttachmentService
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.MockNodeParameters
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.startFlow
import net.corda.testing.node.internal.InternalMockNodeParameters
import net.corda.testing.node.internal.startFlow
import org.junit.After
import org.junit.Before
import org.junit.Test
Expand Down Expand Up @@ -65,7 +65,7 @@ class AttachmentTests {
mockNet.runNetwork()
val bobFlow = bobNode.startAttachmentFlow(setOf(id), alice)
mockNet.runNetwork()
assertEquals(0, bobFlow.getOrThrow().fromDisk.size)
assertEquals(0, bobFlow.resultFuture.getOrThrow().fromDisk.size)

// Verify it was inserted into node one's store.
val attachment = bobNode.database.transaction {
Expand All @@ -77,7 +77,7 @@ class AttachmentTests {
// Shut down node zero and ensure node one can still resolve the attachment.
aliceNode.dispose()

val response: FetchDataFlow.Result<Attachment> = bobNode.startAttachmentFlow(setOf(id), alice).getOrThrow()
val response: FetchDataFlow.Result<Attachment> = bobNode.startAttachmentFlow(setOf(id), alice).resultFuture.getOrThrow()
assertEquals(attachment, response.fromDisk[0])
}

Expand All @@ -92,19 +92,19 @@ class AttachmentTests {
val alice = aliceNode.info.singleIdentity()
val bobFlow = bobNode.startAttachmentFlow(setOf(hash), alice)
mockNet.runNetwork()
val e = assertFailsWith<FetchDataFlow.HashNotFound> { bobFlow.getOrThrow() }
val e = assertFailsWith<FetchDataFlow.HashNotFound> { bobFlow.resultFuture.getOrThrow() }
assertEquals(hash, e.requested)
}

@Test
fun maliciousResponse() {
// Make a node that doesn't do sanity checking at load time.
val aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME), nodeFactory = { args ->
val aliceNode = mockNet.createNode(InternalMockNodeParameters(legalName = ALICE_NAME), nodeFactory = { args ->
object : InternalMockNetwork.MockNode(args) {
override fun start() = super.start().apply { attachments.checkAttachmentsOnLoad = false }
}
})
val bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
val bobNode = mockNet.createNode(InternalMockNodeParameters(legalName = BOB_NAME))
val alice = aliceNode.info.singleIdentity()
aliceNode.registerInitiatedFlow(FetchAttachmentsResponse::class.java)
bobNode.registerInitiatedFlow(FetchAttachmentsResponse::class.java)
Expand All @@ -127,7 +127,7 @@ class AttachmentTests {
mockNet.runNetwork()
val bobFlow = bobNode.startAttachmentFlow(setOf(id), alice)
mockNet.runNetwork()
assertFailsWith<FetchDataFlow.DownloadedVsRequestedDataMismatch> { bobFlow.getOrThrow() }
assertFailsWith<FetchDataFlow.DownloadedVsRequestedDataMismatch> { bobFlow.resultFuture.getOrThrow() }
}

private fun StartedNode<*>.startAttachmentFlow(hashes: Set<SecureHash>, otherSide: Party) = services.startFlow(InitiatingFetchAttachmentsFlow(otherSide, hashes))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockServices
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.InternalMockNetwork.MockNode
import net.corda.testing.node.startFlow
import net.corda.testing.node.internal.startFlow
import org.junit.After
import org.junit.Before
import org.junit.Test
Expand Down Expand Up @@ -116,7 +116,7 @@ class CollectSignaturesFlowTests {
val state = DummyContract.MultiOwnerState(magicNumber, parties)
val flow = aliceNode.services.startFlow(TestFlow.Initiator(state, notary))
mockNet.runNetwork()
val result = flow.getOrThrow()
val result = flow.resultFuture.getOrThrow()
result.verifyRequiredSignatures()
println(result.tx)
println(result.sigs)
Expand All @@ -128,7 +128,7 @@ class CollectSignaturesFlowTests {
val ptx = aliceNode.services.signInitialTransaction(onePartyDummyContract)
val flow = aliceNode.services.startFlow(CollectSignaturesFlow(ptx, emptySet()))
mockNet.runNetwork()
val result = flow.getOrThrow()
val result = flow.resultFuture.getOrThrow()
result.verifyRequiredSignatures()
println(result.tx)
println(result.sigs)
Expand All @@ -142,7 +142,7 @@ class CollectSignaturesFlowTests {
val flow = aliceNode.services.startFlow(CollectSignaturesFlow(ptx, emptySet()))
mockNet.runNetwork()
assertFailsWith<IllegalArgumentException>("The Initiator of CollectSignaturesFlow must have signed the transaction.") {
flow.getOrThrow()
flow.resultFuture.getOrThrow()
}
}

Expand All @@ -156,7 +156,7 @@ class CollectSignaturesFlowTests {
val signedByBoth = bobNode.services.addSignature(signedByA)
val flow = aliceNode.services.startFlow(CollectSignaturesFlow(signedByBoth, emptySet()))
mockNet.runNetwork()
val result = flow.getOrThrow()
val result = flow.resultFuture.getOrThrow()
println(result.tx)
println(result.sigs)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ 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
import org.junit.Test
Expand Down Expand Up @@ -81,25 +80,25 @@ class ContractUpgradeFlowTest {
// The request is expected to be rejected because party B hasn't authorised the upgrade yet.
val rejectedFuture = aliceNode.services.startFlow(ContractUpgradeFlow.Initiate(atx!!.tx.outRef(0), DummyContractV2::class.java))
mockNet.runNetwork()
assertFailsWith(UnexpectedFlowEndException::class) { rejectedFuture.getOrThrow() }
assertFailsWith(UnexpectedFlowEndException::class) { rejectedFuture.resultFuture.getOrThrow() }

// Party B authorise the contract state upgrade, and immediately deauthorise the same.
bobNode.services.startFlow(ContractUpgradeFlow.Authorise(btx!!.tx.outRef<ContractState>(0), DummyContractV2::class.java)).getOrThrow()
bobNode.services.startFlow(ContractUpgradeFlow.Deauthorise(btx.tx.outRef<ContractState>(0).ref)).getOrThrow()
bobNode.services.startFlow(ContractUpgradeFlow.Authorise(btx!!.tx.outRef<ContractState>(0), DummyContractV2::class.java)).resultFuture.getOrThrow()
bobNode.services.startFlow(ContractUpgradeFlow.Deauthorise(btx.tx.outRef<ContractState>(0).ref)).resultFuture.getOrThrow()

// The request is expected to be rejected because party B has subsequently deauthorised and a previously authorised upgrade.
val deauthorisedFuture = aliceNode.services.startFlow(ContractUpgradeFlow.Initiate(atx.tx.outRef(0), DummyContractV2::class.java))
mockNet.runNetwork()
assertFailsWith(UnexpectedFlowEndException::class) { deauthorisedFuture.getOrThrow() }
assertFailsWith(UnexpectedFlowEndException::class) { deauthorisedFuture.resultFuture.getOrThrow() }

// Party B authorise the contract state upgrade
bobNode.services.startFlow(ContractUpgradeFlow.Authorise(btx.tx.outRef<ContractState>(0), DummyContractV2::class.java)).getOrThrow()
bobNode.services.startFlow(ContractUpgradeFlow.Authorise(btx.tx.outRef<ContractState>(0), DummyContractV2::class.java)).resultFuture.getOrThrow()

// Party A initiates contract upgrade flow, expected to succeed this time.
val resultFuture = aliceNode.services.startFlow(ContractUpgradeFlow.Initiate(atx.tx.outRef(0), DummyContractV2::class.java))
mockNet.runNetwork()

val result = resultFuture.getOrThrow()
val result = resultFuture.resultFuture.getOrThrow()

fun check(node: StartedNode<MockNode>) {
val upgradeTx = node.database.transaction {
Expand Down Expand Up @@ -201,15 +200,15 @@ class ContractUpgradeFlowTest {
val chosenIdentity = alice
val result = aliceNode.services.startFlow(CashIssueFlow(Amount(1000, USD), OpaqueBytes.of(1), notary))
mockNet.runNetwork()
val stx = result.getOrThrow().stx
val anonymisedRecipient = result.get().recipient!!
val stx = result.resultFuture.getOrThrow().stx
val anonymisedRecipient = result.resultFuture.get().recipient!!
val stateAndRef = stx.tx.outRef<Cash.State>(0)
val baseState = aliceNode.database.transaction { aliceNode.services.vaultService.queryBy<ContractState>().states.single() }
assertTrue(baseState.state.data is Cash.State, "Contract state is old version.")
// Starts contract upgrade flow.
val upgradeResult = aliceNode.services.startFlow(ContractUpgradeFlow.Initiate(stateAndRef, CashV2::class.java))
mockNet.runNetwork()
upgradeResult.getOrThrow()
upgradeResult.resultFuture.getOrThrow()
// Get contract state from the vault.
val upgradedStateFromVault = aliceNode.database.transaction { aliceNode.services.vaultService.queryBy<CashV2.State>().states.single() }
assertEquals(Amount(1000000, USD).`issued by`(chosenIdentity.ref(1)), upgradedStateFromVault.state.data.amount, "Upgraded cash contain the correct amount.")
Expand All @@ -225,7 +224,7 @@ class ContractUpgradeFlowTest {
.addCommand(CashV2.Move(), alice.owningKey)

)
aliceNode.services.startFlow(FinalityFlow(spendUpgradedTx)).apply {
aliceNode.services.startFlow(FinalityFlow(spendUpgradedTx)).resultFuture.apply {
mockNet.runNetwork()
get()
}
Expand Down
Loading

0 comments on commit 5770334

Please sign in to comment.