From 8e61d11a4922bd367c4f732b68fe3b452a9847dd Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Tue, 8 Jan 2019 11:55:23 +0000 Subject: [PATCH] CORDA-2399: Samples using public TestCordapp API rather than internal one (#4521) Also moved the contents of TestCordappUtils.kt to InternalTestUtils.kt to make it more obvious they're internal. --- .../net/corda/core/flows/FlowsInJavaTest.java | 2 +- .../test/JavaIntegrationTestingTutorial.java | 2 +- .../corda/finance/flows/CashSelectionTest.kt | 6 +- .../internal/CashConfigDataFlowTest.kt | 9 +-- .../net/corda/traderdemo/TraderDemoTest.kt | 15 +++- .../node/internal/InternalTestUtils.kt | 75 +++++++++++++++++++ .../node/internal/TestCordappsUtils.kt | 75 ------------------- .../TestResponseFlowInIsolationInJava.java | 2 +- .../node/internal/CustomCordappTest.kt | 10 +-- ...sUtilsTest.kt => InternalTestUtilsTest.kt} | 2 +- 10 files changed, 102 insertions(+), 96 deletions(-) delete mode 100644 testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/TestCordappsUtils.kt rename testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/{TestCordappsUtilsTest.kt => InternalTestUtilsTest.kt} (97%) diff --git a/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java b/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java index d90e720a873..6237084f694 100644 --- a/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java +++ b/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java @@ -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; diff --git a/docs/source/example-code/src/integration-test/java/net/corda/docs/java/tutorial/test/JavaIntegrationTestingTutorial.java b/docs/source/example-code/src/integration-test/java/net/corda/docs/java/tutorial/test/JavaIntegrationTestingTutorial.java index 2446ccf6997..c1253193f0e 100644 --- a/docs/source/example-code/src/integration-test/java/net/corda/docs/java/tutorial/test/JavaIntegrationTestingTutorial.java +++ b/docs/source/example-code/src/integration-test/java/net/corda/docs/java/tutorial/test/JavaIntegrationTestingTutorial.java @@ -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 { diff --git a/finance/workflows/src/test/kotlin/net/corda/finance/flows/CashSelectionTest.kt b/finance/workflows/src/test/kotlin/net/corda/finance/flows/CashSelectionTest.kt index 5e379489d8f..9aaa797b317 100644 --- a/finance/workflows/src/test/kotlin/net/corda/finance/flows/CashSelectionTest.kt +++ b/finance/workflows/src/test/kotlin/net/corda/finance/flows/CashSelectionTest.kt @@ -7,12 +7,12 @@ 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 @@ -20,7 +20,7 @@ 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() { diff --git a/finance/workflows/src/test/kotlin/net/corda/finance/internal/CashConfigDataFlowTest.kt b/finance/workflows/src/test/kotlin/net/corda/finance/internal/CashConfigDataFlowTest.kt index 3239a5f1bd6..1461d67b09e 100644 --- a/finance/workflows/src/test/kotlin/net/corda/finance/internal/CashConfigDataFlowTest.kt +++ b/finance/workflows/src/test/kotlin/net/corda/finance/internal/CashConfigDataFlowTest.kt @@ -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 @@ -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) } diff --git a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt index 78ea8686999..2682bafaeb3 100644 --- a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt +++ b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt @@ -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 @@ -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 @@ -37,7 +36,11 @@ class TraderDemoTest { startFlow(), startFlow(), 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)), @@ -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(), all())) val bankUser = User("user1", "test", permissions = setOf(all())) val (nodeA, nodeB, bankNode) = listOf( diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/InternalTestUtils.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/InternalTestUtils.kt index e37370bc50c..da13ab9e7fe 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/InternalTestUtils.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/InternalTestUtils.kt @@ -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 @@ -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 @@ -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 = setOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP) + +fun cordappsForPackages(vararg packageNames: String): Set = cordappsForPackages(packageNames.asList()) + +fun cordappsForPackages(packageNames: Iterable): Set { + 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): Set { + 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. */ diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/TestCordappsUtils.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/TestCordappsUtils.kt deleted file mode 100644 index 6ac1f3c216f..00000000000 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/TestCordappsUtils.kt +++ /dev/null @@ -1,75 +0,0 @@ -package net.corda.testing.node.internal - -import net.corda.testing.node.TestCordapp -import kotlin.reflect.KClass - -/** - * 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 = setOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP) - -fun cordappsForPackages(vararg packageNames: String): Set = cordappsForPackages(packageNames.asList()) - -fun cordappsForPackages(packageNames: Iterable): Set { - 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 - -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"]. - */ -fun simplifyScanPackages(scanPackages: Iterable): Set { - return scanPackages.sorted().fold(emptySet()) { soFar, packageName -> - when { - soFar.isEmpty() -> setOf(packageName) - packageName.startsWith("${soFar.last()}.") -> soFar - else -> soFar + packageName - } - } -} diff --git a/testing/node-driver/src/test/java/net/corda/testing/node/TestResponseFlowInIsolationInJava.java b/testing/node-driver/src/test/java/net/corda/testing/node/TestResponseFlowInIsolationInJava.java index 9832a68847a..64871a45aa0 100644 --- a/testing/node-driver/src/test/java/net/corda/testing/node/TestResponseFlowInIsolationInJava.java +++ b/testing/node-driver/src/test/java/net/corda/testing/node/TestResponseFlowInIsolationInJava.java @@ -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; /** diff --git a/testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/CustomCordappTest.kt b/testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/CustomCordappTest.kt index 1844ee45a0e..9d2c2097a60 100644 --- a/testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/CustomCordappTest.kt +++ b/testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/CustomCordappTest.kt @@ -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") } } @@ -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" @@ -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" ) diff --git a/testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/TestCordappsUtilsTest.kt b/testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/InternalTestUtilsTest.kt similarity index 97% rename from testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/TestCordappsUtilsTest.kt rename to testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/InternalTestUtilsTest.kt index 4aa06a0a411..92197051664 100644 --- a/testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/TestCordappsUtilsTest.kt +++ b/testing/node-driver/src/test/kotlin/net/corda/testing/node/internal/InternalTestUtilsTest.kt @@ -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()