use std::io;
use std::sync::{Arc, Mutex};
use ticklog::{info, Backpressure, Level, LogSink};
const PRODUCED: usize = 50_000;
struct CaptureSink {
lines: Arc<Mutex<Vec<String>>>,
}
impl LogSink for CaptureSink {
fn accept(&mut self, line: &[u8], _level: Level) -> io::Result<()> {
self.lines
.lock()
.unwrap()
.push(String::from_utf8_lossy(line).into_owned());
Ok(())
}
}
fn seq_of(line: &str) -> Option<usize> {
line.rsplit("seq=").next()?.trim().parse().ok()
}
#[test]
fn block_policy_never_loses_a_record() {
let lines = Arc::new(Mutex::new(Vec::new()));
let sink = CaptureSink {
lines: Arc::clone(&lines),
};
let guard = ticklog::builder()
.sink(sink)
.max_level(Level::Info)
.backpressure(Backpressure::Block)
.build()
.expect("first build in a fresh process must succeed");
for i in 0..PRODUCED {
info!("seq={}", i as u64);
}
drop(guard);
let captured = lines.lock().unwrap();
assert_eq!(
captured.len(),
PRODUCED,
"Block must not drop any record; lost {}",
PRODUCED - captured.len()
);
let seqs: Vec<usize> = captured
.iter()
.map(|line| seq_of(line).expect("each line ends in seq=<i>"))
.collect();
let expected: Vec<usize> = (0..PRODUCED).collect();
assert_eq!(seqs, expected, "records must arrive in program order");
}