| 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 | |