1 | // A separate test crate for `Option<Filter>` for isolation from other tests |
2 | // that may influence the interest cache. |
3 | |
4 | use std::sync::{ |
5 | atomic::{AtomicUsize, Ordering}, |
6 | Arc, |
7 | }; |
8 | use tracing_mock::{expect, layer}; |
9 | use tracing_subscriber::{filter, prelude::*, Layer}; |
10 | |
11 | /// A `None` filter should always be interested in events, and it should not |
12 | /// needlessly degrade the caching of other filters. |
13 | #[test] |
14 | fn none_interest_cache() { |
15 | let (layer_none, handle_none) = layer::mock() |
16 | .event(expect::event()) |
17 | .event(expect::event()) |
18 | .only() |
19 | .run_with_handle(); |
20 | let layer_none = layer_none.with_filter(None::<filter::DynFilterFn<_>>); |
21 | |
22 | let times_filtered = Arc::new(AtomicUsize::new(0)); |
23 | let (layer_filter_fn, handle_filter_fn) = layer::mock() |
24 | .event(expect::event()) |
25 | .event(expect::event()) |
26 | .only() |
27 | .run_with_handle(); |
28 | let layer_filter_fn = layer_filter_fn.with_filter(filter::filter_fn({ |
29 | let times_filtered = Arc::clone(×_filtered); |
30 | move |_| { |
31 | times_filtered.fetch_add(1, Ordering::Relaxed); |
32 | true |
33 | } |
34 | })); |
35 | |
36 | let subscriber = tracing_subscriber::registry() |
37 | .with(layer_none) |
38 | .with(layer_filter_fn); |
39 | |
40 | let _guard = subscriber.set_default(); |
41 | for _ in 0..2 { |
42 | tracing::debug!(target: "always_interesting" , x="bar" ); |
43 | } |
44 | |
45 | // The `None` filter is unchanging and performs no filtering, so it should |
46 | // be cacheable and always be interested in events. The filter fn is a |
47 | // non-dynamic filter fn, which means the result can be cached per callsite. |
48 | // The filter fn should only need to be called once, and the `Option` filter |
49 | // should not interfere in the caching of that result. |
50 | assert_eq!(times_filtered.load(Ordering::Relaxed), 1); |
51 | handle_none.assert_finished(); |
52 | handle_filter_fn.assert_finished(); |
53 | } |
54 | |