1 | use super::*; |
2 | use tracing::Subscriber; |
3 | use tracing_subscriber::{ |
4 | filter::{self, LevelFilter}, |
5 | prelude::*, |
6 | Layer, |
7 | }; |
8 | |
9 | fn 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] |
16 | fn 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] |
30 | fn 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] |
48 | fn 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] |
70 | fn 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] |
108 | fn 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 | |