use assert_cmd::prelude::*;
use predicates::prelude::*;
use std::process::Command;
use std::time::{Duration, Instant};
use tempfile::TempDir;
fn pend_bin() -> Command {
Command::cargo_bin("pend").expect("binary exists")
}
fn pend_with_tmpdir() -> (TempDir, Command) {
let tmp = TempDir::new().expect("create temp dir");
let mut cmd = pend_bin();
cmd.env("PEND_DIR", tmp.path());
(tmp, cmd)
}
#[test]
fn timeout_enforced() {
let python = ["python3", "python"]
.iter()
.find(|prog| Command::new(prog).arg("--version").output().is_ok())
.cloned();
let Some(python) = python else {
eprintln!(
"warning: skipping timeout_enforced test – no python interpreter found in PATH"
);
return;
};
let (tmp, mut pend_cmd) = pend_with_tmpdir();
pend_cmd
.args([
"do",
"timeoutjob",
"--timeout",
"1",
python,
"-c",
"import time; time.sleep(5)",
])
.assert()
.success();
let start = Instant::now();
pend_bin()
.env("PEND_DIR", tmp.path())
.args(["--no-color", "wait", "timeoutjob"])
.assert()
.failure();
let elapsed = start.elapsed();
assert!(
elapsed < Duration::from_secs(4),
"expected timeout to abort the job early (elapsed = {elapsed:?})"
);
}
#[test]
fn retries_eventual_success() {
let python = ["python3", "python"]
.iter()
.find(|prog| Command::new(prog).arg("--version").output().is_ok())
.cloned();
let Some(python) = python else {
eprintln!(
"warning: skipping retries_eventual_success test – no python interpreter found in PATH"
);
return;
};
let script_dir = TempDir::new().expect("create script dir");
let sentinel_path = script_dir.path().join("sentinel.txt");
let helper_script = script_dir.path().join("flaky.py");
std::fs::write(
&helper_script,
format!(
r#"import os, sys, pathlib
sentinel = pathlib.Path(r"{}")
if sentinel.exists():
print("second run – success")
sys.exit(0)
else:
sentinel.write_text("created")
print("first run – failing")
sys.exit(3)
"#,
sentinel_path.display()
),
)
.expect("write helper script");
let (tmp, mut pend_cmd) = pend_with_tmpdir();
pend_cmd
.args([
"do",
"flakyjob",
"--retries",
"1",
python,
helper_script.to_str().unwrap(),
])
.assert()
.success();
pend_bin()
.env("PEND_DIR", tmp.path())
.args(["--no-color", "wait", "flakyjob"])
.assert()
.success()
.stdout(predicate::str::contains("second run – success"));
}