From b61b36289125105ac6c606c0459c34c17dc113c3 Mon Sep 17 00:00:00 2001 From: Clinton Alexander Date: Tue, 7 Jun 2016 18:25:11 +0100 Subject: [PATCH] Setup TraderDemo test. Moved DemoNode to a common file. Modified TraderDemo to be tested. --- src/main/kotlin/com/r3corda/demos/DemoNode.kt | 27 +++++++++++++ src/main/kotlin/com/r3corda/demos/IRSDemo.kt | 15 ------- .../kotlin/com/r3corda/demos/TraderDemo.kt | 39 ++++++++++++------- .../com/r3corda/core/testing/TradeDemoTest.kt | 34 ++++++++++++++++ 4 files changed, 87 insertions(+), 28 deletions(-) create mode 100644 src/main/kotlin/com/r3corda/demos/DemoNode.kt create mode 100644 src/test/kotlin/com/r3corda/core/testing/TradeDemoTest.kt diff --git a/src/main/kotlin/com/r3corda/demos/DemoNode.kt b/src/main/kotlin/com/r3corda/demos/DemoNode.kt new file mode 100644 index 0000000000..6f04fbabea --- /dev/null +++ b/src/main/kotlin/com/r3corda/demos/DemoNode.kt @@ -0,0 +1,27 @@ +package com.r3corda.demos + +import com.google.common.net.HostAndPort +import com.r3corda.core.messaging.MessagingService +import com.r3corda.core.node.NodeInfo +import com.r3corda.core.node.services.ServiceType +import com.r3corda.node.internal.Node +import com.r3corda.node.serialization.NodeClock +import com.r3corda.node.services.config.NodeConfiguration +import com.r3corda.node.services.network.InMemoryMessagingNetwork +import java.nio.file.Path +import java.time.Clock + +val messageNetwork = InMemoryMessagingNetwork() + +class DemoNode(messagingService: MessagingService, dir: Path, p2pAddr: HostAndPort, config: NodeConfiguration, + networkMapAddress: NodeInfo?, advertisedServices: Set, + clock: Clock = NodeClock(), clientAPIs: List> = listOf()) +: Node(dir, p2pAddr, config, networkMapAddress, advertisedServices, clock, clientAPIs) { + + val messagingService = messagingService + override fun makeMessagingService(): MessagingService { + return messagingService + } + + override fun startMessagingService() = Unit +} \ No newline at end of file diff --git a/src/main/kotlin/com/r3corda/demos/IRSDemo.kt b/src/main/kotlin/com/r3corda/demos/IRSDemo.kt index d598c010a4..f06f54097d 100644 --- a/src/main/kotlin/com/r3corda/demos/IRSDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/IRSDemo.kt @@ -86,21 +86,6 @@ private class NotSetupException: Throwable { constructor(message: String): super(message) {} } -val messageNetwork = InMemoryMessagingNetwork() - -class DemoNode(messagingService: MessagingService, dir: Path, p2pAddr: HostAndPort, config: NodeConfiguration, - networkMapAddress: NodeInfo?, advertisedServices: Set, - clock: Clock, clientAPIs: List> = listOf()) - : Node(dir, p2pAddr, config, networkMapAddress, advertisedServices, clock, clientAPIs) { - - val messagingService = messagingService - override fun makeMessagingService(): MessagingService { - return messagingService - } - - override fun startMessagingService() = Unit -} - fun main(args: Array) { exitProcess(runIRSDemo(args)) } diff --git a/src/main/kotlin/com/r3corda/demos/TraderDemo.kt b/src/main/kotlin/com/r3corda/demos/TraderDemo.kt index 90d7917d7d..e89ae844df 100644 --- a/src/main/kotlin/com/r3corda/demos/TraderDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/TraderDemo.kt @@ -68,13 +68,27 @@ enum class Role { val DIRNAME = "trader-demo" fun main(args: Array) { + exitProcess(runTraderDemo(args)) +} + +fun runTraderDemo(args: Array, useInMemoryMessaging: Boolean = false): Int { + val cashIssuerKey = generateKeyPair() + val cashIssuer = Party("Trusted cash issuer", cashIssuerKey.public) + val amount = 1000.DOLLARS `issued by` cashIssuer.ref(1) val parser = OptionParser() val roleArg = parser.accepts("role").withRequiredArg().ofType(Role::class.java).required() val myNetworkAddress = parser.accepts("network-address").withRequiredArg().defaultsTo("localhost") val theirNetworkAddress = parser.accepts("other-network-address").withRequiredArg().defaultsTo("localhost") - val options = parseOptions(args, parser) + val options = try { + parser.parse(*args) + } catch (e: Exception) { + println(e.message) + println("Please refer to the documentation in docs/build/index.html to learn how to run the demo.") + return 1 + } + val role = options.valueOf(roleArg)!! val myNetAddr = HostAndPort.fromString(options.valueOf(myNetworkAddress)).withDefaultPort( @@ -130,6 +144,11 @@ fun main(args: Array) { NodeInfo(ArtemisMessagingService.makeRecipient(theirNetAddr), party, setOf(NetworkMapService.Type)) } + val id = when(role) { + Role.BUYER -> 0 + Role.SELLER -> 1 + } + val messageService = messageNetwork.createNodeWithID(false, id).start().get() // And now construct then start the node object. It takes a little while. val node = logElapsedTime("Node startup") { Node(directory, myNetAddr, config, networkMapId, advertisedServices).setup().start() @@ -148,19 +167,13 @@ fun main(args: Array) { } else { runSeller(myNetAddr, node, theirNetAddr, amount) } + + return 0 } -fun parseOptions(args: Array, parser: OptionParser): OptionSet { - try { - return parser.parse(*args) - } catch (e: Exception) { - println(e.message) - println("Please refer to the documentation in docs/build/index.html to learn how to run the demo.") - exitProcess(1) - } } -fun runSeller(myNetAddr: HostAndPort, node: Node, theirNetAddr: HostAndPort, amount: Amount>) { +private fun runSeller(myNetAddr: HostAndPort, node: Node, theirNetAddr: HostAndPort) { // The seller will sell some commercial paper to the buyer, who will pay with (self issued) cash. // // The CP sale transaction comes with a prospectus PDF, which will tag along for the ride in an @@ -187,7 +200,7 @@ fun runSeller(myNetAddr: HostAndPort, node: Node, theirNetAddr: HostAndPort, amo node.stop() } -fun runBuyer(node: Node, amount: Amount>) { +private fun runBuyer(node: Node, amount: Amount>) { // Buyer will fetch the attachment from the seller automatically when it resolves the transaction. // For demo purposes just extract attachment jars when saved to disk, so the user can explore them. val attachmentsPath = (node.storage.attachments as NodeAttachmentService).let { @@ -211,7 +224,7 @@ fun runBuyer(node: Node, amount: Amount>) { val DEMO_TOPIC = "initiate.demo.trade" -class TraderDemoProtocolBuyer(private val attachmentsPath: Path, +private class TraderDemoProtocolBuyer(private val attachmentsPath: Path, val notary: Party, val amount: Amount>) : ProtocolLogic() { companion object { @@ -289,7 +302,7 @@ ${Emoji.renderIfSupported(cpIssuance)}""") } } -class TraderDemoProtocolSeller(val myAddress: HostAndPort, +private class TraderDemoProtocolSeller(val myAddress: HostAndPort, val otherSide: SingleMessageRecipient, val amount: Amount>, override val progressTracker: ProgressTracker = TraderDemoProtocolSeller.tracker()) : ProtocolLogic() { diff --git a/src/test/kotlin/com/r3corda/core/testing/TradeDemoTest.kt b/src/test/kotlin/com/r3corda/core/testing/TradeDemoTest.kt new file mode 100644 index 0000000000..489cf5b74a --- /dev/null +++ b/src/test/kotlin/com/r3corda/core/testing/TradeDemoTest.kt @@ -0,0 +1,34 @@ +package com.r3corda.core.testing + +import com.r3corda.demos.runTraderDemo +import org.junit.Test +import java.nio.file.Path +import java.nio.file.Paths +import kotlin.concurrent.thread +import kotlin.test.assertEquals + +class TraderDemoTest { + @Test fun `runs trader demo`() { + try { + runBuyer() + runSeller() + } finally { + cleanup() + } + } +} + +private fun runBuyer() { + thread(true, false, null, "Buyer", -1, { runTraderDemo(arrayOf("--role", "BUYER"), true) }) + Thread.sleep(5000) +} + +private fun runSeller() { + assertEquals(runTraderDemo(arrayOf("--role", "SELLER"), true), 0) +} + +private fun cleanup() { + val dir = Paths.get("trader-demo") + println("Erasing " + dir) + dir.toFile().deleteRecursively() +} \ No newline at end of file