Files

149 lines
4.3 KiB
Rust

//! Integration tests for the `runprobe` command.
use std::fs;
use assert_cmd::Command;
use predicates::prelude::*;
use tempfile::TempDir;
fn cargo_command() -> Command {
Command::cargo_bin("runprobe").expect("binary")
}
#[cfg(windows)]
fn pwsh_success_args() -> Vec<&'static str> {
vec!["Write-Output", "done"]
}
#[test]
fn help_mentions_shell_tail_and_log_dir_flags() {
let mut command = cargo_command();
command
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("--shell <MODE>"))
.stdout(predicate::str::contains("--tail-bytes <COUNT>"))
.stdout(predicate::str::contains("--log-dir <PATH>"));
}
#[cfg(windows)]
#[test]
fn json_output_reports_shell_run_and_cwd() {
let temp = TempDir::new().expect("temp dir");
let mut command = cargo_command();
command
.arg("--json")
.arg("--shell")
.arg("pwsh")
.arg("--cwd")
.arg(temp.path())
.arg("--")
.args(pwsh_success_args())
.assert()
.success()
.stdout(predicate::str::contains("\"ok\":true"))
.stdout(predicate::str::contains("\"exit_code\":0"))
.stdout(predicate::str::contains("\"timed_out\":false"))
.stdout(predicate::str::contains("\"stdout_tail\":\"done"))
.stdout(predicate::str::contains(format!(
"\"cwd\":\"{}\"",
temp.path().display().to_string().replace('\\', "\\\\")
)));
}
#[cfg(windows)]
#[test]
fn failure_text_includes_stdout_and_stderr_tails() {
let temp = TempDir::new().expect("temp dir");
let script = temp.path().join("fail.ps1");
fs::write(&script, "Write-Error 'boom'\nWrite-Output 'out'\nexit 9\n").expect("script");
let mut command = cargo_command();
command
.arg("--shell")
.arg("pwsh")
.arg("--tail-bytes")
.arg("32")
.arg("--")
.arg(script)
.assert()
.success()
.stdout(predicate::str::contains("fail exit_code=9"))
.stdout(predicate::str::contains("stderr_tail:"))
.stdout(predicate::str::contains("boom"))
.stdout(predicate::str::contains("stdout_tail:"))
.stdout(predicate::str::contains("out"));
}
#[cfg(windows)]
#[test]
fn timeout_json_reports_log_path_when_requested() {
let log_dir = TempDir::new().expect("log dir");
let script_dir = TempDir::new().expect("script dir");
let script = script_dir.path().join("slow.ps1");
fs::write(
&script,
"Start-Sleep -Milliseconds 500\nWrite-Output 'late'\n",
)
.expect("script");
let mut command = cargo_command();
let assert = command
.arg("--json")
.arg("--shell")
.arg("pwsh")
.arg("--timeout")
.arg("100ms")
.arg("--log-dir")
.arg(log_dir.path())
.arg("--")
.arg(script)
.assert()
.success()
.stdout(predicate::str::contains("\"timed_out\":true"))
.stdout(predicate::str::contains("\"log_path\":\""));
let output = String::from_utf8(assert.get_output().stdout.clone()).expect("utf8 stdout");
let json: serde_json::Value = serde_json::from_str(&output).expect("json");
let log_path = json["log_path"].as_str().expect("log path");
let log_body = fs::read_to_string(log_path).expect("log body");
assert!(log_body.contains("[stdout]"));
assert!(log_body.contains("[stderr]"));
}
#[cfg(windows)]
#[test]
fn raw_shell_runs_native_command_directly() {
let mut command = cargo_command();
command
.arg("--json")
.arg("--")
.arg("pwsh")
.arg("-NoProfile")
.arg("-Command")
.arg("Write-Output raw-ok")
.assert()
.success()
.stdout(predicate::str::contains("\"ok\":true"))
.stdout(predicate::str::contains("\"stdout_tail\":\"raw-ok"));
}
#[cfg(windows)]
#[test]
fn cmd_shell_runs_command_through_wrapper() {
let mut command = cargo_command();
command
.arg("--json")
.arg("--shell")
.arg("cmd")
.arg("--")
.arg("cmd")
.arg("/d")
.arg("/s")
.arg("/c")
.arg("echo cmd-ok")
.assert()
.success()
.stdout(predicate::str::contains("\"ok\":true"))
.stdout(predicate::str::contains("\"stdout_tail\":\"cmd-ok"));
}