Merge remote-tracking branch 'open/master' into colljos-os-merge-rc01

This commit is contained in:
josecoll
2017-12-18 10:24:38 +00:00
215 changed files with 4624 additions and 1717 deletions

View File

@ -3,11 +3,9 @@
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
@ -15,25 +13,20 @@ import net.corda.core.internal.cert
import net.corda.core.internal.x500Name
import net.corda.core.node.NodeInfo
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.loggerFor
import net.corda.node.services.config.configureDevKeyAndTrustStores
import net.corda.nodeapi.internal.config.SSLConfiguration
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
import net.corda.nodeapi.internal.crypto.CertificateType
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.serialization.amqp.AMQP_ENABLED
import org.bouncycastle.asn1.x509.GeneralName
import org.bouncycastle.asn1.x509.GeneralSubtree
import org.bouncycastle.asn1.x509.NameConstraints
import org.bouncycastle.cert.X509CertificateHolder
import org.mockito.Mockito.mock
import org.mockito.internal.stubbing.answers.ThrowsException
import java.lang.reflect.Modifier
import java.math.BigInteger
import java.nio.file.Files
import java.security.KeyPair
import java.security.PublicKey
import java.util.*
import java.util.concurrent.atomic.AtomicInteger
/**
@ -81,7 +74,7 @@ fun freePort(): Int = freePortCounter.getAndAccumulate(0) { prev, _ -> 30000 + (
*/
fun getFreeLocalPorts(hostName: String, numberToAlloc: Int): List<NetworkHostAndPort> {
val freePort = freePortCounter.getAndAccumulate(0) { prev, _ -> 30000 + (prev - 30000 + numberToAlloc) % 10000 }
return (freePort..freePort + numberToAlloc - 1).map { NetworkHostAndPort(hostName, it) }
return (0 until numberToAlloc).map { NetworkHostAndPort(hostName, freePort + it) }
}
fun configureTestSSL(legalName: CordaX500Name): SSLConfiguration = object : SSLConfiguration {
@ -93,18 +86,29 @@ fun configureTestSSL(legalName: CordaX500Name): SSLConfiguration = object : SSLC
configureDevKeyAndTrustStores(legalName)
}
}
fun getTestPartyAndCertificate(party: Party): PartyAndCertificate {
val trustRoot: X509CertificateHolder = DEV_TRUST_ROOT
val intermediate: CertificateAndKeyPair = DEV_CA
val nodeCaName = party.name.copy(commonName = X509Utilities.CORDA_CLIENT_CA_CN)
val nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, party.name.x500Name))), arrayOf())
val issuerKeyPair = Crypto.generateKeyPair(Crypto.ECDSA_SECP256K1_SHA256)
val issuerCertificate = X509Utilities.createCertificate(CertificateType.NODE_CA, intermediate.certificate, intermediate.keyPair, nodeCaName, issuerKeyPair.public,
nameConstraints = nameConstraints)
val nodeCaKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)
val nodeCaCert = X509Utilities.createCertificate(
CertificateType.NODE_CA,
intermediate.certificate,
intermediate.keyPair,
nodeCaName,
nodeCaKeyPair.public,
nameConstraints = NameConstraints(arrayOf(GeneralSubtree(GeneralName(GeneralName.directoryName, party.name.x500Name))), arrayOf()))
val certHolder = X509Utilities.createCertificate(CertificateType.WELL_KNOWN_IDENTITY, issuerCertificate, issuerKeyPair, party.name, party.owningKey)
val pathElements = listOf(certHolder, issuerCertificate, intermediate.certificate, trustRoot)
val identityCert = X509Utilities.createCertificate(
CertificateType.WELL_KNOWN_IDENTITY,
nodeCaCert,
nodeCaKeyPair,
party.name,
party.owningKey)
val pathElements = listOf(identityCert, nodeCaCert, intermediate.certificate, trustRoot)
val certPath = X509CertificateFactory().generateCertPath(pathElements.map(X509CertificateHolder::cert))
return PartyAndCertificate(certPath)
}
@ -116,26 +120,29 @@ fun getTestPartyAndCertificate(name: CordaX500Name, publicKey: PublicKey): Party
return getTestPartyAndCertificate(Party(name, publicKey))
}
class TestIdentity @JvmOverloads constructor(val name: CordaX500Name, entropy: Long? = null) {
val key = if (entropy != null) entropyToKeyPair(BigInteger.valueOf(entropy)) else generateKeyPair()
val pubkey get() = key.public!!
val party = Party(name, pubkey)
val identity by lazy { getTestPartyAndCertificate(party) } // Often not needed.
fun ref(vararg bytes: Byte) = party.ref(*bytes)
}
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)
}
}
@Suppress("unused")
inline fun <reified T : Any> T.kryoSpecific(reason: String, function: () -> Unit) = if (!AMQP_ENABLED) {
function()
} else {
loggerFor<T>().info("Ignoring Kryo specific test, reason: $reason")
}
/** Creates an identity with a deterministic [keyPair] i.e. same [entropy] same keyPair .*/
constructor(name: CordaX500Name, entropy: Long) : this(name, entropyToKeyPair(BigInteger.valueOf(entropy)))
@Suppress("unused")
inline fun <reified T : Any> T.amqpSpecific(reason: String, function: () -> Unit) = if (AMQP_ENABLED) {
function()
} else {
loggerFor<T>().info("Ignoring AMQP specific test, reason: $reason")
/** Creates an identity with the given name and a fresh keyPair. */
constructor(name: CordaX500Name) : this(name, generateKeyPair())
val publicKey: PublicKey get() = keyPair.public
val party: Party = Party(name, publicKey)
val identity: PartyAndCertificate by lazy { getTestPartyAndCertificate(party) } // Often not needed.
fun ref(vararg bytes: Byte): PartyAndReference = party.ref(*bytes)
}
/**
@ -154,25 +161,3 @@ fun NodeInfo.singleIdentityAndCert(): PartyAndCertificate = legalIdentitiesAndCe
* Extract a single identity from the node info. Throws an error if the node has multiple identities.
*/
fun NodeInfo.singleIdentity(): Party = singleIdentityAndCert().party
/**
* A method on a mock was called, but no behaviour was previously specified for that method.
* You can use [com.nhaarman.mockito_kotlin.doReturn] or similar to specify behaviour, see Mockito documentation for details.
*/
class UndefinedMockBehaviorException(message: String) : RuntimeException(message)
inline fun <reified T : Any> rigorousMock() = rigorousMock(T::class.java)
/**
* Create a Mockito mock that has [UndefinedMockBehaviorException] as the default behaviour of all abstract methods,
* and [org.mockito.invocation.InvocationOnMock.callRealMethod] as the default for all concrete methods.
* @param T the type to mock. Note if you want concrete methods of a Kotlin interface to be invoked,
* it won't work unless you mock a (trivial) abstract implementation of that interface instead.
*/
fun <T> rigorousMock(clazz: Class<T>): T = mock(clazz) {
if (Modifier.isAbstract(it.method.modifiers)) {
// Use ThrowsException to hack the stack trace, and lazily so we can customise the message:
ThrowsException(UndefinedMockBehaviorException("Please specify what should happen when '${it.method}' is called, or don't call it. Args: ${Arrays.toString(it.arguments)}")).answer(it)
} else {
it.callRealMethod()
}
}

View File

@ -1,25 +0,0 @@
package net.corda.testing
import java.time.Duration
/**
* Ideas borrowed from "io.kotlintest" with some improvements made
* This is meant for use from Kotlin code use only mainly due to it's inline/reified nature
*/
inline fun <reified E : Throwable, R> eventually(duration: Duration, f: () -> R): R {
val end = System.nanoTime() + duration.toNanos()
var times = 0
while (System.nanoTime() < end) {
try {
return f()
} catch (e: Throwable) {
when (e) {
is E -> {
}// ignore and continue
else -> throw e // unexpected exception type - rethrow
}
}
times++
}
throw AssertionError("Test failed after $duration; attempted $times times")
}

View File

@ -1,54 +0,0 @@
package net.corda.testing
import net.corda.core.internal.uncheckedCast
import kotlin.reflect.KCallable
import kotlin.reflect.jvm.reflect
/**
* These functions may be used to run measurements of a function where the parameters are chosen from corresponding
* [Iterable]s in a lexical manner. An example use case would be benchmarking the speed of a certain function call using
* different combinations of parameters.
*/
fun <A : Any, R> measure(a: Iterable<A>, f: (A) -> R) =
measure(listOf(a), f.reflect()!!) { f(uncheckedCast(it[0])) }
fun <A : Any, B : Any, R> measure(a: Iterable<A>, b: Iterable<B>, f: (A, B) -> R) =
measure(listOf(a, b), f.reflect()!!) { f(uncheckedCast(it[0]), uncheckedCast(it[1])) }
fun <A : Any, B : Any, C : Any, R> measure(a: Iterable<A>, b: Iterable<B>, c: Iterable<C>, f: (A, B, C) -> R) =
measure(listOf(a, b, c), f.reflect()!!) { f(uncheckedCast(it[0]), uncheckedCast(it[1]), uncheckedCast(it[2])) }
fun <A : Any, B : Any, C : Any, D : Any, R> measure(a: Iterable<A>, b: Iterable<B>, c: Iterable<C>, d: Iterable<D>, f: (A, B, C, D) -> R) =
measure(listOf(a, b, c, d), f.reflect()!!) { f(uncheckedCast(it[0]), uncheckedCast(it[1]), uncheckedCast(it[2]), uncheckedCast(it[3])) }
private fun <R> measure(paramIterables: List<Iterable<Any?>>, kCallable: KCallable<R>, call: (Array<Any?>) -> R): Iterable<MeasureResult<R>> {
val kParameters = kCallable.parameters
return iterateLexical(paramIterables).map { params ->
MeasureResult(
// For example an underscore param in a lambda does not have a name:
parameters = params.mapIndexed { index, param -> Pair(kParameters[index].name, param) },
result = call(params.toTypedArray())
)
}
}
data class MeasureResult<out R>(
val parameters: List<Pair<String?, Any?>>,
val result: R
)
fun <A> iterateLexical(iterables: List<Iterable<A>>): Iterable<List<A>> {
val result = ArrayList<List<A>>()
fun iterateLexicalHelper(index: Int, list: List<A>) {
if (index < iterables.size) {
iterables[index].forEach {
iterateLexicalHelper(index + 1, list + it)
}
} else {
result.add(list)
}
}
iterateLexicalHelper(0, emptyList())
return result
}

View File

@ -9,6 +9,7 @@ import net.corda.nodeapi.internal.serialization.*
import net.corda.nodeapi.internal.serialization.amqp.AMQPClientSerializationScheme
import net.corda.nodeapi.internal.serialization.amqp.AMQPServerSerializationScheme
import net.corda.testing.common.internal.asContextEnv
import net.corda.testing.internal.rigorousMock
import net.corda.testing.internal.testThreadFactory
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnector
import org.junit.rules.TestRule
@ -33,19 +34,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)
}
}
}
@ -55,25 +67,6 @@ interface GlobalSerializationEnvironment : SerializationEnvironment {
fun unset()
}
/** @param inheritable whether new threads inherit the environment, use sparingly. */
fun <T> withTestSerialization(inheritable: Boolean = false, callable: (SerializationEnvironment) -> T): T {
return createTestSerializationEnv("<context>").asContextEnv(inheritable, callable)
}
/**
* For example your test class uses [SerializationEnvironmentRule] but you want to turn it off for one method.
* Use sparingly, ideally a test class shouldn't mix serializers init mechanisms.
*/
fun <T> withoutTestSerialization(callable: () -> T): T {
val (property, env) = listOf(_contextSerializationEnv, _inheritableContextSerializationEnv).map { Pair(it, it.get()) }.single { it.second != null }
property.set(null)
try {
return callable()
} finally {
property.set(env)
}
}
/**
* Should only be used by Driver and MockNode.
* @param armed true to install, false to do nothing and return a dummy env.
@ -95,22 +88,21 @@ fun setGlobalSerialization(armed: Boolean): GlobalSerializationEnvironment {
}
}
private fun createTestSerializationEnv(label: String) = object : SerializationEnvironmentImpl(
SerializationFactoryImpl().apply {
registerScheme(KryoClientSerializationScheme())
registerScheme(KryoServerSerializationScheme())
registerScheme(AMQPClientSerializationScheme(emptyList()))
registerScheme(AMQPServerSerializationScheme(emptyList()))
},
AMQP_P2P_CONTEXT,
KRYO_RPC_SERVER_CONTEXT,
KRYO_RPC_CLIENT_CONTEXT,
AMQP_STORAGE_CONTEXT,
KRYO_CHECKPOINT_CONTEXT) {
override fun toString() = "testSerializationEnv($label)"
private fun createTestSerializationEnv(label: String): SerializationEnvironmentImpl {
val factory = SerializationFactoryImpl().apply {
registerScheme(KryoClientSerializationScheme())
registerScheme(KryoServerSerializationScheme())
registerScheme(AMQPClientSerializationScheme(emptyList()))
registerScheme(AMQPServerSerializationScheme(emptyList()))
}
return object : SerializationEnvironmentImpl(
factory,
AMQP_P2P_CONTEXT,
KRYO_RPC_SERVER_CONTEXT,
KRYO_RPC_CLIENT_CONTEXT,
AMQP_STORAGE_CONTEXT,
KRYO_CHECKPOINT_CONTEXT
) {
override fun toString() = "testSerializationEnv($label)"
}
}
private const val AMQP_ENABLE_PROP_NAME = "net.corda.testing.amqp.enable"
// TODO: Remove usages of this function when we fully switched to AMQP
private fun isAmqpEnabled(): Boolean = java.lang.Boolean.getBoolean(AMQP_ENABLE_PROP_NAME)

View File

@ -13,14 +13,23 @@ import java.security.PublicKey
import java.time.Instant
// A dummy time at which we will be pretending test transactions are created.
val TEST_TX_TIME: Instant get() = Instant.parse("2015-04-17T12:00:00.00Z")
@JvmField
val TEST_TX_TIME = Instant.parse("2015-04-17T12:00:00.00Z")
@JvmField
val DUMMY_NOTARY_NAME = CordaX500Name("Notary Service", "Zurich", "CH")
@JvmField
val DUMMY_BANK_A_NAME = CordaX500Name("Bank A", "London", "GB")
@JvmField
val DUMMY_BANK_B_NAME = CordaX500Name("Bank B", "New York", "US")
@JvmField
val DUMMY_BANK_C_NAME = CordaX500Name("Bank C", "Tokyo", "JP")
@JvmField
val BOC_NAME = CordaX500Name("BankOfCorda", "London", "GB")
@JvmField
val ALICE_NAME = CordaX500Name("Alice Corp", "Madrid", "ES")
@JvmField
val BOB_NAME = CordaX500Name("Bob Plc", "Rome", "IT")
@JvmField
val CHARLIE_NAME = CordaX500Name("Charlie Ltd", "Athens", "GR")
val DEV_CA: CertificateAndKeyPair by lazy {
// TODO: Should be identity scheme
@ -42,3 +51,6 @@ val DEV_TRUST_ROOT: X509CertificateHolder by lazy {
fun dummyCommand(vararg signers: PublicKey = arrayOf(generateKeyPair().public)) = Command<TypeOnlyCommandData>(DummyCommandData, signers.toList())
object DummyCommandData : TypeOnlyCommandData()
/** Maximum artemis message size. 10 MiB maximum allowed file size for attachments, including message headers. */
const val MAX_MESSAGE_SIZE: Int = 10485760

View File

@ -1,10 +0,0 @@
package net.corda.testing
import org.junit.Rule
@Deprecated("Instead of extending this class, use SerializationEnvironmentRule in the same way.")
abstract class TestDependencyInjectionBase {
@Rule
@JvmField
val testSerialization = SerializationEnvironmentRule()
}

View File

@ -1,20 +0,0 @@
package net.corda.testing
import net.corda.testing.TestTimestamp.Companion.timestamp
import java.text.SimpleDateFormat
import java.util.*
/**
* [timestamp] holds a formatted (UTC) timestamp that's set the first time it is queried. This is used to
* provide a uniform timestamp for tests.
*/
class TestTimestamp {
companion object {
val timestamp: String = {
val tz = TimeZone.getTimeZone("UTC")
val df = SimpleDateFormat("yyyyMMddHHmmss")
df.timeZone = tz
df.format(Date())
}()
}
}

View File

@ -1,4 +1,4 @@
package net.corda.testing
package net.corda.testing.dsl
import net.corda.core.contracts.ContractState
import net.corda.core.contracts.StateAndRef

View File

@ -1,4 +1,4 @@
package net.corda.testing
package net.corda.testing.dsl
import net.corda.core.contracts.*
import net.corda.core.cordapp.CordappProvider
@ -12,9 +12,9 @@ import net.corda.core.node.ServicesForResolution
import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.transactions.WireTransaction
import net.corda.testing.contracts.DummyContract
import net.corda.testing.services.MockAttachmentStorage
import net.corda.testing.services.MockCordappProvider
import net.corda.testing.dummyCommand
import java.io.InputStream
import java.security.PublicKey
import java.util.*

View File

@ -1,4 +1,4 @@
package net.corda.testing
package net.corda.testing.dsl
import net.corda.core.contracts.AlwaysAcceptAttachmentConstraint
import net.corda.core.contracts.Attachment

View File

@ -0,0 +1,19 @@
package net.corda.testing.internal
import net.corda.core.serialization.internal._contextSerializationEnv
import net.corda.core.serialization.internal._inheritableContextSerializationEnv
import net.corda.testing.SerializationEnvironmentRule
/**
* For example your test class uses [SerializationEnvironmentRule] but you want to turn it off for one method.
* Use sparingly, ideally a test class shouldn't mix serializers init mechanisms.
*/
fun <T> withoutTestSerialization(callable: () -> T): T { // TODO: Delete this, see CORDA-858.
val (property, env) = listOf(_contextSerializationEnv, _inheritableContextSerializationEnv).map { Pair(it, it.get()) }.single { it.second != null }
property.set(null)
try {
return callable()
} finally {
property.set(env)
}
}

View File

@ -0,0 +1,44 @@
package net.corda.testing.internal
import net.corda.core.utilities.loggerFor
import net.corda.nodeapi.internal.serialization.amqp.AMQP_ENABLED
import org.mockito.Mockito
import org.mockito.internal.stubbing.answers.ThrowsException
import java.lang.reflect.Modifier
import java.util.*
@Suppress("unused")
inline fun <reified T : Any> T.kryoSpecific(reason: String, function: () -> Unit) = if (!AMQP_ENABLED) {
function()
} else {
loggerFor<T>().info("Ignoring Kryo specific test, reason: $reason")
}
@Suppress("unused")
inline fun <reified T : Any> T.amqpSpecific(reason: String, function: () -> Unit) = if (AMQP_ENABLED) {
function()
} else {
loggerFor<T>().info("Ignoring AMQP specific test, reason: $reason")
}
/**
* A method on a mock was called, but no behaviour was previously specified for that method.
* You can use [com.nhaarman.mockito_kotlin.doReturn] or similar to specify behaviour, see Mockito documentation for details.
*/
class UndefinedMockBehaviorException(message: String) : RuntimeException(message)
inline fun <reified T : Any> rigorousMock() = rigorousMock(T::class.java)
/**
* Create a Mockito mock that has [UndefinedMockBehaviorException] as the default behaviour of all abstract methods,
* and [org.mockito.invocation.InvocationOnMock.callRealMethod] as the default for all concrete methods.
* @param T the type to mock. Note if you want concrete methods of a Kotlin interface to be invoked,
* it won't work unless you mock a (trivial) abstract implementation of that interface instead.
*/
fun <T> rigorousMock(clazz: Class<T>): T = Mockito.mock(clazz) {
if (Modifier.isAbstract(it.method.modifiers)) {
// Use ThrowsException to hack the stack trace, and lazily so we can customise the message:
ThrowsException(UndefinedMockBehaviorException("Please specify what should happen when '${it.method}' is called, or don't call it. Args: ${Arrays.toString(it.arguments)}")).answer(it)
} else {
it.callRealMethod()
}
}

View File

@ -1,4 +1,4 @@
package net.corda.testing
package net.corda.testing.internal
import net.corda.core.internal.packageName
import org.apache.logging.log4j.Level

View File

@ -0,0 +1,55 @@
package net.corda.testing.internal
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.sign
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.NodeInfo
import net.corda.core.serialization.serialize
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.nodeapi.internal.SignedNodeInfo
import net.corda.testing.getTestPartyAndCertificate
import java.security.PrivateKey
class TestNodeInfoBuilder {
private val identitiesAndPrivateKeys = ArrayList<Pair<PartyAndCertificate, PrivateKey>>()
fun addIdentity(name: CordaX500Name): Pair<PartyAndCertificate, PrivateKey> {
val identityKeyPair = Crypto.generateKeyPair()
val identity = getTestPartyAndCertificate(name, identityKeyPair.public)
return Pair(identity, identityKeyPair.private).also {
identitiesAndPrivateKeys += it
}
}
fun build(serial: Long = 1): NodeInfo {
return NodeInfo(
listOf(NetworkHostAndPort("my.${identitiesAndPrivateKeys[0].first.party.name.organisation}.com", 1234)),
identitiesAndPrivateKeys.map { it.first },
1,
serial
)
}
fun buildWithSigned(serial: Long = 1): Pair<NodeInfo, SignedNodeInfo> {
val nodeInfo = build(serial)
val privateKeys = identitiesAndPrivateKeys.map { it.second }
return Pair(nodeInfo, nodeInfo.signWith(privateKeys))
}
fun reset() {
identitiesAndPrivateKeys.clear()
}
}
fun createNodeInfoAndSigned(vararg names: CordaX500Name, serial: Long = 1): Pair<NodeInfo, SignedNodeInfo> {
val nodeInfoBuilder = TestNodeInfoBuilder()
names.forEach { nodeInfoBuilder.addIdentity(it) }
return nodeInfoBuilder.buildWithSigned(serial)
}
fun NodeInfo.signWith(keys: List<PrivateKey>): SignedNodeInfo {
val serialized = serialize()
val signatures = keys.map { it.sign(serialized.bytes) }
return SignedNodeInfo(serialized, signatures)
}

View File

@ -1,4 +1,4 @@
package net.corda.testing.contracts
package net.corda.testing.internal.vault
import net.corda.core.contracts.Contract
import net.corda.core.contracts.UniqueIdentifier
@ -10,9 +10,8 @@ import net.corda.core.schemas.QueryableState
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.finance.contracts.DealState
import net.corda.testing.schemas.DummyDealStateSchemaV1
val DUMMY_DEAL_PROGRAM_ID = "net.corda.testing.contracts.DummyDealContract"
val DUMMY_DEAL_PROGRAM_ID = "net.corda.testing.internal.vault.DummyDealContract"
class DummyDealContract : Contract {
override fun verify(tx: LedgerTransaction) {}

View File

@ -1,4 +1,4 @@
package net.corda.testing.schemas
package net.corda.testing.internal.vault
import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.identity.AbstractParty

View File

@ -1,4 +1,4 @@
package net.corda.testing.contracts
package net.corda.testing.internal.vault
import net.corda.core.contracts.Contract
import net.corda.core.contracts.LinearState
@ -10,12 +10,10 @@ import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import net.corda.core.schemas.QueryableState
import net.corda.core.transactions.LedgerTransaction
import net.corda.testing.schemas.DummyLinearStateSchemaV1
import net.corda.testing.schemas.DummyLinearStateSchemaV2
import java.time.LocalDateTime
import java.time.ZoneOffset.UTC
const val DUMMY_LINEAR_CONTRACT_PROGRAM_ID = "net.corda.testing.contracts.DummyLinearContract"
const val DUMMY_LINEAR_CONTRACT_PROGRAM_ID = "net.corda.testing.internal.vault.DummyLinearContract"
class DummyLinearContract : Contract {
override fun verify(tx: LedgerTransaction) {

View File

@ -1,4 +1,4 @@
package net.corda.testing.schemas
package net.corda.testing.internal.vault
import net.corda.core.contracts.ContractState
import net.corda.core.identity.AbstractParty

View File

@ -1,4 +1,4 @@
package net.corda.testing.schemas
package net.corda.testing.internal.vault
import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.identity.AbstractParty

View File

@ -1,6 +1,4 @@
@file:JvmName("VaultFiller")
package net.corda.testing.contracts
package net.corda.testing.internal.vault
import net.corda.core.contracts.*
import net.corda.core.crypto.Crypto
@ -80,7 +78,7 @@ class VaultFiller @JvmOverloads constructor(
addCommand(dummyCommand())
}
val stx = issuerServices.signInitialTransaction(dummyIssue)
return@map services.addSignature(stx, defaultNotary.pubkey)
return@map services.addSignature(stx, defaultNotary.publicKey)
}
services.recordTransactions(transactions)
// Get all the StateAndRefs of all the generated transactions.
@ -101,7 +99,7 @@ class VaultFiller @JvmOverloads constructor(
linearTimestamp: Instant = now()): Vault<LinearState> {
val myKey: PublicKey = services.myInfo.chooseIdentity().owningKey
val me = AnonymousParty(myKey)
val issuerKey = defaultNotary.key
val issuerKey = defaultNotary.keyPair
val signatureMetadata = SignatureMetadata(services.myInfo.platformVersion, Crypto.findSignatureScheme(issuerKey.public).schemeNumberID)
val transactions: List<SignedTransaction> = (1..numberToCreate).map {
// Issue a Linear state

View File

@ -1,47 +0,0 @@
package net.corda.testing.messaging
import net.corda.core.identity.CordaX500Name
import net.corda.core.serialization.internal.nodeSerializationEnv
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.nodeapi.ArtemisTcpTransport
import net.corda.nodeapi.ConnectionDirection
import net.corda.nodeapi.internal.config.SSLConfiguration
import net.corda.testing.configureTestSSL
import org.apache.activemq.artemis.api.core.client.*
/**
* As the name suggests this is a simple client for connecting to MQ brokers.
*/
class SimpleMQClient(val target: NetworkHostAndPort,
private val config: SSLConfiguration? = configureTestSSL(DEFAULT_MQ_LEGAL_NAME)) {
companion object {
val DEFAULT_MQ_LEGAL_NAME = CordaX500Name(organisation = "SimpleMQClient", locality = "London", country = "GB")
}
lateinit var sessionFactory: ClientSessionFactory
lateinit var session: ClientSession
lateinit var producer: ClientProducer
fun start(username: String? = null, password: String? = null, enableSSL: Boolean = true) {
val tcpTransport = ArtemisTcpTransport.tcpTransport(ConnectionDirection.Outbound(), target, config, enableSSL = enableSSL)
val locator = ActiveMQClient.createServerLocatorWithoutHA(tcpTransport).apply {
isBlockOnNonDurableSend = true
threadPoolMaxSize = 1
isUseGlobalPools = nodeSerializationEnv != null
}
sessionFactory = locator.createSessionFactory()
session = sessionFactory.createSession(username, password, false, true, true, locator.isPreAcknowledge, locator.ackBatchSize)
session.start()
producer = session.createProducer()
}
fun createMessage(): ClientMessage = session.createMessage(false)
fun stop() {
try {
sessionFactory.close()
} catch (e: Exception) {
// sessionFactory might not have initialised.
}
}
}

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