ENT-3496 Improve test to check for zip and json file existence

This commit is contained in:
LankyDan 2019-06-12 10:31:15 +01:00
parent 245a14d499
commit b2148354a5

View File

@ -1,5 +1,6 @@
package net.corda.tools.shell package net.corda.tools.shell
import co.paralleluniverse.fibers.Suspendable
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.type.TypeFactory import com.fasterxml.jackson.databind.type.TypeFactory
import com.google.common.io.Files import com.google.common.io.Files
@ -10,14 +11,16 @@ import com.nhaarman.mockito_kotlin.doAnswer
import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.mock
import net.corda.client.jackson.JacksonSupport import net.corda.client.jackson.JacksonSupport
import net.corda.client.rpc.RPCException import net.corda.client.rpc.RPCException
import net.corda.core.flows.FlowLogic import net.corda.core.flows.*
import net.corda.core.flows.StartableByRPC import net.corda.core.identity.Party
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.messaging.InternalCordaRPCOps import net.corda.core.internal.messaging.InternalCordaRPCOps
import net.corda.core.messaging.ClientRpcSslOptions import net.corda.core.messaging.ClientRpcSslOptions
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.startFlow
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.unwrap
import net.corda.node.services.Permissions import net.corda.node.services.Permissions
import net.corda.node.services.Permissions.Companion.all import net.corda.node.services.Permissions.Companion.all
import net.corda.node.services.config.shell.toShellConfig 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.node.utilities.saveToTrustStore
import net.corda.nodeapi.BrokerRpcSslOptions import net.corda.nodeapi.BrokerRpcSslOptions
import net.corda.testing.core.ALICE_NAME 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.DriverParameters
import net.corda.testing.driver.driver import net.corda.testing.driver.driver
import net.corda.testing.driver.internal.NodeHandleInternal import net.corda.testing.driver.internal.NodeHandleInternal
@ -42,8 +47,10 @@ import org.junit.Ignore
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.TemporaryFolder import org.junit.rules.TemporaryFolder
import java.util.zip.ZipFile
import javax.security.auth.x500.X500Principal import javax.security.auth.x500.X500Principal
import kotlin.test.assertNotEquals import kotlin.test.assertNotEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue import kotlin.test.assertTrue
class InteractiveShellIntegrationTest { class InteractiveShellIntegrationTest {
@ -290,30 +297,6 @@ class InteractiveShellIntegrationTest {
assertThat(successful).isTrue() 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<RenderPrintWriter> {
on { println(any<String>()) } 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 @Test
fun `shell should start flow with unique un-qualified class name`() { fun `shell should start flow with unique un-qualified class name`() {
val user = User("u", "p", setOf(all())) val user = User("u", "p", setOf(all()))
@ -410,6 +393,41 @@ class InteractiveShellIntegrationTest {
assertThat(successful).isTrue() 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<RenderPrintWriter> {
on { println(any<String>()) } 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 { private fun objectMapperWithClassLoader(classLoader: ClassLoader?): ObjectMapper {
val objectMapper = JacksonSupport.createNonRpcMapper() val objectMapper = JacksonSupport.createNonRpcMapper()
val tf = TypeFactory.defaultInstance().withClassLoader(classLoader) val tf = TypeFactory.defaultInstance().withClassLoader(classLoader)
@ -444,4 +462,25 @@ class BurbleFlow : FlowLogic<Unit>() {
override fun call() { override fun call() {
println("NO OP! (Burble)") println("NO OP! (Burble)")
} }
} }
@StartableByRPC
@InitiatingFlow
class SendFlow(private val party: Party) : FlowLogic<Unit>() {
override val progressTracker = ProgressTracker()
@Suspendable
override fun call() {
initiateFlow(party).sendAndReceive<String>("hi").unwrap { it }
}
}
@InitiatedBy(SendFlow::class)
class ReceiveFlow(private val session: FlowSession) : FlowLogic<Unit>() {
override val progressTracker = ProgressTracker()
@Suspendable
override fun call() {
session.receive<String>().unwrap { it }
session.send("hi")
}
}