Skip to content

Commit

Permalink
CORDA-2399: Samples using public TestCordapp API rather than internal…
Browse files Browse the repository at this point in the history
… one (corda#4521)

Also moved the contents of TestCordappUtils.kt to InternalTestUtils.kt to make it more obvious they're internal.
  • Loading branch information
shamsasari authored Jan 8, 2019
1 parent 8e0b255 commit 8e61d11
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import java.util.concurrent.Future;

import static net.corda.testing.core.TestUtils.singleIdentity;
import static net.corda.testing.node.internal.TestCordappsUtilsKt.cordappsForPackages;
import static net.corda.testing.node.internal.InternalTestUtilsKt.cordappsForPackages;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.Assert.fail;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import static net.corda.testing.core.TestConstants.ALICE_NAME;
import static net.corda.testing.core.TestConstants.BOB_NAME;
import static net.corda.testing.driver.Driver.driver;
import static net.corda.testing.node.internal.TestCordappsUtilsKt.FINANCE_CORDAPPS;
import static net.corda.testing.node.internal.InternalTestUtilsKt.FINANCE_CORDAPPS;
import static org.junit.Assert.assertEquals;

public class JavaIntegrationTestingTutorial {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS
import net.corda.finance.contracts.asset.Cash
import net.corda.finance.contracts.asset.AbstractCashSelection
import net.corda.finance.contracts.asset.Cash
import net.corda.finance.contracts.getCashBalance
import net.corda.finance.issuedBy
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.internal.cordappsForPackages
import net.corda.testing.node.internal.FINANCE_CORDAPPS
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.startFlow
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Test

class CashSelectionTest {
private val mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.finance"), threadPerNode = true)
private val mockNet = InternalMockNetwork(cordappsForAllNodes = FINANCE_CORDAPPS, threadPerNode = true)

@After
fun cleanUp() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package net.corda.finance.internal

import net.corda.core.internal.packageName
import net.corda.core.utilities.getOrThrow
import net.corda.finance.EUR
import net.corda.finance.USD
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetworkParameters
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.internal.cordappWithPackages
import net.corda.testing.node.internal.FINANCE_WORKFLOWS_CORDAPP
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Test
Expand All @@ -20,9 +19,9 @@ class CashConfigDataFlowTest {

@Test
fun `issuable currencies read in from cordapp config`() {
val node = mockNet.createNode(MockNodeParameters(additionalCordapps = listOf(
cordappWithPackages(javaClass.packageName).copy(config = mapOf("issuableCurrencies" to listOf("EUR", "USD")))
)))
val node = mockNet.createNode(MockNodeParameters(
additionalCordapps = listOf(FINANCE_WORKFLOWS_CORDAPP.withConfig(mapOf("issuableCurrencies" to listOf("EUR", "USD"))))
))
val config = node.startFlow(CashConfigDataFlow()).getOrThrow()
assertThat(config.issuableCurrencies).containsExactly(EUR, USD)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package net.corda.traderdemo

import net.corda.client.rpc.CordaRPCClient
import net.corda.core.internal.packageName
import net.corda.core.messaging.startFlow
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.millis
Expand All @@ -18,9 +17,9 @@ import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.InProcess
import net.corda.testing.driver.OutOfProcess
import net.corda.testing.driver.driver
import net.corda.testing.node.TestCordapp
import net.corda.testing.node.User
import net.corda.testing.node.internal.FINANCE_CORDAPPS
import net.corda.testing.node.internal.cordappWithPackages
import net.corda.testing.node.internal.poll
import net.corda.traderdemo.flow.CommercialPaperIssueFlow
import net.corda.traderdemo.flow.SellerFlow
Expand All @@ -37,7 +36,11 @@ class TraderDemoTest {
startFlow<CashPaymentFlow>(),
startFlow<CommercialPaperIssueFlow>(),
all()))
driver(DriverParameters(startNodesInProcess = true, inMemoryDB = false, cordappsForAllNodes = FINANCE_CORDAPPS + cordappWithPackages(javaClass.packageName))) {
driver(DriverParameters(
startNodesInProcess = true,
inMemoryDB = false,
cordappsForAllNodes = FINANCE_CORDAPPS + TestCordapp.findCordapp("net.corda.traderdemo")
)) {
val (nodeA, nodeB, bankNode) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser)),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser)),
Expand Down Expand Up @@ -80,7 +83,11 @@ class TraderDemoTest {

@Test
fun `Test restart node during flow works properly`() {
driver(DriverParameters(startNodesInProcess = false, inMemoryDB = false, cordappsForAllNodes = FINANCE_CORDAPPS + cordappWithPackages(javaClass.packageName))) {
driver(DriverParameters(
startNodesInProcess = false,
inMemoryDB = false,
cordappsForAllNodes = FINANCE_CORDAPPS + TestCordapp.findCordapp("net.corda.traderdemo")
)) {
val demoUser = User("demo", "demo", setOf(startFlow<SellerFlow>(), all()))
val bankUser = User("user1", "test", permissions = setOf(all()))
val (nodeA, nodeB, bankNode) = listOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import net.corda.core.concurrent.CordaFuture
import net.corda.core.context.InvocationContext
import net.corda.core.flows.FlowLogic
import net.corda.core.internal.FlowStateMachine
import net.corda.core.internal.VisibleForTesting
import net.corda.core.internal.concurrent.openFuture
import net.corda.core.internal.times
import net.corda.core.messaging.CordaRPCOps
Expand All @@ -24,6 +25,7 @@ import net.corda.testing.internal.chooseIdentity
import net.corda.testing.internal.createTestSerializationEnv
import net.corda.testing.internal.inVMExecutors
import net.corda.testing.node.InMemoryMessagingNetwork
import net.corda.testing.node.TestCordapp
import net.corda.testing.node.User
import net.corda.testing.node.testContext
import org.slf4j.LoggerFactory
Expand All @@ -37,9 +39,82 @@ import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit
import java.util.jar.JarOutputStream
import java.util.zip.ZipEntry
import kotlin.reflect.KClass

private val log = LoggerFactory.getLogger("net.corda.testing.internal.InternalTestUtils")

/**
* Reference to the finance-contracts CorDapp in this repo. The metadata is taken directly from finance/contracts/build.gradle, including the
* fact that the jar is signed. If you need an unsigned jar then use `cordappWithPackages("net.corda.finance.contracts")`.
*
* You will probably need to use [FINANCE_CORDAPPS] instead to get access to the flows as well.
*/
// TODO We can't use net.corda.finance.contracts as finance-workflows contains the package net.corda.finance.contracts.asset.cash.selection. This should be renamed.
@JvmField
val FINANCE_CONTRACTS_CORDAPP: TestCordappImpl = findCordapp("net.corda.finance.schemas")

/**
* Reference to the finance-workflows CorDapp in this repo. The metadata is taken directly from finance/workflows/build.gradle, including the
* fact that the jar is signed. If you need an unsigned jar then use `cordappWithPackages("net.corda.finance.flows")`.
*
* You will probably need to use [FINANCE_CORDAPPS] instead to get access to the contract classes as well.
*/
@JvmField
val FINANCE_WORKFLOWS_CORDAPP: TestCordappImpl = findCordapp("net.corda.finance.flows")

@JvmField
val FINANCE_CORDAPPS: Set<TestCordappInternal> = setOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP)

fun cordappsForPackages(vararg packageNames: String): Set<CustomCordapp> = cordappsForPackages(packageNames.asList())

fun cordappsForPackages(packageNames: Iterable<String>): Set<CustomCordapp> {
return simplifyScanPackages(packageNames).mapTo(HashSet()) { cordappWithPackages(it) }
}

/**
* Create a *custom* CorDapp which contains all the classes and resoures located in the given packages. The CorDapp's metadata will be the
* default values as defined in the [CustomCordapp] c'tor. Use the `copy` to change them. This means the metadata will *not* be the one defined
* in the original CorDapp(s) that the given packages may represent. If this is not what you want then use [findCordapp] instead.
*/
fun cordappWithPackages(vararg packageNames: String): CustomCordapp = CustomCordapp(packages = simplifyScanPackages(packageNames.asList()))

/** Create a *custom* CorDapp which contains just the given classes. */
// TODO Rename to cordappWithClasses
fun cordappForClasses(vararg classes: Class<*>): CustomCordapp = CustomCordapp(packages = emptySet(), classes = classes.toSet())

/**
* Find the single CorDapp jar on the current classpath which contains the given package. This is a convenience method for
* [TestCordapp.findCordapp] but returns the internal [TestCordappImpl].
*/
fun findCordapp(scanPackage: String): TestCordappImpl = TestCordapp.findCordapp(scanPackage) as TestCordappImpl

private fun getCallerClass(directCallerClass: KClass<*>): Class<*>? {
val stackTrace = Throwable().stackTrace
val index = stackTrace.indexOfLast { it.className == directCallerClass.java.name }
if (index == -1) return null
return try {
Class.forName(stackTrace[index + 1].className)
} catch (e: ClassNotFoundException) {
null
}
}

fun getCallerPackage(directCallerClass: KClass<*>): String? = getCallerClass(directCallerClass)?.`package`?.name

/**
* Squashes child packages if the parent is present. Example: ["com.foo", "com.foo.bar"] into just ["com.foo"].
*/
@VisibleForTesting
internal fun simplifyScanPackages(scanPackages: Iterable<String>): Set<String> {
return scanPackages.sorted().fold(emptySet()) { soFar, packageName ->
when {
soFar.isEmpty() -> setOf(packageName)
packageName.startsWith("${soFar.last()}.") -> soFar
else -> soFar + packageName
}
}
}

/**
* @throws ListenProcessDeathException if [listenProcess] dies before the check succeeds, i.e. the check can't succeed as intended.
*/
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

import java.util.concurrent.Future;

import static net.corda.testing.node.internal.TestCordappsUtilsKt.cordappsForPackages;
import static net.corda.testing.node.internal.InternalTestUtilsKt.cordappsForPackages;
import static org.hamcrest.Matchers.instanceOf;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ class CustomCordappTest {

@Test
fun `packageAsJar writes out the CorDapp info into the manifest`() {
val cordapp = cordappWithPackages("net.corda.testing.node.internal").copy(targetPlatformVersion = 123, name = "TestCordappsUtilsTest")
val cordapp = cordappWithPackages("net.corda.testing.node.internal").copy(targetPlatformVersion = 123, name = "CustomCordappTest")
val jarFile = packageAsJar(cordapp)
JarInputStream(jarFile.inputStream()).use {
assertThat(it.manifest[CordappImpl.TARGET_PLATFORM_VERSION]).isEqualTo("123")
assertThat(it.manifest[CordappImpl.CORDAPP_CONTRACT_NAME]).isEqualTo("TestCordappsUtilsTest")
assertThat(it.manifest[CordappImpl.CORDAPP_WORKFLOW_NAME]).isEqualTo("TestCordappsUtilsTest")
assertThat(it.manifest[CordappImpl.CORDAPP_CONTRACT_NAME]).isEqualTo("CustomCordappTest")
assertThat(it.manifest[CordappImpl.CORDAPP_WORKFLOW_NAME]).isEqualTo("CustomCordappTest")
}
}

Expand All @@ -31,7 +31,7 @@ class CustomCordappTest {
val entries = packageAsJarThenReadBack(cordappWithPackages("net.corda.testing.node.internal"))

assertThat(entries).contains(
"net/corda/testing/node/internal/TestCordappsUtilsTest.class",
"net/corda/testing/node/internal/CustomCordappTest.class",
"net/corda/testing/node/internal/resource.txt" // Make sure non-class resource files are also picked up
).doesNotContain(
"net/corda/testing/node/MockNetworkTest.class"
Expand All @@ -46,7 +46,7 @@ class CustomCordappTest {
val entries = packageAsJarThenReadBack(cordappWithPackages("net.corda.testing.node"))

assertThat(entries).contains(
"net/corda/testing/node/internal/TestCordappsUtilsTest.class",
"net/corda/testing/node/internal/CustomCordappTest.class",
"net/corda/testing/node/internal/resource.txt",
"net/corda/testing/node/MockNetworkTest.class"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package net.corda.testing.node.internal
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test

class TestCordappsUtilsTest {
class InternalTestUtilsTest {
@Test
fun `test simplifyScanPackages`() {
assertThat(simplifyScanPackages(emptyList())).isEmpty()
Expand Down

0 comments on commit 8e61d11

Please sign in to comment.