use denet::ProcessMonitor;
use std::process::Command;
use std::time::{Duration, Instant};
#[test]
#[cfg(target_os = "linux")]
fn test_multicore_cpu_measurement() {
if std::env::var("CI").is_ok() {
println!("Skipping multi-core stress test in CI environment");
return;
}
let num_cores = std::thread::available_parallelism()
.map(|n| n.get().min(4))
.unwrap_or(1);
println!("Running multi-core stress test with {num_cores} workers");
let stress_cmd = format!(
r#"
python3 -c '
import multiprocessing
import time
def cpu_stress():
# Pure CPU stress with no sleeps
start = time.time()
while True:
for i in range(10000000):
x = i * i
# Check if we should exit (after 10 seconds)
if time.time() - start > 10:
break
if __name__ == "__main__":
# Create workers equal to core count
workers = []
for _ in range({}):
p = multiprocessing.Process(target=cpu_stress)
p.start()
workers.append(p)
# Wait for workers to complete
for p in workers:
p.join()
'
"#,
num_cores
);
let mut child = Command::new("bash")
.arg("-c")
.arg(stress_cmd)
.spawn()
.expect("Failed to spawn CPU burner");
let base_interval = Duration::from_millis(100);
let max_interval = Duration::from_millis(500);
let mut monitor = ProcessMonitor::from_pid(child.id() as usize, base_interval, max_interval)
.expect("Failed to create process monitor");
std::thread::sleep(Duration::from_millis(1000));
let start = Instant::now();
let timeout = Duration::from_secs(5);
let mut samples = Vec::new();
while start.elapsed() < timeout {
let tree_metrics = monitor.sample_tree_metrics();
if let Some(agg) = tree_metrics.aggregated {
samples.push(agg.cpu_usage);
println!(
"Sample: CPU {}%, Process count: {}",
agg.cpu_usage, agg.process_count
);
}
std::thread::sleep(Duration::from_millis(200));
}
let _ = child.kill();
let _ = child.wait();
assert!(!samples.is_empty(), "No samples collected");
let avg_cpu = samples.iter().sum::<f32>() / samples.len() as f32;
let max_cpu = samples.iter().fold(0.0f32, |max, &x| max.max(x));
println!(
"Average CPU usage: {:.1}%, Max CPU usage: {:.1}%",
avg_cpu, max_cpu
);
println!("CPU usage samples: {:?}", samples);
assert!(max_cpu > 50.0, "Maximum CPU usage should be significant");
if num_cores >= 2 {
assert!(
max_cpu > 100.0,
"Multi-core CPU usage should exceed 100% with {} cores (max: {:.1}%, avg: {:.1}%)",
num_cores,
max_cpu,
avg_cpu
);
}
}