mirror of
https://github.com/corda/corda.git
synced 2025-06-01 23:20:54 +00:00
Added tests to make sure the platform version is correctly available
This commit is contained in:
parent
2ceb6283af
commit
4ca54b73fe
@ -6,8 +6,7 @@ buildscript {
|
|||||||
// Our version: bump this on release.
|
// Our version: bump this on release.
|
||||||
ext.corda_release_version = "3.0-SNAPSHOT"
|
ext.corda_release_version = "3.0-SNAPSHOT"
|
||||||
// Increment this on any release that changes public APIs anywhere in the Corda platform
|
// Increment this on any release that changes public APIs anywhere in the Corda platform
|
||||||
// TODO This is going to be difficult until we have a clear separation throughout the code of what is public and what is internal
|
ext.corda_platform_version = constants.getProperty("platformVersion")
|
||||||
ext.corda_platform_version = 2
|
|
||||||
ext.gradle_plugins_version = constants.getProperty("gradlePluginsVersion")
|
ext.gradle_plugins_version = constants.getProperty("gradlePluginsVersion")
|
||||||
|
|
||||||
// Dependency versions. Can run 'gradle dependencyUpdates' to find new versions of things.
|
// Dependency versions. Can run 'gradle dependencyUpdates' to find new versions of things.
|
||||||
|
@ -74,7 +74,7 @@ public class StandaloneCordaRPCJavaClientTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void copyFinanceCordapp() {
|
private void copyFinanceCordapp() {
|
||||||
Path cordappsDir = (factory.baseDirectory(notaryConfig).resolve("cordapps"));
|
Path cordappsDir = (factory.baseDirectory(notaryConfig).resolve(NodeProcess.CORDAPPS_DIR_NAME));
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(cordappsDir);
|
Files.createDirectories(cordappsDir);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
|
@ -86,7 +86,7 @@ class StandaloneCordaRPClientTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun copyFinanceCordapp() {
|
private fun copyFinanceCordapp() {
|
||||||
val cordappsDir = (factory.baseDirectory(notaryConfig) / "cordapps").createDirectories()
|
val cordappsDir = (factory.baseDirectory(notaryConfig) / NodeProcess.CORDAPPS_DIR_NAME).createDirectories()
|
||||||
// Find the finance jar file for the smoke tests of this module
|
// Find the finance jar file for the smoke tests of this module
|
||||||
val financeJar = Paths.get("build", "resources", "smokeTest").list {
|
val financeJar = Paths.get("build", "resources", "smokeTest").list {
|
||||||
it.filter { "corda-finance" in it.toString() }.toList().single()
|
it.filter { "corda-finance" in it.toString() }.toList().single()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
gradlePluginsVersion=2.0.9
|
gradlePluginsVersion=2.0.9
|
||||||
kotlinVersion=1.1.60
|
kotlinVersion=1.1.60
|
||||||
|
platformVersion=2
|
||||||
guavaVersion=21.0
|
guavaVersion=21.0
|
||||||
bouncycastleVersion=1.57
|
bouncycastleVersion=1.57
|
||||||
typesafeConfigVersion=1.3.1
|
typesafeConfigVersion=1.3.1
|
@ -0,0 +1,75 @@
|
|||||||
|
package net.corda.core
|
||||||
|
|
||||||
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
|
import net.corda.core.flows.FlowLogic
|
||||||
|
import net.corda.core.flows.StartableByRPC
|
||||||
|
import net.corda.core.identity.CordaX500Name
|
||||||
|
import net.corda.core.internal.*
|
||||||
|
import net.corda.core.messaging.startFlow
|
||||||
|
import net.corda.core.utilities.getOrThrow
|
||||||
|
import net.corda.nodeapi.User
|
||||||
|
import net.corda.smoketesting.NodeConfig
|
||||||
|
import net.corda.smoketesting.NodeProcess
|
||||||
|
import net.corda.testing.common.internal.ProjectStructure
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.Test
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import java.util.*
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
import java.util.jar.JarFile
|
||||||
|
import kotlin.streams.toList
|
||||||
|
|
||||||
|
class NodeVersioningTest {
|
||||||
|
private companion object {
|
||||||
|
val user = User("user1", "test", permissions = setOf("ALL"))
|
||||||
|
val port = AtomicInteger(15100)
|
||||||
|
|
||||||
|
val expectedPlatformVersion = (ProjectStructure.projectRootDir / "constants.properties").read {
|
||||||
|
val constants = Properties()
|
||||||
|
constants.load(it)
|
||||||
|
constants.getProperty("platformVersion").toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val factory = NodeProcess.Factory()
|
||||||
|
|
||||||
|
private val aliceConfig = NodeConfig(
|
||||||
|
legalName = CordaX500Name(organisation = "Alice Corp", locality = "Madrid", country = "ES"),
|
||||||
|
p2pPort = port.andIncrement,
|
||||||
|
rpcPort = port.andIncrement,
|
||||||
|
webPort = port.andIncrement,
|
||||||
|
isNotary = false,
|
||||||
|
users = listOf(user)
|
||||||
|
)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `platform version in manifest file`() {
|
||||||
|
val manifest = JarFile(factory.cordaJar.toFile()).manifest
|
||||||
|
assertThat(manifest.mainAttributes.getValue("Corda-Platform-Version").toInt()).isEqualTo(expectedPlatformVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `platform version from RPC`() {
|
||||||
|
val cordappsDir = (factory.baseDirectory(aliceConfig) / NodeProcess.CORDAPPS_DIR_NAME).createDirectories()
|
||||||
|
// Find the jar file for the smoke tests of this module
|
||||||
|
val selfCordapp = Paths.get("build", "libs").list {
|
||||||
|
it.filter { "-smokeTests" in it.toString() }.toList().single()
|
||||||
|
}
|
||||||
|
selfCordapp.copyToDirectory(cordappsDir)
|
||||||
|
|
||||||
|
factory.create(aliceConfig).use { alice ->
|
||||||
|
alice.connect().use {
|
||||||
|
val rpc = it.proxy
|
||||||
|
assertThat(rpc.protocolVersion).isEqualTo(expectedPlatformVersion)
|
||||||
|
assertThat(rpc.nodeInfo().platformVersion).isEqualTo(expectedPlatformVersion)
|
||||||
|
assertThat(rpc.startFlow(NodeVersioningTest::GetPlatformVersionFlow).returnValue.getOrThrow()).isEqualTo(expectedPlatformVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@StartableByRPC
|
||||||
|
class GetPlatformVersionFlow : FlowLogic<Int>() {
|
||||||
|
@Suspendable
|
||||||
|
override fun call(): Int = serviceHub.myInfo.platformVersion
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ import net.corda.core.utilities.unwrap
|
|||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.smoketesting.NodeConfig
|
import net.corda.smoketesting.NodeConfig
|
||||||
import net.corda.smoketesting.NodeProcess
|
import net.corda.smoketesting.NodeProcess
|
||||||
|
import net.corda.smoketesting.NodeProcess.Companion.CORDAPPS_DIR_NAME
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
@ -22,7 +23,6 @@ import kotlin.streams.toList
|
|||||||
|
|
||||||
class CordappSmokeTest {
|
class CordappSmokeTest {
|
||||||
private companion object {
|
private companion object {
|
||||||
private const val CORDAPPS_DIR_NAME = "cordapps"
|
|
||||||
val user = User("user1", "test", permissions = setOf("ALL"))
|
val user = User("user1", "test", permissions = setOf("ALL"))
|
||||||
val port = AtomicInteger(15100)
|
val port = AtomicInteger(15100)
|
||||||
}
|
}
|
||||||
@ -38,7 +38,6 @@ class CordappSmokeTest {
|
|||||||
users = listOf(user)
|
users = listOf(user)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `FlowContent appName returns the filename of the CorDapp jar`() {
|
fun `FlowContent appName returns the filename of the CorDapp jar`() {
|
||||||
val cordappsDir = (factory.baseDirectory(aliceConfig) / CORDAPPS_DIR_NAME).createDirectories()
|
val cordappsDir = (factory.baseDirectory(aliceConfig) / CORDAPPS_DIR_NAME).createDirectories()
|
||||||
|
@ -10,7 +10,7 @@ import net.corda.node.internal.NodeStartup
|
|||||||
import net.corda.node.services.Permissions.Companion.startFlow
|
import net.corda.node.services.Permissions.Companion.startFlow
|
||||||
import net.corda.nodeapi.User
|
import net.corda.nodeapi.User
|
||||||
import net.corda.testing.ALICE
|
import net.corda.testing.ALICE
|
||||||
import net.corda.testing.ProjectStructure.projectRootDir
|
import net.corda.testing.common.internal.ProjectStructure.projectRootDir
|
||||||
import net.corda.testing.driver.driver
|
import net.corda.testing.driver.driver
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.assertj.core.api.Assertions.assertThatThrownBy
|
import org.assertj.core.api.Assertions.assertThatThrownBy
|
||||||
|
@ -190,11 +190,13 @@ fun <M : Any> MessagingService.onNext(topic: String, sessionId: Long): CordaFutu
|
|||||||
return messageFuture
|
return messageFuture
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MessagingService.send(topic: String, sessionID: Long, payload: Any, to: MessageRecipients, uuid: UUID = UUID.randomUUID())
|
fun MessagingService.send(topic: String, sessionID: Long, payload: Any, to: MessageRecipients, uuid: UUID = UUID.randomUUID()) {
|
||||||
= send(TopicSession(topic, sessionID), payload, to, uuid)
|
send(TopicSession(topic, sessionID), payload, to, uuid)
|
||||||
|
}
|
||||||
|
|
||||||
fun MessagingService.send(topicSession: TopicSession, payload: Any, to: MessageRecipients, uuid: UUID = UUID.randomUUID(), retryId: Long? = null)
|
fun MessagingService.send(topicSession: TopicSession, payload: Any, to: MessageRecipients, uuid: UUID = UUID.randomUUID(), retryId: Long? = null) {
|
||||||
= send(createMessage(topicSession, payload.serialize().bytes, uuid), to, retryId)
|
send(createMessage(topicSession, payload.serialize().bytes, uuid), to, retryId)
|
||||||
|
}
|
||||||
|
|
||||||
interface MessageHandlerRegistration
|
interface MessageHandlerRegistration
|
||||||
|
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package net.corda.node.services.messaging
|
package net.corda.node.services.messaging
|
||||||
|
|
||||||
import net.corda.core.concurrent.CordaFuture
|
|
||||||
import net.corda.core.crypto.generateKeyPair
|
import net.corda.core.crypto.generateKeyPair
|
||||||
import net.corda.core.internal.concurrent.doneFuture
|
|
||||||
import net.corda.core.internal.concurrent.openFuture
|
|
||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.node.services.RPCUserService
|
import net.corda.node.services.RPCUserService
|
||||||
import net.corda.node.services.RPCUserServiceImpl
|
import net.corda.node.services.RPCUserServiceImpl
|
||||||
@ -27,13 +24,13 @@ import org.junit.Rule
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
import java.net.ServerSocket
|
import java.net.ServerSocket
|
||||||
|
import java.util.concurrent.BlockingQueue
|
||||||
import java.util.concurrent.LinkedBlockingQueue
|
import java.util.concurrent.LinkedBlockingQueue
|
||||||
import java.util.concurrent.TimeUnit.MILLISECONDS
|
import java.util.concurrent.TimeUnit.MILLISECONDS
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
|
|
||||||
//TODO This needs to be merged into P2PMessagingTest as that creates a more realistic environment
|
|
||||||
class ArtemisMessagingTests {
|
class ArtemisMessagingTests {
|
||||||
companion object {
|
companion object {
|
||||||
const val TOPIC = "platform.self"
|
const val TOPIC = "platform.self"
|
||||||
@ -54,21 +51,19 @@ class ArtemisMessagingTests {
|
|||||||
private lateinit var config: NodeConfiguration
|
private lateinit var config: NodeConfiguration
|
||||||
private lateinit var database: CordaPersistence
|
private lateinit var database: CordaPersistence
|
||||||
private lateinit var userService: RPCUserService
|
private lateinit var userService: RPCUserService
|
||||||
private lateinit var networkMapRegistrationFuture: CordaFuture<Unit>
|
|
||||||
private var messagingClient: P2PMessagingClient? = null
|
private var messagingClient: P2PMessagingClient? = null
|
||||||
private var messagingServer: ArtemisMessagingServer? = null
|
private var messagingServer: ArtemisMessagingServer? = null
|
||||||
|
|
||||||
private lateinit var networkMapCache: NetworkMapCacheImpl
|
private lateinit var networkMapCache: NetworkMapCacheImpl
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
val baseDirectory = temporaryFolder.root.toPath()
|
|
||||||
userService = RPCUserServiceImpl(emptyList())
|
userService = RPCUserServiceImpl(emptyList())
|
||||||
config = testNodeConfiguration(
|
config = testNodeConfiguration(
|
||||||
baseDirectory = baseDirectory,
|
baseDirectory = temporaryFolder.root.toPath(),
|
||||||
myLegalName = ALICE.name)
|
myLegalName = ALICE.name)
|
||||||
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
LogHelper.setLevel(PersistentUniquenessProvider::class)
|
||||||
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock())
|
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock())
|
||||||
networkMapRegistrationFuture = doneFuture(Unit)
|
|
||||||
networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database), rigorousMock())
|
networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database), rigorousMock())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,8 +71,6 @@ class ArtemisMessagingTests {
|
|||||||
fun cleanUp() {
|
fun cleanUp() {
|
||||||
messagingClient?.stop()
|
messagingClient?.stop()
|
||||||
messagingServer?.stop()
|
messagingServer?.stop()
|
||||||
messagingClient = null
|
|
||||||
messagingServer = null
|
|
||||||
database.close()
|
database.close()
|
||||||
LogHelper.reset(PersistentUniquenessProvider::class)
|
LogHelper.reset(PersistentUniquenessProvider::class)
|
||||||
}
|
}
|
||||||
@ -120,9 +113,7 @@ class ArtemisMessagingTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `client should be able to send message to itself`() {
|
fun `client should be able to send message to itself`() {
|
||||||
val receivedMessages = LinkedBlockingQueue<Message>()
|
val (messagingClient, receivedMessages) = createAndStartClientAndServer()
|
||||||
|
|
||||||
val messagingClient = createAndStartClientAndServer(receivedMessages)
|
|
||||||
val message = messagingClient.createMessage(TOPIC, data = "first msg".toByteArray())
|
val message = messagingClient.createMessage(TOPIC, data = "first msg".toByteArray())
|
||||||
messagingClient.send(message, messagingClient.myAddress)
|
messagingClient.send(message, messagingClient.myAddress)
|
||||||
|
|
||||||
@ -132,76 +123,45 @@ class ArtemisMessagingTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `client should be able to send message to itself before network map is available, and receive after`() {
|
fun `platform version is included in the message`() {
|
||||||
val settableFuture = openFuture<Unit>()
|
val (messagingClient, receivedMessages) = createAndStartClientAndServer(platformVersion = 3)
|
||||||
networkMapRegistrationFuture = settableFuture
|
|
||||||
|
|
||||||
val receivedMessages = LinkedBlockingQueue<Message>()
|
|
||||||
|
|
||||||
val messagingClient = createAndStartClientAndServer(receivedMessages)
|
|
||||||
val message = messagingClient.createMessage(TOPIC, data = "first msg".toByteArray())
|
val message = messagingClient.createMessage(TOPIC, data = "first msg".toByteArray())
|
||||||
messagingClient.send(message, messagingClient.myAddress)
|
messagingClient.send(message, messagingClient.myAddress)
|
||||||
|
|
||||||
settableFuture.set(Unit)
|
val received = receivedMessages.take()
|
||||||
val firstActual: Message = receivedMessages.take()
|
assertThat(received.platformVersion).isEqualTo(3)
|
||||||
assertEquals("first msg", String(firstActual.data))
|
|
||||||
assertNull(receivedMessages.poll(200, MILLISECONDS))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `client should be able to send large numbers of messages to itself before network map is available and survive restart, then receive messages`() {
|
|
||||||
// Crank the iteration up as high as you want... just takes longer to run.
|
|
||||||
val iterations = 100
|
|
||||||
networkMapRegistrationFuture = openFuture()
|
|
||||||
|
|
||||||
val receivedMessages = LinkedBlockingQueue<Message>()
|
|
||||||
|
|
||||||
val messagingClient = createAndStartClientAndServer(receivedMessages)
|
|
||||||
for (iter in 1..iterations) {
|
|
||||||
val message = messagingClient.createMessage(TOPIC, data = "first msg $iter".toByteArray())
|
|
||||||
messagingClient.send(message, messagingClient.myAddress)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop client and server and create afresh.
|
|
||||||
messagingClient.stop()
|
|
||||||
messagingServer?.stop()
|
|
||||||
|
|
||||||
networkMapRegistrationFuture = doneFuture(Unit)
|
|
||||||
|
|
||||||
createAndStartClientAndServer(receivedMessages)
|
|
||||||
for (iter in 1..iterations) {
|
|
||||||
val firstActual: Message = receivedMessages.take()
|
|
||||||
assertThat(String(firstActual.data)).isEqualTo("first msg $iter")
|
|
||||||
}
|
|
||||||
assertNull(receivedMessages.poll(200, MILLISECONDS))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startNodeMessagingClient() {
|
private fun startNodeMessagingClient() {
|
||||||
messagingClient!!.start()
|
messagingClient!!.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createAndStartClientAndServer(receivedMessages: LinkedBlockingQueue<Message>): P2PMessagingClient {
|
private fun createAndStartClientAndServer(platformVersion: Int = 1): Pair<P2PMessagingClient, BlockingQueue<ReceivedMessage>> {
|
||||||
|
val receivedMessages = LinkedBlockingQueue<ReceivedMessage>()
|
||||||
|
|
||||||
createMessagingServer().start()
|
createMessagingServer().start()
|
||||||
|
|
||||||
val messagingClient = createMessagingClient()
|
val messagingClient = createMessagingClient(platformVersion = platformVersion)
|
||||||
startNodeMessagingClient()
|
startNodeMessagingClient()
|
||||||
messagingClient.addMessageHandler(TOPIC) { message, _ ->
|
messagingClient.addMessageHandler(TOPIC) { message, _ ->
|
||||||
receivedMessages.add(message)
|
receivedMessages.add(message)
|
||||||
}
|
}
|
||||||
// Run after the handlers are added, otherwise (some of) the messages get delivered and discarded / dead-lettered.
|
// Run after the handlers are added, otherwise (some of) the messages get delivered and discarded / dead-lettered.
|
||||||
thread { messagingClient.run() }
|
thread(isDaemon = true) { messagingClient.run() }
|
||||||
return messagingClient
|
|
||||||
|
return Pair(messagingClient, receivedMessages)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createMessagingClient(server: NetworkHostAndPort = NetworkHostAndPort("localhost", serverPort)): P2PMessagingClient {
|
private fun createMessagingClient(server: NetworkHostAndPort = NetworkHostAndPort("localhost", serverPort), platformVersion: Int = 1): P2PMessagingClient {
|
||||||
return database.transaction {
|
return database.transaction {
|
||||||
P2PMessagingClient(
|
P2PMessagingClient(
|
||||||
config,
|
config,
|
||||||
MOCK_VERSION_INFO,
|
MOCK_VERSION_INFO.copy(platformVersion = platformVersion),
|
||||||
server,
|
server,
|
||||||
identity.public,
|
identity.public,
|
||||||
ServiceAffinityExecutor("ArtemisMessagingTests", 1),
|
ServiceAffinityExecutor("ArtemisMessagingTests", 1),
|
||||||
database).apply {
|
database
|
||||||
|
).apply {
|
||||||
config.configureWithDevSSLCertificate()
|
config.configureWithDevSSLCertificate()
|
||||||
messagingClient = this
|
messagingClient = this
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import net.corda.node.internal.NodeStartup
|
|||||||
import net.corda.testing.DUMMY_BANK_A
|
import net.corda.testing.DUMMY_BANK_A
|
||||||
import net.corda.testing.DUMMY_NOTARY
|
import net.corda.testing.DUMMY_NOTARY
|
||||||
import net.corda.testing.DUMMY_REGULATOR
|
import net.corda.testing.DUMMY_REGULATOR
|
||||||
import net.corda.testing.ProjectStructure.projectRootDir
|
import net.corda.testing.common.internal.ProjectStructure.projectRootDir
|
||||||
import net.corda.testing.node.NotarySpec
|
import net.corda.testing.node.NotarySpec
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
@ -21,7 +21,8 @@ class NodeProcess(
|
|||||||
private val node: Process,
|
private val node: Process,
|
||||||
private val client: CordaRPCClient
|
private val client: CordaRPCClient
|
||||||
) : AutoCloseable {
|
) : AutoCloseable {
|
||||||
private companion object {
|
companion object {
|
||||||
|
const val CORDAPPS_DIR_NAME = "cordapps"
|
||||||
private val log = contextLogger()
|
private val log = contextLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,9 +43,11 @@ class NodeProcess(
|
|||||||
(nodeDir / "artemis").toFile().deleteRecursively()
|
(nodeDir / "artemis").toFile().deleteRecursively()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO All use of this factory have duplicate code which is either bundling the calling module or a 3rd party module
|
||||||
|
// as a CorDapp for the nodes.
|
||||||
class Factory(
|
class Factory(
|
||||||
private val buildDirectory: Path = Paths.get("build"),
|
val buildDirectory: Path = Paths.get("build"),
|
||||||
private val cordaJar: Path = Paths.get(this::class.java.getResource("/corda.jar").toURI())
|
val cordaJar: Path = Paths.get(this::class.java.getResource("/corda.jar").toURI())
|
||||||
) {
|
) {
|
||||||
private companion object {
|
private companion object {
|
||||||
val javaPath: Path = Paths.get(System.getProperty("java.home"), "bin", "java")
|
val javaPath: Path = Paths.get(System.getProperty("java.home"), "bin", "java")
|
||||||
@ -71,36 +74,37 @@ class NodeProcess(
|
|||||||
|
|
||||||
val process = startNode(nodeDir)
|
val process = startNode(nodeDir)
|
||||||
val client = CordaRPCClient(NetworkHostAndPort("localhost", config.rpcPort))
|
val client = CordaRPCClient(NetworkHostAndPort("localhost", config.rpcPort))
|
||||||
val user = config.users[0]
|
waitForNode(process, config, client)
|
||||||
|
return NodeProcess(config, nodeDir, process, client)
|
||||||
|
}
|
||||||
|
|
||||||
val setupExecutor = Executors.newSingleThreadScheduledExecutor()
|
private fun waitForNode(process: Process, config: NodeConfig, client: CordaRPCClient) {
|
||||||
|
val executor = Executors.newSingleThreadScheduledExecutor()
|
||||||
try {
|
try {
|
||||||
setupExecutor.scheduleWithFixedDelay({
|
executor.scheduleWithFixedDelay({
|
||||||
try {
|
try {
|
||||||
if (!process.isAlive) {
|
if (!process.isAlive) {
|
||||||
log.error("Node '${config.commonName}' has died.")
|
log.error("Node '${config.commonName}' has died.")
|
||||||
return@scheduleWithFixedDelay
|
return@scheduleWithFixedDelay
|
||||||
}
|
}
|
||||||
val conn = client.start(user.username, user.password)
|
val rpcConnection = config.users[0].let { client.start(it.username, it.password) }
|
||||||
conn.close()
|
rpcConnection.close()
|
||||||
|
|
||||||
// Cancel the "setup" task now that we've created the RPC client.
|
// Cancel the "setup" task now that we've created the RPC client.
|
||||||
setupExecutor.shutdown()
|
executor.shutdown()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.warn("Node '{}' not ready yet (Error: {})", config.commonName, e.message)
|
log.warn("Node '{}' not ready yet (Error: {})", config.commonName, e.message)
|
||||||
}
|
}
|
||||||
}, 5, 1, SECONDS)
|
}, 5, 1, SECONDS)
|
||||||
|
|
||||||
val setupOK = setupExecutor.awaitTermination(120, SECONDS)
|
val setupOK = executor.awaitTermination(120, SECONDS)
|
||||||
check(setupOK && process.isAlive) { "Failed to create RPC connection" }
|
check(setupOK && process.isAlive) { "Failed to create RPC connection" }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
process.destroyForcibly()
|
process.destroyForcibly()
|
||||||
throw e
|
throw e
|
||||||
} finally {
|
} finally {
|
||||||
setupExecutor.shutdownNow()
|
executor.shutdownNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
return NodeProcess(config, nodeDir, process, client)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startNode(nodeDir: Path): Process {
|
private fun startNode(nodeDir: Path): Process {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package net.corda.testing
|
package net.corda.testing.common.internal
|
||||||
|
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
import net.corda.core.internal.isDirectory
|
import net.corda.core.internal.isDirectory
|
Loading…
x
Reference in New Issue
Block a user