Reputation: 42340
I am unit testing a flow that I know will fail.
assertFailsWith<JdbcSQLIntegrityConstraintViolationException> {
nodeA.issueState(...) // Note, issueState is an extension on StartedMockNode
}
The reason for the failure is that the state being output in the transaction cannot be duplicated due to a unique key/index violation on the schema:
org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation
When this happens in a unit test the output displays:
[INFO] 12:41:22,600 [Mock network] statemachine.StaffedFlowHospital. - Flow error kept for overnight observation by [net.corda.node.services.statemachine.StaffedFlowHospital$TransitionErrorGeneralPractitioner@49a4216e] (error was org.hibernate.exception.ConstraintViolationException: could not execute statement) {actor_id=Only For Testing, actor_owning_identity=O=PartyA, L=London, C=GB, actor_store_id=TEST, fiber-id=10000012, flow-id=932a7d4e-e695-4096-b3d8-efbcdbfa5b21, invocation_id=fcf25c8a-6bf1-4dce-8e65-3c84c96b8523, invocation_timestamp=2019-12-28T12:41:22.402Z, origin=Only For Testing, session_id=fcf25c8a-6bf1-4dce-8e65-3c84c96b8523, session_timestamp=2019-12-28T12:41:22.402Z, thread-id=1309}
[WARN] 12:42:18,805 [FlowHospitalJobTimer] statemachine.StaffedFlowHospital. - There are 1 flows kept for overnight observation. Affected flow ids: 932a7d4e-e695-4096-b3d8-efbcdbfa5b21
[WARN] 12:43:18,804 [FlowHospitalJobTimer] statemachine.StaffedFlowHospital. - There are 1 flows kept for overnight observation. Affected flow ids: 932a7d4e-e695-4096-b3d8-efbcdbfa5b21
The problem is that the test hangs and never completes. I've managed to get the test to fail by adding a duration to the getOrThrow
function on the resulting CordaFuture
, but this seems wrong to me, as the flow is failing due to a timeout, rather than because of the underlying exception.
.getOrThrow(Duration.ofSeconds(10))
java.lang.AssertionError: Expected an exception of class org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException to be thrown, but was java.util.concurrent.TimeoutException
What is the correct way to test flows that end up being sent to the flow hospital?
Upvotes: 1
Views: 299
Reputation: 920
I test these by asserting on the TimeoutException
like you mentioned using assertFailsWith
. The current hospital logic is to keep the flow in for observation if any database errors occur, including constraint violations. Logic should be added to the flow to precheck the constrained fields.
Because the official error is a timeout due to the flow not actually failing exceptionally, there is not a way around this.
Upvotes: 1