1 | use std::{sync::mpsc, thread, time::Duration}; |
2 | use tracing::{ |
3 | metadata::Metadata, |
4 | span, |
5 | subscriber::{self, Interest, Subscriber}, |
6 | Event, |
7 | }; |
8 | |
9 | #[test] |
10 | fn register_callsite_doesnt_deadlock() { |
11 | pub struct EvilSubscriber; |
12 | |
13 | impl Subscriber for EvilSubscriber { |
14 | fn register_callsite(&self, meta: &'static Metadata<'static>) -> Interest { |
15 | tracing::info!(?meta, "registered a callsite" ); |
16 | Interest::always() |
17 | } |
18 | |
19 | fn enabled(&self, _: &Metadata<'_>) -> bool { |
20 | true |
21 | } |
22 | fn new_span(&self, _: &span::Attributes<'_>) -> span::Id { |
23 | span::Id::from_u64(1) |
24 | } |
25 | fn record(&self, _: &span::Id, _: &span::Record<'_>) {} |
26 | fn record_follows_from(&self, _: &span::Id, _: &span::Id) {} |
27 | fn event(&self, _: &Event<'_>) {} |
28 | fn enter(&self, _: &span::Id) {} |
29 | fn exit(&self, _: &span::Id) {} |
30 | } |
31 | |
32 | subscriber::set_global_default(EvilSubscriber).unwrap(); |
33 | |
34 | // spawn a thread, and assert it doesn't hang... |
35 | let (tx, didnt_hang) = mpsc::channel(); |
36 | let th = thread::spawn(move || { |
37 | tracing::info!("hello world!" ); |
38 | tx.send(()).unwrap(); |
39 | }); |
40 | |
41 | didnt_hang |
42 | // Note: 60 seconds is *way* more than enough, but let's be generous in |
43 | // case of e.g. slow CI machines. |
44 | .recv_timeout(Duration::from_secs(60)) |
45 | .expect("the thread must not have hung!" ); |
46 | th.join().expect("thread should join successfully" ); |
47 | } |
48 | |