| 1 | // Tests that depend on a count of the number of times their filter is evaluated |
| 2 | // cant exist in the same file with other tests that add subscribers to the |
| 3 | // registry. The registry was changed so that each time a new dispatcher is |
| 4 | // added all filters are re-evaluated. The tests being run only in separate |
| 5 | // threads with shared global state lets them interfere with each other |
| 6 | #[cfg (not(feature = "std" ))] |
| 7 | extern crate std; |
| 8 | |
| 9 | use tracing::{span, Level}; |
| 10 | use tracing_mock::*; |
| 11 | |
| 12 | use std::sync::{ |
| 13 | atomic::{AtomicUsize, Ordering}, |
| 14 | Arc, |
| 15 | }; |
| 16 | |
| 17 | #[cfg_attr (target_arch = "wasm32" , wasm_bindgen_test::wasm_bindgen_test)] |
| 18 | #[test] |
| 19 | fn filters_are_not_reevaluated_for_the_same_span() { |
| 20 | // Asserts that the `span!` macro caches the result of calling |
| 21 | // `Subscriber::enabled` for each span. |
| 22 | let alice_count = Arc::new(AtomicUsize::new(0)); |
| 23 | let bob_count = Arc::new(AtomicUsize::new(0)); |
| 24 | let alice_count2 = alice_count.clone(); |
| 25 | let bob_count2 = bob_count.clone(); |
| 26 | |
| 27 | let (subscriber, handle) = subscriber::mock() |
| 28 | .with_filter(move |meta| match meta.name() { |
| 29 | "alice" => { |
| 30 | alice_count2.fetch_add(1, Ordering::Relaxed); |
| 31 | false |
| 32 | } |
| 33 | "bob" => { |
| 34 | bob_count2.fetch_add(1, Ordering::Relaxed); |
| 35 | true |
| 36 | } |
| 37 | _ => false, |
| 38 | }) |
| 39 | .run_with_handle(); |
| 40 | |
| 41 | // Since this test is in its own file anyway, we can do this. Thus, this |
| 42 | // test will work even with no-std. |
| 43 | tracing::subscriber::set_global_default(subscriber).unwrap(); |
| 44 | |
| 45 | // Enter "alice" and then "bob". The dispatcher expects to see "bob" but |
| 46 | // not "alice." |
| 47 | let alice = span!(Level::TRACE, "alice" ); |
| 48 | let bob = alice.in_scope(|| { |
| 49 | let bob = span!(Level::TRACE, "bob" ); |
| 50 | bob.in_scope(|| ()); |
| 51 | bob |
| 52 | }); |
| 53 | |
| 54 | // The filter should have seen each span a single time. |
| 55 | assert_eq!(alice_count.load(Ordering::Relaxed), 1); |
| 56 | assert_eq!(bob_count.load(Ordering::Relaxed), 1); |
| 57 | |
| 58 | alice.in_scope(|| bob.in_scope(|| {})); |
| 59 | |
| 60 | // The subscriber should see "bob" again, but the filter should not have |
| 61 | // been called. |
| 62 | assert_eq!(alice_count.load(Ordering::Relaxed), 1); |
| 63 | assert_eq!(bob_count.load(Ordering::Relaxed), 1); |
| 64 | |
| 65 | bob.in_scope(|| {}); |
| 66 | assert_eq!(alice_count.load(Ordering::Relaxed), 1); |
| 67 | assert_eq!(bob_count.load(Ordering::Relaxed), 1); |
| 68 | |
| 69 | handle.assert_finished(); |
| 70 | } |
| 71 | |