use std::fs;
use std::num::NonZeroUsize;
use std::path::Path;
use std::thread;
use std::time::Duration;
use logforth_append_file::FileBuilder;
use logforth_core::Append;
use logforth_core::record::Record;
use tempfile::TempDir;
#[test]
fn test_global_file_count_limit() {
let temp_dir = TempDir::new().expect("failed to create a temporary directory");
let max_files = 10; let max_size = 100;
let writer = FileBuilder::new(temp_dir.path(), "test_prefix")
.rollover_hourly()
.rollover_size(NonZeroUsize::new(max_size).unwrap())
.max_log_files(NonZeroUsize::new(max_files).unwrap())
.build()
.unwrap();
println!("Starting test_global_file_count_limit");
for i in 0..50 {
writer
.append(
&Record::builder()
.payload(format_args!("Log entry {}: {}\n", i, "A".repeat(50)))
.build(),
&[],
)
.unwrap();
writer.flush().unwrap();
}
let files = fs::read_dir(temp_dir.path())
.unwrap()
.filter_map(|entry| {
let entry = entry.ok()?;
let filename = entry.file_name().to_str()?.to_string();
if filename.starts_with("test_prefix") {
Some(filename)
} else {
None
}
})
.collect::<Vec<_>>();
println!("Found {} files: {:?}", files.len(), files);
assert!(
files.len() <= max_files,
"Expected at most {} files, but found {}: {:?}",
max_files,
files.len(),
files
);
println!("Test passed! File count is limited to {}", max_files);
}
#[test]
fn test_file_limit_across_multiple_dates() {
let temp_dir = TempDir::new().expect("failed to create a temporary directory");
let max_files = 10; let max_size = 50;
println!("Creating multiple log files with different date patterns");
create_logs(
temp_dir.path(),
max_files,
max_size,
"databend-query-default",
15,
);
create_logs(
temp_dir.path(),
max_files,
max_size,
"databend-query-default",
20,
);
create_logs(
temp_dir.path(),
max_files,
max_size,
"databend-query-default",
10,
);
let files = count_log_files(temp_dir.path(), "databend-query-default");
println!("Total files across all dates: {}", files.len());
println!("Files: {:?}", files);
assert!(
files.len() <= max_files,
"Expected at most {} files, but found {} files across multiple dates",
max_files,
files.len()
);
}
fn create_logs(dir: &Path, max_files: usize, max_size: usize, filename: &str, count: usize) {
let writer = FileBuilder::new(dir, filename)
.rollover_hourly() .rollover_size(NonZeroUsize::new(max_size).unwrap())
.max_log_files(NonZeroUsize::new(max_files).unwrap())
.build()
.unwrap();
println!("Creating logs with filename: {filename}");
for i in 0..count * 5 {
writer
.append(
&Record::builder()
.payload(format_args!(
"Prefix {}, Log {}: {}\n",
filename,
i,
"X".repeat(20)
))
.build(),
&[],
)
.unwrap();
writer.flush().unwrap();
thread::sleep(Duration::from_millis(10));
}
}
fn count_log_files(dir: &Path, prefix: &str) -> Vec<String> {
fs::read_dir(dir)
.unwrap()
.filter_map(|entry| {
let entry = entry.ok()?;
let filename = entry.file_name().to_str()?.to_string();
if filename.starts_with(prefix) {
Some(filename)
} else {
None
}
})
.collect::<Vec<_>>()
}