Skip to content

Commit

Permalink
Added tests to make sure the platform version is correctly available
Browse files Browse the repository at this point in the history
  • Loading branch information
shamsasari committed Nov 27, 2017
1 parent 2ceb628 commit 4ca54b7
Showing 12 changed files with 125 additions and 85 deletions.
3 changes: 1 addition & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -6,8 +6,7 @@ buildscript {
// Our version: bump this on release.
ext.corda_release_version = "3.0-SNAPSHOT"
// 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 = 2
ext.corda_platform_version = constants.getProperty("platformVersion")
ext.gradle_plugins_version = constants.getProperty("gradlePluginsVersion")

// Dependency versions. Can run 'gradle dependencyUpdates' to find new versions of things.
Original file line number Diff line number Diff line change
@@ -74,7 +74,7 @@ public void done() {
}

private void copyFinanceCordapp() {
Path cordappsDir = (factory.baseDirectory(notaryConfig).resolve("cordapps"));
Path cordappsDir = (factory.baseDirectory(notaryConfig).resolve(NodeProcess.CORDAPPS_DIR_NAME));
try {
Files.createDirectories(cordappsDir);
} catch (IOException ex) {
Original file line number Diff line number Diff line change
@@ -86,7 +86,7 @@ class StandaloneCordaRPClientTest {
}

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
val financeJar = Paths.get("build", "resources", "smokeTest").list {
it.filter { "corda-finance" in it.toString() }.toList().single()
1 change: 1 addition & 0 deletions constants.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
gradlePluginsVersion=2.0.9
kotlinVersion=1.1.60
platformVersion=2
guavaVersion=21.0
bouncycastleVersion=1.57
typesafeConfigVersion=1.3.1
75 changes: 75 additions & 0 deletions core/src/smoke-test/kotlin/net/corda/core/NodeVersioningTest.kt
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ import net.corda.core.utilities.unwrap
import net.corda.nodeapi.User
import net.corda.smoketesting.NodeConfig
import net.corda.smoketesting.NodeProcess
import net.corda.smoketesting.NodeProcess.Companion.CORDAPPS_DIR_NAME
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import java.nio.file.Paths
@@ -22,7 +23,6 @@ import kotlin.streams.toList

class CordappSmokeTest {
private companion object {
private const val CORDAPPS_DIR_NAME = "cordapps"
val user = User("user1", "test", permissions = setOf("ALL"))
val port = AtomicInteger(15100)
}
@@ -38,7 +38,6 @@ class CordappSmokeTest {
users = listOf(user)
)


@Test
fun `FlowContent appName returns the filename of the CorDapp jar`() {
val cordappsDir = (factory.baseDirectory(aliceConfig) / CORDAPPS_DIR_NAME).createDirectories()
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ import net.corda.node.internal.NodeStartup
import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.nodeapi.User
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 org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
Original file line number Diff line number Diff line change
@@ -190,11 +190,13 @@ fun <M : Any> MessagingService.onNext(topic: String, sessionId: Long): CordaFutu
return messageFuture
}

fun MessagingService.send(topic: String, sessionID: Long, payload: Any, to: MessageRecipients, uuid: UUID = UUID.randomUUID())
= send(TopicSession(topic, sessionID), payload, to, uuid)
fun MessagingService.send(topic: String, sessionID: Long, payload: Any, to: MessageRecipients, uuid: UUID = UUID.randomUUID()) {
send(TopicSession(topic, sessionID), payload, to, uuid)
}

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

interface MessageHandlerRegistration

Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package net.corda.node.services.messaging

import net.corda.core.concurrent.CordaFuture
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.node.services.RPCUserService
import net.corda.node.services.RPCUserServiceImpl
@@ -27,13 +24,13 @@ import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import java.net.ServerSocket
import java.util.concurrent.BlockingQueue
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.TimeUnit.MILLISECONDS
import kotlin.concurrent.thread
import kotlin.test.assertEquals
import kotlin.test.assertNull

//TODO This needs to be merged into P2PMessagingTest as that creates a more realistic environment
class ArtemisMessagingTests {
companion object {
const val TOPIC = "platform.self"
@@ -54,30 +51,26 @@ class ArtemisMessagingTests {
private lateinit var config: NodeConfiguration
private lateinit var database: CordaPersistence
private lateinit var userService: RPCUserService
private lateinit var networkMapRegistrationFuture: CordaFuture<Unit>
private var messagingClient: P2PMessagingClient? = null
private var messagingServer: ArtemisMessagingServer? = null

private lateinit var networkMapCache: NetworkMapCacheImpl

@Before
fun setUp() {
val baseDirectory = temporaryFolder.root.toPath()
userService = RPCUserServiceImpl(emptyList())
config = testNodeConfiguration(
baseDirectory = baseDirectory,
baseDirectory = temporaryFolder.root.toPath(),
myLegalName = ALICE.name)
LogHelper.setLevel(PersistentUniquenessProvider::class)
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock())
networkMapRegistrationFuture = doneFuture(Unit)
networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database), rigorousMock())
}

@After
fun cleanUp() {
messagingClient?.stop()
messagingServer?.stop()
messagingClient = null
messagingServer = null
database.close()
LogHelper.reset(PersistentUniquenessProvider::class)
}
@@ -120,9 +113,7 @@ class ArtemisMessagingTests {

@Test
fun `client should be able to send message to itself`() {
val receivedMessages = LinkedBlockingQueue<Message>()

val messagingClient = createAndStartClientAndServer(receivedMessages)
val (messagingClient, receivedMessages) = createAndStartClientAndServer()
val message = messagingClient.createMessage(TOPIC, data = "first msg".toByteArray())
messagingClient.send(message, messagingClient.myAddress)

@@ -132,76 +123,45 @@ class ArtemisMessagingTests {
}

@Test
fun `client should be able to send message to itself before network map is available, and receive after`() {
val settableFuture = openFuture<Unit>()
networkMapRegistrationFuture = settableFuture

val receivedMessages = LinkedBlockingQueue<Message>()

val messagingClient = createAndStartClientAndServer(receivedMessages)
fun `platform version is included in the message`() {
val (messagingClient, receivedMessages) = createAndStartClientAndServer(platformVersion = 3)
val message = messagingClient.createMessage(TOPIC, data = "first msg".toByteArray())
messagingClient.send(message, messagingClient.myAddress)

settableFuture.set(Unit)
val firstActual: Message = receivedMessages.take()
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))
val received = receivedMessages.take()
assertThat(received.platformVersion).isEqualTo(3)
}

private fun startNodeMessagingClient() {
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()

val messagingClient = createMessagingClient()
val messagingClient = createMessagingClient(platformVersion = platformVersion)
startNodeMessagingClient()
messagingClient.addMessageHandler(TOPIC) { message, _ ->
receivedMessages.add(message)
}
// Run after the handlers are added, otherwise (some of) the messages get delivered and discarded / dead-lettered.
thread { messagingClient.run() }
return messagingClient
thread(isDaemon = true) { messagingClient.run() }

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 {
P2PMessagingClient(
config,
MOCK_VERSION_INFO,
MOCK_VERSION_INFO.copy(platformVersion = platformVersion),
server,
identity.public,
ServiceAffinityExecutor("ArtemisMessagingTests", 1),
database).apply {
database
).apply {
config.configureWithDevSSLCertificate()
messagingClient = this
}
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import net.corda.node.internal.NodeStartup
import net.corda.testing.DUMMY_BANK_A
import net.corda.testing.DUMMY_NOTARY
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 org.assertj.core.api.Assertions.assertThat
import org.junit.Test
Loading
Oops, something went wrong.

0 comments on commit 4ca54b7

Please sign in to comment.