Testing with Java
Java tests use the Embedded engine’s server form: one tinyconductor --mode embedded process, driven over the REST API with the JDK’s
HttpClient. Nothing is linked into the JVM.
The runnable project is testing/java in the
examples download: Gradle, JUnit 5 and
Jackson, Java 21.
Start the engine
Section titled “Start the engine”From the container image:
export TINYCONDUCTOR_TOKEN=test-tokendocker run --rm -d --name tinyconductor-test -p 127.0.0.1:8080:8080 \ -e CONDUCTOR_AUTH_CREDENTIALS_JSON='[{"token":"test-token","subject":"tests","tenantId":"default","kind":"service","actions":["*"]}]' \ registry.tinyfactory.ai/tinyblox/tinyconductor:0.1.0 --mode embeddedOr from the release archive for your platform (downloads are listed in Embedded mode); on loopback it needs no credential:
./tinyconductor-0.1.0-linux-x86_64/tinyconductor --mode embeddedThe tests read TINYCONDUCTOR_URL (default http://127.0.0.1:8080) and, if
the engine was started with credentials, TINYCONDUCTOR_TOKEN. In a pipeline,
see CI recipes.
The calls
Section titled “The calls”| Step | Request |
|---|---|
| start clean | POST /v1/embedded/reset |
| deploy | POST /v1/deployments, multipart, one resource part per file |
| start an instance | POST /v1/process-instances {"processDefinitionId": "order-process", "variables": {…}} |
| take a job | POST /v1/jobs/activation {"type": "charge-card", "timeout": 30000, "maxJobsToActivate": 1} |
| complete it | POST /v1/jobs/{jobKey}/completion {"leaseEpoch": …, "variables": {…}} (204) |
| move time | POST /v1/embedded/clock/advance-by {"milliseconds": 86400000} |
| find a user task | POST /v1/user-tasks/search {"processInstanceKey": "…"} |
| complete it | POST /v1/user-tasks/{userTaskKey}/completion {"variables": {…}} (204) |
| assert | GET /v1/embedded/records |
The test
Section titled “The test”@BeforeEachvoid resetAndDeploy() throws Exception { // Every test starts from an empty engine at the fixed epoch. call("POST", "/v1/embedded/reset", null); deploy("order.form", "application/json"); deploy("order-decisions.dmn", "application/xml"); deploy("order.bpmn", "application/xml");}
@Testvoid orderCompletesAfterTheReviewPeriod() throws Exception { String key = call("POST", "/v1/process-instances", Map.of( "processDefinitionId", "order-process", "variables", Map.of("orderId", 4711, "amount", 99.9))) .get("processInstanceKey").asText(); // keys are JSON strings
completeJob("charge-card", Map.of("charged", true)); // The 24-hour review timer fires inside this call; no sleeping or polling. call("POST", "/v1/embedded/clock/advance-by", Map.of("milliseconds", 86_400_000L)); completeJob("send-invoice", Map.of());
JsonNode tasks = call("POST", "/v1/user-tasks/search", Map.of("processInstanceKey", key)).get("items"); assertEquals("confirm-shipment", tasks.get(0).get("elementId").asText()); call("POST", "/v1/user-tasks/" + tasks.get(0).get("userTaskKey").asText() + "/completion", Map.of("variables", Map.of("shipped", true)));
Set<String> completed = new HashSet<>(); for (JsonNode record : call("GET", "/v1/embedded/records", null).get("records")) { if (record.get("valueType").asText().equals("PROCESS_INSTANCE") && record.get("intent").asText().equals("ELEMENT_COMPLETED") && record.get("value").get("processInstanceKey").asText().equals(key)) { completed.add(record.get("value").get("elementId").asText()); } } for (String element : new String[] {"order-process", "charge-card", "send-invoice", "confirm-shipment"}) { assertTrue(completed.contains(element), element + " completed"); }}call, deploy and completeJob are small helpers over HttpClient in
the example (src/test/java/example/OrderProcessTest.java); deploy builds
the multipart body by hand, so no HTTP library is needed. Run it:
cd tinyconductor-0.1.0-examples/testing/javagradle testExisting process-testing suites
Section titled “Existing process-testing suites”The Embedded server also serves the v2-shaped clock operations
(PUT /v2/clock, POST /v2/clock/reset) and the v2 API, which is what the
remote-runtime configuration of compatible Java process-testing libraries
calls. Running such a suite unchanged against an Embedded engine is the
intent, but it has not yet been verified end to end; until it is, write
tests against the REST API as shown here. What compatibility covers is on the
Compatibility page.