wsb 0.275.7622

Workspace tools for every project under $PRJ: git across submodules, template stamping, GitHub, and the workbench
Documentation
//! What the wrapper must and must not do.

use super::*;

/// TEST9035: the wrapped command is the same command, in its own scope.
///
/// Everything after `--` has to arrive at the program unchanged. A wrapper
/// that reordered or dropped an argument would make every operation fail in a
/// way that looked like the operation's own bug.
#[test]
fn test9035_the_command_survives_being_wrapped() {
    let argv: Vec<String> = ["wsb", "run", "--client", "unifloom", "--verbose"]
        .iter()
        .map(|s| s.to_string())
        .collect();

    let Some(wrapped) = wrap(&argv, "wsb-op-1234", &[]) else {
        // No systemd here; the caller runs the command as it is, which is
        // exactly what None means.
        return;
    };

    let separator = wrapped
        .iter()
        .position(|arg| arg == "--")
        .expect("a wrapped command is separated from the wrapper");
    assert_eq!(&wrapped[separator + 1..], argv.as_slice());
    assert_eq!(wrapped[0], "systemd-run");
    assert!(wrapped.contains(&"--scope".to_string()));
    // Cleaned up when it exits, and silent: an announcement on stderr would
    // be the one line of a packaged run that is not a record.
    assert!(wrapped.contains(&"--collect".to_string()));
    assert!(wrapped.contains(&"--quiet".to_string()));
    assert!(wrapped.contains(&"--unit=wsb-op-1234".to_string()));
}

/// TEST9036: the daemon asks the reaper to look elsewhere.
///
/// The daemon holds almost no memory and everything else is reachable through
/// it; a build that runs the machine out of memory can be run again.
#[test]
fn test9036_the_daemon_asks_to_be_spared() {
    assert!(
        DAEMON_PROPERTIES
            .iter()
            .any(|p| p.contains("ManagedOOMPreference=avoid")),
        "the daemon must ask systemd's reaper to prefer anything else"
    );
}

/// TEST9037: a name that systemd would refuse never reaches it.
///
/// The unit name is built from a worktree's directory name. A stray slash or
/// space would be rejected at spawn time, turning a naming mistake into a
/// daemon that will not start — with an error about unit names.
#[test]
fn test9037_unit_names_are_made_safe_rather_than_trusted() {
    assert_eq!(unit_name("wsb-op-abc123"), "wsb-op-abc123");
    assert_eq!(unit_name("cartridge build/2"), "cartridge-build-2");
    assert_eq!(unit_name("--weird--"), "weird");
    assert_eq!(unit_name(""), "wsb");
    assert_eq!(unit_name("///"), "wsb");
    for name in ["wsb-op-abc", "cartridge build/2", "a b c", "", "///"] {
        let made = unit_name(name);
        assert!(
            made.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_'),
            "{made} is not a unit name systemd would take"
        );
    }
}

/// TEST9038: an empty command is not wrapped into a valid-looking one.
#[test]
fn test9038_nothing_is_not_wrapped() {
    assert!(wrap(&[], "wsb-op", &[]).is_none());
}