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.
This commit is contained in:
Shams Asari 2019-01-08 11:55:23 +00:00 committed by GitHub
parent 8e0b2558ad
commit 8e61d11a49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 102 additions and 96 deletions

View File

@ -15,7 +15,7 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import static net.corda.testing.core.TestUtils.singleIdentity; 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.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;

View File

@ -32,7 +32,7 @@ import static net.corda.testing.core.ExpectKt.expectEvents;
import static net.corda.testing.core.TestConstants.ALICE_NAME; import static net.corda.testing.core.TestConstants.ALICE_NAME;
import static net.corda.testing.core.TestConstants.BOB_NAME; import static net.corda.testing.core.TestConstants.BOB_NAME;
import static net.corda.testing.driver.Driver.driver; 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; import static org.junit.Assert.assertEquals;
public class JavaIntegrationTestingTutorial { public class JavaIntegrationTestingTutorial {

View File

@ -7,12 +7,12 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS 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.AbstractCashSelection
import net.corda.finance.contracts.asset.Cash
import net.corda.finance.contracts.getCashBalance import net.corda.finance.contracts.getCashBalance
import net.corda.finance.issuedBy import net.corda.finance.issuedBy
import net.corda.testing.core.singleIdentity 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.InternalMockNetwork
import net.corda.testing.node.internal.startFlow import net.corda.testing.node.internal.startFlow
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
@ -20,7 +20,7 @@ import org.junit.After
import org.junit.Test import org.junit.Test
class CashSelectionTest { class CashSelectionTest {
private val mockNet = InternalMockNetwork(cordappsForAllNodes = cordappsForPackages("net.corda.finance"), threadPerNode = true) private val mockNet = InternalMockNetwork(cordappsForAllNodes = FINANCE_CORDAPPS, threadPerNode = true)
@After @After
fun cleanUp() { fun cleanUp() {

View File

@ -1,13 +1,12 @@
package net.corda.finance.internal package net.corda.finance.internal
import net.corda.core.internal.packageName
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.finance.EUR import net.corda.finance.EUR
import net.corda.finance.USD import net.corda.finance.USD
import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetworkParameters import net.corda.testing.node.MockNetworkParameters
import net.corda.testing.node.MockNodeParameters 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.assertj.core.api.Assertions.assertThat
import org.junit.After import org.junit.After
import org.junit.Test import org.junit.Test
@ -20,9 +19,9 @@ class CashConfigDataFlowTest {
@Test @Test
fun `issuable currencies read in from cordapp config`() { fun `issuable currencies read in from cordapp config`() {
val node = mockNet.createNode(MockNodeParameters(additionalCordapps = listOf( val node = mockNet.createNode(MockNodeParameters(
cordappWithPackages(javaClass.packageName).copy(config = mapOf("issuableCurrencies" to listOf("EUR", "USD"))) additionalCordapps = listOf(FINANCE_WORKFLOWS_CORDAPP.withConfig(mapOf("issuableCurrencies" to listOf("EUR", "USD"))))
))) ))
val config = node.startFlow(CashConfigDataFlow()).getOrThrow() val config = node.startFlow(CashConfigDataFlow()).getOrThrow()
assertThat(config.issuableCurrencies).containsExactly(EUR, USD) assertThat(config.issuableCurrencies).containsExactly(EUR, USD)
} }

View File

@ -1,7 +1,6 @@
package net.corda.traderdemo package net.corda.traderdemo
import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCClient
import net.corda.core.internal.packageName
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.millis 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.InProcess
import net.corda.testing.driver.OutOfProcess import net.corda.testing.driver.OutOfProcess
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
import net.corda.testing.node.TestCordapp
import net.corda.testing.node.User import net.corda.testing.node.User
import net.corda.testing.node.internal.FINANCE_CORDAPPS 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.testing.node.internal.poll
import net.corda.traderdemo.flow.CommercialPaperIssueFlow import net.corda.traderdemo.flow.CommercialPaperIssueFlow
import net.corda.traderdemo.flow.SellerFlow import net.corda.traderdemo.flow.SellerFlow
@ -37,7 +36,11 @@ class TraderDemoTest {
startFlow<CashPaymentFlow>(), startFlow<CashPaymentFlow>(),
startFlow<CommercialPaperIssueFlow>(), startFlow<CommercialPaperIssueFlow>(),
all())) 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( val (nodeA, nodeB, bankNode) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser)), startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser)),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser)), startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser)),
@ -80,7 +83,11 @@ class TraderDemoTest {
@Test @Test
fun `Test restart node during flow works properly`() { 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 demoUser = User("demo", "demo", setOf(startFlow<SellerFlow>(), all()))
val bankUser = User("user1", "test", permissions = setOf(all())) val bankUser = User("user1", "test", permissions = setOf(all()))
val (nodeA, nodeB, bankNode) = listOf( val (nodeA, nodeB, bankNode) = listOf(

View File

@ -7,6 +7,7 @@ import net.corda.core.concurrent.CordaFuture
import net.corda.core.context.InvocationContext import net.corda.core.context.InvocationContext
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.internal.FlowStateMachine import net.corda.core.internal.FlowStateMachine
import net.corda.core.internal.VisibleForTesting
import net.corda.core.internal.concurrent.openFuture import net.corda.core.internal.concurrent.openFuture
import net.corda.core.internal.times import net.corda.core.internal.times
import net.corda.core.messaging.CordaRPCOps 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.createTestSerializationEnv
import net.corda.testing.internal.inVMExecutors import net.corda.testing.internal.inVMExecutors
import net.corda.testing.node.InMemoryMessagingNetwork import net.corda.testing.node.InMemoryMessagingNetwork
import net.corda.testing.node.TestCordapp
import net.corda.testing.node.User import net.corda.testing.node.User
import net.corda.testing.node.testContext import net.corda.testing.node.testContext
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@ -37,9 +39,82 @@ import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.jar.JarOutputStream import java.util.jar.JarOutputStream
import java.util.zip.ZipEntry import java.util.zip.ZipEntry
import kotlin.reflect.KClass
private val log = LoggerFactory.getLogger("net.corda.testing.internal.InternalTestUtils") 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. * @throws ListenProcessDeathException if [listenProcess] dies before the check succeeds, i.e. the check can't succeed as intended.
*/ */

View File

@ -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<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
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<String>): Set<String> {
return scanPackages.sorted().fold(emptySet()) { soFar, packageName ->
when {
soFar.isEmpty() -> setOf(packageName)
packageName.startsWith("${soFar.last()}.") -> soFar
else -> soFar + packageName
}
}
}

View File

@ -13,7 +13,7 @@ import org.junit.rules.ExpectedException;
import java.util.concurrent.Future; 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; import static org.hamcrest.Matchers.instanceOf;
/** /**

View File

@ -17,12 +17,12 @@ class CustomCordappTest {
@Test @Test
fun `packageAsJar writes out the CorDapp info into the manifest`() { 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) val jarFile = packageAsJar(cordapp)
JarInputStream(jarFile.inputStream()).use { JarInputStream(jarFile.inputStream()).use {
assertThat(it.manifest[CordappImpl.TARGET_PLATFORM_VERSION]).isEqualTo("123") assertThat(it.manifest[CordappImpl.TARGET_PLATFORM_VERSION]).isEqualTo("123")
assertThat(it.manifest[CordappImpl.CORDAPP_CONTRACT_NAME]).isEqualTo("TestCordappsUtilsTest") assertThat(it.manifest[CordappImpl.CORDAPP_CONTRACT_NAME]).isEqualTo("CustomCordappTest")
assertThat(it.manifest[CordappImpl.CORDAPP_WORKFLOW_NAME]).isEqualTo("TestCordappsUtilsTest") assertThat(it.manifest[CordappImpl.CORDAPP_WORKFLOW_NAME]).isEqualTo("CustomCordappTest")
} }
} }
@ -31,7 +31,7 @@ class CustomCordappTest {
val entries = packageAsJarThenReadBack(cordappWithPackages("net.corda.testing.node.internal")) val entries = packageAsJarThenReadBack(cordappWithPackages("net.corda.testing.node.internal"))
assertThat(entries).contains( 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 "net/corda/testing/node/internal/resource.txt" // Make sure non-class resource files are also picked up
).doesNotContain( ).doesNotContain(
"net/corda/testing/node/MockNetworkTest.class" "net/corda/testing/node/MockNetworkTest.class"
@ -46,7 +46,7 @@ class CustomCordappTest {
val entries = packageAsJarThenReadBack(cordappWithPackages("net.corda.testing.node")) val entries = packageAsJarThenReadBack(cordappWithPackages("net.corda.testing.node"))
assertThat(entries).contains( 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/internal/resource.txt",
"net/corda/testing/node/MockNetworkTest.class" "net/corda/testing/node/MockNetworkTest.class"
) )

View File

@ -3,7 +3,7 @@ package net.corda.testing.node.internal
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.Test import org.junit.Test
class TestCordappsUtilsTest { class InternalTestUtilsTest {
@Test @Test
fun `test simplifyScanPackages`() { fun `test simplifyScanPackages`() {
assertThat(simplifyScanPackages(emptyList())).isEmpty() assertThat(simplifyScanPackages(emptyList())).isEmpty()