test(e2e): server-direction real-tool e2e rows (w5-e2e-server)
The POC-3 gates re-landed against the shipped crate in a dedicated tests/e2e_server.rs binary (reusing tests/common; the mapping binaries keep their single-writer posture): OpenSSH pty/shell + pipe exec, -L/-R/-D+curl (the -R arrival leg and -D's direct-tcpip leg end to end), git clone AND push (rev parity + CAS row), and six decline-observability rows (unfeatured pty/-L/-R from real clients, the sftp subsystem decline, the unknown-repo collapsed generic denial — each pinned by its door-side decline event). All rows are check-gated skipped-with-reason and deadline-bounded. E2e-graph fixes (no src/ changes): per-row key workdirs, an in-process port allocator below the ephemeral range, the fabric registration settle, and event_capture::captured_with + support::decline_event (poll-within-row-deadline event observation). Verification: scripts/matrix.sh green (cargo test x6 builds, clippy x2 -D warnings, fmt, doc); 10 consecutive all-features e2e runs green. taskgraph validate: 42 tasks valid.
This commit is contained in:
1 parent
d5be18baed
commit
567a34a5e1
3 files changed
+1827
-3
No files matched your search
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: w5-e2e-server
|
||||
name: Wave 5 — real-tool e2e, server direction (OpenSSH / git / curl against the door)
|
||||
status: pending
|
||||
status: completed
|
||||
depends_on: [review-wave-4]
|
||||
scope: moderate
|
||||
risk: medium
|
||||
@@ -76,8 +76,65 @@ check-gated **skipped-with-reason** posture (never silently green):
|
||||
|
||||
## Notes
|
||||
|
||||
> To be filled by implementation agent
|
||||
**The e2e home decided**: `tests/e2e_server.rs` (the new binary), reusing `tests/common` — the
|
||||
mapping binaries stay single-writer per the decomposition's file map; this task edits only its own
|
||||
binary. Its fixtures live in-file: a `support` module (tool gates, the fixture-key/option builders,
|
||||
the registered identity provider, the port allocator, the real-TCP mount) and a tunnel-gated
|
||||
`fabric` module (the trimmed leg-1/leg-2 fabric double — TCP-only, happy-path: the decline and
|
||||
collision machinery stays the mapping binaries'). Everything is `#[cfg(unix)]` with the body
|
||||
feature-gated per row group; no src/ changes were needed — every observed issue was e2e-graph
|
||||
local.
|
||||
|
||||
**Row inventory** (all check-gated, **skipped-with-reason** when a tool is absent / short, never
|
||||
silently green; each row's real-process interaction is deadline-bounded and asserts the door's
|
||||
decline event through the capture's deadline-bounded poll):
|
||||
|
||||
| Row | Build(s) | What it pins |
|
||||
|---|---|---|
|
||||
| `git_rows::real_git_clones_the_empty_repo_through_the_door` | git (+all) | the wave-3 clone smoke re-landed: real `git clone ssh://…` → unborn-HEAD advertisement, normalized resolved id |
|
||||
| `git_rows::real_git_push_creates_the_ref_through_the_door` | git (+all) | **push** (the wave-3 smoke's gap): receive-pack through the real client, rev parity (`refs/heads/main` new-oid == local `rev-parse HEAD`), CAS-application row |
|
||||
| `session_rows::real_openssh_pty_shell_session_serves_through_the_door` | session (+all) | the wave-3 pty smoke re-landed + extended: the `echo` marker rides the real PTY round trip, exit-status(0) before close |
|
||||
| `session_rows::real_openssh_pipe_exec_separates_stdout_and_stderr_through_the_door` | session (+all) | `ssh host "cmd"` through the exec wrapper (`wrapper ++ [cmd]`): stdout rides SSH data, stderr rides `extended_data(1)` — POC-3 §D.1's pipe split end to end |
|
||||
| `tunnel_rows::real_ssh_local_forward_serves_the_direct_tcpip_leg` | tunnel (+all) | `-L` smoke re-landed: route-1 bridge + real `tcp_dial`, body parity |
|
||||
| `tunnel_rows::real_ssh_remote_forward_serves_the_arrival_and_data_legs` | tunnel (+all) | `-R`: listen, fabric-bound port, the server-initiated `forwarded-tcpip` arrival on the real wire, the client-dialed data leg — the leg the in-process smokes covered only through the fabric double |
|
||||
| `tunnel_rows::real_ssh_dynamic_forward_serves_curl_through_the_direct_tcpip_leg` | tunnel (+all) | **`-D`**: curl `--socks5-hostname` through vanilla OpenSSH's client-side SOCKS → the door's `direct-tcpip` leg (POC-3 correction 2 end to end); two requests pin the per-connection channel opens |
|
||||
| `unfeatured_session_decline::real_openssh_pty_attempt_declines_cleanly_in_a_feature_limited_build` | not-session (none/git/tunnel/sftp) | real `ssh -tt … echo` → nonzero exit, clean diagnostic, no hang; the decline event pins the build's class (`pty_request` "unfeatured" request-decline in the git build, `session` "unfeatured" open-decline otherwise) |
|
||||
| `unfeatured_tunnel_declines::real_openssh_remote_forward_attempt_declines_cleanly` | not-tunnel | real `ssh -N -R -o ExitOnForwardFailure=yes` → exit + OpenSSH's `forwarding failed` diagnostic; `tcpip_forward` global-request decline event |
|
||||
| `unfeatured_tunnel_declines::real_openssh_local_forward_connections_decline_per_connection` | not-tunnel | real `ssh -N -L` + repeated curls: every connection fails promptly (exit 7-class, no hang); `direct-tcpip` open-decline event |
|
||||
| `subsystem_decline::real_sftp_subsystem_attempt_declines_with_reason` | any(session,git) | the OQ-13 placeholder from a real `sftp` client: nonzero exit, clean diagnostic; `subsystem_request` request-decline event (`unimplemented`) |
|
||||
| `unknown_repo_decline::real_git_clone_of_an_unknown_repo_collapses_to_the_generic_denial` | git (+all) | real `git clone` of a nonexistent repo → exit 128, the collapsed `access denied` band naming the normalized id, **no existence oracle** |
|
||||
|
||||
**Findings fixed in-task** (no src/ changes; all e2e-graph local):
|
||||
|
||||
1. **Parallel-row flake — the shared key workdir**: the three tunnel rows initially shared one
|
||||
`write_key` workdir, so concurrent rows raced on the same key file and one row's cleanup
|
||||
deleted the dir under the others (observed as refused forwards / curl exit 7). Fixed: per-row
|
||||
workdirs (`tunnel-l` / `tunnel-r` / `tunnel-d`).
|
||||
2. **Parallel-row flake — port collisions**: the probe-and-drop ephemeral port picker let parallel
|
||||
rows (and under load, re-entries) collide on named binds. Fixed: an in-process monotonic
|
||||
allocator over the 2000–16999 window (below the kernel's ephemeral range, so `bind(0)` can
|
||||
never steal one), probe-verified per allocation.
|
||||
3. **Fabric-registration race**: the leg-2 fabric's openables register on a spawned task; an
|
||||
`ssh -R` listen dial ahead of registration is refused, not retried (`curl never got through`
|
||||
exit 7). Fixed: both fabric constructors settle on the direct/listen openables' registration
|
||||
before returning (`settle`, bounded poll on `OperationRegistry::registration`).
|
||||
4. **Event-window flake under CI load**: the decline rows' fixed 10 s `await_event` window can
|
||||
expire on a loaded host. Fixed: `event_capture::captured_with` (additive, non-blocking peek)
|
||||
+ `support::decline_event` — the rows poll within the row deadline instead of a fixed window.
|
||||
|
||||
## Summary
|
||||
|
||||
> To be filled on completion
|
||||
Completed 2026-10-30. The server-direction real-tool e2e landed as `tests/e2e_server.rs` (the
|
||||
placement decision above): 12 rows over the six build shapes — OpenSSH pty/shell + pipe exec
|
||||
(stderr separation), `-L`/`-R`/`-D`+curl (with curl's two-request per-connection pin), git
|
||||
clone **and** push (rev parity + CAS row pinned through the recording quartet), and the six
|
||||
decline-observability rows (unfeatured pty/`-L`/`-R` from real clients, the sftp subsystem
|
||||
decline, the unknown-repo collapsed generic denial — each also pinned by its door-side decline
|
||||
event). Every finding fixed in-task (four, listed in Notes — flake hardening only, no src/
|
||||
changes). Verification: full `scripts/matrix.sh` run green — `cargo test` per build (none / git
|
||||
/ session / tunnel / sftp / --all-features; the new binary rides each build compiling and
|
||||
running only its rows' builds), both clippy runs `-D warnings` clean, fmt clean,
|
||||
`cargo doc --no-deps` clean; plus 10 consecutive all-features e2e runs green after the flake
|
||||
fixes (the parallel-port + shared-workdir + fabric-settle + event-poll hardening). Skips are
|
||||
reasoned prints only (tool absence; on this host Git 2.43 / OpenSSH 9.6 / curl 8.5 / sftp are
|
||||
present, so every row ran).
|
||||
@@ -108,6 +108,22 @@ pub fn install() {
|
||||
let _ = capture();
|
||||
}
|
||||
|
||||
/// The non-blocking peek — `Some` when a matching event is already on
|
||||
/// record, `None` otherwise. The e2e rows poll this alongside their
|
||||
/// bounded curls (the awaiting rows' `await_event` stays fixed-window;
|
||||
/// a slow CI host turns the wait-then-window shape into a flake, the
|
||||
/// poll-with-row-deadline shape does not).
|
||||
pub fn captured_with(want: &[(&str, &str)]) -> Option<Captured> {
|
||||
let capture = capture();
|
||||
capture
|
||||
.0
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner())
|
||||
.clone()
|
||||
.into_iter()
|
||||
.find(|e| e.has(want))
|
||||
}
|
||||
|
||||
/// Waits until an event matching every field pair appears, then
|
||||
/// returns it — the spawned-task surfaces land their events
|
||||
/// asynchronously (the deadline loop is the observe-suite convention).
|
||||
|
||||
+1751
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user