Skip to content

Commit

Permalink
CORDA-716 Devrel feedback (corda#2266)
Browse files Browse the repository at this point in the history
* * Document TestIdentity entropy and enforce that it actually works
* Ledger/transaction DSL default notary with fresh key
* MockServices default identity with fresh key
* makeTestIdentityService now takes vararg
* Require cordappPackages for MockServices
* DSL automatic serialization init
* Improve error when two MockNetworks used

* * Make cordappPackages required by MockNetwork
* Default identity service in MockServices
* Make notarySpecs Java-friendly
  • Loading branch information
andr3ej authored Dec 15, 2017
1 parent 595d41a commit 2652ae1
Show file tree
Hide file tree
Showing 40 changed files with 170 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class SwapIdentitiesFlowTests {
@Before
fun setup() {
// We run this in parallel threads to help catch any race conditions that may exist.
mockNet = MockNetwork(networkSendManuallyPumped = false, threadPerNode = true)
mockNet = MockNetwork(emptyList(), networkSendManuallyPumped = false, threadPerNode = true)
}

@Test
Expand Down
6 changes: 4 additions & 2 deletions core/src/main/kotlin/net/corda/core/identity/CordaX500Name.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package net.corda.core.identity

import com.google.common.collect.ImmutableSet
import net.corda.core.internal.LegalNameValidator
import net.corda.core.internal.VisibleForTesting
import net.corda.core.internal.x500Name
import net.corda.core.serialization.CordaSerializable
import org.bouncycastle.asn1.ASN1Encodable
Expand Down Expand Up @@ -78,8 +79,9 @@ data class CordaX500Name(val commonName: String?,
const val MAX_LENGTH_ORGANISATION_UNIT = 64
const val MAX_LENGTH_COMMON_NAME = 64
private val supportedAttributes = setOf(BCStyle.O, BCStyle.C, BCStyle.L, BCStyle.CN, BCStyle.ST, BCStyle.OU)
private val countryCodes: Set<String> = ImmutableSet.copyOf(Locale.getISOCountries())

@VisibleForTesting
val unspecifiedCountry = "ZZ"
private val countryCodes: Set<String> = ImmutableSet.copyOf(Locale.getISOCountries() + unspecifiedCountry)
@JvmStatic
fun build(principal: X500Principal): CordaX500Name {
val x500Name = X500Name.getInstance(principal.encoded)
Expand Down
3 changes: 2 additions & 1 deletion core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import static java.util.Collections.emptyList;
import static net.corda.testing.CoreTestUtils.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();
private final MockNetwork mockNet = new MockNetwork(emptyList());
private StartedNode<MockNetwork.MockNode> aliceNode;
private StartedNode<MockNetwork.MockNode> bobNode;
private Party bob;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class PartialMerkleTreeTest {
hashed = nodes.map { it.serialize().sha256() }
expectedRoot = MerkleTree.getMerkleTree(hashed.toMutableList() + listOf(zeroHash, zeroHash)).hash
merkleTree = MerkleTree.getMerkleTree(hashed)
testLedger = MockServices(rigorousMock<IdentityServiceInternal>().also {
testLedger = MockServices(emptyList(), rigorousMock<IdentityServiceInternal>().also {
doReturn(MEGA_CORP).whenever(it).partyFromKey(MEGA_CORP_PUBKEY)
}, MEGA_CORP.name).ledger(DUMMY_NOTARY) {
unverifiedTransaction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class AttachmentTests {

@Before
fun setUp() {
mockNet = MockNetwork()
mockNet = MockNetwork(emptyList())
}

@After
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import org.junit.After
import org.junit.Test

class ReceiveMultipleFlowTests {
private val mockNet = MockNetwork()
private val mockNet = MockNetwork(emptyList())
private val nodes = (0..2).map { mockNet.createPartyNode() }
@After
fun stopNodes() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class AttachmentSerializationTest {

@Before
fun setUp() {
mockNet = MockNetwork()
mockNet = MockNetwork(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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class TransactionSerializationTests {
Command(TestCash.Commands.Move(), DUMMY_KEY_2.public))

val ptx2 = notaryServices.signInitialTransaction(tx2)
val dummyServices = MockServices(rigorousMock(), MEGA_CORP.name, DUMMY_KEY_2)
val dummyServices = MockServices(emptyList(), rigorousMock(), MEGA_CORP.name, DUMMY_KEY_2)
val stx2 = dummyServices.addSignature(ptx2)

stx.copy(sigs = stx2.sigs).verifyRequiredSignatures()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class LedgerTransactionQueryTests {
@JvmField
val testSerialization = SerializationEnvironmentRule()
private val keyPair = generateKeyPair()
private val services = MockServices(rigorousMock<IdentityServiceInternal>().also {
private val services = MockServices(emptyList(), rigorousMock<IdentityServiceInternal>().also {
doReturn(null).whenever(it).partyFromKey(keyPair.public)
}, CordaX500Name("MegaCorp", "London", "GB"), keyPair)
private val identity: Party = services.myInfo.singleIdentity()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class TransactionEncumbranceTests {
}
}

private val ledgerServices = MockServices(rigorousMock<IdentityServiceInternal>().also {
private val ledgerServices = MockServices(emptyList(), rigorousMock<IdentityServiceInternal>().also {
doReturn(MEGA_CORP).whenever(it).partyFromKey(MEGA_CORP_PUBKEY)
}, MEGA_CORP.name)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,33 @@
import kotlin.Unit;
import net.corda.core.contracts.PartyAndReference;
import net.corda.core.identity.CordaX500Name;
import net.corda.core.identity.Party;
import net.corda.finance.contracts.ICommercialPaperState;
import net.corda.finance.contracts.JavaCommercialPaper;
import net.corda.finance.contracts.asset.Cash;
import net.corda.node.services.api.IdentityServiceInternal;
import net.corda.testing.SerializationEnvironmentRule;
import net.corda.testing.node.MockServices;
import net.corda.testing.TestIdentity;
import org.junit.Rule;
import org.junit.Test;

import java.security.PublicKey;
import java.time.temporal.ChronoUnit;

import static java.util.Collections.emptyList;
import static net.corda.core.crypto.Crypto.generateKeyPair;
import static net.corda.finance.Currencies.DOLLARS;
import static net.corda.finance.Currencies.issuedBy;
import static net.corda.finance.contracts.JavaCommercialPaper.JCP_PROGRAM_ID;
import static net.corda.testing.node.MockServicesKt.makeTestIdentityService;
import static net.corda.testing.node.NodeTestUtils.ledger;
import static net.corda.testing.node.NodeTestUtils.transaction;
import static net.corda.testing.CoreTestUtils.rigorousMock;
import static net.corda.testing.TestConstants.*;
import static org.mockito.Mockito.doReturn;

public class CommercialPaperTest {
private static final TestIdentity ALICE = new TestIdentity(ALICE_NAME, 70L);
private static final PublicKey BIG_CORP_PUBKEY = generateKeyPair().getPublic();
private static final TestIdentity BOB = new TestIdentity(BOB_NAME, 80L);
private static final TestIdentity MEGA_CORP = new TestIdentity(new CordaX500Name("MegaCorp", "London", "GB"));
private static final Party DUMMY_NOTARY = new TestIdentity(DUMMY_NOTARY_NAME, 20L).getParty();
@Rule
public final SerializationEnvironmentRule testSerialization = new SerializationEnvironmentRule();
private final byte[] defaultRef = {123};
private final MockServices ledgerServices;

{
IdentityServiceInternal identityService = rigorousMock(IdentityServiceInternal.class);
doReturn(MEGA_CORP.getParty()).when(identityService).partyFromKey(MEGA_CORP.getPublicKey());
doReturn(null).when(identityService).partyFromKey(BIG_CORP_PUBKEY);
doReturn(null).when(identityService).partyFromKey(ALICE.getPublicKey());
ledgerServices = new MockServices(identityService, MEGA_CORP.getName());
}
private final MockServices ledgerServices = new MockServices(emptyList(), makeTestIdentityService(MEGA_CORP.getIdentity()));

// DOCSTART 1
private ICommercialPaperState getPaper() {
Expand All @@ -61,7 +46,7 @@ private ICommercialPaperState getPaper() {
@Test
public void simpleCP() {
ICommercialPaperState inState = getPaper();
ledger(ledgerServices, DUMMY_NOTARY, l -> {
ledger(ledgerServices, l -> {
l.transaction(tx -> {
tx.attachments(JCP_PROGRAM_ID);
tx.input(JCP_PROGRAM_ID, inState);
Expand All @@ -76,7 +61,7 @@ public void simpleCP() {
@Test
public void simpleCPMove() {
ICommercialPaperState inState = getPaper();
ledger(ledgerServices, DUMMY_NOTARY, l -> {
ledger(ledgerServices, l -> {
l.transaction(tx -> {
tx.input(JCP_PROGRAM_ID, inState);
tx.command(MEGA_CORP.getPublicKey(), new JavaCommercialPaper.Commands.Move());
Expand All @@ -92,7 +77,7 @@ public void simpleCPMove() {
@Test
public void simpleCPMoveFails() {
ICommercialPaperState inState = getPaper();
ledger(ledgerServices, DUMMY_NOTARY, l -> {
ledger(ledgerServices, l -> {
l.transaction(tx -> {
tx.input(JCP_PROGRAM_ID, inState);
tx.command(MEGA_CORP.getPublicKey(), new JavaCommercialPaper.Commands.Move());
Expand All @@ -108,7 +93,7 @@ public void simpleCPMoveFails() {
@Test
public void simpleCPMoveSuccess() {
ICommercialPaperState inState = getPaper();
ledger(ledgerServices, DUMMY_NOTARY, l -> {
ledger(ledgerServices, l -> {
l.transaction(tx -> {
tx.input(JCP_PROGRAM_ID, inState);
tx.command(MEGA_CORP.getPublicKey(), new JavaCommercialPaper.Commands.Move());
Expand All @@ -125,7 +110,7 @@ public void simpleCPMoveSuccess() {
// DOCSTART 6
@Test
public void simpleIssuanceWithTweak() {
ledger(ledgerServices, DUMMY_NOTARY, l -> {
ledger(ledgerServices, l -> {
l.transaction(tx -> {
tx.output(JCP_PROGRAM_ID, "paper", getPaper()); // Some CP is issued onto the ledger by MegaCorp.
tx.attachments(JCP_PROGRAM_ID);
Expand All @@ -146,7 +131,7 @@ public void simpleIssuanceWithTweak() {
// DOCSTART 7
@Test
public void simpleIssuanceWithTweakTopLevelTx() {
transaction(ledgerServices, DUMMY_NOTARY, tx -> {
transaction(ledgerServices, tx -> {
tx.output(JCP_PROGRAM_ID, "paper", getPaper()); // Some CP is issued onto the ledger by MegaCorp.
tx.attachments(JCP_PROGRAM_ID);
tx.tweak(tw -> {
Expand All @@ -165,7 +150,7 @@ public void simpleIssuanceWithTweakTopLevelTx() {
@Test
public void chainCommercialPaper() {
PartyAndReference issuer = MEGA_CORP.ref(defaultRef);
ledger(ledgerServices, DUMMY_NOTARY, l -> {
ledger(ledgerServices, l -> {
l.unverifiedTransaction(tx -> {
tx.output(Cash.PROGRAM_ID, "alice's $900",
new Cash.State(issuedBy(DOLLARS(900), issuer), ALICE.getParty()));
Expand Down Expand Up @@ -201,7 +186,7 @@ public void chainCommercialPaper() {
@Test
public void chainCommercialPaperDoubleSpend() {
PartyAndReference issuer = MEGA_CORP.ref(defaultRef);
ledger(ledgerServices, DUMMY_NOTARY, l -> {
ledger(ledgerServices, l -> {
l.unverifiedTransaction(tx -> {
tx.output(Cash.PROGRAM_ID, "alice's $900",
new Cash.State(issuedBy(DOLLARS(900), issuer), ALICE.getParty()));
Expand Down Expand Up @@ -247,7 +232,7 @@ public void chainCommercialPaperDoubleSpend() {
@Test
public void chainCommercialPaperTweak() {
PartyAndReference issuer = MEGA_CORP.ref(defaultRef);
ledger(ledgerServices, DUMMY_NOTARY, l -> {
ledger(ledgerServices, l -> {
l.unverifiedTransaction(tx -> {
tx.output(Cash.PROGRAM_ID, "alice's $900",
new Cash.State(issuedBy(DOLLARS(900), issuer), ALICE.getParty()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class TutorialMockNetwork {

@Before
fun setUp() {
mockNet = MockNetwork()
mockNet = MockNetwork(emptyList())
nodeA = mockNet.createPartyNode()
nodeB = mockNet.createPartyNode()
nodeB.registerInitiatedFlow(FlowB::class.java)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class CommercialPaperTest {
@Rule
@JvmField
val testSerialization = SerializationEnvironmentRule()
private val ledgerServices = MockServices(rigorousMock<IdentityServiceInternal>().also {
private val ledgerServices = MockServices(emptyList(), rigorousMock<IdentityServiceInternal>().also {
doReturn(MEGA_CORP).whenever(it).partyFromKey(MEGA_CORP_PUBKEY)
doReturn(null).whenever(it).partyFromKey(BIG_CORP_PUBKEY)
doReturn(null).whenever(it).partyFromKey(ALICE_PUBKEY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.junit.Rule;
import org.junit.Test;

import static java.util.Collections.emptyList;
import static net.corda.finance.Currencies.DOLLARS;
import static net.corda.finance.Currencies.issuedBy;
import static net.corda.testing.node.NodeTestUtils.transaction;
Expand All @@ -37,7 +38,7 @@ public void trivial() {
IdentityServiceInternal identityService = rigorousMock(IdentityServiceInternal.class);
doReturn(MEGA_CORP.getParty()).when(identityService).partyFromKey(MEGA_CORP.getPublicKey());
doReturn(MINI_CORP.getParty()).when(identityService).partyFromKey(MINI_CORP.getPublicKey());
transaction(new MockServices(identityService, MEGA_CORP.getName()), DUMMY_NOTARY, tx -> {
transaction(new MockServices(emptyList(), identityService, MEGA_CORP.getName()), DUMMY_NOTARY, tx -> {
tx.attachment(Cash.PROGRAM_ID);

tx.input(Cash.PROGRAM_ID, inState);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class CommercialPaperTestsGeneric {
@JvmField
val testSerialization = SerializationEnvironmentRule()
val issuer = MEGA_CORP.ref(123)
private val ledgerServices = MockServices(rigorousMock<IdentityServiceInternal>().also {
private val ledgerServices = MockServices(emptyList(), rigorousMock<IdentityServiceInternal>().also {
doReturn(MEGA_CORP).whenever(it).partyFromKey(MEGA_CORP_PUBKEY)
doReturn(MINI_CORP).whenever(it).partyFromKey(MINI_CORP_PUBKEY)
doReturn(null).whenever(it).partyFromKey(ALICE_PUBKEY)
Expand Down Expand Up @@ -260,14 +260,14 @@ class CommercialPaperTestsGeneric {
private lateinit var aliceServices: MockServices
private lateinit var aliceVaultService: VaultService
private lateinit var alicesVault: Vault<ContractState>
private val notaryServices = MockServices(rigorousMock(), MEGA_CORP.name, dummyNotary.keyPair)
private val notaryServices = MockServices(emptyList(), rigorousMock(), MEGA_CORP.name, dummyNotary.keyPair)
private val issuerServices = MockServices(listOf("net.corda.finance.contracts"), rigorousMock(), MEGA_CORP.name, dummyCashIssuer.keyPair)
private lateinit var moveTX: SignedTransaction
@Test
fun `issue move and then redeem`() {
val aliceDatabaseAndServices = makeTestDatabaseAndMockServices(
listOf("net.corda.finance.contracts"),
makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)),
makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY),
TestIdentity(MEGA_CORP.name, ALICE_KEY))
val databaseAlice = aliceDatabaseAndServices.first
aliceServices = aliceDatabaseAndServices.second
Expand All @@ -279,7 +279,7 @@ class CommercialPaperTestsGeneric {
}
val bigCorpDatabaseAndServices = makeTestDatabaseAndMockServices(
listOf("net.corda.finance.contracts"),
makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)),
makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY),
TestIdentity(MEGA_CORP.name, BIG_CORP_KEY))
val databaseBigCorp = bigCorpDatabaseAndServices.first
bigCorpServices = bigCorpDatabaseAndServices.second
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class CashTests {
val notaryServices = MockServices(listOf("net.corda.finance.contracts.asset"), rigorousMock(), DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
val databaseAndServices = makeTestDatabaseAndMockServices(
listOf("net.corda.finance.contracts.asset"),
makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY)),
makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, DUMMY_CASH_ISSUER_IDENTITY, DUMMY_NOTARY_IDENTITY),
TestIdentity(CordaX500Name("Me", "London", "GB")))
database = databaseAndServices.first
ourServices = databaseAndServices.second
Expand Down Expand Up @@ -136,7 +136,7 @@ class CashTests {
}

private fun transaction(script: TransactionDSL<TransactionDSLInterpreter>.() -> EnforceVerifyOrFail) = run {
MockServices(rigorousMock<IdentityServiceInternal>().also {
MockServices(emptyList(), rigorousMock<IdentityServiceInternal>().also {
doReturn(MEGA_CORP).whenever(it).partyFromKey(MEGA_CORP_PUBKEY)
doReturn(MINI_CORP).whenever(it).partyFromKey(MINI_CORP_PUBKEY)
doReturn(null).whenever(it).partyFromKey(ALICE_PUBKEY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class ObligationTests {
)
private val outState = inState.copy(beneficiary = AnonymousParty(BOB_PUBKEY))
private val miniCorpServices = MockServices(listOf("net.corda.finance.contracts.asset"), rigorousMock(), miniCorp)
private val notaryServices = MockServices(rigorousMock(), MEGA_CORP.name, dummyNotary.keyPair)
private val notaryServices = MockServices(emptyList(), rigorousMock(), MEGA_CORP.name, dummyNotary.keyPair)
private val identityService = rigorousMock<IdentityServiceInternal>().also {
doReturn(null).whenever(it).partyFromKey(ALICE_PUBKEY)
doReturn(null).whenever(it).partyFromKey(BOB_PUBKEY)
Expand All @@ -86,7 +86,7 @@ class ObligationTests {
doReturn(MINI_CORP).whenever(it).partyFromKey(MINI_CORP_PUBKEY)
}
private val mockService = MockServices(listOf("net.corda.finance.contracts.asset"), identityService, MEGA_CORP.name)
private val ledgerServices get() = MockServices(identityService, MEGA_CORP.name)
private val ledgerServices get() = MockServices(emptyList(), identityService, MEGA_CORP.name)
private fun cashObligationTestRoots(
group: LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>
) = group.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class ContractAttachmentSerializerTest {
private lateinit var factory: SerializationFactory
private lateinit var context: SerializationContext
private lateinit var contextWithToken: SerializationContext
private val mockServices = MockServices(rigorousMock(), CordaX500Name("MegaCorp", "London", "GB"))
private val mockServices = MockServices(emptyList(), rigorousMock(), CordaX500Name("MegaCorp", "London", "GB"))
@Before
fun setup() {
factory = testSerialization.env.serializationFactory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import kotlin.test.assertEquals
import kotlin.test.assertTrue

class BFTNotaryServiceTests {
private val mockNet = MockNetwork()
private val mockNet = MockNetwork(emptyList())
private lateinit var notary: Party
private lateinit var node: StartedNode<MockNode>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import javax.annotation.concurrent.ThreadSafe
* @param identities initial set of identities for the service, typically only used for unit tests.
*/
@ThreadSafe
class InMemoryIdentityService(identities: Iterable<PartyAndCertificate>,
class InMemoryIdentityService(identities: Array<out PartyAndCertificate>,
trustRoot: X509CertificateHolder) : SingletonSerializeAsToken(), IdentityServiceInternal {
companion object {
private val log = contextLogger()
Expand Down
Loading

0 comments on commit 2652ae1

Please sign in to comment.