use std::path::{Path, PathBuf};
use std::process::Command;
fn repo_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.and_then(Path::parent)
.expect("smix-cli lives under <repo>/crates")
.to_path_buf()
}
fn script_path() -> PathBuf {
repo_root().join("scripts/v5/selftest-gate-multi.sh")
}
#[test]
fn case01_script_exists() {
let p = script_path();
assert!(p.is_file(), "missing {p:?} — c7 hasn't landed");
}
#[test]
fn case02_script_executable_or_runnable() {
let p = script_path();
let out = Command::new("bash")
.args(["-n", p.to_str().unwrap()])
.output()
.expect("bash -n");
assert!(
out.status.success(),
"bash -n failed: stderr=\n{}",
String::from_utf8_lossy(&out.stderr)
);
}
#[test]
fn case03_mentions_required_subjects() {
let body = std::fs::read_to_string(script_path()).expect("read script");
for needle in [
"smix capsule up",
"smix capsule down",
"smix selftest multi",
"summary.json",
".smix/selftest-multi",
"trap cleanup EXIT",
"SMIX_UDIDS",
"SMIX_RUNNER_PORT",
] {
assert!(body.contains(needle), "script body must mention `{needle}`");
}
}
#[test]
fn case04_mentions_required_exit_codes() {
let body = std::fs::read_to_string(script_path()).expect("read script");
for code in [
"exit 9", "exit 10", "exit 11", "exit 12", "exit 13", "exit 14",
] {
assert!(body.contains(code), "script body must mention `{code}`");
}
}
#[test]
fn case05_no_simctl_shutdown_all() {
let body = std::fs::read_to_string(script_path()).expect("read script");
assert!(
!body.contains("simctl shutdown all"),
"script must not invoke `simctl shutdown all`(违反 smix-sim-guard-hook);用 per-UDID `smix capsule down` 兜底"
);
assert!(
!body.contains("simctl shutdown booted"),
"script must not invoke `simctl shutdown booted`"
);
}