diff --git a/src/lib.rs b/src/lib.rs index e10dcab..525f21c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -697,3 +697,51 @@ impl, R: Iterator, T, U: PartialEq, F: Fn(&T) -> } } } + +#[cfg(test)] +mod tests { + use std::{io, str, sync::Mutex}; + + use tracing::subscriber::set_global_default; + use tracing_subscriber::{layer::SubscriberExt, registry}; + + use crate::HierarchicalLayer; + + struct RecursiveWriter(Mutex>); + + impl io::Write for &RecursiveWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0.lock().unwrap().extend(buf); + + tracing::error!("Nobody expects the Spanish Inquisition"); + + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + tracing::error!("Nobody expects the Spanish Inquisition"); + Ok(()) + } + } + + /// This test checks that if `tracing` events happen during processing of + /// `on_event`, the library does not deadlock. + #[test] + fn recursive_event() { + static WRITER: RecursiveWriter = RecursiveWriter(Mutex::new(Vec::new())); + + let subscriber = registry().with(HierarchicalLayer::new(2).with_writer(|| &WRITER)); + set_global_default(subscriber).unwrap(); + + tracing::error!("We can never expect the unexpected."); + + let output = WRITER.0.lock().unwrap(); + let output = str::from_utf8(&output).unwrap(); + + // If this test finished we're happy. Let's just also check that we did + // in fact log _something_ and that the logs from within the writer did + // not actually go through. + assert!(output.contains("We can never expect the unexpected.")); + assert!(!output.contains("Nobody expects the Spanish Inquisition")); + } +}