1 // These tests require the thread-local scoped dispatcher, which only works when
2 // we have a standard library. The behaviour being tested should be the same
3 // with the standard lib disabled.
4 //
5 // The alternative would be for each of these tests to be defined in a separate
6 // file, which is :(
7 #![cfg(feature = "std")]
8 use tracing::{
9 field::display,
10 span::{Attributes, Id, Record},
11 subscriber::{with_default, Interest, Subscriber},
12 Event, Level, Metadata,
13 };
14 use tracing_mock::{expect, subscriber};
15
16 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
17 #[test]
event_macros_dont_infinite_loop()18 fn event_macros_dont_infinite_loop() {
19 // This test ensures that an event macro within a subscriber
20 // won't cause an infinite loop of events.
21 struct TestSubscriber;
22 impl Subscriber for TestSubscriber {
23 fn register_callsite(&self, _: &Metadata<'_>) -> Interest {
24 // Always return sometimes so that `enabled` will be called
25 // (which can loop).
26 Interest::sometimes()
27 }
28
29 fn enabled(&self, meta: &Metadata<'_>) -> bool {
30 assert!(meta.fields().iter().any(|f| f.name() == "foo"));
31 tracing::event!(Level::TRACE, bar = false);
32 true
33 }
34
35 fn new_span(&self, _: &Attributes<'_>) -> Id {
36 Id::from_u64(0xAAAA)
37 }
38
39 fn record(&self, _: &Id, _: &Record<'_>) {}
40
41 fn record_follows_from(&self, _: &Id, _: &Id) {}
42
43 fn event(&self, event: &Event<'_>) {
44 assert!(event.metadata().fields().iter().any(|f| f.name() == "foo"));
45 tracing::event!(Level::TRACE, baz = false);
46 }
47
48 fn enter(&self, _: &Id) {}
49
50 fn exit(&self, _: &Id) {}
51 }
52
53 with_default(TestSubscriber, || {
54 tracing::event!(Level::TRACE, foo = false);
55 })
56 }
57
58 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
59 #[test]
boxed_subscriber()60 fn boxed_subscriber() {
61 let (subscriber, handle) = subscriber::mock()
62 .new_span(
63 expect::span().named("foo").with_fields(
64 expect::field("bar")
65 .with_value(&display("hello from my span"))
66 .only(),
67 ),
68 )
69 .enter(expect::span().named("foo"))
70 .exit(expect::span().named("foo"))
71 .drop_span(expect::span().named("foo"))
72 .only()
73 .run_with_handle();
74 let subscriber: Box<dyn Subscriber + Send + Sync + 'static> = Box::new(subscriber);
75
76 with_default(subscriber, || {
77 let from = "my span";
78 let span = tracing::span!(
79 Level::TRACE,
80 "foo",
81 bar = format_args!("hello from {}", from)
82 );
83 span.in_scope(|| {});
84 });
85
86 handle.assert_finished();
87 }
88
89 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
90 #[test]
arced_subscriber()91 fn arced_subscriber() {
92 use std::sync::Arc;
93
94 let (subscriber, handle) = subscriber::mock()
95 .new_span(
96 expect::span().named("foo").with_fields(
97 expect::field("bar")
98 .with_value(&display("hello from my span"))
99 .only(),
100 ),
101 )
102 .enter(expect::span().named("foo"))
103 .exit(expect::span().named("foo"))
104 .drop_span(expect::span().named("foo"))
105 .event(
106 expect::event()
107 .with_fields(expect::field("message").with_value(&display("hello from my event"))),
108 )
109 .only()
110 .run_with_handle();
111 let subscriber: Arc<dyn Subscriber + Send + Sync + 'static> = Arc::new(subscriber);
112
113 // Test using a clone of the `Arc`ed subscriber
114 with_default(subscriber.clone(), || {
115 let from = "my span";
116 let span = tracing::span!(
117 Level::TRACE,
118 "foo",
119 bar = format_args!("hello from {}", from)
120 );
121 span.in_scope(|| {});
122 });
123
124 with_default(subscriber, || {
125 tracing::info!("hello from my event");
126 });
127
128 handle.assert_finished();
129 }
130