1// A separate test crate for `Option<Filter>` for isolation from other tests
2// that may influence the interest cache.
3
4use std::sync::{
5 atomic::{AtomicUsize, Ordering},
6 Arc,
7};
8use tracing_mock::{expect, layer};
9use 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]
14fn 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(&times_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