From b2148354a59820d96ca31a8aa9a0c2104df628e3 Mon Sep 17 00:00:00 2001 From: LankyDan Date: Wed, 12 Jun 2019 10:31:15 +0100 Subject: [PATCH] ENT-3496 Improve test to check for zip and json file existence --- .../shell/InteractiveShellIntegrationTest.kt | 93 +++++++++++++------ 1 file changed, 66 insertions(+), 27 deletions(-) diff --git a/tools/shell/src/integration-test/kotlin/net/corda/tools/shell/InteractiveShellIntegrationTest.kt b/tools/shell/src/integration-test/kotlin/net/corda/tools/shell/InteractiveShellIntegrationTest.kt index bf0a868e33..0fa062553b 100644 --- a/tools/shell/src/integration-test/kotlin/net/corda/tools/shell/InteractiveShellIntegrationTest.kt +++ b/tools/shell/src/integration-test/kotlin/net/corda/tools/shell/InteractiveShellIntegrationTest.kt @@ -1,5 +1,6 @@ package net.corda.tools.shell +import co.paralleluniverse.fibers.Suspendable import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.type.TypeFactory import com.google.common.io.Files @@ -10,14 +11,16 @@ import com.nhaarman.mockito_kotlin.doAnswer import com.nhaarman.mockito_kotlin.mock import net.corda.client.jackson.JacksonSupport import net.corda.client.rpc.RPCException -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.StartableByRPC +import net.corda.core.flows.* +import net.corda.core.identity.Party import net.corda.core.internal.div import net.corda.core.internal.messaging.InternalCordaRPCOps import net.corda.core.messaging.ClientRpcSslOptions import net.corda.core.messaging.CordaRPCOps +import net.corda.core.messaging.startFlow import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.getOrThrow +import net.corda.core.utilities.unwrap import net.corda.node.services.Permissions import net.corda.node.services.Permissions.Companion.all import net.corda.node.services.config.shell.toShellConfig @@ -26,6 +29,8 @@ import net.corda.node.utilities.saveToKeyStore import net.corda.node.utilities.saveToTrustStore import net.corda.nodeapi.BrokerRpcSslOptions import net.corda.testing.core.ALICE_NAME +import net.corda.testing.core.BOB_NAME +import net.corda.testing.core.singleIdentity import net.corda.testing.driver.DriverParameters import net.corda.testing.driver.driver import net.corda.testing.driver.internal.NodeHandleInternal @@ -42,8 +47,10 @@ import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder +import java.util.zip.ZipFile import javax.security.auth.x500.X500Principal import kotlin.test.assertNotEquals +import kotlin.test.assertNotNull import kotlin.test.assertTrue class InteractiveShellIntegrationTest { @@ -290,30 +297,6 @@ class InteractiveShellIntegrationTest { assertThat(successful).isTrue() } - @Test - fun `can run dumpCheckpoints`() { - val user = User("u", "p", setOf(all())) - driver(DriverParameters(notarySpecs = emptyList())) { - val nodeFuture = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user), startInSameProcess = true) - val node = nodeFuture.getOrThrow() - - val conf = ShellConfiguration(commandsDirectory = Files.createTempDir().toPath(), - user = user.username, password = user.password, - hostAndPort = node.rpcAddress) - InteractiveShell.startShell(conf) - // setup and configure some mocks required by InteractiveShell.runFlowByNameFragment() - val output = mock { - on { println(any()) } doAnswer { - val line = it.arguments[0] - assertNotEquals("Please try 'man run' to learn what syntax is acceptable", line) - } - } - // can call without causing any errors, no output to easily check - InteractiveShell.runRPCFromString( - listOf("dumpCheckpoints"), output, mock(), node.rpc as InternalCordaRPCOps, inputObjectMapper) - } - } - @Test fun `shell should start flow with unique un-qualified class name`() { val user = User("u", "p", setOf(all())) @@ -410,6 +393,41 @@ class InteractiveShellIntegrationTest { assertThat(successful).isTrue() } + @Test + fun `dumpCheckpoints creates zip with json file for suspended flow`() { + val user = User("u", "p", setOf(all())) + driver(DriverParameters(notarySpecs = emptyList())) { + val aliceNode = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user), startInSameProcess = true).getOrThrow() + val bobNode = startNode(providedName = BOB_NAME, rpcUsers = listOf(user), startInSameProcess = true).getOrThrow() + bobNode.stop() + + val conf = ShellConfiguration(commandsDirectory = Files.createTempDir().toPath(), + user = user.username, password = user.password, + hostAndPort = aliceNode.rpcAddress) + InteractiveShell.startShell(conf) + // setup and configure some mocks required by InteractiveShell.runFlowByNameFragment() + val output = mock { + on { println(any()) } doAnswer { + val line = it.arguments[0] + assertNotEquals("Please try 'man run' to learn what syntax is acceptable", line) + } + } + + aliceNode.rpc.startFlow(::SendFlow, bobNode.nodeInfo.singleIdentity()) + + InteractiveShell.runRPCFromString( + listOf("dumpCheckpoints"), output, mock(), aliceNode.rpc as InternalCordaRPCOps, inputObjectMapper) + + // assert that the checkpoint dump zip has been created + val zip = (aliceNode.baseDirectory / "logs").toFile().list().find { it.contains("checkpoints_dump-") } + assertNotNull(zip) + // assert that a json file has been created for the suspended flow + val json = ZipFile((aliceNode.baseDirectory / "logs" / zip!!).toFile()).entries().asSequence() + .find { it.name.contains(SendFlow::class.simpleName!!) } + assertNotNull(json) + } + } + private fun objectMapperWithClassLoader(classLoader: ClassLoader?): ObjectMapper { val objectMapper = JacksonSupport.createNonRpcMapper() val tf = TypeFactory.defaultInstance().withClassLoader(classLoader) @@ -444,4 +462,25 @@ class BurbleFlow : FlowLogic() { override fun call() { println("NO OP! (Burble)") } -} \ No newline at end of file +} + +@StartableByRPC +@InitiatingFlow +class SendFlow(private val party: Party) : FlowLogic() { + override val progressTracker = ProgressTracker() + @Suspendable + override fun call() { + initiateFlow(party).sendAndReceive("hi").unwrap { it } + } +} + +@InitiatedBy(SendFlow::class) +class ReceiveFlow(private val session: FlowSession) : FlowLogic() { + override val progressTracker = ProgressTracker() + @Suspendable + override fun call() { + session.receive().unwrap { it } + session.send("hi") + } +} +