1 use tracing::subscriber::with_default;
2 use tracing::Level;
3 use tracing_attributes::instrument;
4 use 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]
repro_2294()10 fn repro_2294() {
11 #![allow(unused_variables)]
12 let i = 42;
13 }
14
15 #[test]
override_everything()16 fn 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]
fields()52 fn fields() {
53 #[instrument(target = "my_target", level = "debug")]
54 fn my_fn(arg1: usize, arg2: bool, arg3: String) {}
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_fields(
68 expect::field("arg1")
69 .with_value(&2usize)
70 .and(expect::field("arg2").with_value(&false))
71 .and(expect::field("arg3").with_value(&"Cool".to_string()))
72 .only(),
73 ),
74 )
75 .enter(span.clone())
76 .exit(span.clone())
77 .drop_span(span)
78 .new_span(
79 span2.clone().with_fields(
80 expect::field("arg1")
81 .with_value(&3usize)
82 .and(expect::field("arg2").with_value(&true))
83 .and(expect::field("arg3").with_value(&"Still Cool".to_string()))
84 .only(),
85 ),
86 )
87 .enter(span2.clone())
88 .exit(span2.clone())
89 .drop_span(span2)
90 .only()
91 .run_with_handle();
92
93 with_default(subscriber, || {
94 my_fn(2, false, "Cool".to_string());
95 my_fn(3, true, "Still Cool".to_string());
96 });
97
98 handle.assert_finished();
99 }
100
101 #[test]
skip()102 fn skip() {
103 struct UnDebug();
104
105 #[instrument(target = "my_target", level = "debug", skip(_arg2, _arg3))]
106 fn my_fn(arg1: usize, _arg2: UnDebug, _arg3: UnDebug) {}
107
108 #[instrument(target = "my_target", level = "debug", skip_all)]
109 fn my_fn2(_arg1: usize, _arg2: UnDebug, _arg3: UnDebug) {}
110
111 let span = expect::span()
112 .named("my_fn")
113 .at_level(Level::DEBUG)
114 .with_target("my_target");
115
116 let span2 = expect::span()
117 .named("my_fn")
118 .at_level(Level::DEBUG)
119 .with_target("my_target");
120
121 let span3 = expect::span()
122 .named("my_fn2")
123 .at_level(Level::DEBUG)
124 .with_target("my_target");
125
126 let (subscriber, handle) = subscriber::mock()
127 .new_span(
128 span.clone()
129 .with_fields(expect::field("arg1").with_value(&2usize).only()),
130 )
131 .enter(span.clone())
132 .exit(span.clone())
133 .drop_span(span)
134 .new_span(
135 span2
136 .clone()
137 .with_fields(expect::field("arg1").with_value(&3usize).only()),
138 )
139 .enter(span2.clone())
140 .exit(span2.clone())
141 .drop_span(span2)
142 .new_span(span3.clone())
143 .enter(span3.clone())
144 .exit(span3.clone())
145 .drop_span(span3)
146 .only()
147 .run_with_handle();
148
149 with_default(subscriber, || {
150 my_fn(2, UnDebug(), UnDebug());
151 my_fn(3, UnDebug(), UnDebug());
152 my_fn2(2, UnDebug(), UnDebug());
153 });
154
155 handle.assert_finished();
156 }
157
158 #[test]
generics()159 fn generics() {
160 #[derive(Debug)]
161 struct Foo;
162
163 #[instrument]
164 fn my_fn<S, T: std::fmt::Debug>(arg1: S, arg2: T)
165 where
166 S: std::fmt::Debug,
167 {
168 }
169
170 let span = expect::span().named("my_fn");
171
172 let (subscriber, handle) = subscriber::mock()
173 .new_span(
174 span.clone().with_fields(
175 expect::field("arg1")
176 .with_value(&format_args!("Foo"))
177 .and(expect::field("arg2").with_value(&format_args!("false"))),
178 ),
179 )
180 .enter(span.clone())
181 .exit(span.clone())
182 .drop_span(span)
183 .only()
184 .run_with_handle();
185
186 with_default(subscriber, || {
187 my_fn(Foo, false);
188 });
189
190 handle.assert_finished();
191 }
192
193 #[test]
methods()194 fn methods() {
195 #[derive(Debug)]
196 struct Foo;
197
198 impl Foo {
199 #[instrument]
200 fn my_fn(&self, arg1: usize) {}
201 }
202
203 let span = expect::span().named("my_fn");
204
205 let (subscriber, handle) = subscriber::mock()
206 .new_span(
207 span.clone().with_fields(
208 expect::field("self")
209 .with_value(&format_args!("Foo"))
210 .and(expect::field("arg1").with_value(&42usize)),
211 ),
212 )
213 .enter(span.clone())
214 .exit(span.clone())
215 .drop_span(span)
216 .only()
217 .run_with_handle();
218
219 with_default(subscriber, || {
220 let foo = Foo;
221 foo.my_fn(42);
222 });
223
224 handle.assert_finished();
225 }
226
227 #[test]
impl_trait_return_type()228 fn impl_trait_return_type() {
229 #[instrument]
230 fn returns_impl_trait(x: usize) -> impl Iterator<Item = usize> {
231 0..x
232 }
233
234 let span = expect::span().named("returns_impl_trait");
235
236 let (subscriber, handle) = subscriber::mock()
237 .new_span(
238 span.clone()
239 .with_fields(expect::field("x").with_value(&10usize).only()),
240 )
241 .enter(span.clone())
242 .exit(span.clone())
243 .drop_span(span)
244 .only()
245 .run_with_handle();
246
247 with_default(subscriber, || {
248 for _ in returns_impl_trait(10) {
249 // nop
250 }
251 });
252
253 handle.assert_finished();
254 }
255
256 #[test]
name_ident()257 fn name_ident() {
258 const MY_NAME: &str = "my_name";
259 #[instrument(name = MY_NAME)]
260 fn name() {}
261
262 let span_name = expect::span().named(MY_NAME);
263
264 let (subscriber, handle) = subscriber::mock()
265 .new_span(span_name.clone())
266 .enter(span_name.clone())
267 .exit(span_name.clone())
268 .drop_span(span_name)
269 .only()
270 .run_with_handle();
271
272 with_default(subscriber, || {
273 name();
274 });
275
276 handle.assert_finished();
277 }
278
279 #[test]
target_ident()280 fn target_ident() {
281 const MY_TARGET: &str = "my_target";
282
283 #[instrument(target = MY_TARGET)]
284 fn target() {}
285
286 let span_target = expect::span().named("target").with_target(MY_TARGET);
287
288 let (subscriber, handle) = subscriber::mock()
289 .new_span(span_target.clone())
290 .enter(span_target.clone())
291 .exit(span_target.clone())
292 .drop_span(span_target)
293 .only()
294 .run_with_handle();
295
296 with_default(subscriber, || {
297 target();
298 });
299
300 handle.assert_finished();
301 }
302
303 #[test]
target_name_ident()304 fn target_name_ident() {
305 const MY_NAME: &str = "my_name";
306 const MY_TARGET: &str = "my_target";
307
308 #[instrument(target = MY_TARGET, name = MY_NAME)]
309 fn name_target() {}
310
311 let span_name_target = expect::span().named(MY_NAME).with_target(MY_TARGET);
312
313 let (subscriber, handle) = subscriber::mock()
314 .new_span(span_name_target.clone())
315 .enter(span_name_target.clone())
316 .exit(span_name_target.clone())
317 .drop_span(span_name_target)
318 .only()
319 .run_with_handle();
320
321 with_default(subscriber, || {
322 name_target();
323 });
324
325 handle.assert_finished();
326 }
327