mirror of
https://github.com/corda/corda.git
synced 2024-12-24 23:26:48 +00:00
Attempting to make VerifierTests more stable (#1883)
* Attempting to make VerifierTests more stable Main point: Alice node will always be faster to locate Alice by name than NotaryNode. Especially given that it may take some time for Alice node to get reflected on the Notary's NetworkMap. Also additional logging which might be helpful during debug and IntelliJ changed project structure reflection. * Introduce a way for nodes to reliably learn about each other existence in the NetworkMap Plus minor refactoring of the Driver code.
This commit is contained in:
parent
be235673e1
commit
99b509cb68
.idea
testing/node-driver/src/main/kotlin/net/corda/testing/driver
verifier/src/integration-test/kotlin/net/corda/verifier
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@ -60,6 +60,8 @@
|
||||
<module name="jfx_integrationTest" target="1.8" />
|
||||
<module name="jfx_main" target="1.8" />
|
||||
<module name="jfx_test" target="1.8" />
|
||||
<module name="kryo-hook_main" target="1.8" />
|
||||
<module name="kryo-hook_test" target="1.8" />
|
||||
<module name="loadtest_main" target="1.8" />
|
||||
<module name="loadtest_test" target="1.8" />
|
||||
<module name="mock_main" target="1.8" />
|
||||
|
@ -67,6 +67,10 @@ import kotlin.concurrent.thread
|
||||
|
||||
private val log: Logger = loggerFor<DriverDSL>()
|
||||
|
||||
private val DEFAULT_POLL_INTERVAL = 500.millis
|
||||
|
||||
private const val DEFAULT_WARN_COUNT = 120
|
||||
|
||||
/**
|
||||
* This is the interface that's exposed to DSL users.
|
||||
*/
|
||||
@ -102,13 +106,12 @@ interface DriverDSLExposedInterface : CordformContext {
|
||||
validating: Boolean = true): CordaFuture<NodeHandle>
|
||||
|
||||
/**
|
||||
* Helper function for starting a [node] with custom parameters from Java.
|
||||
* Helper function for starting a [Node] with custom parameters from Java.
|
||||
*
|
||||
* @param defaultParameters The default parameters for the driver.
|
||||
* @param dsl The dsl itself.
|
||||
* @param parameters The default parameters for the driver.
|
||||
* @return The value returned in the [dsl] closure.
|
||||
*/
|
||||
fun <A> startNode(parameters: NodeParameters): CordaFuture<NodeHandle> {
|
||||
fun startNode(parameters: NodeParameters): CordaFuture<NodeHandle> {
|
||||
return startNode(defaultParameters = parameters)
|
||||
}
|
||||
|
||||
@ -165,16 +168,25 @@ interface DriverDSLExposedInterface : CordformContext {
|
||||
* @param check The function being polled.
|
||||
* @return A future that completes with the non-null value [check] has returned.
|
||||
*/
|
||||
fun <A> pollUntilNonNull(pollName: String, pollInterval: Duration = 500.millis, warnCount: Int = 120, check: () -> A?): CordaFuture<A>
|
||||
fun <A> pollUntilNonNull(pollName: String, pollInterval: Duration = DEFAULT_POLL_INTERVAL, warnCount: Int = DEFAULT_WARN_COUNT, check: () -> A?): CordaFuture<A>
|
||||
|
||||
/**
|
||||
* Polls the given function until it returns true.
|
||||
* @see pollUntilNonNull
|
||||
*/
|
||||
fun pollUntilTrue(pollName: String, pollInterval: Duration = 500.millis, warnCount: Int = 120, check: () -> Boolean): CordaFuture<Unit> {
|
||||
fun pollUntilTrue(pollName: String, pollInterval: Duration = DEFAULT_POLL_INTERVAL, warnCount: Int = DEFAULT_WARN_COUNT, check: () -> Boolean): CordaFuture<Unit> {
|
||||
return pollUntilNonNull(pollName, pollInterval, warnCount) { if (check()) Unit else null }
|
||||
}
|
||||
|
||||
/**
|
||||
* Polls until a given node knows about presence of another node via its own NetworkMap
|
||||
*/
|
||||
fun NodeHandle.pollUntilKnowsAbout(another: NodeHandle, pollInterval: Duration = DEFAULT_POLL_INTERVAL, warnCount: Int = DEFAULT_WARN_COUNT): CordaFuture<Unit> {
|
||||
return pollUntilTrue("${nodeInfo.legalIdentities} knows about ${another.nodeInfo.legalIdentities}", pollInterval, warnCount) {
|
||||
another.nodeInfo in rpc.networkMapSnapshot()
|
||||
}
|
||||
}
|
||||
|
||||
val shutdownManager: ShutdownManager
|
||||
}
|
||||
|
||||
@ -345,7 +357,7 @@ fun <A> driver(
|
||||
/**
|
||||
* Helper function for starting a [driver] with custom parameters from Java.
|
||||
*
|
||||
* @param defaultParameters The default parameters for the driver.
|
||||
* @param parameters The default parameters for the driver.
|
||||
* @param dsl The dsl itself.
|
||||
* @return The value returned in the [dsl] closure.
|
||||
*/
|
||||
@ -706,7 +718,7 @@ class DriverDSL(
|
||||
"webAddress" to webAddress.toString(),
|
||||
"networkMapService" to networkMapServiceConfigLookup(name),
|
||||
"useTestClock" to useTestClock,
|
||||
"rpcUsers" to if (rpcUsers.isEmpty()) defaultRpcUserList else rpcUsers.map { it.toMap() },
|
||||
"rpcUsers" to if (rpcUsers.isEmpty()) defaultRpcUserList else rpcUsers.map { it.toConfig().root().unwrapped() },
|
||||
"verifierType" to verifierType.name
|
||||
) + customOverrides
|
||||
)
|
||||
@ -883,14 +895,16 @@ class DriverDSL(
|
||||
}
|
||||
establishRpc(nodeConfiguration, processDeathFuture).flatMap { rpc ->
|
||||
// Call waitUntilNetworkReady in background in case RPC is failing over:
|
||||
val networkMapFuture = executorService.fork {
|
||||
val forked = executorService.fork {
|
||||
rpc.waitUntilNetworkReady()
|
||||
}.flatMap { it }
|
||||
}
|
||||
val networkMapFuture = forked.flatMap { it }
|
||||
firstOf(processDeathFuture, networkMapFuture) {
|
||||
if (it == processDeathFuture) {
|
||||
throw ListenProcessDeathException(nodeConfiguration.p2pAddress, process)
|
||||
}
|
||||
processDeathFuture.cancel(false)
|
||||
log.info("Node handle is ready. NodeInfo: ${rpc.nodeInfo()}, WebAddress: ${webAddress}")
|
||||
NodeHandle.OutOfProcess(rpc.nodeInfo(), rpc, nodeConfiguration, webAddress, debugPort, process)
|
||||
}
|
||||
}
|
||||
@ -905,7 +919,7 @@ class DriverDSL(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val defaultRpcUserList = listOf(User("default", "default", setOf("ALL")).toMap())
|
||||
private val defaultRpcUserList = listOf(User("default", "default", setOf("ALL")).toConfig().root().unwrapped())
|
||||
|
||||
private val names = arrayOf(
|
||||
ALICE.name,
|
||||
|
@ -6,20 +6,19 @@ import net.corda.core.messaging.startFlow
|
||||
import net.corda.core.transactions.LedgerTransaction
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.finance.DOLLARS
|
||||
import net.corda.finance.flows.CashIssueFlow
|
||||
import net.corda.finance.flows.CashPaymentFlow
|
||||
import net.corda.node.services.config.VerifierType
|
||||
import net.corda.testing.ALICE
|
||||
import net.corda.testing.DUMMY_NOTARY
|
||||
import net.corda.testing.chooseIdentity
|
||||
import net.corda.node.services.transactions.ValidatingNotaryService
|
||||
import net.corda.nodeapi.internal.ServiceInfo
|
||||
import net.corda.testing.*
|
||||
import net.corda.testing.driver.NetworkMapStartStrategy
|
||||
import org.junit.Test
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
class VerifierTests {
|
||||
private fun generateTransactions(number: Int): List<LedgerTransaction> {
|
||||
@ -121,13 +120,16 @@ class VerifierTests {
|
||||
val notaryFuture = startNotaryNode(DUMMY_NOTARY.name, verifierType = VerifierType.OutOfProcess)
|
||||
val aliceNode = aliceFuture.get()
|
||||
val notaryNode = notaryFuture.get()
|
||||
val alice = notaryNode.rpc.wellKnownPartyFromX500Name(ALICE_NAME)!!
|
||||
val alice = aliceNode.rpc.wellKnownPartyFromX500Name(ALICE_NAME)!!
|
||||
val notary = notaryNode.rpc.notaryPartyFromX500Name(DUMMY_NOTARY_SERVICE_NAME)!!
|
||||
startVerifier(notaryNode)
|
||||
notaryNode.pollUntilKnowsAbout(aliceNode).getOrThrow()
|
||||
aliceNode.pollUntilKnowsAbout(notaryNode).getOrThrow()
|
||||
aliceNode.rpc.startFlow(::CashIssueFlow, 10.DOLLARS, OpaqueBytes.of(0), notary).returnValue.get()
|
||||
notaryNode.waitUntilNumberOfVerifiers(1)
|
||||
for (i in 1..10) {
|
||||
aliceNode.rpc.startFlow(::CashPaymentFlow, 10.DOLLARS, alice).returnValue.get()
|
||||
val cashFlowResult = aliceNode.rpc.startFlow(::CashPaymentFlow, 10.DOLLARS, alice).returnValue.get()
|
||||
assertNotNull(cashFlowResult)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user