Files
announcement/tests/tracing_coverage.rs
T
swaits e8e55b7676 chore: initial release v0.1.0
Runtime-agnostic oneshot broadcast channel for Rust.
2025-10-13 19:36:37 -06:00

164 lines
5.9 KiB
Rust

//! 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::<i32>::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::<String>::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::<Vec<u8>>::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::<String>::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::<i32>::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::<String>::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::<i32>::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::<Arc<String>>::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())));
}
});
}
}