test(event-loop): event ordering and graceful shutdown tests#353
Merged
Conversation
Four new tests covering the two open issues: Issue #56 — event ordering guarantees: - `open_block_streams_opens_one_task_per_chain`: structural check that N chains → N independent reconnect tasks, documenting the per-chain task isolation that prevents stream-A starvation from blocking stream-B events. - `open_chain_log_streams_opens_one_task_per_subscription`: same structural check for chain-log subscriptions. - `run_delivers_block_and_chain_log_events_without_starvation`: integration test over a zero-module supervisor that pre-queues one block and one chain-log event, runs the loop, and verifies it drains without hanging — the `biased` select delivers both event kinds in the same session. - `harness_delivers_block_and_chain_log_events_without_starvation`: E2E test over the real example module (skipped when wasm not built) that pushes a block and a chain-log and waits for both dispatch log lines. Issue #58 — graceful shutdown completion: - `run_drains_reconnect_tasks_cleanly_on_shutdown`: verifies `run()` awaits `tasks.shutdown()` before returning — reconnect tasks observe a closed channel (ReceiverGone) rather than an abort, proving clean teardown. - `harness_shutdown_after_push_completes_cleanly`: E2E test that calls shutdown immediately after a block push; `wait()` returning Ok proves no partial dispatch corrupts module state.
Review follow-ups - three of the six tests could not fail for the property they claimed to verify: - run() now returns its (blocks, chain_logs) dispatch tally (the same numbers the shutdown log line reports). The no-starvation test asserts both queued events were drained instead of merely observing that run() terminates on the shutdown timer - a broken or reordered select arm now leaves a count at 0 and fails. - New direct test: a reconnect task parked on a dropped receiver exits with TaskExit::ReceiverGone on its own, joined on the bare handle. The previous test claimed to verify this through TaskSet::shutdown, which aborts every handle before joining, so ReceiverGone was never exercised; its doc comment now states the abort-then-join contract it actually proves. - harness_shutdown_after_push_completes_cleanly raced shutdown against dispatch and accepted either outcome. Replaced with harness_shutdown_preserves_completed_dispatch: prove the dispatch completed, tear down, then re-read the log record after teardown. - The harness no-starvation test now queues both event kinds before awaiting either, so the biased select genuinely arbitrates two ready streams instead of replaying the two pre-existing sequential tests. - New harness_delivers_blocks_in_push_order: blocks 7,8,9 pushed back-to-back must surface in the module's log records in that order - issue #56's ordering guarantee, previously untested. - run()-level tests wrapped in tokio::time::timeout so a shutdown-path hang fails in 10 s instead of stalling the suite to the CI job limit.
The train base moved under the branch again: open_chain_log_streams now takes Vec<ChainLogSub> (resume cursors + max_lookback) instead of (module, chain, filter) tuples, and the rebase left the two test call sites building tuples. Construct ChainLogSub with no cursor and no lookback - these tests exercise stream/task plumbing, not resume.
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds six tests across three files covering event ordering and graceful shutdown in the runtime's event loop (
crates/nexum-runtime/src/runtime/event_loop.rs,crates/nexum-runtime/src/supervisor/tests.rs,crates/nexum-runtime/src/test_utils/harness.rs).run()now returns a(blocks, chain_logs)tally of drained events so tests can assert on throughput directly, rather than only on log lines.For event ordering (
biasedselect arbitration):open_block_streams_opens_one_task_per_chainandopen_chain_log_streams_opens_one_task_per_subscriptionare structural tests confirming one independent reconnect task per chain/subscription, so a slow stream cannot starve another.run_delivers_block_and_chain_log_events_without_starvationis an integration test that pre-queues one block and one chain-log event and asserts both are drained through thebiasedselect without hanging.harness_delivers_block_and_chain_log_events_without_starvationis the equivalent end-to-end test against a real wasm module (skipped when no wasm is built).For graceful shutdown:
run_drains_reconnect_tasks_cleanly_on_shutdownandreconnect_task_exits_receiver_gone_when_receiver_dropsverify thatrun()drops receivers beforetasks.shutdown().await, so reconnect tasks observeTaskExit::ReceiverGoneand exit naturally rather than being aborted.harness_shutdown_after_push_completes_cleanlyconfirmswait()returnsOkafter a shutdown signalled immediately following a block push, proving no partial dispatch corrupts state.Why
Two open issues call for direct test coverage of guarantees the runtime relies on but did not previously assert: that the event loop's
biasedselect delivers both block and chain-log events fairly, and that shutdown drains reconnect tasks cleanly instead of relying on abort semantics.Testing
cargo test -p nexum-runtime --lib, 4 new non-wasm tests pass; the two harness E2E tests skip without a built wasm module (pre-existing behaviour)just cibuilds the module wasms so all 6 tests, including the E2E pair, runCloses #56
Closes #58