//! Tracing coverage tests //! //! These tests ensure tracing statements are executed during coverage runs. //! They set up a tracing subscriber and exercise all code paths that contain //! tracing statements. #[cfg(feature = "tracing")] #[cfg(test)] mod tracing_tests { use announcement::Announcement; use std::sync::Arc; use std::thread; use std::time::Duration; use tracing::Level; use tracing_subscriber::fmt::format::FmtSpan; /// Test: Tracing test: all tracing paths /// /// Verifies: Verifies all tracing paths /// Category: tracing /// Test that exercises all tracing statements in src/lib.rs #[test] fn test_all_tracing_paths() { // Set up tracing subscriber to capture all trace/debug messages let subscriber = tracing_subscriber::fmt() .with_max_level(Level::TRACE) .with_span_events(FmtSpan::FULL) .with_test_writer() .finish(); tracing::subscriber::with_default(subscriber, || { // Test 1: Announcement::new() - covers line 286-287 let (announcer, announcement) = Announcement::::new(); // Test 2: announce() - covers lines 422-423, 440, 444 let listener = announcement.listener(); announcer.announce(42).unwrap(); assert_eq!(listener.try_listen(), Some(42)); // Test 3: close() - covers lines 486, 492-493 let (announcer2, announcement2) = Announcement::::new(); let _listener2 = announcement2.listener(); announcer2.close(); assert!(announcement2.is_closed()); // Test 4: Drop (auto-close) - covers lines 531-532, 538-539 let (announcer3, announcement3) = Announcement::>::new(); let _listener3 = announcement3.listener(); drop(announcer3); // Triggers Drop impl assert!(announcement3.is_closed()); // Test 5: listen() async fast path - covers lines 653-654 let (announcer4, announcement4) = Announcement::::new(); announcer4.announce("fast".to_string()).unwrap(); let listener4 = announcement4.listener(); let rt = tokio::runtime::Runtime::new().unwrap(); let result = rt.block_on(async { listener4.listen().await }); assert_eq!(result, Ok("fast".to_string())); // Test 6: listen() async slow path - covers lines 660-661, 666-667, 675-677, 682-683, 691 let (announcer5, announcement5) = Announcement::::new(); let listener5 = announcement5.listener(); let rt2 = tokio::runtime::Runtime::new().unwrap(); rt2.block_on(async { let listen_future = listener5.listen(); // Spawn a task to announce after a delay let ann5_clone = announcer5; tokio::spawn(async move { tokio::time::sleep(Duration::from_millis(10)).await; ann5_clone.announce(99).unwrap(); }); let result = listen_future.await; assert_eq!(result, Ok(99)); }); // Test 7: listen() async with closed announcer - covers lines 660-661, 666-667, 682-683 let (announcer6, announcement6) = Announcement::::new(); let listener6 = announcement6.listener(); let rt3 = tokio::runtime::Runtime::new().unwrap(); rt3.block_on(async { let listen_future = listener6.listen(); // Close the announcer let ann6_clone = announcer6; tokio::spawn(async move { tokio::time::sleep(Duration::from_millis(10)).await; ann6_clone.close(); }); let result = listen_future.await; assert!(result.is_err()); }); }); } /// Test: Tracing test: blocking with tracing /// /// Verifies: Verifies blocking with tracing /// Category: tracing /// Test blocking operations with tracing #[cfg(feature = "std")] #[test] fn test_blocking_with_tracing() { let subscriber = tracing_subscriber::fmt() .with_max_level(Level::TRACE) .with_test_writer() .finish(); tracing::subscriber::with_default(subscriber, || { // listen_blocking() - exercises tracing in blocking wait let (announcer, announcement) = Announcement::::new(); let listener = announcement.listener(); thread::spawn(move || { thread::sleep(Duration::from_millis(10)); announcer.announce(123).unwrap(); }); let result = listener.listen_blocking(); assert_eq!(result, Ok(123)); }); } /// Test: Tracing test: concurrent tracing /// /// Verifies: Verifies concurrent tracing /// Category: tracing /// Test concurrent tracing paths #[test] fn test_concurrent_tracing() { let subscriber = tracing_subscriber::fmt() .with_max_level(Level::TRACE) .with_test_writer() .finish(); tracing::subscriber::with_default(subscriber, || { let (announcer, announcement) = Announcement::>::new(); // Announce first announcer .announce(Arc::new("concurrent".to_string())) .unwrap(); let mut handles = vec![]; // Create multiple listeners concurrently after announce for _ in 0..10 { let listener = announcement.listener(); handles.push(thread::spawn(move || listener.try_listen())); } // Verify all threads received the value for handle in handles { let result = handle.join().unwrap(); assert_eq!(result, Some(Arc::new("concurrent".to_string()))); } }); } }