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")]
8use tracing::{
9 field::display,
10 span::{Attributes, Id, Record},
11 subscriber::{with_default, Interest, Subscriber},
12 Event, Level, Metadata,
13};
14use tracing_mock::{expect, subscriber};
15
16#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
17#[test]
18fn 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]
60fn boxed_subscriber() {
61 let (subscriber, handle) = subscriber::mock()
62 .new_span(
63 expect::span().named("foo").with_field(
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]
91fn arced_subscriber() {
92 use std::sync::Arc;
93
94 let (subscriber, handle) = subscriber::mock()
95 .new_span(
96 expect::span().named("foo").with_field(
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