use std::process::{Command, Stdio};
use std::time::{Duration, Instant};
use assert_cmd::prelude::*;
use tempfile::TempDir;
const WALL_CLOCK_CEILING: Duration = Duration::from_secs(10);
fn spawn_bare_mnem(cwd: &std::path::Path) -> std::process::Child {
let path = Command::cargo_bin("mnem").unwrap().get_program().to_owned();
Command::new(path)
.current_dir(cwd)
.env_remove("MNEM_NO_WIZARD")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("spawn mnem")
}
#[test]
fn bare_mnem_under_non_tty_exits_fast_not_hangs() {
let td = TempDir::new().unwrap();
let mut child = spawn_bare_mnem(td.path());
drop(child.stdin.take());
let started = Instant::now();
loop {
match child.try_wait() {
Ok(Some(status)) => {
assert!(
status.success(),
"bare `mnem` in non-tty must exit 0; got {status:?}"
);
let out = child.wait_with_output().expect("wait_with_output");
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(
stderr.contains("mnem: no subcommand given") || stderr.contains("mnem --help"),
"expected non-interactive hint in stderr, got:\n{stderr}"
);
return;
}
Ok(None) => {
if started.elapsed() > WALL_CLOCK_CEILING {
let _ = child.kill();
panic!(
"bare `mnem` under non-tty hung for {:?} (ceiling {WALL_CLOCK_CEILING:?}); wizard fast-path regressed?",
started.elapsed()
);
}
std::thread::sleep(Duration::from_millis(50));
}
Err(e) => panic!("try_wait failed: {e}"),
}
}
}
#[test]
fn bare_mnem_with_mnem_no_wizard_also_exits_fast() {
let td = TempDir::new().unwrap();
let path = Command::cargo_bin("mnem").unwrap().get_program().to_owned();
let mut child = Command::new(path)
.current_dir(td.path())
.env("MNEM_NO_WIZARD", "1")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("spawn mnem");
drop(child.stdin.take());
let started = Instant::now();
loop {
match child.try_wait() {
Ok(Some(status)) => {
assert!(
status.success(),
"env-var bypass must exit 0; got {status:?}"
);
return;
}
Ok(None) => {
if started.elapsed() > WALL_CLOCK_CEILING {
let _ = child.kill();
panic!(
"bare `mnem` with MNEM_NO_WIZARD=1 hung for {:?}",
started.elapsed()
);
}
std::thread::sleep(Duration::from_millis(50));
}
Err(e) => panic!("try_wait failed: {e}"),
}
}
}