Skip to content

Commit ada9786

Browse files
fix(up): fail errored one-shot passes
agent-identity: dev3.direct.omp.vjwqaz7t agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.0.11 agent-runtime: OMP 18.0.11 tooling-profile: dotfiles@000f2b3
1 parent e0a155e commit ada9786

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

src/main.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3579,6 +3579,9 @@ fn up_spec_fleet(spec_file: &Path, host: Option<String>, once: bool, interval: u
35793579
if report.skipped {
35803580
anyhow::bail!("one-shot reconcile pass was skipped");
35813581
}
3582+
if !report.errors.is_empty() {
3583+
anyhow::bail!("one-shot reconcile pass reported errors");
3584+
}
35823585
return Ok(());
35833586
}
35843587

@@ -3717,6 +3720,9 @@ fn up(
37173720
if targeted && !report.errors.is_empty() {
37183721
anyhow::bail!("targeted one-shot reconcile pass reported errors");
37193722
}
3723+
if !report.errors.is_empty() {
3724+
anyhow::bail!("one-shot reconcile pass reported errors");
3725+
}
37203726
return Ok(());
37213727
}
37223728

tests/up_once_exit.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,35 @@ fn failing_pty_path() -> tempfile::TempDir {
1414
bin
1515
}
1616

17+
fn failing_pty_spawn_path() -> tempfile::TempDir {
18+
let bin = tempfile::tempdir().unwrap();
19+
executable(
20+
&bin.path().join("pty"),
21+
"#!/bin/sh\nif [ \"$1\" = list ]; then\n printf '[]\\n'\n exit 0\nfi\nprintf 'forced pty failure\\n' >&2\nexit 42\n",
22+
);
23+
bin
24+
}
25+
26+
fn assert_errors_once_exits_nonzero(command: &mut Command) {
27+
let output = command.output().unwrap();
28+
assert!(
29+
!output.status.success(),
30+
"an errored --once pass reported success\nstdout:\n{}\nstderr:\n{}",
31+
String::from_utf8_lossy(&output.stdout),
32+
String::from_utf8_lossy(&output.stderr)
33+
);
34+
let stderr = String::from_utf8_lossy(&output.stderr);
35+
assert!(
36+
stderr.contains("error: spawn")
37+
&& stderr.contains("one-shot reconcile pass reported errors"),
38+
"missing errored-pass report:\n{stderr}"
39+
);
40+
assert!(
41+
!stderr.contains("pass skipped"),
42+
"spawn failure incorrectly skipped the pass:\n{stderr}"
43+
);
44+
}
45+
1746
fn assert_skipped_once_exits_nonzero(command: &mut Command) {
1847
let output = command.output().unwrap();
1948
assert!(
@@ -53,6 +82,29 @@ fn catalog_up_once_exits_nonzero_when_the_pass_is_skipped() {
5382
);
5483
}
5584

85+
#[test]
86+
fn catalog_up_once_exits_nonzero_when_the_report_has_errors() {
87+
let tmp = tempfile::tempdir().unwrap();
88+
let bin = failing_pty_spawn_path();
89+
let agent = tmp.path().join("catalog/agents/h/worker/agent.kdl");
90+
fs::create_dir_all(agent.parent().unwrap()).unwrap();
91+
fs::write(
92+
&agent,
93+
"agent \"worker\" { host \"h\"; command \"true\" }\n",
94+
)
95+
.unwrap();
96+
97+
assert_errors_once_exits_nonzero(
98+
Command::new(env!("CARGO_BIN_EXE_st2"))
99+
.arg("up")
100+
.arg("--catalog")
101+
.arg(tmp.path().join("catalog"))
102+
.args(["--host", "h", "--once"])
103+
.env("PATH", bin.path())
104+
.env("XDG_STATE_HOME", tmp.path().join("state")),
105+
);
106+
}
107+
56108
#[test]
57109
fn spec_up_once_exits_nonzero_when_the_pass_is_skipped() {
58110
let tmp = tempfile::tempdir().unwrap();
@@ -73,3 +125,24 @@ fn spec_up_once_exits_nonzero_when_the_pass_is_skipped() {
73125
.env("XDG_STATE_HOME", tmp.path().join("state")),
74126
);
75127
}
128+
129+
#[test]
130+
fn spec_up_once_exits_nonzero_when_the_report_has_errors() {
131+
let tmp = tempfile::tempdir().unwrap();
132+
let bin = failing_pty_spawn_path();
133+
let spec = tmp.path().join("fleet.kdl");
134+
fs::write(
135+
&spec,
136+
"host \"h\"\nteam \"fleet\" { agent \"worker\" { command \"true\" } }\n",
137+
)
138+
.unwrap();
139+
140+
assert_errors_once_exits_nonzero(
141+
Command::new(env!("CARGO_BIN_EXE_st2"))
142+
.arg("up")
143+
.arg(&spec)
144+
.args(["--host", "h", "--once"])
145+
.env("PATH", bin.path())
146+
.env("XDG_STATE_HOME", tmp.path().join("state")),
147+
);
148+
}

0 commit comments

Comments
 (0)