1use std::{sync::mpsc, thread, time::Duration};
2use tracing::{
3 metadata::Metadata,
4 span,
5 subscriber::{self, Interest, Subscriber},
6 Event,
7};
8
9#[test]
10fn 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