CORDA-3663 MockServices crashes when two of the provided packages to … (#6472)

* CORDA-3663 MockServices crashes when two of the provided packages to scan are deemed empty in 4.4 RC05

this happends when a given package is not found on the classpath. Now it is handled and an exception is thrown

* replace dummy package names in tests with valid ones

* allow empty package list for CustomCordapps and exclude those from the created jars

* detekt fix

* always true logic fix

* fix to check for empty packages instead of empty classes

* fix for classes and fixups

* logic refactor because of detekt stupidity

* PR related minor refactors
This commit is contained in:
Tamas Veingartner 2020-08-03 09:19:48 +01:00 committed by GitHub
parent c288073e7c
commit 85be50779b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 41 additions and 13 deletions

View File

@ -96,5 +96,5 @@ class FinalityFlowTests : WithFinality {
} }
/** "Old" CorDapp which will force its node to keep its FinalityHandler enabled */ /** "Old" CorDapp which will force its node to keep its FinalityHandler enabled */
private fun tokenOldCordapp() = cordappWithPackages("com.template").copy(targetPlatformVersion = 3) private fun tokenOldCordapp() = cordappWithPackages().copy(targetPlatformVersion = 3)
} }

View File

@ -6,6 +6,8 @@ import net.corda.core.context.InvocationOrigin
import net.corda.core.contracts.ContractState import net.corda.core.contracts.ContractState
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByService import net.corda.core.flows.StartableByService
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.packageName
import net.corda.core.node.AppServiceHub import net.corda.core.node.AppServiceHub
import net.corda.core.node.ServiceHub import net.corda.core.node.ServiceHub
import net.corda.core.node.services.CordaService import net.corda.core.node.services.CordaService
@ -16,12 +18,20 @@ import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
import net.corda.finance.DOLLARS import net.corda.finance.DOLLARS
import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.schemas.CashSchemaV1
import net.corda.node.internal.cordapp.DummyRPCFlow import net.corda.node.internal.cordapp.DummyRPCFlow
import net.corda.testing.core.BOC_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.TestIdentity
import net.corda.testing.internal.vault.DummyLinearStateSchemaV1
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.MockServices
import net.corda.testing.node.StartedMockNode import net.corda.testing.node.StartedMockNode
import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP
import net.corda.testing.node.internal.enclosedCordapp import net.corda.testing.node.internal.enclosedCordapp
import net.corda.testing.node.makeTestIdentityService
import org.assertj.core.api.Assertions
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
@ -100,6 +110,22 @@ class CordaServiceTest {
nodeA.services.cordaService(EntityManagerService::class.java) nodeA.services.cordaService(EntityManagerService::class.java)
} }
@Test(timeout=300_000)
fun `MockServices when initialized with package name not on classpath throws ClassNotFoundException`() {
val cordappPackages = listOf(
"com.r3.corda.sdk.tokens.money",
"net.corda.finance.contracts",
CashSchemaV1::class.packageName,
DummyLinearStateSchemaV1::class.packageName)
val bankOfCorda = TestIdentity(BOC_NAME)
val dummyCashIssuer = TestIdentity(CordaX500Name("Snake Oil Issuer", "London", "GB"), 10)
val dummyNotary = TestIdentity(DUMMY_NOTARY_NAME, 20)
val identityService = makeTestIdentityService(dummyNotary.identity)
Assertions.assertThatThrownBy { MockServices(cordappPackages, dummyNotary, identityService, dummyCashIssuer.keyPair, bankOfCorda.keyPair) }
.isInstanceOf(ClassNotFoundException::class.java).hasMessage("Could not create jar file as the given package is not found on the classpath: com.r3.corda.sdk.tokens.money")
}
@StartableByService @StartableByService
class DummyServiceFlow : FlowLogic<InvocationContext>() { class DummyServiceFlow : FlowLogic<InvocationContext>() {
companion object { companion object {

View File

@ -37,11 +37,6 @@ data class CustomCordapp(
val signingInfo: SigningInfo? = null, val signingInfo: SigningInfo? = null,
override val config: Map<String, Any> = emptyMap() override val config: Map<String, Any> = emptyMap()
) : TestCordappInternal() { ) : TestCordappInternal() {
init {
require(packages.isNotEmpty() || classes.isNotEmpty() || fixups.isNotEmpty()) {
"At least one package or class must be specified"
}
}
override val jarFile: Path get() = getJarFile(this) override val jarFile: Path get() = getJarFile(this)
@ -78,6 +73,10 @@ data class CustomCordapp(
} }
} }
if (scanResult.allResources.isEmpty()){
throw ClassNotFoundException("Could not create jar file as the given package is not found on the classpath: ${packages.toList()[0]}")
}
// The same resource may be found in different locations (this will happen when running from gradle) so just // The same resource may be found in different locations (this will happen when running from gradle) so just
// pick the first one found. // pick the first one found.
scanResult.allResources.asMap().forEach { path, resourceList -> scanResult.allResources.asMap().forEach { path, resourceList ->
@ -178,7 +177,7 @@ data class CustomCordapp(
val jarFile = cordappsDirectory.createDirectories() / filename val jarFile = cordappsDirectory.createDirectories() / filename
if (it.fixups.isNotEmpty()) { if (it.fixups.isNotEmpty()) {
it.createFixupJar(jarFile) it.createFixupJar(jarFile)
} else { } else if(it.packages.isNotEmpty() || it.classes.isNotEmpty() || it.fixups.isNotEmpty()) {
it.packageAsJar(jarFile) it.packageAsJar(jarFile)
} }
it.signJar(jarFile) it.signJar(jarFile)

View File

@ -30,14 +30,17 @@ abstract class TestCordappInternal : TestCordapp() {
// Precedence is given to node-specific CorDapps // Precedence is given to node-specific CorDapps
val allCordapps = nodeSpecificCordapps + generalCordapps.filter { it.withOnlyJarContents() !in nodeSpecificCordappsWithoutMeta } val allCordapps = nodeSpecificCordapps + generalCordapps.filter { it.withOnlyJarContents() !in nodeSpecificCordappsWithoutMeta }
// Ignore any duplicate jar files // Ignore any duplicate jar files
val jarToCordapp = allCordapps.associateBy { it.jarFile } val jarToCordapp = allCordapps.filter {
it !is CustomCordapp || it.packages.isNotEmpty() || it.classes.isNotEmpty() || it.fixups.isNotEmpty() }.associateBy { it.jarFile }
val cordappsDir = baseDirectory / "cordapps" val cordappsDir = baseDirectory / "cordapps"
val configDir = (cordappsDir / "config").createDirectories() val configDir = (cordappsDir / "config").createDirectories()
jarToCordapp.forEach { jar, cordapp -> jarToCordapp.forEach { jar, cordapp ->
try { try {
if (jar.toFile().exists()) {
jar.copyToDirectory(cordappsDir) jar.copyToDirectory(cordappsDir)
}
} catch (e: FileAlreadyExistsException) { } catch (e: FileAlreadyExistsException) {
// Ignore if the node already has the same CorDapp jar. This can happen if the node is being restarted. // Ignore if the node already has the same CorDapp jar. This can happen if the node is being restarted.
} }

View File

@ -22,7 +22,7 @@ import org.junit.Test
*/ */
class TestResponseFlowInIsolation { class TestResponseFlowInIsolation {
private val network: MockNetwork = MockNetwork(MockNetworkParameters(cordappsForAllNodes = cordappsForPackages("com.template"))) private val network: MockNetwork = MockNetwork(MockNetworkParameters(cordappsForAllNodes = cordappsForPackages()))
private val a = network.createNode() private val a = network.createNode()
private val b = network.createNode() private val b = network.createNode()

View File

@ -28,7 +28,7 @@ import static org.hamcrest.Matchers.instanceOf;
*/ */
public class TestResponseFlowInIsolationInJava { public class TestResponseFlowInIsolationInJava {
private final MockNetwork network = new MockNetwork(new MockNetworkParameters().withCordappsForAllNodes(cordappsForPackages("com.template"))); private final MockNetwork network = new MockNetwork(new MockNetworkParameters().withCordappsForAllNodes(cordappsForPackages()));
private final StartedMockNode a = network.createNode(); private final StartedMockNode a = network.createNode();
private final StartedMockNode b = network.createNode(); private final StartedMockNode b = network.createNode();