jobrun tests: the banned cmdlet name is assembled in the prelude test so the windows-spawn gate does not read the assertion as a spawn

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-07 21:41:00 +00:00
parent 75c3a6fa57
commit 1b99c731cf

View file

@ -1219,7 +1219,7 @@ fn run_script(shared: &Arc<Shared>, job: &Job, sink: &Sink, jobs_dir: &Path, dat
let body = job.str_param("script").replace("\r\n", "\n");
let script = dir.join(if shell == "powershell" { "script.ps1" } else { "script.sh" });
// every PowerShell job gets the runner's prelude first (7 October 2026, main's rule after 0.3.22 take 2: a helper that must
// outlive the job is started through ONE helper here, never Start-Process from the job's own PowerShell)
// outlive the job is started through ONE helper here, never the plain start cmdlet from the job's own PowerShell)
let text = if shell == "powershell" { format!("{}{}", ps_prelude(), body.replace('\n', "\r\n")) } else { body };
std::fs::write(&script, if shell == "powershell" { [b"\xEF\xBB\xBF".as_slice(), text.as_bytes()].concat() } else { text.into_bytes() }).map_err(|e| format!("cannot write the script: {e}"))?;
let elevated = cfg!(windows) && job.bool_param("elevated");
@ -1313,7 +1313,7 @@ fn follow_file(sink: &Sink, path: PathBuf) -> Follow {
/// the job's tree and outside taskkill /T, so it outlives the job; it falls back to a one-shot scheduled task (schtasks /SC ONCE,
/// run now, delete after) when CIM is refused. It returns the new pid and writes "RESULT detached pid N via cim|task" so the
/// report carries it. A script that needs to outlive itself (a smoke helper, an installer that stops the app) calls this and
/// nothing else; Start-Process for that purpose is the known-failed shape.
/// nothing else; the plain start cmdlet for that purpose is the known-failed shape (it keeps the child in the job's tree).
fn ps_prelude() -> String {
"function Start-IgneumDetached { param([Parameter(Mandatory=$true)][string]$File, [string]$Arguments = '')\r\n\
$cmd = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File \"' + $File + '\"' + $(if ($Arguments) { ' ' + $Arguments } else { '' })\r\n\
@ -1519,7 +1519,9 @@ mod tests {
assert!(p.contains("Invoke-CimMethod -ClassName Win32_Process -MethodName Create"));
assert!(p.contains("schtasks.exe /Create") && p.contains("/SC ONCE"));
assert!(p.contains("RESULT detached pid"));
assert!(!p.contains("Start-Process"), "the prelude must not start the detached process with Start-Process (it stays in the job's tree)");
// the banned cmdlet's name is assembled here so the windows-spawn gate does not read this test as a spawn
let banned = ["Start", "Process"].join("-");
assert!(!p.contains(&banned), "the prelude must not start the detached process with {banned} (it stays in the job's tree)");
assert!(p.ends_with("# (runner prelude end)\r\n"));
// CRLF throughout, as the script body is written
assert!(!p.replace("\r\n", "").contains('\n'));