]>
Commit | Line | Data |
---|---|---|
04454e1e FG |
1 | #![cfg(feature = "registry")] |
2 | mod support; | |
3 | use self::support::*; | |
4 | ||
5 | use std::{ | |
6 | collections::HashMap, | |
7 | sync::{Arc, Mutex}, | |
8 | }; | |
9 | use tracing::{Level, Subscriber}; | |
10 | use tracing_subscriber::{filter, prelude::*}; | |
11 | ||
12 | #[test] | |
13 | fn vec_layer_filter_interests_are_cached() { | |
14 | let mk_filtered = |level: Level, subscriber: ExpectLayer| { | |
15 | let seen = Arc::new(Mutex::new(HashMap::new())); | |
16 | let filter = filter::filter_fn({ | |
17 | let seen = seen.clone(); | |
18 | move |meta| { | |
19 | *seen.lock().unwrap().entry(*meta.level()).or_insert(0usize) += 1; | |
20 | meta.level() <= &level | |
21 | } | |
22 | }); | |
23 | (subscriber.with_filter(filter).boxed(), seen) | |
24 | }; | |
25 | ||
26 | // This layer will return Interest::always for INFO and lower. | |
27 | let (info_layer, info_handle) = layer::named("info") | |
28 | .event(event::mock().at_level(Level::INFO)) | |
29 | .event(event::mock().at_level(Level::WARN)) | |
30 | .event(event::mock().at_level(Level::ERROR)) | |
31 | .event(event::mock().at_level(Level::INFO)) | |
32 | .event(event::mock().at_level(Level::WARN)) | |
33 | .event(event::mock().at_level(Level::ERROR)) | |
34 | .done() | |
35 | .run_with_handle(); | |
36 | let (info_layer, seen_info) = mk_filtered(Level::INFO, info_layer); | |
37 | ||
38 | // This layer will return Interest::always for WARN and lower. | |
39 | let (warn_layer, warn_handle) = layer::named("warn") | |
40 | .event(event::mock().at_level(Level::WARN)) | |
41 | .event(event::mock().at_level(Level::ERROR)) | |
42 | .event(event::mock().at_level(Level::WARN)) | |
43 | .event(event::mock().at_level(Level::ERROR)) | |
44 | .done() | |
45 | .run_with_handle(); | |
46 | let (warn_layer, seen_warn) = mk_filtered(Level::WARN, warn_layer); | |
47 | ||
48 | let subscriber = tracing_subscriber::registry().with(vec![warn_layer, info_layer]); | |
49 | assert!(subscriber.max_level_hint().is_none()); | |
50 | ||
51 | let _subscriber = subscriber.set_default(); | |
52 | ||
53 | fn events() { | |
54 | tracing::trace!("hello trace"); | |
55 | tracing::debug!("hello debug"); | |
56 | tracing::info!("hello info"); | |
57 | tracing::warn!("hello warn"); | |
58 | tracing::error!("hello error"); | |
59 | } | |
60 | ||
61 | events(); | |
62 | { | |
63 | let lock = seen_info.lock().unwrap(); | |
64 | for (&level, &count) in lock.iter() { | |
65 | if level == Level::INFO { | |
66 | continue; | |
67 | } | |
68 | assert_eq!( | |
69 | count, 1, | |
70 | "level {:?} should have been seen 1 time by the INFO subscriber (after first set of events)", | |
71 | level | |
72 | ); | |
73 | } | |
74 | ||
75 | let lock = seen_warn.lock().unwrap(); | |
76 | for (&level, &count) in lock.iter() { | |
77 | if level == Level::INFO { | |
78 | continue; | |
79 | } | |
80 | assert_eq!( | |
81 | count, 1, | |
82 | "level {:?} should have been seen 1 time by the WARN subscriber (after first set of events)", | |
83 | level | |
84 | ); | |
85 | } | |
86 | } | |
87 | ||
88 | events(); | |
89 | { | |
90 | let lock = seen_info.lock().unwrap(); | |
91 | for (&level, &count) in lock.iter() { | |
92 | if level == Level::INFO { | |
93 | continue; | |
94 | } | |
95 | assert_eq!( | |
96 | count, 1, | |
97 | "level {:?} should have been seen 1 time by the INFO subscriber (after second set of events)", | |
98 | level | |
99 | ); | |
100 | } | |
101 | ||
102 | let lock = seen_warn.lock().unwrap(); | |
103 | for (&level, &count) in lock.iter() { | |
104 | if level == Level::INFO { | |
105 | continue; | |
106 | } | |
107 | assert_eq!( | |
108 | count, 1, | |
109 | "level {:?} should have been seen 1 time by the WARN subscriber (after second set of events)", | |
110 | level | |
111 | ); | |
112 | } | |
113 | } | |
114 | ||
115 | info_handle.assert_finished(); | |
116 | warn_handle.assert_finished(); | |
117 | } |