use assert_cmd::Command;
use std::path::{Path, PathBuf};
use tempfile::TempDir;
mod python_enrichment_test;
mod rust_enrichment_test;
mod typescript_enrichment_test;
#[derive(Debug)]
pub struct ExpectedEnrichment {
pub function_name: String,
pub min_calls: usize,
pub latency_p50_range: Option<(f64, f64)>,
pub has_errors: bool,
pub error_message: Option<String>,
}
pub fn run_telemetry_command(
source_dir: &Path,
telemetry_file: &Path,
service_filter: Option<&str>,
) -> Result<String, Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin("context-creator")?;
cmd.arg("telemetry").arg("-t").arg(telemetry_file);
if let Some(service) = service_filter {
cmd.arg("--service").arg(service);
}
cmd.arg(source_dir);
let output = cmd.output()?;
if !output.status.success() {
return Err(format!(
"Command failed: {}",
String::from_utf8_lossy(&output.stderr)
)
.into());
}
Ok(String::from_utf8_lossy(&output.stdout).to_string())
}
pub fn setup_test_directory(
source_files: &[(PathBuf, String)],
) -> Result<TempDir, Box<dyn std::error::Error>> {
let temp_dir = TempDir::new()?;
for (relative_path, content) in source_files {
let full_path = temp_dir.path().join(relative_path);
if let Some(parent) = full_path.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(full_path, content)?;
}
Ok(temp_dir)
}
pub fn assert_enrichments(output: &str, expected: &[ExpectedEnrichment]) {
assert!(
output.contains("Telemetry Correlation Summary:"),
"Missing correlation summary"
);
for enrichment in expected {
assert!(
output.contains(&enrichment.function_name),
"Function {} not found in output",
enrichment.function_name
);
if enrichment.min_calls > 0 {
let calls_pattern = format!("Calls: {}", enrichment.min_calls);
assert!(
output.contains(&calls_pattern)
|| output.contains(&format!("Calls: {}", enrichment.min_calls + 1))
|| output.contains(&format!("Calls: {}", enrichment.min_calls + 2)),
"Expected at least {} calls for {}, but pattern not found",
enrichment.min_calls,
enrichment.function_name
);
}
if let Some((min_p50, max_p50)) = enrichment.latency_p50_range {
assert!(
output.contains("Latency p50:"),
"Missing latency metrics for {}",
enrichment.function_name
);
let p50_present = output.lines().any(|line| {
if line.contains("Latency p50:") {
if let Some(p50_str) = line.split("Latency p50:").nth(1) {
if let Some(ms_str) = p50_str.split("ms").next() {
if let Ok(p50_val) = ms_str.trim().parse::<f64>() {
return p50_val >= min_p50 && p50_val <= max_p50;
}
}
}
}
false
});
assert!(
p50_present,
"p50 latency for {} not in expected range {}-{}ms",
enrichment.function_name, min_p50, max_p50
);
}
if enrichment.has_errors {
assert!(
output.contains("Error Rate:")
|| output.contains("error")
|| output.contains("ERROR"),
"Expected errors for {} but none found",
enrichment.function_name
);
if let Some(ref error_msg) = enrichment.error_message {
assert!(
output.contains(error_msg),
"Expected error message '{error_msg}' not found"
);
}
}
}
}
pub fn get_test_data_path(language: &str, filename: &str) -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join("acceptance")
.join(language)
.join(filename)
}