- tests/end_to_end.rs: 1 MiB backpressure, deadline→timeout (ADR-049 §2), CF-006 witness (transport + token), odd-ID asserts + distinctness (ADR-047 §5), full CF-005 precedence chain (ServingConfig override, distinct-id token probe, fail-closed), R-01 concurrency ×3, listen FIFO + typed-error table, datagram batching + 7-byte chunk-split codec probe + reverse codec session + TCP/UDP concurrent, teardown matrix arms (close-with-pump / join copy counts / Drop-with-pump / failed-adopt), no-phantom-channel + R-02 data-plane-tracking asserts - tests/harness.rs: RegistrationMode::Timeout (hanging establisher, per-registration bound), wire_serving_identity (CF-005 (a) shape) - task doc: status completed, notes + summary Verified: cargo test (68), cargo test --features local (75), 3× repeat-run clean both configs, clippy -D warnings (all-targets, local, wasm32), fmt --check, wasm32 check
7.2 KiB
id, name, status, depends_on, scope, risk, impact, level, tags
| id | name | status | depends_on | scope | risk | impact | level | tags | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| tunnels/end-to-end-suite | End-to-end suite — forward, reverse, listen, datagram, teardown matrix | completed |
|
broad | medium | phase | implementation |
|
Description
Consolidate the integration coverage into tests/ as the crate's
end-to-end suite: every validated POC behavior, re-expressed against the
crate's public API (not the POCs' internals). This is the quality gate
before the implementation review — the suite is the spec's executable
form.
Suites
- Forward (
-L): consumeropen→ producer establisher dials →pump_bidi→ round-trip; 1 MiB backpressure; typed errors (unknown_resource / dial_failed / FORBIDDEN / timeout-adjacent); per-call opener identity witness (CF-006). - Reverse (
-R): hub initiator —open_reverse_channel+adopt+pump_against; odd-ID allocation asserted (ADR-047 §5); identity precedence chain (transport alone /ServingConfig. identityoverride / token override / identity-less fail-closed); half-close (W4); out-of-bandchannel/close+ self-reaping (W3); concurrent same-resource opens (R-01, no handoff race). - Listen producer: the accept-queue flow end-to-end + its typed
errors (from
tunnels/producer-listen). - Datagram (
udp): forward + reverse datagram sessions via the codec — round-trip, empty datagram (the F-2 layering), chunk-split survival, TCP+UDP concurrent channels on one connection. - Teardown matrix (ADR-005): close / join (with + without pump) /
Drop —
channel_ids()asserts no leaks on either side after each. localfeature suite: real sockets end-to-end (fromtunnels/local-socket-halves— runs after that task lands; the duplex-transport suites above do not need it).
Transport stand-in: tokio::io::duplex (both POCs' harness; the
alkcall layer owns real transports — unchanged scope). The suite may
share one harness module (tests/common/); the POC harnesses
(/workspace/alktunnels-udp-poc/src/harness.rs,
/workspace/alktunnels-reverse-poc/src/harness.rs) are the two
topologies to unify.
The spec-conformance assertions to keep visible
- A failed open never returns a
channel_id(no phantom channel — both sides'channel_ids()hold only 0 afterward). - A failed adopt never leaks the session (Drop reaps).
- The pump handler's
JoinHandletracks the data plane (a test that simulates early-return would hang/EOF-instantly — the R-02 shape; assert the correct shape survives).
Acceptance Criteria
- All 6 suites present; ≥20 integration tests total
cargo testgreen;cargo test --features localgreen- Repeat-run stable (3× clean — the POCs' flakiness bar)
- Clippy/fmt clean; wasm32 check passes
References
- docs/architecture/wire.md + consumer.md + producer.md (the normative behaviors under test)
- POC test suites:
/workspace/alktunnels-udp-poc/tests/tunnel_poc.rs(10),/workspace/alktunnels-reverse-poc/tests/tunnel_poc.rs(16)
Notes
Agent fills during implementation.
Implementation notes (2026-09-08)
The pre-existing per-task suites (36 integration tests across
producer_open_op, consumer_session, producer_listen,
local_halves) already carried much of the per-suite coverage; this
task consolidated the remaining POC-validated behaviors they didn't
cover into tests/end_to_end.rs (18 tests, the suites as enumerated)
and extended tests/harness.rs:
RegistrationMode::Timeout(Duration)— a hanging establisher with an explicit per-registration establishment timeout (the ADR-049 §2 deadline-expiry probe; the wrapper maps expiry to reasontimeoutwith no channel surviving).wire_serving_identity— theServingConfig.identityoverride probe shape (CF-005 (a)).
Gaps the suite filled (behaviors the per-task suites did not cover):
1 MiB backpressure round-trip (both POCs' sizing probe); the
deadline→timeout wire mapping; odd-ID allocation asserts (ADR-047 §5)
plus distinctness; the FULL identity precedence chain — the
ServingConfig.identity override and the token-over-transport
precedence with a DISTINCT resolved id (the existing token test
resolved to the same id as the transport identity, so it proved
authorization but not precedence — the new DistinctTokenProvider
probe proves precedence); reverse datagram sessions via the codec
(pump-less (0, 0, reaped) join shape); 40-datagram bursts with
batching (the pending-queue cover, both directions); the 7-byte
chunk-split codec probe (100 datagrams); TCP+UDP interleaved on one
connection; teardown matrix arms: close-with-pump (abort + reap both
sides), join copy counts, Drop-with-pump (abort AND reap), and the
failed-adopt no-leak arm; R-02's JoinHandle-tracks-the-data-plane
assertion (alive-and-pumpable long after the open, completion only at
both-direction EOF).
Test-side findings (not product bugs — recorded for the record)
- Parked ≠ adopted.
teardown_channelon a reverse-open'd but never-adopted channel id isUnknownChannel— the manager parks early arrivals for unseen ids (the adoption-race cover, ADR-047 §5) but does not install a channel entry until adopt. Cleanup for such ids is adopt-then-close (what the tests do). Worth knowing when an assembly layer errors betweenopen_reverse_channelandadopt. read(&mut Vec)vsread(buf)— an unpopulatedVecpassed toAsyncReadExt::readhas len 0 and reads nothing (instant EOF); the 1 MiB loop needed a size-expectedbuffer with&mut received[got..].- The empty-queue-vs-error posture from
tunnels/producer-listencarries over verbatim: the queue's pop waits; mapping empty-pop toresource_shortageis the assembly closure's posture (producer.md's table), asserted here with a fail-fast closure.
Summary
Agent fills this on completion.
Summary
tests/end_to_end.rs (18 tests) consolidates the POC-validated
behaviors into the crate's end-to-end suite over the shared duplex
harness: forward (1 MiB backpressure, deadline→timeout, CF-006
witness on transport + token paths), reverse (odd-ID asserts +
distinctness, the full CF-005 precedence chain incl. the
ServingConfig override and a distinct-id token probe, R-01 same-
resource concurrency ×3), listen (FIFO always-before-take, the typed
error table), datagram (batching survival, 7-byte chunk-split codec
probe, reverse codec session, TCP+UDP concurrent), teardown matrix
(close-with-pump / join copy counts / Drop-with-pump / failed-adopt),
and the spec-conformance assertions (no phantom channel, no leaked
session, R-02's data-plane-tracking pump handle).
Harness grew RegistrationMode::Timeout + wire_serving_identity.
Existing suites untouched. Verification: cargo test green (68 tests
incl. unit + doc), cargo test --features local green (75), 3×
repeat-run clean (both feature configs), clippy -D warnings clean
(all-targets, --features local, wasm32), cargo fmt --check clean,
wasm32 check passes. No product-code changes were needed — the
failures during development were all test-harness bugs (zero-len read
buffer, teardown-on-parked-id), recorded above.