feat: end-to-end suite — 18-test consolidation over the shared harness

- 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
This commit is contained in:
2026-09-08 10:03:42 +00:00
parent 65fb69db61
commit 2efac9b609
3 changed files with 1270 additions and 2 deletions
+76 -2
View File
@@ -1,7 +1,7 @@
---
id: tunnels/end-to-end-suite
name: End-to-end suite — forward, reverse, listen, datagram, teardown matrix
status: pending
status: completed
depends_on: [tunnels/consumer-session, tunnels/producer-listen, tunnels/local-socket-halves]
scope: broad
risk: medium
@@ -75,6 +75,80 @@ topologies to unify.
> 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 reason `timeout`
with no channel surviving).
- `wire_serving_identity` — the `ServingConfig.identity` override
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_channel` on a reverse-open'd but
never-adopted channel id is `UnknownChannel` — 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 between `open_reverse_channel` and `adopt`.
- **`read(&mut Vec)` vs `read(buf)`** — an unpopulated `Vec` passed to
`AsyncReadExt::read` has len 0 and reads nothing (instant EOF); the
1 MiB loop needed a size-`expected` buffer with `&mut received[got..]`.
- The empty-queue-vs-error posture from `tunnels/producer-listen`
carries over verbatim: the queue's pop waits; mapping empty-pop to
`resource_shortage` is the assembly closure's posture (producer.md's
table), asserted here with a fail-fast closure.
## Summary
> Agent fills this on completion.
> 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.