Files
boxmaker/docs/plans/M3b/files/crates/toolkit/tests/shell.rs
T
kyleandClaude Opus 5.5 b426ca1958 Specify and plan M3b: the runner and the tools
A draft spec for the owner's review and 13 offline tasks with their given
tests: shared tool arguments and host rules in proto, the sealed fetch
target (M3a finding 14), the toolkit tools and SOCKS5 egress proxy, and
brokerd's [runner], podman argument lists, runtime and proxy lifecycle. Each
task's tests were run against a reference at that task's end state (560 to
638 tests, clippy clean); the reference is not in the repository. Adds the
runner-unavailable runbook entry and tip T23 (ETXTBSY in script tests).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-22 22:29:27 -07:00

90 lines
2.4 KiB
Rust

//! `toolkit shell`, run as `brokerd` runs it, with the host's `/bin/sh`. Do not edit.
mod support;
use proto::tools::ShellArgs;
use support::{TempDir, json, toolkit};
use toolkit::shell::MAX_OUTPUT;
fn sh(command: &str, cwd: Option<&str>) -> support::Ran {
let args = ShellArgs {
command: command.to_string(),
cwd: cwd.map(str::to_string),
};
toolkit(&["shell"], &json(&args))
}
#[test]
fn output_and_errors_come_back_in_order_then_the_exit_status() {
let ran = sh("echo one; echo two >&2; echo three", None);
assert_eq!(ran.code, 0);
assert_eq!(ran.stdout, "one\ntwo\nthree\n\n[exit 0]");
}
#[test]
fn a_failing_command_is_still_a_result_with_its_status() {
let ran = sh("echo nope; exit 3", None);
assert_eq!((ran.code, ran.stdout.as_str()), (0, "nope\n\n[exit 3]"));
let ran = sh("true", None);
assert_eq!(ran.stdout, "\n[exit 0]");
}
#[test]
fn a_command_killed_by_a_signal_says_so() {
let ran = sh("kill -9 $$", None);
assert_eq!(
(ran.code, ran.stdout.as_str()),
(0, "\n[killed by signal 9]")
);
}
#[test]
fn the_command_runs_in_cwd_or_in_tmp() {
let dir = TempDir::new("cwd");
let here = dir.path().to_str().unwrap();
let ran = sh("pwd", Some(here));
assert_eq!(ran.stdout, format!("{here}\n\n[exit 0]"));
let ran = sh("pwd", None);
assert_eq!(ran.stdout, "/tmp\n\n[exit 0]");
}
#[test]
fn a_missing_cwd_is_exit_1() {
let ran = sh("pwd", Some("/no/such/dir"));
assert_eq!(
(ran.code, ran.stdout.as_str()),
(1, "shell: /no/such/dir: no such directory")
);
}
#[test]
fn standard_input_is_empty() {
let ran = sh("cat; echo done", None);
assert_eq!(ran.stdout, "done\n\n[exit 0]");
}
#[test]
fn output_past_the_limit_is_dropped_and_the_command_still_finishes() {
let ran = sh(
&format!(
"head -c {} /dev/zero | tr '\\0' a; echo; echo end >&2; exit 4",
MAX_OUTPUT + 5000
),
None,
);
assert_eq!(ran.code, 0);
let expected_tail = format!("\n[output after {MAX_OUTPUT} bytes dropped]\n[exit 4]");
assert!(
ran.stdout.ends_with(&expected_tail),
"{}",
&ran.stdout[ran.stdout.len() - 80..]
);
assert_eq!(ran.stdout.len(), MAX_OUTPUT + expected_tail.len());
}
#[test]
fn output_that_is_not_utf8_is_replaced_not_refused() {
let ran = sh("printf 'a\\377b'", None);
assert_eq!(ran.stdout, "a\u{fffd}b\n[exit 0]");
}