1use tracing::subscriber::with_default;
2use tracing::Level;
3use tracing_attributes::instrument;
4use tracing_mock::*;
5
6// Reproduces a compile error when an instrumented function body contains inner
7// attributes (https://github.com/tokio-rs/tracing/issues/2294).
8#[deny(unused_variables)]
9#[instrument]
10fn repro_2294() {
11 #![allow(unused_variables)]
12 let i = 42;
13}
14
15#[test]
16fn override_everything() {
17 #[instrument(target = "my_target", level = "debug")]
18 fn my_fn() {}
19
20 #[instrument(level = Level::DEBUG, target = "my_target")]
21 fn my_other_fn() {}
22
23 let span = expect::span()
24 .named("my_fn")
25 .at_level(Level::DEBUG)
26 .with_target("my_target");
27 let span2 = expect::span()
28 .named("my_other_fn")
29 .at_level(Level::DEBUG)
30 .with_target("my_target");
31 let (subscriber, handle) = subscriber::mock()
32 .new_span(span.clone())
33 .enter(span.clone())
34 .exit(span.clone())
35 .drop_span(span)
36 .new_span(span2.clone())
37 .enter(span2.clone())
38 .exit(span2.clone())
39 .drop_span(span2)
40 .only()
41 .run_with_handle();
42
43 with_default(subscriber, || {
44 my_fn();
45 my_other_fn();
46 });
47
48 handle.assert_finished();
49}
50
51#[test]
52fn fields() {
53 #[instrument(target = "my_target", level = "debug")]
54 fn my_fn(arg1: usize, arg2: bool) {}
55
56 let span = expect::span()
57 .named("my_fn")
58 .at_level(Level::DEBUG)
59 .with_target("my_target");
60
61 let span2 = expect::span()
62 .named("my_fn")
63 .at_level(Level::DEBUG)
64 .with_target("my_target");
65 let (subscriber, handle) = subscriber::mock()
66 .new_span(
67 span.clone().with_field(
68 expect::field("arg1")
69 .with_value(&2usize)
70 .and(expect::field("arg2").with_value(&false))
71 .only(),
72 ),
73 )
74 .enter(span.clone())
75 .exit(span.clone())
76 .drop_span(span)
77 .new_span(
78 span2.clone().with_field(
79 expect::field("arg1")
80 .with_value(&3usize)
81 .and(expect::field("arg2").with_value(&true))
82 .only(),
83 ),
84 )
85 .enter(span2.clone())
86 .exit(span2.clone())
87 .drop_span(span2)
88 .only()
89 .run_with_handle();
90
91 with_default(subscriber, || {
92 my_fn(2, false);
93 my_fn(3, true);
94 });
95
96 handle.assert_finished();
97}
98
99#[test]
100fn skip() {
101 struct UnDebug(pub u32);
102
103 #[instrument(target = "my_target", level = "debug", skip(_arg2, _arg3))]
104 fn my_fn(arg1: usize, _arg2: UnDebug, _arg3: UnDebug) {}
105
106 #[instrument(target = "my_target", level = "debug", skip_all)]
107 fn my_fn2(_arg1: usize, _arg2: UnDebug, _arg3: UnDebug) {}
108
109 let span = expect::span()
110 .named("my_fn")
111 .at_level(Level::DEBUG)
112 .with_target("my_target");
113
114 let span2 = expect::span()
115 .named("my_fn")
116 .at_level(Level::DEBUG)
117 .with_target("my_target");
118
119 let span3 = expect::span()
120 .named("my_fn2")
121 .at_level(Level::DEBUG)
122 .with_target("my_target");
123
124 let (subscriber, handle) = subscriber::mock()
125 .new_span(
126 span.clone()
127 .with_field(expect::field("arg1").with_value(&2usize).only()),
128 )
129 .enter(span.clone())
130 .exit(span.clone())
131 .drop_span(span)
132 .new_span(
133 span2
134 .clone()
135 .with_field(expect::field("arg1").with_value(&3usize).only()),
136 )
137 .enter(span2.clone())
138 .exit(span2.clone())
139 .drop_span(span2)
140 .new_span(span3.clone())
141 .enter(span3.clone())
142 .exit(span3.clone())
143 .drop_span(span3)
144 .only()
145 .run_with_handle();
146
147 with_default(subscriber, || {
148 my_fn(2, UnDebug(0), UnDebug(1));
149 my_fn(3, UnDebug(0), UnDebug(1));
150 my_fn2(2, UnDebug(0), UnDebug(1));
151 });
152
153 handle.assert_finished();
154}
155
156#[test]
157fn generics() {
158 #[derive(Debug)]
159 struct Foo;
160
161 #[instrument]
162 fn my_fn<S, T: std::fmt::Debug>(arg1: S, arg2: T)
163 where
164 S: std::fmt::Debug,
165 {
166 }
167
168 let span = expect::span().named("my_fn");
169
170 let (subscriber, handle) = subscriber::mock()
171 .new_span(
172 span.clone().with_field(
173 expect::field("arg1")
174 .with_value(&format_args!("Foo"))
175 .and(expect::field("arg2").with_value(&format_args!("false"))),
176 ),
177 )
178 .enter(span.clone())
179 .exit(span.clone())
180 .drop_span(span)
181 .only()
182 .run_with_handle();
183
184 with_default(subscriber, || {
185 my_fn(Foo, false);
186 });
187
188 handle.assert_finished();
189}
190
191#[test]
192fn methods() {
193 #[derive(Debug)]
194 struct Foo;
195
196 impl Foo {
197 #[instrument]
198 fn my_fn(&self, arg1: usize) {}
199 }
200
201 let span = expect::span().named("my_fn");
202
203 let (subscriber, handle) = subscriber::mock()
204 .new_span(
205 span.clone().with_field(
206 expect::field("self")
207 .with_value(&format_args!("Foo"))
208 .and(expect::field("arg1").with_value(&42usize)),
209 ),
210 )
211 .enter(span.clone())
212 .exit(span.clone())
213 .drop_span(span)
214 .only()
215 .run_with_handle();
216
217 with_default(subscriber, || {
218 let foo = Foo;
219 foo.my_fn(42);
220 });
221
222 handle.assert_finished();
223}
224
225#[test]
226fn impl_trait_return_type() {
227 #[instrument]
228 fn returns_impl_trait(x: usize) -> impl Iterator<Item = usize> {
229 0..x
230 }
231
232 let span = expect::span().named("returns_impl_trait");
233
234 let (subscriber, handle) = subscriber::mock()
235 .new_span(
236 span.clone()
237 .with_field(expect::field("x").with_value(&10usize).only()),
238 )
239 .enter(span.clone())
240 .exit(span.clone())
241 .drop_span(span)
242 .only()
243 .run_with_handle();
244
245 with_default(subscriber, || {
246 for _ in returns_impl_trait(10) {
247 // nop
248 }
249 });
250
251 handle.assert_finished();
252}
253