use std::io::Write;
use std::process::{Command, Stdio};
use crate::common::workspace_bin;
fn wt_perf_bin() -> std::path::PathBuf {
workspace_bin("wt-perf")
}
#[test]
fn test_wt_perf_trace_from_stdin() {
let sample_trace = r#"[wt-trace] ts=1000000 tid=1 cmd="git status" dur_us=10000 ok=true
[wt-trace] ts=1010000 tid=1 cmd="git status" dur_us=15000 ok=true
[wt-trace] ts=1025000 tid=1 cmd="git diff" dur_us=100000 ok=true
[wt-trace] ts=1025000 tid=2 event="Showed skeleton"
[wt-trace] ts=1125000 tid=1 cmd="git merge-base HEAD main" dur_us=500000 ok=true
[wt-trace] ts=1625000 tid=1 cmd="gh pr list" dur_us=200000 ok=true"#;
let mut child = Command::new(wt_perf_bin())
.arg("trace")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("Failed to spawn wt-perf");
child
.stdin
.take()
.unwrap()
.write_all(sample_trace.as_bytes())
.expect("Failed to write to stdin");
let output = child.wait_with_output().expect("Failed to read output");
assert!(output.status.success(), "wt-perf trace should succeed");
let stdout = String::from_utf8_lossy(&output.stdout);
let json: serde_json::Value = serde_json::from_str(&stdout).expect("Should output valid JSON");
assert_eq!(json["displayTimeUnit"], "ms", "Should have displayTimeUnit");
assert!(
json["traceEvents"].is_array(),
"Should have traceEvents array"
);
let events = json["traceEvents"].as_array().unwrap();
assert_eq!(events.len(), 6, "Should have 6 events");
assert_eq!(events[0]["name"], "git status");
assert_eq!(events[0]["ph"], "X"); assert!(events[0]["dur"].is_number());
assert_eq!(events[3]["name"], "Showed skeleton");
assert_eq!(events[3]["ph"], "I"); assert_eq!(events[3]["s"], "g"); assert!(events[3]["dur"].is_null()); }
#[test]
fn test_wt_perf_trace_no_input_shows_usage() {
let output = Command::new(wt_perf_bin())
.args(["trace", "/nonexistent/path/to/file.log"])
.output()
.expect("Failed to run wt-perf");
assert!(
!output.status.success(),
"Should fail with non-existent file"
);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
stderr.contains("Error reading"),
"Should show error message"
);
}
#[test]
fn test_wt_perf_trace_empty_input() {
let mut child = Command::new(wt_perf_bin())
.arg("trace")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("Failed to spawn wt-perf");
child.stdin.take().unwrap();
let output = child.wait_with_output().expect("Failed to read output");
assert!(
!output.status.success(),
"Should fail with no trace entries"
);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
stderr.contains("No [wt-trace] entries found"),
"Should indicate no trace entries"
);
}
#[test]
fn test_wt_perf_trace_from_file() {
let temp_dir = tempfile::tempdir().expect("Failed to create temp dir");
let log_file = temp_dir.path().join("trace.log");
let sample_trace = r#"[wt-trace] ts=1000000 tid=1 cmd="git rev-parse" dur_us=5000 ok=true
[wt-trace] ts=1005000 tid=1 cmd="git status" dur_us=10000 ok=true
[wt-trace] ts=1015000 tid=1 event="Skeleton displayed"
[wt-trace] ts=1015000 tid=2 cmd="git diff" dur_us=50000 ok=true"#;
std::fs::write(&log_file, sample_trace).expect("Failed to write sample log");
let output = Command::new(wt_perf_bin())
.args(["trace", log_file.to_str().unwrap()])
.output()
.expect("Failed to run wt-perf");
assert!(output.status.success(), "Should succeed with sample log");
let stdout = String::from_utf8_lossy(&output.stdout);
let json: serde_json::Value = serde_json::from_str(&stdout).expect("Should output valid JSON");
assert!(json["traceEvents"].is_array(), "Should have traceEvents");
let events = json["traceEvents"].as_array().unwrap();
assert_eq!(events.len(), 4, "Should have 4 events");
assert_eq!(events[0]["name"], "git rev-parse");
assert_eq!(events[2]["name"], "Skeleton displayed");
assert_eq!(events[2]["ph"], "I"); }