@@ -697,3 +697,51 @@ impl<L: Iterator<Item = T>, R: Iterator<Item = T>, T, U: PartialEq, F: Fn(&T) ->
697
697
}
698
698
}
699
699
}
700
+
701
+ #[ cfg( test) ]
702
+ mod tests {
703
+ use std:: { io, str, sync:: Mutex } ;
704
+
705
+ use tracing:: subscriber:: set_global_default;
706
+ use tracing_subscriber:: { layer:: SubscriberExt , registry} ;
707
+
708
+ use crate :: HierarchicalLayer ;
709
+
710
+ struct RecursiveWriter ( Mutex < Vec < u8 > > ) ;
711
+
712
+ impl io:: Write for & RecursiveWriter {
713
+ fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
714
+ self . 0 . lock ( ) . unwrap ( ) . extend ( buf) ;
715
+
716
+ tracing:: error!( "Nobody expects the Spanish Inquisition" ) ;
717
+
718
+ Ok ( buf. len ( ) )
719
+ }
720
+
721
+ fn flush ( & mut self ) -> io:: Result < ( ) > {
722
+ tracing:: error!( "Nobody expects the Spanish Inquisition" ) ;
723
+ Ok ( ( ) )
724
+ }
725
+ }
726
+
727
+ /// This test checks that if `tracing` events happen during processing of
728
+ /// `on_event`, the library does not deadlock.
729
+ #[ test]
730
+ fn recursive_event ( ) {
731
+ static WRITER : RecursiveWriter = RecursiveWriter ( Mutex :: new ( Vec :: new ( ) ) ) ;
732
+
733
+ let subscriber = registry ( ) . with ( HierarchicalLayer :: new ( 2 ) . with_writer ( || & WRITER ) ) ;
734
+ set_global_default ( subscriber) . unwrap ( ) ;
735
+
736
+ tracing:: error!( "We can never expect the unexpected." ) ;
737
+
738
+ let output = WRITER . 0 . lock ( ) . unwrap ( ) ;
739
+ let output = str:: from_utf8 ( & output) . unwrap ( ) ;
740
+
741
+ // If this test finished we're happy. Let's just also check that we did
742
+ // in fact log _something_ and that the logs from within the writer did
743
+ // not actually go through.
744
+ assert ! ( output. contains( "We can never expect the unexpected." ) ) ;
745
+ assert ! ( !output. contains( "Nobody expects the Spanish Inquisition" ) ) ;
746
+ }
747
+ }
0 commit comments