brokerd tests: a slow fake podman no longer fails the time-limit tests
The fake wrote each argument with its own printf. On a loaded machine (titan, serving Ornith while the gate runs) the 300 ms limit fired while `run` was still recording, and the `kill` call's lines landed inside `run`'s: `a_tool_past_its_time_limit_is_killed_removed_and_failed` failed about one run in five. The fake now writes each call to a file of its own and appends it with one `cat` (bash's printf writes line by line), and the two time-limit tests check the calls other than `run`, which may be killed before it records itself. Test-only; 20 of 20 runs pass, and both tests pass with a forced one-second start. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -214,10 +214,10 @@ fn a_tool_past_its_time_limit_is_killed_removed_and_failed() {
|
|||||||
assert_eq!(got, failed(TIMED_OUT));
|
assert_eq!(got, failed(TIMED_OUT));
|
||||||
assert!(took >= Duration::from_millis(300), "{took:?}");
|
assert!(took >= Duration::from_millis(300), "{took:?}");
|
||||||
assert!(took < Duration::from_secs(5), "{took:?}");
|
assert!(took < Duration::from_secs(5), "{took:?}");
|
||||||
let calls = fake.calls();
|
let calls = fake.calls_but_run();
|
||||||
assert_eq!(calls.len(), 3, "{calls:?}");
|
assert_eq!(calls.len(), 2, "{calls:?}");
|
||||||
assert_eq!(calls[1], ["kill", "boxmaker-s1-1-0"]);
|
assert_eq!(calls[0], ["kill", "boxmaker-s1-1-0"]);
|
||||||
assert_eq!(calls[2], ["rm", "-f", "boxmaker-s1-1-0"]);
|
assert_eq!(calls[1], ["rm", "-f", "boxmaker-s1-1-0"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -154,10 +154,8 @@ fn a_tool_that_runs_too_long_still_leaves_nothing_behind() {
|
|||||||
log.sink(),
|
log.sink(),
|
||||||
));
|
));
|
||||||
assert_eq!(got, failed(TIMED_OUT));
|
assert_eq!(got, failed(TIMED_OUT));
|
||||||
let calls = fake.calls();
|
|
||||||
let tail: Vec<Vec<String>> = calls[2..].to_vec();
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tail,
|
fake.calls_but_run(),
|
||||||
[
|
[
|
||||||
vec!["kill", "boxmaker-s1-1-0"],
|
vec!["kill", "boxmaker-s1-1-0"],
|
||||||
vec!["rm", "-f", "boxmaker-s1-1-0"],
|
vec!["rm", "-f", "boxmaker-s1-1-0"],
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ impl Drop for Fake {
|
|||||||
|
|
||||||
impl Fake {
|
impl Fake {
|
||||||
/// A fake whose `run` does `run_body` (a shell fragment; `$D` is the fake's directory). Every
|
/// A fake whose `run` does `run_body` (a shell fragment; `$D` is the fake's directory). Every
|
||||||
/// other command (`kill`, `rm`) is recorded and succeeds.
|
/// other command (`kill`, `rm`) is recorded and succeeds. Each call is written to a file
|
||||||
|
/// of its own and then appended by one `cat`, one write, so a `kill` made while a slow `run`
|
||||||
|
/// starts is never mixed into its lines (the shell's `printf` writes line by line).
|
||||||
pub fn new(tag: &str, run_body: &str) -> Fake {
|
pub fn new(tag: &str, run_body: &str) -> Fake {
|
||||||
let n = NEXT.fetch_add(1, Ordering::SeqCst);
|
let n = NEXT.fetch_add(1, Ordering::SeqCst);
|
||||||
let dir = std::env::temp_dir().join(format!("bx-fp-{tag}-{}-{n}", std::process::id()));
|
let dir = std::env::temp_dir().join(format!("bx-fp-{tag}-{}-{n}", std::process::id()));
|
||||||
@@ -45,7 +47,7 @@ impl Fake {
|
|||||||
std::fs::create_dir_all(&dir).unwrap();
|
std::fs::create_dir_all(&dir).unwrap();
|
||||||
let script = dir.join("podman");
|
let script = dir.join("podman");
|
||||||
let text = format!(
|
let text = format!(
|
||||||
"#!/bin/sh\nD='{}'\nfor a in \"$@\"; do printf '%s\\n' \"$a\"; done >> \"$D/calls\"\necho --- >> \"$D/calls\"\n[ \"$1\" = run ] || exit 0\n{run_body}\n",
|
"#!/bin/sh\nD='{}'\nprintf '%s\\n' \"$@\" --- > \"$D/call.$$\"\ncat \"$D/call.$$\" >> \"$D/calls\"\nrm -f \"$D/call.$$\"\n[ \"$1\" = run ] || exit 0\n{run_body}\n",
|
||||||
dir.display()
|
dir.display()
|
||||||
);
|
);
|
||||||
std::fs::write(&script, text).unwrap();
|
std::fs::write(&script, text).unwrap();
|
||||||
@@ -68,6 +70,14 @@ impl Fake {
|
|||||||
calls
|
calls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Every call but `run`, in order. A `run` killed at its time limit may not have recorded
|
||||||
|
/// itself yet, or may record itself after the `kill`, so time-limit tests check these.
|
||||||
|
pub fn calls_but_run(&self) -> Vec<Vec<String>> {
|
||||||
|
let mut calls = self.calls();
|
||||||
|
calls.retain(|call| call.first().map(String::as_str) != Some("run"));
|
||||||
|
calls
|
||||||
|
}
|
||||||
|
|
||||||
/// What the last `run` read on standard input, if the body saved it to `$D/stdin`.
|
/// What the last `run` read on standard input, if the body saved it to `$D/stdin`.
|
||||||
pub fn stdin(&self) -> String {
|
pub fn stdin(&self) -> String {
|
||||||
std::fs::read_to_string(self.dir.join("stdin")).unwrap_or_default()
|
std::fs::read_to_string(self.dir.join("stdin")).unwrap_or_default()
|
||||||
|
|||||||
Reference in New Issue
Block a user