eventually

inline fun eventually(what: String, timeout: Duration = EVENTUALLY_TIMEOUT, poll: Duration = EVENTUALLY_POLL, noinline detail: () -> String? = null, condition: () -> Boolean)

Polls condition until it holds, every poll, for at most timeout, and fails saying what was not reached, with detail then, when one is given (the services' output, the state seen last), and the last failure of condition as its cause: a condition that throws, an assertion among them, has not held yet.

A wait plan waits for what a command causes, to the end of a saga's chain (CommandClient.wait, stream), so a test waits so first. This is for what no wait plan sees: a call a fake peer received, a scheduled command that fires, a projection another service reads.

eventually("the order is cancelled") {
server.queries(alice).snapshots(OrderState::class.java).state(orderId)?.state?.status == OrderStatus.CANCELLED
}

It is inline, so condition runs in the caller's context: a blocking test's or a coroutine's, which may call the typed clients' suspend functions in it. It sleeps the thread between polls, as a test's real time passes.