Skip to content

Commit

Permalink
feat: add launcher session mode
Browse files Browse the repository at this point in the history
  • Loading branch information
manosbatsis committed Jan 4, 2024
1 parent f673c4f commit a8a5399
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 21 deletions.
30 changes: 16 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ In your gradle:
The JUnit5 extension will automatically launch, setup VNodes and (re)deploy CPIs
to the Combined Worker as needed by default. The config exposes three modes:

- SHARED: Default, described above.
- SHARED: Default, described above. Leaves the worker running on finish.
- PER_LAUNCHER: Will force a fresh Combined worker for the current JUnit LauncherSession. Stops the worker on finish.
- PER_CLASS: Will force a fresh Combined worker for the current Test Class.
- NONE: Completely disables automation for the Combined Worker to enable manual or external management.

Expand All @@ -41,15 +42,14 @@ and expose them as a `NodeHandles` parameter to your test methods. Each node has
utility methods like `waitForFlow` that can be used to initiate flows and wait for a final flow status.

```kotlin
import com.fasterxml.jackson.databind.ObjectMapper
import com.github.manosbatsis.corda5.testutils.integration.junit5.CombinedWorkerMode
import com.github.manosbatsis.corda5.testutils.integration.junit5.Corda5NodesConfig
import com.github.manosbatsis.corda5.testutils.integration.junit5.Corda5NodesExtension
import com.github.manosbatsis.corda5.testutils.integration.junit5.nodehandles.NodeHandles
import com.github.manosbatsis.corda5.testutils.rest.client.model.FlowRequest
import net.corda.v5.base.types.MemberX500Name
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import kotlin.test.assertEquals
import kotlin.test.assertTrue

// Add the Corda5 nodes extension
Expand All @@ -73,24 +73,26 @@ open class DemoApplicationTests {

// The Corda5NodesExtension provides the NodeHandles
@Test
fun recordingFlowTests(nodeHandles: NodeHandles) {
fun workFlowTests(nodeHandles: NodeHandles) {
// Get node handles
val aliceNode = nodeHandles.getByCommonName("Alice")
val bobNode = nodeHandles.getByCommonName("Bob")

// Call flow
val myFlowArgs = MyFlowArgs(aliceNode.memberX500Name, bobNode.memberX500Name)
val createdStatus = aliceNode.waitForFlow(
// Create flow args
val flowArgs = MyFirstFlowStartArgs(bobNode.memberX500Name)
// Call Flow
val response = aliceNode.waitForFlow(
FlowRequest(
flowClass = MyFlow::class.java,
requestBody = myFlowArgs,
// Either String or the type
// (here MyFlowResult) marshaled to string by the flow,
flowResultClass = MyFlowResult::class.java
flowClass = MyFirstFlow::class.java,
requestBody = flowArgs,
flowResultClass = Message::class.java
)
)
// Check flow status
assertTrue(createdStatus.isSuccess())

// Check status and deserialized flow result
assertTrue(response.isSuccess())
val expectedMessage = Message(bobNode.memberX500Name, "Hello Alice, best wishes from Bob")
assertEquals(expectedMessage, response.flowResult)
}
}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ abstract class AbstractCorda5Extension : BeforeAllCallback, AfterAllCallback, Ju
val incrementedCallbackCount = extensionContext.root.getStore(GLOBAL).getOrDefault(allCallbackCounterKey, Int::class.java, 0)
.plus(1)
extensionContext.root.getStore(GLOBAL).put(allCallbackCounterKey, incrementedCallbackCount)
if (incrementedCallbackCount == 1) clearNodeHandles()
if (incrementedCallbackCount == 1 && config.combinedWorkerMode != CombinedWorkerMode.SHARED) clearNodeHandles()
initNodeHandles()
}
}
Expand All @@ -45,7 +45,8 @@ abstract class AbstractCorda5Extension : BeforeAllCallback, AfterAllCallback, Ju
val decrementedCallbackCount = extensionContext.root.getStore(GLOBAL).get(allCallbackCounterKey, Int::class.java)
.minus(1)
extensionContext.root.getStore(GLOBAL).put(allCallbackCounterKey, decrementedCallbackCount)
if (decrementedCallbackCount == 0 || config.combinedWorkerMode == CombinedWorkerMode.PER_CLASS)
val launcherFinished = decrementedCallbackCount == 0 && config.combinedWorkerMode == CombinedWorkerMode.PER_LAUNCHER
if (launcherFinished || config.combinedWorkerMode == CombinedWorkerMode.PER_CLASS)
clearNodeHandles()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,23 @@ fun gradleRootDir() {

enum class CombinedWorkerMode {
/**
* Default. Will launch, setup VNodes and (re)deploy to the Combined Worker
* as needed only once and reuse it for all tests.
* Default. Will start, setup VNodes and (re)deploy to the Combined Worker
* as needed only once for all tests. Leaves the worker running.
*/
SHARED,

/**
* Will launch, setup VNodes and (re)deploy to the Combined Worker
* Will re-launch, setup VNodes and (re)deploy to the Combined Worker
* as needed for each individual test class.
*/
PER_CLASS,

/**
* Will re-launch, setup VNodes and (re)deploy to the Combined Worker
* as needed for every JUnit LauncherSession. Stops the worker on finish.
*/
PER_LAUNCHER,

/**
* Completely disables automation for the Combined Worker to enable manual or external management.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ class NodeHandlesHelper(
when (config.combinedWorkerMode) {
CombinedWorkerMode.PER_CLASS ->
reset().also { nodeHandlesCache = buildNodeHandles() }

CombinedWorkerMode.PER_LAUNCHER ->
if (nodeHandlesCache == null) nodeHandlesCache = buildNodeHandles()
CombinedWorkerMode.SHARED ->
if (nodeHandlesCache == null) nodeHandlesCache = buildNodeHandles()

CombinedWorkerMode.NONE ->
nodeHandlesCache = nodeHandles(nodesClient.nodes().virtualNodes)
}
Expand Down

0 comments on commit a8a5399

Please sign in to comment.