Skip to content

test(minimald): nightly coverage for single-host session networking - #761

Closed
norrietaylor wants to merge 2 commits into
mainfrom
test/networking-nightly-single-host
Closed

test(minimald): nightly coverage for single-host session networking#761
norrietaylor wants to merge 2 commits into
mainfrom
test/networking-nightly-single-host

Conversation

@norrietaylor

Copy link
Copy Markdown
Member

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 blocking
networking-integration job 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's minimald-root-integration
job already runs binary(/_root_integration$/) on every PR/push touching
crates/** etc. What #687
retired was the dedicated ci-netns.yml and the networking-proxy /
networking-wg / mesh feature tests — the single-host netns proofs were
re-homed into minimald-root-integration (auto-discovered by the
_root_integration suffix, #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-soak nightly 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)

UC Case Status Notes
UC1 A — no-net → egress refused ✅ covered already netns_nonet_refuses_egress
UC1 B — host-shared ✅ contract-covered isolates_network(HostNet) == false asserted in netns_nonet_refuses_egress; a live host-net egress test needs real internet from the runner (flaky) — deliberately omitted
UC1 C — own-IP + NAT egress ⛔ omitted reaching the real internet through gvproxy NAT is network-dependent/flaky; the own-IP path itself is exercised by the UC6 proofs
UC3 egress policy (deny subnets / DNS allowlist / protocol) 🚫 blocked on missing surface EgressPolicy can be built, but there is no enforcement: net/policy.rs states 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)
UC4 static ingress (host-published port exposed then removed) ✅ covered already netns_ingress_static_port_mapping_exposes_then_unexposes
UC4 default-deny / declared-port enforcement added now netns_ingress_blocks_undeclared_port
UC4 dynamic ingress (min expose / runtime port map) 🚫 blocked on missing surface no CLI/RPC exists; dynamic_allowed_range is recorded-only, enforcement split to #553. Omitted
UC6 session↔session TCP (bare reachability) ✅ covered already netns_ownip_ptask_to_ptask (attaches with no gate)
UC6 session↔session TCP + ingress enforcement added now netns_ingress_blocks_undeclared_port — target attaches with its production IngressGate
UC6 session↔session UDP added now netns_ownip_udp_task_to_task — UDP datagram round-trip + gate udp_allowed admit
UC6 session↔session egress enforcement 🚫 blocked on missing surface same as UC3 — no egress enforcement (#553)

Added now (2 new tests)

  • 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 (an undeclared port
    would be dropped as unsolicited) and the echo reply round-trips.
  • netns_ingress_blocks_undeclared_port — the target attaches with its
    production switch → tap IngressGate; a peer's TCP connect to a declared
    port 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_ptask attaches with no
    gate, so the enforcement path was previously only unit-tested.

Both are auto-discovered by the _root_integration binary-name convention.
Supporting refactor: Ptask::provision gains an Option<IngressGate>; a
spawn_udp_echo helper is added; the netns-connect retry is factored into
connect_from_netns + retry_until_success and reused from the existing TCP
task-to-task proof.

Nightly wiring

New blocking networking-integration job in nightly-tests.yml mirrors
ci-linux-native's minimald-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$/)' with
MINIMALD_NETNS_TEST=1 + GVPROXY_BIN. Failures feed the existing notify
job's ci-nightly tracking issue (added to its needs, 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). This
edit 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 (same rhysd/actionlint:1.7.12 image the nightly hygiene job
    uses) on nightly-tests.yml — clean (exit 0).
  • Could not compile/clippy the tests locally: minimald is Linux-only
    (procfs refuses to build on macOS), and cross-compiling was blocked by
    aws-lc-sys needing 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.
  • Authoritative validation: run workflow_dispatch of nightly-tests.yml
    on this branch
    (and/or let this PR's ci-linux-native minimald-root-integration
    job run the two new tests per-PR). Neither could be exercised from the dev host.

Assumptions I could not verify locally

  • The two new tests type-check and pass under real netns/sudo/gvproxy (logic
    reviewed; not compiled locally — see above).
  • The UDP echo/retry timing is robust on slow runners (echo loops until
    timeout 25; probe retries to a 30s deadline — same pattern as the existing
    TCP proof).
  • The nightly networking-integration job runs green on ubuntu-latest with
    the pinned gvproxy, exactly as minimald-root-integration does today.

🤖 Generated with Claude Code

norrietaylor and others added 2 commits July 14, 2026 17:04
…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>
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 80f2408c-ffaa-479d-98ef-1f41c6a7d8f9

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@norrietaylor

Copy link
Copy Markdown
Member Author

Closed per owner decision — not pursuing the networking nightly track. Branch deleted; commit 0a77100 remains reachable from this PR. The two convention tests it carried (netns_ownip_udp_task_to_task, netns_ingress_blocks_undeclared_port) would run per-PR via minimald-root-integration with no nightly needed, if ever worth salvaging on their own.

@norrietaylor
norrietaylor deleted the test/networking-nightly-single-host branch July 15, 2026 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant