]> git.proxmox.com Git - rustc.git/blob - vendor/tracing-attributes/tests/async_fn.rs
New upstream version 1.57.0+dfsg1
[rustc.git] / vendor / tracing-attributes / tests / async_fn.rs
1 #[path = "../../tracing-futures/tests/support.rs"]
2 // we don't use some of the test support functions, but `tracing-futures` does.
3 #[allow(dead_code)]
4 mod support;
5 use support::*;
6
7 use std::{future::Future, pin::Pin, sync::Arc};
8 use tracing::subscriber::with_default;
9 use tracing_attributes::instrument;
10
11 #[instrument]
12 async fn test_async_fn(polls: usize) -> Result<(), ()> {
13 let future = PollN::new_ok(polls);
14 tracing::trace!(awaiting = true);
15 future.await
16 }
17
18 #[test]
19 fn async_fn_only_enters_for_polls() {
20 let (subscriber, handle) = subscriber::mock()
21 .new_span(span::mock().named("test_async_fn"))
22 .enter(span::mock().named("test_async_fn"))
23 .event(event::mock().with_fields(field::mock("awaiting").with_value(&true)))
24 .exit(span::mock().named("test_async_fn"))
25 .enter(span::mock().named("test_async_fn"))
26 .exit(span::mock().named("test_async_fn"))
27 .drop_span(span::mock().named("test_async_fn"))
28 .done()
29 .run_with_handle();
30 with_default(subscriber, || {
31 block_on_future(async { test_async_fn(2).await }).unwrap();
32 });
33 handle.assert_finished();
34 }
35
36 #[test]
37 fn async_fn_nested() {
38 #[instrument]
39 async fn test_async_fns_nested() {
40 test_async_fns_nested_other().await
41 }
42
43 #[instrument]
44 async fn test_async_fns_nested_other() {
45 tracing::trace!(nested = true);
46 }
47
48 let span = span::mock().named("test_async_fns_nested");
49 let span2 = span::mock().named("test_async_fns_nested_other");
50 let (subscriber, handle) = subscriber::mock()
51 .new_span(span.clone())
52 .enter(span.clone())
53 .new_span(span2.clone())
54 .enter(span2.clone())
55 .event(event::mock().with_fields(field::mock("nested").with_value(&true)))
56 .exit(span2.clone())
57 .drop_span(span2)
58 .exit(span.clone())
59 .drop_span(span)
60 .done()
61 .run_with_handle();
62
63 with_default(subscriber, || {
64 block_on_future(async { test_async_fns_nested().await });
65 });
66
67 handle.assert_finished();
68 }
69
70 #[test]
71 fn async_fn_with_async_trait() {
72 use async_trait::async_trait;
73
74 // test the correctness of the metadata obtained by #[instrument]
75 // (function name, functions parameters) when async-trait is used
76 #[async_trait]
77 pub trait TestA {
78 async fn foo(&mut self, v: usize);
79 }
80
81 // test nesting of async fns with aync-trait
82 #[async_trait]
83 pub trait TestB {
84 async fn bar(&self);
85 }
86
87 // test skip(self) with async-await
88 #[async_trait]
89 pub trait TestC {
90 async fn baz(&self);
91 }
92
93 #[derive(Debug)]
94 struct TestImpl(usize);
95
96 #[async_trait]
97 impl TestA for TestImpl {
98 #[instrument]
99 async fn foo(&mut self, v: usize) {
100 self.baz().await;
101 self.0 = v;
102 self.bar().await
103 }
104 }
105
106 #[async_trait]
107 impl TestB for TestImpl {
108 #[instrument]
109 async fn bar(&self) {
110 tracing::trace!(val = self.0);
111 }
112 }
113
114 #[async_trait]
115 impl TestC for TestImpl {
116 #[instrument(skip(self))]
117 async fn baz(&self) {
118 tracing::trace!(val = self.0);
119 }
120 }
121
122 let span = span::mock().named("foo");
123 let span2 = span::mock().named("bar");
124 let span3 = span::mock().named("baz");
125 let (subscriber, handle) = subscriber::mock()
126 .new_span(
127 span.clone()
128 .with_field(field::mock("self"))
129 .with_field(field::mock("v")),
130 )
131 .enter(span.clone())
132 .new_span(span3.clone())
133 .enter(span3.clone())
134 .event(event::mock().with_fields(field::mock("val").with_value(&2u64)))
135 .exit(span3.clone())
136 .drop_span(span3)
137 .new_span(span2.clone().with_field(field::mock("self")))
138 .enter(span2.clone())
139 .event(event::mock().with_fields(field::mock("val").with_value(&5u64)))
140 .exit(span2.clone())
141 .drop_span(span2)
142 .exit(span.clone())
143 .drop_span(span)
144 .done()
145 .run_with_handle();
146
147 with_default(subscriber, || {
148 let mut test = TestImpl(2);
149 block_on_future(async { test.foo(5).await });
150 });
151
152 handle.assert_finished();
153 }
154
155 #[test]
156 fn async_fn_with_async_trait_and_fields_expressions() {
157 use async_trait::async_trait;
158
159 #[async_trait]
160 pub trait Test {
161 async fn call(&mut self, v: usize);
162 }
163
164 #[derive(Clone, Debug)]
165 struct TestImpl;
166
167 impl TestImpl {
168 fn foo(&self) -> usize {
169 42
170 }
171 }
172
173 #[async_trait]
174 impl Test for TestImpl {
175 // check that self is correctly handled, even when using async_trait
176 #[instrument(fields(val=self.foo(), val2=Self::clone(self).foo(), test=%_v+5))]
177 async fn call(&mut self, _v: usize) {}
178 }
179
180 let span = span::mock().named("call");
181 let (subscriber, handle) = subscriber::mock()
182 .new_span(
183 span.clone().with_field(
184 field::mock("_v")
185 .with_value(&5usize)
186 .and(field::mock("test").with_value(&tracing::field::debug(10)))
187 .and(field::mock("val").with_value(&42u64))
188 .and(field::mock("val2").with_value(&42u64)),
189 ),
190 )
191 .enter(span.clone())
192 .exit(span.clone())
193 .drop_span(span)
194 .done()
195 .run_with_handle();
196
197 with_default(subscriber, || {
198 block_on_future(async { TestImpl.call(5).await });
199 });
200
201 handle.assert_finished();
202 }
203
204 #[test]
205 fn async_fn_with_async_trait_and_fields_expressions_with_generic_parameter() {
206 use async_trait::async_trait;
207
208 #[async_trait]
209 pub trait Test {
210 async fn call();
211 async fn call_with_self(&self);
212 async fn call_with_mut_self(&mut self);
213 }
214
215 #[derive(Clone, Debug)]
216 struct TestImpl;
217
218 // we also test sync functions that return futures, as they should be handled just like
219 // async-trait (>= 0.1.44) functions
220 impl TestImpl {
221 #[instrument(fields(Self=std::any::type_name::<Self>()))]
222 fn sync_fun(&self) -> Pin<Box<dyn Future<Output = ()> + Send + '_>> {
223 let val = self.clone();
224 Box::pin(async move {
225 let _ = val;
226 })
227 }
228 }
229
230 #[async_trait]
231 impl Test for TestImpl {
232 // instrumenting this is currently not possible, see https://github.com/tokio-rs/tracing/issues/864#issuecomment-667508801
233 //#[instrument(fields(Self=std::any::type_name::<Self>()))]
234 async fn call() {}
235
236 #[instrument(fields(Self=std::any::type_name::<Self>()))]
237 async fn call_with_self(&self) {
238 self.sync_fun().await;
239 }
240
241 #[instrument(fields(Self=std::any::type_name::<Self>()))]
242 async fn call_with_mut_self(&mut self) {}
243 }
244
245 //let span = span::mock().named("call");
246 let span2 = span::mock().named("call_with_self");
247 let span3 = span::mock().named("call_with_mut_self");
248 let span4 = span::mock().named("sync_fun");
249 let (subscriber, handle) = subscriber::mock()
250 /*.new_span(span.clone()
251 .with_field(
252 field::mock("Self").with_value(&"TestImpler")))
253 .enter(span.clone())
254 .exit(span.clone())
255 .drop_span(span)*/
256 .new_span(
257 span2
258 .clone()
259 .with_field(field::mock("Self").with_value(&std::any::type_name::<TestImpl>())),
260 )
261 .enter(span2.clone())
262 .new_span(
263 span4
264 .clone()
265 .with_field(field::mock("Self").with_value(&std::any::type_name::<TestImpl>())),
266 )
267 .enter(span4.clone())
268 .exit(span4)
269 .exit(span2.clone())
270 .drop_span(span2)
271 .new_span(
272 span3
273 .clone()
274 .with_field(field::mock("Self").with_value(&std::any::type_name::<TestImpl>())),
275 )
276 .enter(span3.clone())
277 .exit(span3.clone())
278 .drop_span(span3)
279 .done()
280 .run_with_handle();
281
282 with_default(subscriber, || {
283 block_on_future(async {
284 TestImpl::call().await;
285 TestImpl.call_with_self().await;
286 TestImpl.call_with_mut_self().await
287 });
288 });
289
290 handle.assert_finished();
291 }
292
293 #[test]
294 fn out_of_scope_fields() {
295 // Reproduces tokio-rs/tracing#1296
296
297 struct Thing {
298 metrics: Arc<()>,
299 }
300
301 impl Thing {
302 #[instrument(skip(self, _req), fields(app_id))]
303 fn call(&mut self, _req: ()) -> Pin<Box<dyn Future<Output = Arc<()>> + Send + Sync>> {
304 // ...
305 let metrics = self.metrics.clone();
306 // ...
307 Box::pin(async move {
308 // ...
309 metrics // cannot find value `metrics` in this scope
310 })
311 }
312 }
313
314 let span = span::mock().named("call");
315 let (subscriber, handle) = subscriber::mock()
316 .new_span(span.clone())
317 .enter(span.clone())
318 .exit(span.clone())
319 .drop_span(span)
320 .done()
321 .run_with_handle();
322
323 with_default(subscriber, || {
324 block_on_future(async {
325 let mut my_thing = Thing {
326 metrics: Arc::new(()),
327 };
328 my_thing.call(()).await;
329 });
330 });
331
332 handle.assert_finished();
333 }