CORDA-716 Devrel feedback (#2266)

* * 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
This commit is contained in:
Andrzej Cichocki 2017-12-15 19:18:31 +00:00 committed by GitHub
parent 595d41af04
commit 2652ae111a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 170 additions and 102 deletions

View File

@ -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

View File

@ -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
@ -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)

View File

@ -13,13 +13,14 @@ import org.junit.Test;
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;

View File

@ -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 {

View File

@ -29,7 +29,7 @@ class AttachmentTests {
@Before
fun setUp() {
mockNet = MockNetwork()
mockNet = MockNetwork(emptyList())
}
@After

View File

@ -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() {

View File

@ -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.

View File

@ -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()

View File

@ -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()

View File

@ -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)

View File

@ -3,48 +3,33 @@ package net.corda.docs.java.tutorial.testdsl;
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() {
@ -61,7 +46,7 @@ public class CommercialPaperTest {
@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);
@ -76,7 +61,7 @@ public class CommercialPaperTest {
@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());
@ -92,7 +77,7 @@ public class CommercialPaperTest {
@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());
@ -108,7 +93,7 @@ public class CommercialPaperTest {
@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());
@ -125,7 +110,7 @@ public class CommercialPaperTest {
// 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);
@ -146,7 +131,7 @@ public class CommercialPaperTest {
// 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 -> {
@ -165,7 +150,7 @@ public class CommercialPaperTest {
@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()));
@ -201,7 +186,7 @@ public class CommercialPaperTest {
@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()));
@ -247,7 +232,7 @@ public class CommercialPaperTest {
@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()));

View File

@ -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)

View File

@ -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)

View File

@ -12,6 +12,7 @@ import net.corda.testing.node.MockServices;
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;
@ -37,7 +38,7 @@ public class CashTestsJava {
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);

View File

@ -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)
@ -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
@ -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

View File

@ -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
@ -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)

View File

@ -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)
@ -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 {

View File

@ -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

View File

@ -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>

View File

@ -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()

View File

@ -70,7 +70,7 @@ public class VaultQueryJavaTests {
@Before
public void setUp() throws CertificateException, InvalidAlgorithmParameterException {
List<String> cordappPackages = Arrays.asList("net.corda.testing.contracts", "net.corda.finance.contracts.asset", CashSchemaV1.class.getPackage().getName());
IdentityServiceInternal identitySvc = makeTestIdentityService(Arrays.asList(MEGA_CORP.getIdentity(), DUMMY_CASH_ISSUER_INFO.getIdentity(), DUMMY_NOTARY.getIdentity()));
IdentityServiceInternal identitySvc = makeTestIdentityService(MEGA_CORP.getIdentity(), DUMMY_CASH_ISSUER_INFO.getIdentity(), DUMMY_NOTARY.getIdentity());
Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices(
cordappPackages,
identitySvc,

View File

@ -52,7 +52,7 @@ class InteractiveShellTest {
override fun call() = a
}
private val ids = makeTestIdentityService(listOf(megaCorp.identity))
private val ids = makeTestIdentityService(megaCorp.identity)
private val om = JacksonSupport.createInMemoryMapper(ids, YAMLFactory())
private fun check(input: String, expected: String) {

View File

@ -21,6 +21,7 @@ import org.assertj.core.api.Assertions.*
class NetworkParametersTest {
private val mockNet = MockNetwork(
emptyList(),
MockNetworkParameters(networkSendManuallyPumped = true),
notarySpecs = listOf(MockNetwork.NotarySpec(DUMMY_NOTARY_NAME)))

View File

@ -17,7 +17,7 @@ class InMemoryMessagingTests {
@Before
fun setUp() {
mockNet = MockNetwork()
mockNet = MockNetwork(emptyList())
}
@After

View File

@ -32,7 +32,7 @@ class InMemoryIdentityServiceTests {
val BOB get() = bob.party
val BOB_IDENTITY get() = bob.identity
val BOB_PUBKEY get() = bob.publicKey
fun createService(vararg identities: PartyAndCertificate) = InMemoryIdentityService(identities.toSet(), DEV_TRUST_ROOT)
fun createService(vararg identities: PartyAndCertificate) = InMemoryIdentityService(identities, DEV_TRUST_ROOT)
}
@Rule

View File

@ -13,7 +13,7 @@ import java.math.BigInteger
import kotlin.test.assertEquals
class NetworkMapCacheTest {
private val mockNet = MockNetwork()
private val mockNet = MockNetwork(emptyList())
@After
fun teardown() {

View File

@ -87,7 +87,7 @@ class NodeVaultServiceTest {
LogHelper.setLevel(NodeVaultService::class)
val databaseAndServices = MockServices.makeTestDatabaseAndMockServices(
cordappPackages,
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),
megaCorp)
database = databaseAndServices.first
services = databaseAndServices.second
@ -135,7 +135,7 @@ class NodeVaultServiceTest {
assertThat(w1).hasSize(3)
val originalVault = vaultService
val services2 = object : MockServices(rigorousMock(), MEGA_CORP.name) {
val services2 = object : MockServices(emptyList(), rigorousMock(), MEGA_CORP.name) {
override val vaultService: NodeVaultService get() = originalVault
override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) {
for (stx in txs) {
@ -585,7 +585,7 @@ class NodeVaultServiceTest {
val identity = services.myInfo.singleIdentityAndCert()
assertEquals(services.identityService.partyFromKey(identity.owningKey), identity.party)
val anonymousIdentity = services.keyManagementService.freshKeyAndCert(identity, false)
val thirdPartyServices = MockServices(rigorousMock<IdentityServiceInternal>().also {
val thirdPartyServices = MockServices(emptyList(), rigorousMock<IdentityServiceInternal>().also {
doNothing().whenever(it).justVerifyAndRegisterIdentity(argThat { name == MEGA_CORP.name })
}, MEGA_CORP.name)
val thirdPartyIdentity = thirdPartyServices.keyManagementService.freshKeyAndCert(thirdPartyServices.myInfo.singleIdentityAndCert(), false)

View File

@ -105,7 +105,7 @@ class VaultQueryTests {
// register additional identities
val databaseAndServices = makeTestDatabaseAndMockServices(
cordappPackages,
makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, dummyCashIssuer.identity, dummyNotary.identity)),
makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, dummyCashIssuer.identity, dummyNotary.identity),
megaCorp,
DUMMY_NOTARY_KEY)
database = databaseAndServices.first

View File

@ -70,7 +70,7 @@ class VaultWithCashTest {
LogHelper.setLevel(VaultWithCashTest::class)
val databaseAndServices = makeTestDatabaseAndMockServices(
cordappPackages,
makeTestIdentityService(listOf(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, dummyCashIssuer.identity, dummyNotary.identity)),
makeTestIdentityService(MEGA_CORP_IDENTITY, MINI_CORP_IDENTITY, dummyCashIssuer.identity, dummyNotary.identity),
TestIdentity(MEGA_CORP.name, servicesKey),
dummyNotary.keyPair)
database = databaseAndServices.first

View File

@ -236,7 +236,7 @@ class IRSTests {
private val miniCorpServices = MockServices(listOf("net.corda.irs.contract"), rigorousMock(), MINI_CORP.name, MINI_CORP_KEY)
private val notaryServices = MockServices(listOf("net.corda.irs.contract"), rigorousMock(), DUMMY_NOTARY.name, DUMMY_NOTARY_KEY)
private val ledgerServices
get() = MockServices(rigorousMock<IdentityServiceInternal>().also {
get() = MockServices(emptyList(), rigorousMock<IdentityServiceInternal>().also {
doReturn(MEGA_CORP).whenever(it).partyFromKey(MEGA_CORP_PUBKEY)
doReturn(null).whenever(it).partyFromKey(ORACLE_PUBKEY)
}, MEGA_CORP.name)

View File

@ -44,7 +44,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
private val executeOnNextIteration = Collections.synchronizedList(LinkedList<() -> Unit>())
override fun startMainSimulation(): CompletableFuture<Unit> {
om = JacksonSupport.createInMemoryMapper(makeTestIdentityService((banks + regulators + ratesOracle).flatMap { it.started!!.info.legalIdentitiesAndCerts }))
om = JacksonSupport.createInMemoryMapper(makeTestIdentityService(*(banks + regulators + ratesOracle).flatMap { it.started!!.info.legalIdentitiesAndCerts }.toTypedArray()))
registerFinanceJSONMappers(om)
return startIRSDealBetween(0, 1).thenCompose {

View File

@ -288,7 +288,7 @@ class FlowStackSnapshotTest {
@Test
fun `flowStackSnapshot object is serializable`() {
val mockNet = MockNetwork(threadPerNode = true)
val mockNet = MockNetwork(emptyList(), threadPerNode = true)
val node = mockNet.createPartyNode()
node.registerInitiatedFlow(DummyFlow::class.java)
node.services.startFlow(FlowStackSnapshotSerializationTestingFlow()).resultFuture.get()

View File

@ -73,13 +73,13 @@ data class MockNetworkParameters(
val servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = InMemoryMessagingNetwork.ServicePeerAllocationStrategy.Random(),
val defaultFactory: (MockNodeArgs) -> MockNetwork.MockNode = MockNetwork::MockNode,
val initialiseSerialization: Boolean = true,
val cordappPackages: List<String> = emptyList()) {
val notarySpecs: List<MockNetwork.NotarySpec> = 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 setCordappPackages(cordappPackages: List<String>) = copy(cordappPackages = cordappPackages)
fun setNotarySpecs(notarySpecs: List<MockNetwork.NotarySpec>) = copy(notarySpecs = notarySpecs)
}
/**
@ -124,16 +124,17 @@ 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].
*/
class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParameters(),
class MockNetwork(private val cordappPackages: List<String>,
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<NotarySpec> = listOf(NotarySpec(DUMMY_NOTARY_NAME)),
private val cordappPackages: List<String> = defaultParameters.cordappPackages) {
private val notarySpecs: List<NotarySpec> = defaultParameters.notarySpecs) {
/** Helper constructor for creating a [MockNetwork] with custom parameters from Java. */
constructor(parameters: MockNetworkParameters) : this(defaultParameters = parameters)
@JvmOverloads
constructor(cordappPackages: List<String>, parameters: MockNetworkParameters = MockNetworkParameters()) : this(cordappPackages, defaultParameters = parameters)
init {
// Apache SSHD for whatever reason registers a SFTP FileSystemProvider - which gets loaded by JimFS.
@ -151,9 +152,13 @@ class MockNetwork(defaultParameters: MockNetworkParameters = MockNetworkParamete
private val networkId = random63BitValue()
private val networkParameters: NetworkParametersCopier
private val _nodes = mutableListOf<MockNode>()
private val serializationEnv = setGlobalSerialization(initialiseSerialization)
private val serializationEnv = try {
setGlobalSerialization(initialiseSerialization)
} catch (e: IllegalStateException) {
throw IllegalStateException("Using more than one MockNetwork simultaneously is not supported.", e)
}
private val sharedUserCount = AtomicInteger(0)
/** A read only view of the current set of executing nodes. */
/** A read only view of the current set of nodes. */
val nodes: List<MockNode> get() = _nodes
/**

View File

@ -44,7 +44,7 @@ import java.sql.Connection
import java.time.Clock
import java.util.*
fun makeTestIdentityService(identities: Iterable<PartyAndCertificate> = emptySet()) = InMemoryIdentityService(identities, DEV_TRUST_ROOT)
fun makeTestIdentityService(vararg identities: PartyAndCertificate) = InMemoryIdentityService(identities, DEV_TRUST_ROOT)
/**
* A singleton utility that only provides a mock identity, key and storage service. However, this is sufficient for
* building chains of transactions and verifying them. It isn't sufficient for testing flows however.
@ -110,11 +110,17 @@ open class MockServices private constructor(
}
private constructor(cordappLoader: CordappLoader, identityService: IdentityServiceInternal, initialIdentity: TestIdentity, moreKeys: Array<out KeyPair>) : this(cordappLoader, MockTransactionStorage(), identityService, initialIdentity, moreKeys)
constructor(cordappPackages: List<String>, identityService: IdentityServiceInternal, initialIdentity: TestIdentity, vararg moreKeys: KeyPair) : this(CordappLoader.createWithTestPackages(cordappPackages), identityService, initialIdentity, moreKeys)
constructor(cordappPackages: List<String>, identityService: IdentityServiceInternal, initialIdentityName: CordaX500Name, key: KeyPair, vararg moreKeys: KeyPair) : this(cordappPackages, identityService, TestIdentity(initialIdentityName, key), *moreKeys)
constructor(cordappPackages: List<String>, identityService: IdentityServiceInternal, initialIdentityName: CordaX500Name) : this(cordappPackages, identityService, TestIdentity(initialIdentityName))
constructor(identityService: IdentityServiceInternal, initialIdentityName: CordaX500Name, key: KeyPair, vararg moreKeys: KeyPair) : this(emptyList(), identityService, TestIdentity(initialIdentityName, key), *moreKeys)
constructor(identityService: IdentityServiceInternal, initialIdentityName: CordaX500Name) : this(emptyList(), identityService, TestIdentity(initialIdentityName))
@JvmOverloads
constructor(cordappPackages: List<String>, identityService: IdentityServiceInternal = makeTestIdentityService(), initialIdentity: TestIdentity, vararg moreKeys: KeyPair) : this(CordappLoader.createWithTestPackages(cordappPackages), identityService, initialIdentity, moreKeys)
@JvmOverloads
constructor(cordappPackages: List<String>, identityService: IdentityServiceInternal = makeTestIdentityService(), initialIdentityName: CordaX500Name, key: KeyPair, vararg moreKeys: KeyPair) : this(cordappPackages, identityService, TestIdentity(initialIdentityName, key), *moreKeys)
@JvmOverloads
constructor(cordappPackages: List<String>, identityService: IdentityServiceInternal = makeTestIdentityService(), initialIdentityName: CordaX500Name) : this(cordappPackages, identityService, TestIdentity(initialIdentityName))
@JvmOverloads
constructor(cordappPackages: List<String>, identityService: IdentityServiceInternal = makeTestIdentityService(), vararg moreKeys: KeyPair) : this(cordappPackages, identityService, TestIdentity.fresh("MockServices"), *moreKeys)
override fun recordTransactions(statesToRecord: StatesToRecord, txs: Iterable<SignedTransaction>) {
txs.forEach {

View File

@ -11,6 +11,7 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.internal.FlowStateMachine
import net.corda.core.node.ServiceHub
import net.corda.core.serialization.internal.effectiveSerializationEnv
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow
import net.corda.node.services.api.StartedNodeServices
@ -19,11 +20,24 @@ import net.corda.testing.*
/**
* Creates and tests a ledger built by the passed in dsl.
*/
@JvmOverloads
fun ServiceHub.ledger(
notary: Party,
dsl: LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit
notary: Party = TestIdentity.fresh("ledger notary").party,
script: LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit
): LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter> {
return LedgerDSL(TestLedgerDSLInterpreter(this), notary).apply(dsl)
val serializationExists = try {
effectiveSerializationEnv
true
} catch (e: IllegalStateException) {
false
}
return LedgerDSL(TestLedgerDSLInterpreter(this), notary).apply {
if (serializationExists) {
script()
} else {
SerializationEnvironmentRule.run("ledger") { script() }
}
}
}
/**
@ -31,11 +45,12 @@ fun ServiceHub.ledger(
*
* @see LedgerDSLInterpreter._transaction
*/
@JvmOverloads
fun ServiceHub.transaction(
notary: Party,
dsl: TransactionDSL<TransactionDSLInterpreter>.() -> EnforceVerifyOrFail
notary: Party = TestIdentity.fresh("transaction notary").party,
script: TransactionDSL<TransactionDSLInterpreter>.() -> EnforceVerifyOrFail
) = ledger(notary) {
dsl(TransactionDSL(TestTransactionDSLInterpreter(interpreter, TransactionBuilder(notary)), notary))
TransactionDSL(TestTransactionDSLInterpreter(interpreter, TransactionBuilder(notary)), notary).script()
}
fun testActor(owningLegalIdentity: CordaX500Name = CordaX500Name("Test Company Inc.", "London", "GB")) = Actor(Actor.Id("Only For Testing"), AuthServiceId("TEST"), owningLegalIdentity)

View File

@ -2,6 +2,8 @@ package net.corda.testing.node;
import org.jetbrains.annotations.NotNull;
import static java.util.Collections.emptyList;
@SuppressWarnings("unused")
public class MockNodeFactoryInJavaTest {
private static class CustomNode extends MockNetwork.MockNode {
@ -16,10 +18,10 @@ public class MockNodeFactoryInJavaTest {
@SuppressWarnings("unused")
private static void factoryIsEasyToPassInUsingJava() {
//noinspection Convert2MethodRef
new MockNetwork(new MockNetworkParameters().setDefaultFactory(args -> new CustomNode(args)));
new MockNetwork(new MockNetworkParameters().setDefaultFactory(CustomNode::new));
new MockNetwork(emptyList(), new MockNetworkParameters().setDefaultFactory(args -> new CustomNode(args)));
new MockNetwork(emptyList(), new MockNetworkParameters().setDefaultFactory(CustomNode::new));
//noinspection Convert2MethodRef
new MockNetwork().createNode(new MockNodeParameters(), args -> new CustomNode(args));
new MockNetwork().createNode(new MockNodeParameters(), CustomNode::new);
new MockNetwork(emptyList()).createNode(new MockNodeParameters(), args -> new CustomNode(args));
new MockNetwork(emptyList()).createNode(new MockNodeParameters(), CustomNode::new);
}
}

View File

@ -5,10 +5,7 @@ package net.corda.testing
import net.corda.core.contracts.PartyAndReference
import net.corda.core.contracts.StateRef
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.crypto.generateKeyPair
import net.corda.core.crypto.*
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
@ -119,7 +116,22 @@ fun getTestPartyAndCertificate(name: CordaX500Name, publicKey: PublicKey): Party
}
class TestIdentity(val name: CordaX500Name, val keyPair: KeyPair) {
companion object {
/**
* Creates an identity that won't equal any other. This is mostly useful as a throwaway for test helpers.
* @param organisation the organisation part of the new identity's name.
*/
fun fresh(organisation: String): TestIdentity {
val keyPair = generateKeyPair()
val name = CordaX500Name(organisation, keyPair.public.toStringShort(), CordaX500Name.unspecifiedCountry)
return TestIdentity(name, keyPair)
}
}
/** Creates an identity with a deterministic [keyPair] i.e. same [entropy] same keyPair .*/
constructor(name: CordaX500Name, entropy: Long) : this(name, entropyToKeyPair(BigInteger.valueOf(entropy)))
/** Creates an identity with the given name and a fresh keyPair. */
constructor(name: CordaX500Name) : this(name, generateKeyPair())
val publicKey: PublicKey get() = keyPair.public

View File

@ -33,19 +33,30 @@ class SerializationEnvironmentRule(private val inheritable: Boolean = false) : T
}.whenever(it).execute(any())
}
}
/** Do not call, instead use [SerializationEnvironmentRule] as a [org.junit.Rule]. */
fun <T> run(taskLabel: String, task: (SerializationEnvironment) -> T): T {
return SerializationEnvironmentRule().apply { init(taskLabel) }.runTask(task)
}
}
lateinit var env: SerializationEnvironment
override fun apply(base: Statement, description: Description): Statement {
env = createTestSerializationEnv(description.toString())
init(description.toString())
return object : Statement() {
override fun evaluate() {
try {
env.asContextEnv(inheritable) { base.evaluate() }
} finally {
inVMExecutors.remove(env)
}
}
override fun evaluate() = runTask { base.evaluate() }
}
}
private fun init(envLabel: String) {
env = createTestSerializationEnv(envLabel)
}
private fun <T> runTask(task: (SerializationEnvironment) -> T): T {
try {
return env.asContextEnv(inheritable, task)
} finally {
inVMExecutors.remove(env)
}
}
}

View File

@ -0,0 +1,27 @@
package net.corda.testing
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
class TestIdentityTests {
@Test
fun `entropy works`() {
val a = TestIdentity(ALICE_NAME, 123)
val b = TestIdentity(BOB_NAME, 123)
assertEquals(a.publicKey, b.publicKey)
assertEquals(a.keyPair.private, b.keyPair.private)
}
@Test
fun `fresh works`() {
val x = TestIdentity.fresh("xx")
val y = TestIdentity.fresh("yy")
// The param is called organisation so we'd better use it as such:
assertEquals("xx", x.name.organisation)
assertEquals("yy", y.name.organisation)
// A fresh identity shouldn't be equal to anything by accident:
assertNotEquals(x.name, y.name)
assertNotEquals(x.publicKey, y.publicKey)
}
}

View File

@ -27,7 +27,7 @@ data class NotariseCommand(val issueTx: SignedTransaction, val moveTx: SignedTra
val dummyNotarisationTest = LoadTest<NotariseCommand, Unit>(
"Notarising dummy transactions",
generate = { _, _ ->
val issuerServices = MockServices(makeTestIdentityService(listOf(megaCorp.identity, miniCorp.identity, dummyCashIssuer.identity, dummyNotary.identity)), megaCorp.name, dummyCashIssuer.keyPair)
val issuerServices = MockServices(emptyList(), makeTestIdentityService(megaCorp.identity, miniCorp.identity, dummyCashIssuer.identity, dummyNotary.identity), megaCorp.name, dummyCashIssuer.keyPair)
val generateTx = Generator.pickOne(simpleNodes).flatMap { node ->
Generator.int().map {
val issueBuilder = DummyContract.generateInitial(it, notary.info.legalIdentities[0], DUMMY_CASH_ISSUER) // TODO notary choice