test(minimald): nightly coverage for single-host session networking - #761
test(minimald): nightly coverage for single-host session networking#761norrietaylor wants to merge 2 commits into
Conversation
…king Extend the netns root-integration harness with two single-host proofs that were not yet covered end-to-end: * netns_ownip_udp_task_to_task — two own-IP tasks exchange a UDP datagram over the gvproxy switch; the target attaches with its production IngressGate declaring the UDP port, so the gate admits the datagram and the echo reply round-trips (UC6 UDP + ingress udp_allowed admit). * netns_ingress_blocks_undeclared_port — a target attached with its production IngressGate admits a peer's TCP connection to a declared port but drops one to an undeclared port; both ports have a live listener, so the gate is the sole discriminator (UC4 default-deny / UC6 ingress enforcement). Both attach with the real switch->tap IngressGate, which the existing netns_ownip_ptask_to_ptask proof deliberately omits (it attaches with no gate). Thread an Option<IngressGate> through Ptask::provision and add a spawn_udp_echo helper; factor the shared netns-connect retry into connect_from_netns + retry_until_success and reuse it from the existing TCP task-to-task proof. New tests are auto-discovered by the _root_integration binary-name convention, so they run wherever that harness runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a blocking networking-integration job to nightly-tests.yml mirroring ci-linux-native's minimald-root-integration: enable userns, fetch the pinned gvproxy, probe netns capability, then run `cargo nextest run -p minimald --profile ci --run-ignored all --no-tests=fail -E 'binary(/_root_integration$/)'` with MINIMALD_NETNS_TEST=1 and GVPROXY_BIN. Like the installer nightly job, this catches drift (gvproxy pin, runner userns, newest nextest) on days no PR touches the networking crates — the per-PR home for these proofs is path-scoped. Failures feed the existing notify job's tracking issue. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
|
Closed per owner decision — not pursuing the networking nightly track. Branch deleted; commit |
What & why
Adds automated coverage for the CI-automatable, single-host subset of the
networking test plan — the parts that can pass deterministically today — and
wires a nightly job to run them, per owner-directed work under
#687. Draft for
code-owner review (see the workflow-freeze note below).
Two new convention-named proofs extend the existing netns harness
(
crates/minimald/tests/netns_root_integration.rs), and a blockingnetworking-integrationjob is added to.github/workflows/nightly-tests.yml.Important finding: this subset is NOT mothballed from per-PR CI
The task framed the single-host netns subset as mothballed from per-PR CI. In
fact, on
origin/main,ci-linux-native.yml'sminimald-root-integrationjob already runs
binary(/_root_integration$/)on every PR/push touchingcrates/**etc. What #687retired was the dedicated
ci-netns.ymland thenetworking-proxy/networking-wg/ mesh feature tests — the single-host netns proofs werere-homed into
minimald-root-integration(auto-discovered by the_root_integrationsuffix, #732).Consequence: the two new tests get per-PR coverage automatically via the
naming convention (no workflow edit needed). The nightly job therefore serves
the same purpose as the existing
installer/session-e2e-soaknightly jobs— drift detection on days no PR touches the networking crates (gvproxy pin,
runner userns, newest nextest) — not first-time coverage. It runs the same
selector as the per-PR lane; some overlap is the intended nightly-tier pattern.
Flagging so the owner can decide whether the nightly job is worth the overlap
or whether per-PR coverage suffices.
Coverage table (single-host subset)
netns_nonet_refuses_egressisolates_network(HostNet) == falseasserted innetns_nonet_refuses_egress; a live host-net egress test needs real internet from the runner (flaky) — deliberately omittedEgressPolicycan be built, but there is no enforcement:net/policy.rsstates gvproxy v0.8.9 has no per-client egress ACL API and egress enforcement (R2.2) is split to #553. A test could construct the policy but nothing would drop a denied subnet — no passing assertion exists. Omitted (not written as a permanently-red test)netns_ingress_static_port_mapping_exposes_then_unexposesnetns_ingress_blocks_undeclared_portmin expose/ runtime port map)dynamic_allowed_rangeis recorded-only, enforcement split to #553. Omittednetns_ownip_ptask_to_ptask(attaches with no gate)netns_ingress_blocks_undeclared_port— target attaches with its productionIngressGatenetns_ownip_udp_task_to_task— UDP datagram round-trip + gateudp_allowedadmitAdded now (2 new tests)
netns_ownip_udp_task_to_task— two own-IP tasks exchange a UDP datagramover the gvproxy switch. The target attaches with its production
IngressGatedeclaring the UDP port, so the gate admits the datagram (an undeclared port
would be dropped as unsolicited) and the echo reply round-trips.
netns_ingress_blocks_undeclared_port— the target attaches with itsproduction
switch → tapIngressGate; a peer's TCP connect to a declaredport succeeds while a connect to an undeclared port is dropped. Both ports
have a live listener, so the gate is the sole discriminator. This drives the
gate end-to-end — the existing
netns_ownip_ptask_to_ptaskattaches with nogate, so the enforcement path was previously only unit-tested.
Both are auto-discovered by the
_root_integrationbinary-name convention.Supporting refactor:
Ptask::provisiongains anOption<IngressGate>; aspawn_udp_echohelper is added; the netns-connect retry is factored intoconnect_from_netns+retry_until_successand reused from the existing TCPtask-to-task proof.
Nightly wiring
New blocking
networking-integrationjob innightly-tests.ymlmirrorsci-linux-native'sminimald-root-integration: checkout →setup-rust(
shared-key: netns) → install nextest → enable userns →scripts/fetch-gvproxy.sh→ netns capability probe →
cargo nextest run -p minimald --profile ci --run-ignored all --no-tests=fail -E 'binary(/_root_integration$/)'withMINIMALD_NETNS_TEST=1+GVPROXY_BIN. Failures feed the existingnotifyjob's
ci-nightlytracking issue (added to itsneeds,if:, and body).The cross-host WireGuard mesh proof (
mesh_uc7.rs,networking-wg) stays out:feature-gated off and its name doesn't match the convention.
Workflow-freeze authorization
.github/workflows/is normally frozen and CODEOWNER-gated (CLAUDE.md). Thisedit is authorized owner-directed work under
#687, delivered as a draft
for code-owner review.
Validation
cargo fmt— clean (rustfmt fully parses the#![cfg(target_os = "linux")]test file; formatting unchanged).
actionlint(samerhysd/actionlint:1.7.12image the nightlyhygienejobuses) on
nightly-tests.yml— clean (exit 0).minimaldis Linux-only(
procfsrefuses to build on macOS), and cross-compiling was blocked byaws-lc-sysneeding a musl cross-C-toolchain not installed on the dev host.So the Linux-gated test body has no local type-check; it was reviewed by hand
against the exact APIs (
IngressGate::for_session,attach_to_switch,Ptask), and closely mirrors the adjacent tests that do compile in CI.workflow_dispatchofnightly-tests.ymlon this branch (and/or let this PR's
ci-linux-nativeminimald-root-integrationjob run the two new tests per-PR). Neither could be exercised from the dev host.
Assumptions I could not verify locally
reviewed; not compiled locally — see above).
timeout 25; probe retries to a 30s deadline — same pattern as the existingTCP proof).
networking-integrationjob runs green onubuntu-latestwiththe pinned gvproxy, exactly as
minimald-root-integrationdoes today.🤖 Generated with Claude Code