温馨提示:本文翻译自stackoverflow.com,查看原文请点击:其他 - Corda debugging flow tests in MockNetwork with Accounts
corda

其他 - 带帐户的MockNetwork中的Corda调试流程测试

发布于 2020-04-09 10:20:41

还是Corda的新手。

我想通过MockNetwork运行Corda Accounts SupplyChain示例,以便调试流程。为此,我需要创建帐户并运行SendInvoice流。这是我的流量测试

class FlowTests {
    private lateinit var network: MockNetwork
    private lateinit var buyer: StartedMockNode
    private lateinit var seller: StartedMockNode
    private lateinit var shippingCo: StartedMockNode

    @Before
    fun setup() {

        network = MockNetwork(MockNetworkParameters( networkParameters = testNetworkParameters(minimumPlatformVersion = 4),
                cordappsForAllNodes = listOf(
                        TestCordapp.findCordapp("com.accounts_SupplyChain.contracts"),
                        TestCordapp.findCordapp("com.accounts_SupplyChain.flows"),
                        TestCordapp.findCordapp("com.accounts_SupplyChain.schemas"),
                        TestCordapp.findCordapp("com.r3.corda.lib.accounts.contracts"),
                        // This CorDapp has the missing service from your error message.
                        TestCordapp.findCordapp("com.r3.corda.lib.accounts.workflows"),
                        TestCordapp.findCordapp("com.r3.corda.lib.ci")
                )))

        buyer = network.createPartyNode()
        seller = network.createPartyNode()
        shippingCo = network.createPartyNode()
        listOf(buyer,seller,shippingCo).forEach {it.registerInitiatedFlow(SendInvoiceResponder::class.java)}
        network.runNetwork()

    }
    @After
    fun tearDown() {
        network.stopNodes()
    }



    @Test
    fun Test1() {
        // Create Buyer Account
        val flow1 = CreateNewAccount("BuyerProcurement")
        val  future1  = buyer.startFlow(flow1);

        // Share the account
        val flow3 = ShareAccountTo("BuyerProcurement", shareTo = seller.info.singleIdentity())
        val future3 = buyer.startFlow(flow3)


        // On Seller Node
        val flow7 = CreateNewAccount("SellerSales")
        val future7 = seller.startFlow(flow7)

        val flow10 = ShareAccountTo("SellerSales", shareTo =  buyer.info.singleIdentity())
        val future10 = seller.startFlow(flow10)

        // Check the accounts are created on the buyer node
        val flowView = ViewMyAccounts()
        val fut = buyer.startFlow(flowView)

        // Check the accounts are creted on the seller Node
        val flowView2 = ViewMyAccounts()
        val fut2 = seller.startFlow(flowView)

        // Now send an Invoice
        val sendInvoice = SendInvoice(whoAmI = "SellerSales",whereTo = "BuyerProcurement", amount = 500)
        val futureSendInvoice = seller.startFlow(sendInvoice)

        network.runNetwork()

        val resp1= future1.getOrThrow()
        println(resp1.toString())
        val resp2 = future7.getOrThrow()
        println(resp2.toString())


        val buyerAccounts = fut.getOrThrow()
        println(buyerAccounts.toString())

        val sellerAccounts= fut2.getOrThrow()
        println(sellerAccounts.toString())

        // Get the invoice Created
        val invoiceCreation = futureSendInvoice.getOrThrow()
        println(invoiceCreation.toString())

    }
}

不是很优雅,但这只是一个测试。

我得到的答复是:

BuyerProcurement team's account was created. UUID is : 60d91f03-4112-4c2a-801b-95fe4297bf3b

SellerSales team's account was created. UUID is : 09a4a089-2a98-4148-a00d-252438d816f1

[BuyerProcurement]

[SellerSales]

所以我认为帐户已创建(可能不是!)。但是,在运行流程时:

 val flow10 = ShareAccountTo("SellerSales", shareTo =  buyer.info.singleIdentity())
 val future10 = seller.startFlow(flow10)

我得到一个错误:

java.util.NoSuchElementException: List is empty.

    at kotlin.collections.CollectionsKt___CollectionsKt.single(_Collections.kt:478)
    at com.accounts_SupplyChain.flows.SendInvoice.call(SendInvoice.kt:67)
    at com.accounts_SupplyChain.flows.SendInvoice.call(SendInvoice.kt:26)
    at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:270)
    at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:46)
    at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)
    at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)
    at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100)
    at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63)

在SendInvoice.kt中设置断点,我发现这是由于尝试获取targetAccount(BuyerProcurement)引起的:

   @Suspendable
    override fun call(): String {

        //Generate key for transaction
        progressTracker.currentStep = GENERATING_KEYS
        val myAccount = accountService.accountInfo(whoAmI).single().state.data
        val myKey = subFlow(NewKeyForAccount(myAccount.identifier.id)).owningKey

/// ERROR HERE //////
        val targetAccount = accountService.accountInfo(whereTo).single().state.data
        val targetAcctAnonymousParty = subFlow(RequestKeyForAccount(targetAccount))



        //generating State for transfer
        progressTracker.currentStep = GENERATING_TRANSACTION
        val output = InvoiceState(amount, AnonymousParty(myKey),targetAcctAnonymousParty,UUID.randomUUID())
        val transactionBuilder = TransactionBuilder(serviceHub.networkMapCache.notaryIdentities.first())
        transactionBuilder.addOutputState(output)
                .addCommand(InvoiceStateContract.Commands.Create(), listOf(targetAcctAnonymousParty.owningKey,myKey))

有没有人有任何想法。我需要能够单步执行我的流程,以确定为什么它们无法完成。

查看更多

提问者
GarethW
被浏览
33
Haisheng Zhang 2020-02-03 19:51

如果您需要在测试网络中执行某个步骤后查询帐户信息,则可以在每个步骤中调用network.runNetwork(),以便流程正式完成,否则您将无法获取数据(列表为空)