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