test: probe the provider sandbox instead of failing on it
The 16 sandboxed provider tests in `tests/unit/ci-artifact-contract.test.ts` fail wherever unprivileged user namespaces are denied. bubblewrap is installed and answers `--version`, but `bwrap --unshare-net … -- /bin/true` exits 1 with `bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted`, and it fails the same way with no netns flag at all (`setting up uid map: Permission denied`), so this is the whole nested-userns capability and not one option. Sixteen assertion errors on every local run buried whatever else the file had to say. `scripts/lib/provider-sandbox-probe.ts` now runs a trivial command under the real isolation options — `runProviderInSandbox` spreads the same `PROVIDER_SANDBOX_ISOLATION_ARGUMENTS`, and a test fails if an isolation option is added to the run without the probe having to clear it. Capability is measured, never inferred from the binary existing or from a version string; both would pass here. An unusable sandbox means two different things in two places, so the decision is explicit. Locally it is an environment fact: the affected tests skip and carry the bwrap diagnostic as their skip note, visible as `↓ … [reason]`. In CI it is a regression — a security gate that silently stopped running is exactly what these tests exist to catch — so the same probe result fails the run through one guard test that says "the provider sandbox is unavailable" instead of sixteen assertion errors. CI is detected with `CI === "true"` via a new `isCiRun`, sharing the predicate that already gates `ciBuildEnvironmentFailures`. The workflow sets it at the top-level `env:` block, so it holds in every job; `CI_RUN_ID` and its `GITEA_`/`GITHUB_` fallbacks are declared only by the release-tier provider jobs and are absent from the merge gates that run this file, so keying on them would have left the CI branch permanently dead. The three `it.each` groups become `it.for` because only `.for` passes the test context, which is what carries the skip note. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1a40522ff8
commit
74281b0277
@@ -30,6 +30,7 @@ import {
|
||||
type ProviderGuardianLease,
|
||||
} from "./lib/provider-guardian-client.ts";
|
||||
import { createProviderOutputLimiter } from "./lib/provider-output-limiter.ts";
|
||||
import { PROVIDER_SANDBOX_ISOLATION_ARGUMENTS } from "./lib/provider-sandbox-probe.ts";
|
||||
|
||||
const kind = process.argv[process.argv.indexOf("--kind") + 1];
|
||||
const PROVIDER_TMP_BYTES = 16_777_216;
|
||||
@@ -246,10 +247,7 @@ async function runProviderInSandbox(
|
||||
): Promise<void> {
|
||||
const cpuSeconds = providerCpuSeconds();
|
||||
const bwrapArguments = [
|
||||
"--die-with-parent", "--new-session", "--as-pid-1",
|
||||
"--unshare-pid", "--unshare-ipc", "--unshare-uts", "--unshare-net",
|
||||
"--dev", "/dev", "--remount-ro", "/dev",
|
||||
"--proc", "/proc", "--remount-ro", "/proc",
|
||||
...PROVIDER_SANDBOX_ISOLATION_ARGUMENTS,
|
||||
"--size", String(PROVIDER_TMP_BYTES), "--tmpfs", "/tmp",
|
||||
"--dir", "/tmp/provider-home",
|
||||
"--size", String(PROVIDER_MASK_BYTES), "--tmpfs", "/etc",
|
||||
|
||||
Reference in New Issue
Block a user