use backbeat::{
global,
zerocopy::{Immutable, IntoBytes},
};
use std::time::Duration;
#[derive(backbeat::Event, IntoBytes, Immutable)]
#[event(namespace = "test::global_limit")]
#[repr(C)]
struct Beat {
#[event(key)]
seq: u64,
}
fn dump_files(dir: &std::path::Path) -> Vec<std::path::PathBuf> {
let mut files: Vec<_> = std::fs::read_dir(dir)
.into_iter()
.flatten()
.flatten()
.map(|e| e.path())
.filter(|p| {
let name = p.file_name().and_then(|n| n.to_str()).unwrap_or("");
name.starts_with("trace.") && name.ends_with(".bb")
})
.collect();
files.sort();
files
}
fn wait_for_count(dir: &std::path::Path, want: usize) -> Vec<std::path::PathBuf> {
let mut files = dump_files(dir);
for _ in 0..300 {
files = dump_files(dir);
if files.len() >= want {
break;
}
std::thread::sleep(Duration::from_millis(10));
}
files
}
#[test]
fn keep_newest_bounds_file_count_to_limit() {
let dir = std::env::temp_dir().join(format!("backbeat-limit-test-{}", std::process::id()));
std::fs::create_dir_all(&dir).unwrap();
let base = dir.join("trace.bb");
std::env::set_var("BACKBEAT_PATH", &base);
std::env::set_var("BACKBEAT_BYTES", "65536");
std::env::set_var("BACKBEAT_THROTTLE_MS", "0");
std::env::set_var("BACKBEAT_MAX_DUMPS", "2");
std::env::set_var("BACKBEAT_LIMIT_POLICY", "keep-newest");
global::enable();
for seq in 0..3u64 {
global::record(&Beat { seq });
global::trigger();
wait_for_count(&dir, (seq as usize + 1).min(2));
std::thread::sleep(Duration::from_millis(5));
}
let mut settled = Vec::new();
for _ in 0..300 {
settled = dump_files(&dir);
if settled.len() == 2 {
break;
}
std::thread::sleep(Duration::from_millis(10));
}
assert_eq!(
settled.len(),
2,
"keep-newest with max_dumps=2 must keep exactly 2 files, found {settled:?}"
);
let before = dump_files(&dir);
let oldest = before.first().cloned().unwrap();
std::thread::sleep(Duration::from_millis(5));
global::record(&Beat { seq: 99 });
global::trigger();
let mut evicted = false;
for _ in 0..300 {
if !oldest.exists() && dump_files(&dir).len() == 2 {
evicted = true;
break;
}
std::thread::sleep(Duration::from_millis(10));
}
assert!(
evicted,
"a further dump should evict the previously-oldest file and keep the count at 2"
);
let _ = std::fs::remove_dir_all(&dir);
}