Ensure Shell parsing of commands has a database, so that identity lookups can function. (#1608)

Fixup unit tests
This commit is contained in:
Matthew Nesbit 2017-09-22 16:11:45 +01:00 committed by josecoll
parent 21cb1bf6f3
commit addd3b34c8
2 changed files with 24 additions and 5 deletions

View File

@ -29,6 +29,7 @@ import net.corda.node.services.messaging.CURRENT_RPC_CONTEXT
import net.corda.node.services.messaging.RpcContext import net.corda.node.services.messaging.RpcContext
import net.corda.node.services.statemachine.FlowStateMachineImpl import net.corda.node.services.statemachine.FlowStateMachineImpl
import net.corda.node.utilities.ANSIProgressRenderer import net.corda.node.utilities.ANSIProgressRenderer
import net.corda.node.utilities.CordaPersistence
import net.corda.nodeapi.ArtemisMessagingComponent import net.corda.nodeapi.ArtemisMessagingComponent
import net.corda.nodeapi.User import net.corda.nodeapi.User
import org.crsh.command.InvocationContext import org.crsh.command.InvocationContext
@ -77,6 +78,8 @@ import kotlin.concurrent.thread
object InteractiveShell { object InteractiveShell {
private val log = loggerFor<InteractiveShell>() private val log = loggerFor<InteractiveShell>()
private lateinit var node: StartedNode<Node> private lateinit var node: StartedNode<Node>
@VisibleForTesting
internal lateinit var database: CordaPersistence
/** /**
* Starts an interactive shell connected to the local terminal. This shell gives administrator access to the node * Starts an interactive shell connected to the local terminal. This shell gives administrator access to the node
@ -84,6 +87,7 @@ object InteractiveShell {
*/ */
fun startShell(dir: Path, runLocalShell: Boolean, runSSHServer: Boolean, node: StartedNode<Node>) { fun startShell(dir: Path, runLocalShell: Boolean, runSSHServer: Boolean, node: StartedNode<Node>) {
this.node = node this.node = node
this.database = node.database
var runSSH = runSSHServer var runSSH = runSSHServer
val config = Properties() val config = Properties()
@ -287,8 +291,10 @@ object InteractiveShell {
try { try {
// Attempt construction with the given arguments. // Attempt construction with the given arguments.
val args = database.transaction {
paramNamesFromConstructor = parser.paramNamesFromConstructor(ctor) paramNamesFromConstructor = parser.paramNamesFromConstructor(ctor)
val args = parser.parseArguments(clazz.name, paramNamesFromConstructor.zip(ctor.parameterTypes), inputData) parser.parseArguments(clazz.name, paramNamesFromConstructor!!.zip(ctor.parameterTypes), inputData)
}
if (args.size != ctor.parameterTypes.size) { if (args.size != ctor.parameterTypes.size) {
errors.add("${getPrototype()}: Wrong number of arguments (${args.size} provided, ${ctor.parameterTypes.size} needed)") errors.add("${getPrototype()}: Wrong number of arguments (${args.size} provided, ${ctor.parameterTypes.size} needed)")
continue continue
@ -358,7 +364,7 @@ object InteractiveShell {
var result: Any? = null var result: Any? = null
try { try {
InputStreamSerializer.invokeContext = context InputStreamSerializer.invokeContext = context
val call = parser.parse(context.attributes["ops"] as CordaRPCOps, cmd) val call = database.transaction { parser.parse(context.attributes["ops"] as CordaRPCOps, cmd) }
result = call.call() result = call.call()
if (result != null && result !is kotlin.Unit && result !is Void) { if (result != null && result !is kotlin.Unit && result !is Void) {
result = printAndFollowRPCResponse(result, out) result = printAndFollowRPCResponse(result, out)

View File

@ -7,20 +7,33 @@ import net.corda.core.contracts.Amount
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.FlowStateMachine import net.corda.core.internal.FlowStateMachine
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
import net.corda.core.utilities.UntrustworthyData
import net.corda.node.services.identity.InMemoryIdentityService import net.corda.node.services.identity.InMemoryIdentityService
import net.corda.node.shell.InteractiveShell import net.corda.node.shell.InteractiveShell
import net.corda.node.utilities.configureDatabase
import net.corda.testing.DEV_TRUST_ROOT import net.corda.testing.DEV_TRUST_ROOT
import net.corda.testing.MEGA_CORP import net.corda.testing.MEGA_CORP
import net.corda.testing.MEGA_CORP_IDENTITY import net.corda.testing.MEGA_CORP_IDENTITY
import net.corda.testing.node.MockServices
import net.corda.testing.node.MockServices.Companion.makeTestIdentityService
import org.junit.After
import org.junit.Before
import org.junit.Test import org.junit.Test
import java.util.* import java.util.*
import kotlin.test.assertEquals import kotlin.test.assertEquals
class InteractiveShellTest { class InteractiveShellTest {
@Before
fun setup() {
InteractiveShell.database = configureDatabase(MockServices.makeTestDataSourceProperties(), MockServices.makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService)
}
@After
fun shutdown() {
InteractiveShell.database.close()
}
@Suppress("UNUSED") @Suppress("UNUSED")
class FlowA(val a: String) : FlowLogic<String>() { class FlowA(val a: String) : FlowLogic<String>() {
constructor(b: Int) : this(b.toString()) constructor(b: Int) : this(b.toString())