1 | #![cfg (feature = "registry" )] |
2 | use tracing_core::{subscriber::Interest, LevelFilter, Metadata, Subscriber}; |
3 | use tracing_subscriber::{layer, prelude::*}; |
4 | |
5 | // A basic layer that returns its inner for `max_level_hint` |
6 | #[derive(Debug)] |
7 | struct BasicLayer(Option<LevelFilter>); |
8 | impl<S: Subscriber> tracing_subscriber::Layer<S> for BasicLayer { |
9 | fn register_callsite(&self, _m: &Metadata<'_>) -> Interest { |
10 | Interest::sometimes() |
11 | } |
12 | |
13 | fn enabled(&self, _m: &Metadata<'_>, _: layer::Context<'_, S>) -> bool { |
14 | true |
15 | } |
16 | |
17 | fn max_level_hint(&self) -> Option<LevelFilter> { |
18 | self.0 |
19 | } |
20 | } |
21 | |
22 | // This test is just used to compare to the tests below |
23 | #[test] |
24 | fn just_layer() { |
25 | let subscriber = tracing_subscriber::registry().with(LevelFilter::INFO); |
26 | assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::INFO)); |
27 | } |
28 | |
29 | #[test] |
30 | fn subscriber_and_option_some_layer() { |
31 | let subscriber = tracing_subscriber::registry() |
32 | .with(LevelFilter::INFO) |
33 | .with(Some(LevelFilter::DEBUG)); |
34 | assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::DEBUG)); |
35 | } |
36 | |
37 | #[test] |
38 | fn subscriber_and_option_none_layer() { |
39 | // None means the other layer takes control |
40 | let subscriber = tracing_subscriber::registry() |
41 | .with(LevelFilter::ERROR) |
42 | .with(None::<LevelFilter>); |
43 | assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::ERROR)); |
44 | } |
45 | |
46 | #[test] |
47 | fn just_option_some_layer() { |
48 | // Just a None means everything is off |
49 | let subscriber = tracing_subscriber::registry().with(None::<LevelFilter>); |
50 | assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::OFF)); |
51 | } |
52 | |
53 | /// Tests that the logic tested in `doesnt_override_none` works through the reload subscriber |
54 | #[test] |
55 | fn just_option_none_layer() { |
56 | let subscriber = tracing_subscriber::registry().with(Some(LevelFilter::ERROR)); |
57 | assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::ERROR)); |
58 | } |
59 | |
60 | // Test that the `None` max level hint only applies if its the only layer |
61 | #[test] |
62 | fn none_outside_doesnt_override_max_level() { |
63 | // None means the other layer takes control |
64 | let subscriber = tracing_subscriber::registry() |
65 | .with(BasicLayer(None)) |
66 | .with(None::<LevelFilter>); |
67 | assert_eq!( |
68 | subscriber.max_level_hint(), |
69 | None, |
70 | " \n stack: {:#?}" , |
71 | subscriber |
72 | ); |
73 | |
74 | // The `None`-returning layer still wins |
75 | let subscriber = tracing_subscriber::registry() |
76 | .with(BasicLayer(None)) |
77 | .with(Some(LevelFilter::ERROR)); |
78 | assert_eq!( |
79 | subscriber.max_level_hint(), |
80 | Some(LevelFilter::ERROR), |
81 | " \n stack: {:#?}" , |
82 | subscriber |
83 | ); |
84 | |
85 | // Check that we aren't doing anything truly wrong |
86 | let subscriber = tracing_subscriber::registry() |
87 | .with(BasicLayer(Some(LevelFilter::DEBUG))) |
88 | .with(None::<LevelFilter>); |
89 | assert_eq!( |
90 | subscriber.max_level_hint(), |
91 | Some(LevelFilter::DEBUG), |
92 | " \n stack: {:#?}" , |
93 | subscriber |
94 | ); |
95 | |
96 | // Test that per-subscriber filters aren't affected |
97 | |
98 | // One layer is None so it "wins" |
99 | let subscriber = tracing_subscriber::registry() |
100 | .with(BasicLayer(None)) |
101 | .with(None::<LevelFilter>.with_filter(LevelFilter::DEBUG)); |
102 | assert_eq!( |
103 | subscriber.max_level_hint(), |
104 | None, |
105 | " \n stack: {:#?}" , |
106 | subscriber |
107 | ); |
108 | |
109 | // The max-levels wins |
110 | let subscriber = tracing_subscriber::registry() |
111 | .with(BasicLayer(Some(LevelFilter::INFO))) |
112 | .with(None::<LevelFilter>.with_filter(LevelFilter::DEBUG)); |
113 | assert_eq!( |
114 | subscriber.max_level_hint(), |
115 | Some(LevelFilter::DEBUG), |
116 | " \n stack: {:#?}" , |
117 | subscriber |
118 | ); |
119 | |
120 | // Test filter on the other layer |
121 | let subscriber = tracing_subscriber::registry() |
122 | .with(BasicLayer(Some(LevelFilter::INFO)).with_filter(LevelFilter::DEBUG)) |
123 | .with(None::<LevelFilter>); |
124 | assert_eq!( |
125 | subscriber.max_level_hint(), |
126 | Some(LevelFilter::DEBUG), |
127 | " \n stack: {:#?}" , |
128 | subscriber |
129 | ); |
130 | let subscriber = tracing_subscriber::registry() |
131 | .with(BasicLayer(None).with_filter(LevelFilter::DEBUG)) |
132 | .with(None::<LevelFilter>); |
133 | assert_eq!( |
134 | subscriber.max_level_hint(), |
135 | Some(LevelFilter::DEBUG), |
136 | " \n stack: {:#?}" , |
137 | subscriber |
138 | ); |
139 | |
140 | // The `OFF` from `None` over overridden. |
141 | let subscriber = tracing_subscriber::registry() |
142 | .with(BasicLayer(Some(LevelFilter::INFO))) |
143 | .with(None::<LevelFilter>); |
144 | assert_eq!( |
145 | subscriber.max_level_hint(), |
146 | Some(LevelFilter::INFO), |
147 | " \n stack: {:#?}" , |
148 | subscriber |
149 | ); |
150 | } |
151 | |
152 | // Test that the `None` max level hint only applies if its the only layer |
153 | #[test] |
154 | fn none_inside_doesnt_override_max_level() { |
155 | // None means the other layer takes control |
156 | let subscriber = tracing_subscriber::registry() |
157 | .with(None::<LevelFilter>) |
158 | .with(BasicLayer(None)); |
159 | assert_eq!( |
160 | subscriber.max_level_hint(), |
161 | None, |
162 | " \n stack: {:#?}" , |
163 | subscriber |
164 | ); |
165 | |
166 | // The `None`-returning layer still wins |
167 | let subscriber = tracing_subscriber::registry() |
168 | .with(Some(LevelFilter::ERROR)) |
169 | .with(BasicLayer(None)); |
170 | assert_eq!( |
171 | subscriber.max_level_hint(), |
172 | Some(LevelFilter::ERROR), |
173 | " \n stack: {:#?}" , |
174 | subscriber |
175 | ); |
176 | |
177 | // Check that we aren't doing anything truly wrong |
178 | let subscriber = tracing_subscriber::registry() |
179 | .with(None::<LevelFilter>) |
180 | .with(BasicLayer(Some(LevelFilter::DEBUG))); |
181 | assert_eq!( |
182 | subscriber.max_level_hint(), |
183 | Some(LevelFilter::DEBUG), |
184 | " \n stack: {:#?}" , |
185 | subscriber |
186 | ); |
187 | |
188 | // Test that per-subscriber filters aren't affected |
189 | |
190 | // One layer is None so it "wins" |
191 | let subscriber = tracing_subscriber::registry() |
192 | .with(None::<LevelFilter>.with_filter(LevelFilter::DEBUG)) |
193 | .with(BasicLayer(None)); |
194 | assert_eq!( |
195 | subscriber.max_level_hint(), |
196 | None, |
197 | " \n stack: {:#?}" , |
198 | subscriber |
199 | ); |
200 | |
201 | // The max-levels wins |
202 | let subscriber = tracing_subscriber::registry() |
203 | .with(None::<LevelFilter>.with_filter(LevelFilter::DEBUG)) |
204 | .with(BasicLayer(Some(LevelFilter::INFO))); |
205 | assert_eq!( |
206 | subscriber.max_level_hint(), |
207 | Some(LevelFilter::DEBUG), |
208 | " \n stack: {:#?}" , |
209 | subscriber |
210 | ); |
211 | |
212 | // Test filter on the other layer |
213 | let subscriber = tracing_subscriber::registry() |
214 | .with(None::<LevelFilter>) |
215 | .with(BasicLayer(Some(LevelFilter::INFO)).with_filter(LevelFilter::DEBUG)); |
216 | assert_eq!( |
217 | subscriber.max_level_hint(), |
218 | Some(LevelFilter::DEBUG), |
219 | " \n stack: {:#?}" , |
220 | subscriber |
221 | ); |
222 | let subscriber = tracing_subscriber::registry() |
223 | .with(None::<LevelFilter>) |
224 | .with(BasicLayer(None).with_filter(LevelFilter::DEBUG)); |
225 | assert_eq!( |
226 | subscriber.max_level_hint(), |
227 | Some(LevelFilter::DEBUG), |
228 | " \n stack: {:#?}" , |
229 | subscriber |
230 | ); |
231 | |
232 | // The `OFF` from `None` over overridden. |
233 | let subscriber = tracing_subscriber::registry() |
234 | .with(None::<LevelFilter>) |
235 | .with(BasicLayer(Some(LevelFilter::INFO))); |
236 | assert_eq!( |
237 | subscriber.max_level_hint(), |
238 | Some(LevelFilter::INFO), |
239 | " \n stack: {:#?}" , |
240 | subscriber |
241 | ); |
242 | } |
243 | |
244 | /// Tests that the logic tested in `doesnt_override_none` works through the reload layer |
245 | #[test] |
246 | fn reload_works_with_none() { |
247 | let (layer1, handle1) = tracing_subscriber::reload::Layer::new(None::<BasicLayer>); |
248 | let (layer2, _handle2) = tracing_subscriber::reload::Layer::new(None::<BasicLayer>); |
249 | |
250 | let subscriber = tracing_subscriber::registry().with(layer1).with(layer2); |
251 | assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::OFF)); |
252 | |
253 | // reloading one should pass through correctly. |
254 | handle1.reload(Some(BasicLayer(None))).unwrap(); |
255 | assert_eq!(subscriber.max_level_hint(), None); |
256 | |
257 | // Check pass-through of an actual level as well |
258 | handle1 |
259 | .reload(Some(BasicLayer(Some(LevelFilter::DEBUG)))) |
260 | .unwrap(); |
261 | assert_eq!(subscriber.max_level_hint(), Some(LevelFilter::DEBUG)); |
262 | } |
263 | |