1use super::*;
2use tracing::Subscriber;
3use tracing_subscriber::{
4 filter::{self, LevelFilter},
5 prelude::*,
6 Layer,
7};
8
9fn filter_out_everything<S>() -> filter::DynFilterFn<S> {
10 // Use dynamic filter fn to disable interest caching and max-level hints,
11 // allowing us to put all of these tests in the same file.
12 filter::dynamic_filter_fn(|_, _| false)
13}
14
15#[test]
16fn option_some() {
17 let (layer, handle) = layer::mock().only().run_with_handle();
18 let layer = layer.with_filter(Some(filter_out_everything()));
19
20 let _guard = tracing_subscriber::registry().with(layer).set_default();
21
22 for i in 0..2 {
23 tracing::info!(i);
24 }
25
26 handle.assert_finished();
27}
28
29#[test]
30fn option_none() {
31 let (layer, handle) = layer::mock()
32 .event(expect::event())
33 .event(expect::event())
34 .only()
35 .run_with_handle();
36 let layer = layer.with_filter(None::<filter::DynFilterFn<_>>);
37
38 let _guard = tracing_subscriber::registry().with(layer).set_default();
39
40 for i in 0..2 {
41 tracing::info!(i);
42 }
43
44 handle.assert_finished();
45}
46
47#[test]
48fn option_mixed() {
49 let (layer, handle) = layer::mock()
50 .event(expect::event())
51 .only()
52 .run_with_handle();
53 let layer = layer
54 .with_filter(filter::dynamic_filter_fn(|meta, _ctx| {
55 meta.target() == "interesting"
56 }))
57 .with_filter(None::<filter::DynFilterFn<_>>);
58
59 let _guard = tracing_subscriber::registry().with(layer).set_default();
60
61 tracing::info!(target: "interesting", x="foo");
62 tracing::info!(target: "boring", x="bar");
63
64 handle.assert_finished();
65}
66
67/// The lack of a max level hint from a `None` filter should result in no max
68/// level hint when combined with other filters/layer.
69#[test]
70fn none_max_level_hint() {
71 let (layer_some, handle_none) = layer::mock()
72 .event(expect::event())
73 .event(expect::event())
74 .only()
75 .run_with_handle();
76 let subscribe_none = layer_some.with_filter(None::<filter::DynFilterFn<_>>);
77 assert!(subscribe_none.max_level_hint().is_none());
78
79 let (layer_filter_fn, handle_filter_fn) = layer::mock()
80 .event(expect::event())
81 .only()
82 .run_with_handle();
83 let max_level = Level::INFO;
84 let layer_filter_fn = layer_filter_fn.with_filter(
85 filter::dynamic_filter_fn(move |meta, _| return meta.level() <= &max_level)
86 .with_max_level_hint(max_level),
87 );
88 assert_eq!(layer_filter_fn.max_level_hint(), Some(LevelFilter::INFO));
89
90 let subscriber = tracing_subscriber::registry()
91 .with(subscribe_none)
92 .with(layer_filter_fn);
93 // The absence of a hint from the `None` filter upgrades the `INFO` hint
94 // from the filter fn layer.
95 assert!(subscriber.max_level_hint().is_none());
96
97 let _guard = subscriber.set_default();
98 tracing::info!(target: "interesting", x="foo");
99 tracing::debug!(target: "sometimes_interesting", x="bar");
100
101 handle_none.assert_finished();
102 handle_filter_fn.assert_finished();
103}
104
105/// The max level hint from inside a `Some(filter)` filter should be propagated
106/// and combined with other filters/layers.
107#[test]
108fn some_max_level_hint() {
109 let (layer_some, handle_some) = layer::mock()
110 .event(expect::event())
111 .event(expect::event())
112 .only()
113 .run_with_handle();
114 let layer_some = layer_some.with_filter(Some(
115 filter::dynamic_filter_fn(move |meta, _| return meta.level() <= &Level::DEBUG)
116 .with_max_level_hint(Level::DEBUG),
117 ));
118 assert_eq!(layer_some.max_level_hint(), Some(LevelFilter::DEBUG));
119
120 let (layer_filter_fn, handle_filter_fn) = layer::mock()
121 .event(expect::event())
122 .only()
123 .run_with_handle();
124 let layer_filter_fn = layer_filter_fn.with_filter(
125 filter::dynamic_filter_fn(move |meta, _| return meta.level() <= &Level::INFO)
126 .with_max_level_hint(Level::INFO),
127 );
128 assert_eq!(layer_filter_fn.max_level_hint(), Some(LevelFilter::INFO));
129
130 let subscriber = tracing_subscriber::registry()
131 .with(layer_some)
132 .with(layer_filter_fn);
133 // The `DEBUG` hint from the `Some` filter upgrades the `INFO` hint from the
134 // filter fn layer.
135 assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::DEBUG));
136
137 let _guard = subscriber.set_default();
138 tracing::info!(target: "interesting", x="foo");
139 tracing::debug!(target: "sometimes_interesting", x="bar");
140
141 handle_some.assert_finished();
142 handle_filter_fn.assert_finished();
143}
144