Repository navigation
tests: keep three tests off host state they don't own - #278
Conversation
CI runs the whole workspace, ignored tests included, as root in a privileged host-network container, so a test's host assumptions run there and on any reused development host. - node-mgr: ensure_capacity_creates_attachable_devices_past_max_loop removes and re-creates /dev/loop63 and leaves up to 64 kernel loop devices behind. It now returns early unless SPACE_NODEMGR_TEST_LOOP_DEVICES is set, the same skip the crate's SPACE_NODEMGR_TEST_BTRFS_DIR tests use. No CI job sets either opt-in. - api: the e2b routes' test_state() lazy pool pointed at localhost:5432, which a dev box or host-network runner may serve. It now points at the closed 127.0.0.1:1, like the cluster_admission tests. - sbx-mgr: runtime_liveness_options, behind service_with_runtime_liveness, used the production host-control and credential-manager socket paths. It now uses absent paths in a per-service directory nothing creates. The _and_absent_sockets variant keeps its caller-owned directory, so the two helpers stay separate.
Review — 2 findingsLow
For each of the three tests I checked what it touched before and that it still can fail. The loop test ran in CI under Verified against |
the-gigi-pplx
left a comment
There was a problem hiding this comment.
Approved. 2 non-blocking findings in the review comment above.
|
Thanks. Both noted as follow-ups:
|
Tests only. CI's "Rust tests" job runs the whole workspace, ignored tests included (
ci/scripts/run-rust-checks.shpasses--run-ignored all), as root in a--privileged --network hostcontainer. That means a test's assumptions about the host also run on any reused development host. Reviews of #275 found three tests that touch host state they don't own.Gaps and changes
1. node-mgr
loop_devices/tests.rs:ensure_capacity_creates_attachable_devices_past_max_loop#[ignore]. The test needs root, removes and re-creates/dev/loop63, and provisions up to 64 kernel loop devices that it never removes. Since CI runs ignored tests, it ran there. On a reused host the devices leak, and the test fails instead of skipping whenmax_loop >= 64or loop63 is busy.SPACE_NODEMGR_TEST_LOOP_DEVICESis set. This follows the crate's existingSPACE_NODEMGR_TEST_BTRFS_DIRtests: the same// CI includes ignored tests; host mutation still requires explicit opt-in.comment and the samenot opted in: …message. The doc comment's invocation and theignorereason now name the opt-in.SPACE_NODEMGR_TEST_BTRFS_DIRor any similar node-mgr opt-in. I searched.github/,ci/, the Kind scripts and the rest of the tree outsidecrates/, and the variable appears only in the tests that read it. So this test now runs only where someone opts in, and CI no longer exercises it. No CI job was added. The fake-provisioner tests in the same file still cover the reconcile logic.2. api
routes/e2b/tests.rs:test_state()connect_lazy("postgresql://postgres:postgres@localhost/space")used the default port 5432, under a comment saying nothing listens there. A dev box or host-network runner may serve 5432.postgresql://127.0.0.1:1/unused, a closed port, likecluster_admission/tests.rsand the kubernetessubstrate_with_unreachable_store. The existing 100 ms acquire timeout stays, and the comment now says why the port is safe.3. sbx-mgr
service/tests.rs:runtime_liveness_optionsSANDBOX_HOST_CONTROL_SOCKETandCREDMGR_SOCKETpaths and backsservice_with_runtime_liveness(about 61 callers). Only the_and_absent_socketsvariant overrode them.space-sbx-mgr-test-<uuidv7>/absent-*.sock). Any path that reaches either socket fails to connect instead of reaching the host's services. The helpers were not folded:_and_absent_socketstakes a caller-owned directory, so its signature still differs, and its callers are ingrpc_lifecycle/tests.rs, which open PRs are editing. Only its doc comment changed.Overlap with open PRs
routes/e2b/tests.rsis also edited by fix(k8s): retire a deleted sandbox's pods even when teardown fails #152, Remove legacy Falcon policy integration after caller migration #191 and Accept client TLS interception exemptions on ECW creates #194. None of their hunks touchtest_state(), which is near the top of the file.service/tests.rsis also edited by Quarantine sandboxes after sustained guest-agent probe failure #110, sbx-mgr: keep teardown polls pending while a delete is in flight #201 and sbx-mgr: keep quarantined rows through inventory and bound recovery that can never succeed #270. Their hunks are at lines 6453–11340, and this change touches onlyruntime_liveness_optionsand its sibling helper near line 12280.grpc_core/tests.rsorgrpc_lifecycle/tests.rs.Validation
cargo fmt --all -- --checkcargo clippy --locked -p pplx-space-node-mgr -p pplx-space-api -p pplx-space-sbx-mgr --all-targets --all-features -- -D warningscargo nextest run -p pplx-space-api --all-targets --all-features --run-ignored all,SPACE_CI_REQUIRE_TEST_DEPS=1, Postgres and Redis from the nextest setup scripts, ×2-p pplx-space-sbx-mgr, ×2-p pplx-space-node-mgr, ×2not opted in: set SPACE_NODEMGR_TEST_LOOP_DEVICES=1 …, and/dev/loop63is untouchedSPACE_NODEMGR_TEST_LOOP_DEVICES=1, as rootThe local nextest runs were done as a non-root user. Each run had exactly one failure, in a root-only ignored test whose file this PR doesn't touch, and each fails on its own root assertion:
clone_tree::tests::private_clone_blocks_foreign_uid_grafts_and_shared_clone_is_held: "run in a disposable root container"transfer_directory::tests::distinct_service_uids_can_exchange_downloads: "run this test with a root runner"I didn't re-run those two as root on a shared development host. CI runs them as root.
The opted-in root run used a host whose kernel already had more than 64 loop devices and whose
/devis a container tmpfs. So it re-created only the/dev/loop63node and added no kernel devices, and loop63 was unbound afterwards. The test still passedensure_capacity, attached and detached loop63, and checked the node's mode and group.Not changed
The same class of gap remains elsewhere in sbx-mgr's tests. It needs either a crate-wide test-constructor change or a node-manager client seam, so it is left for follow-ups:
service_for_teardown_test(about 121 callers across 11 test files),service_with_runtime_probe, andSandboxManagerService::newstill build options withDefault. That uses the production host-control and credential-manager socket paths, andservice_with_runtime_probealso reads the host's node identity. A shared absent-socket test-options base would close this. Much of the file is also edited by open PRs.pplx_space_node_mgr_client::{connect, lazy}) always dials the fixed/space/run/node-managersocket. Tests that reach it, such asfatal_kill_signal_failure_still_schedules_admitted_cleanup, would contact a live node-manager on a SPACE node, and theirInternalassertion would also accept that server's rejection. Fixing this needs an injectable node-manager transport.LOOP_CTL_ADDpath or the post-mknodchmod/chown. Kind runs the realensure_capacityat node-manager startup, but it only logs failures. An opted-in job on a disposable runner, or a small test for the permission step, would restore coverage.Other test pools still name a default-port
localhostPostgres:routes/e2b/template_build/translate/tests.rsandinternal/api/server/src/run/tests.rs. They are outside this PR's scope and could get the same treatment in a follow-up.🤖 Generated with Claude Code