Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:35:57.327Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

sandbox_tests.rs

124 lines · 4.0 KB · rust
1#![allow(clippy::disallowed_methods, reason = "tooling is exempt")]
2
3use std::process::Command;
4
5use anyhow::{Context as _, Result, bail};
6use clap::Parser;
7
8/// Runs the Linux Bubblewrap sandboxing NixOS VM tests (see `nix/tests/sandboxing`).
9///
10/// Each test boots a real kernel under QEMU to exercise bwrap behavior across
11/// host configurations: a working host (the sandbox must be enforced and the
12/// full fs x network policy matrix must hold), and degraded hosts (no bwrap,
13/// setuid-only bwrap, user namespaces disabled) where `Sandbox::can_create`
14/// must report the specific failure and the consumer must fail closed. They
15/// therefore only run on Linux with `/dev/kvm` available, and require `nix`
16/// with flakes enabled.
17#[derive(Parser)]
18pub struct SandboxTestsArgs {
19    /// Names of specific tests to run (e.g. `sandbox-working`). Defaults
20    /// to all.
21    tests: Vec<String>,
22
23    /// Nix system to build for. Defaults to the host system.
24    #[arg(long)]
25    system: Option<String>,
26
27    /// Force already-built tests to re-run instead of returning the cached
28    /// result (passes `--rebuild` to `nix build`).
29    ///
30    /// This only works once a test has been built at least once; after changing
31    /// the test code the derivation changes, so run without `--rebuild` first.
32    #[arg(long)]
33    rebuild: bool,
34
35    /// List the available tests and exit without running anything.
36    #[arg(long)]
37    list: bool,
38}
39
40/// Tests in `nix/tests/sandboxing` are exposed as flake checks with this prefix.
41const TEST_PREFIX: &str = "sandbox-";
42
43pub fn run_sandbox_tests(args: SandboxTestsArgs) -> Result<()> {
44    let system = args.system.unwrap_or_else(host_system);
45    let available = available_tests(&system)?;
46
47    if args.list {
48        for name in &available {
49            println!("{name}");
50        }
51        return Ok(());
52    }
53
54    let selected = if args.tests.is_empty() {
55        available
56    } else {
57        for name in &args.tests {
58            if !available.contains(name) {
59                bail!(
60                    "unknown sandbox test {name:?}; available: {}",
61                    available.join(", ")
62                );
63            }
64        }
65        args.tests
66    };
67
68    if selected.is_empty() {
69        bail!("no sandbox tests found for system `{system}`");
70    }
71
72    let mut command = Command::new("nix");
73    command.args(["build", "-L", "--keep-going"]);
74    if args.rebuild {
75        command.arg("--rebuild");
76    }
77    for name in &selected {
78        command.arg(format!(".#checks.{system}.{name}"));
79    }
80
81    eprintln!("Running sandbox tests: {}", selected.join(", "));
82    let status = command.status().context("failed to run `nix build`")?;
83    if !status.success() {
84        bail!("sandbox tests failed");
85    }
86    Ok(())
87}
88
89/// The Nix system double for the host. These tests are Linux-only, so we always
90/// target a `*-linux` system (overridable via `--system`).
91fn host_system() -> String {
92    format!("{}-linux", std::env::consts::ARCH)
93}
94
95/// Query the flake for the names of the sandbox-test checks, so the task stays
96/// in sync with `nix/tests/sandboxing` without a hardcoded list.
97fn available_tests(system: &str) -> Result<Vec<String>> {
98    let output = Command::new("nix")
99        .args([
100            "eval",
101            &format!(".#checks.{system}"),
102            "--apply",
103            "checks: builtins.concatStringsSep \"\\n\" (builtins.attrNames checks)",
104            "--raw",
105        ])
106        .output()
107        .context("failed to run `nix eval` to list checks (is `nix` installed?)")?;
108    if !output.status.success() {
109        bail!(
110            "`nix eval` failed: {}",
111            String::from_utf8_lossy(&output.stderr).trim()
112        );
113    }
114
115    let names = String::from_utf8(output.stdout).context("`nix eval` output was not UTF-8")?;
116    let mut tests: Vec<String> = names
117        .lines()
118        .filter(|name| name.starts_with(TEST_PREFIX))
119        .map(str::to_string)
120        .collect();
121    tests.sort();
122    Ok(tests)
123}
124
Served at tenant.openagents/omega Member data and write actions are omitted.