| 1 | // These tests require the thread-local scoped dispatcher, which only works when |
| 2 | // we have a standard library. The behaviour being tested should be the same |
| 3 | // with the standard lib disabled. |
| 4 | // |
| 5 | // The alternative would be for each of these tests to be defined in a separate |
| 6 | // file, which is :( |
| 7 | #![cfg (feature = "std" )] |
| 8 | use tracing::{ |
| 9 | field::display, |
| 10 | span::{Attributes, Id, Record}, |
| 11 | subscriber::{with_default, Interest, Subscriber}, |
| 12 | Event, Level, Metadata, |
| 13 | }; |
| 14 | use tracing_mock::{expect, subscriber}; |
| 15 | |
| 16 | #[cfg_attr (target_arch = "wasm32" , wasm_bindgen_test::wasm_bindgen_test)] |
| 17 | #[test] |
| 18 | fn event_macros_dont_infinite_loop() { |
| 19 | // This test ensures that an event macro within a subscriber |
| 20 | // won't cause an infinite loop of events. |
| 21 | struct TestSubscriber; |
| 22 | impl Subscriber for TestSubscriber { |
| 23 | fn register_callsite(&self, _: &Metadata<'_>) -> Interest { |
| 24 | // Always return sometimes so that `enabled` will be called |
| 25 | // (which can loop). |
| 26 | Interest::sometimes() |
| 27 | } |
| 28 | |
| 29 | fn enabled(&self, meta: &Metadata<'_>) -> bool { |
| 30 | assert!(meta.fields().iter().any(|f| f.name() == "foo" )); |
| 31 | tracing::event!(Level::TRACE, bar = false); |
| 32 | true |
| 33 | } |
| 34 | |
| 35 | fn new_span(&self, _: &Attributes<'_>) -> Id { |
| 36 | Id::from_u64(0xAAAA) |
| 37 | } |
| 38 | |
| 39 | fn record(&self, _: &Id, _: &Record<'_>) {} |
| 40 | |
| 41 | fn record_follows_from(&self, _: &Id, _: &Id) {} |
| 42 | |
| 43 | fn event(&self, event: &Event<'_>) { |
| 44 | assert!(event.metadata().fields().iter().any(|f| f.name() == "foo" )); |
| 45 | tracing::event!(Level::TRACE, baz = false); |
| 46 | } |
| 47 | |
| 48 | fn enter(&self, _: &Id) {} |
| 49 | |
| 50 | fn exit(&self, _: &Id) {} |
| 51 | } |
| 52 | |
| 53 | with_default(TestSubscriber, || { |
| 54 | tracing::event!(Level::TRACE, foo = false); |
| 55 | }) |
| 56 | } |
| 57 | |
| 58 | #[cfg_attr (target_arch = "wasm32" , wasm_bindgen_test::wasm_bindgen_test)] |
| 59 | #[test] |
| 60 | fn boxed_subscriber() { |
| 61 | let (subscriber, handle) = subscriber::mock() |
| 62 | .new_span( |
| 63 | expect::span().named("foo" ).with_field( |
| 64 | expect::field("bar" ) |
| 65 | .with_value(&display("hello from my span" )) |
| 66 | .only(), |
| 67 | ), |
| 68 | ) |
| 69 | .enter(expect::span().named("foo" )) |
| 70 | .exit(expect::span().named("foo" )) |
| 71 | .drop_span(expect::span().named("foo" )) |
| 72 | .only() |
| 73 | .run_with_handle(); |
| 74 | let subscriber: Box<dyn Subscriber + Send + Sync + 'static> = Box::new(subscriber); |
| 75 | |
| 76 | with_default(subscriber, || { |
| 77 | let from = "my span" ; |
| 78 | let span = tracing::span!( |
| 79 | Level::TRACE, |
| 80 | "foo" , |
| 81 | bar = format_args!("hello from {}" , from) |
| 82 | ); |
| 83 | span.in_scope(|| {}); |
| 84 | }); |
| 85 | |
| 86 | handle.assert_finished(); |
| 87 | } |
| 88 | |
| 89 | #[cfg_attr (target_arch = "wasm32" , wasm_bindgen_test::wasm_bindgen_test)] |
| 90 | #[test] |
| 91 | fn arced_subscriber() { |
| 92 | use std::sync::Arc; |
| 93 | |
| 94 | let (subscriber, handle) = subscriber::mock() |
| 95 | .new_span( |
| 96 | expect::span().named("foo" ).with_field( |
| 97 | expect::field("bar" ) |
| 98 | .with_value(&display("hello from my span" )) |
| 99 | .only(), |
| 100 | ), |
| 101 | ) |
| 102 | .enter(expect::span().named("foo" )) |
| 103 | .exit(expect::span().named("foo" )) |
| 104 | .drop_span(expect::span().named("foo" )) |
| 105 | .event( |
| 106 | expect::event() |
| 107 | .with_fields(expect::field("message" ).with_value(&display("hello from my event" ))), |
| 108 | ) |
| 109 | .only() |
| 110 | .run_with_handle(); |
| 111 | let subscriber: Arc<dyn Subscriber + Send + Sync + 'static> = Arc::new(subscriber); |
| 112 | |
| 113 | // Test using a clone of the `Arc`ed subscriber |
| 114 | with_default(subscriber.clone(), || { |
| 115 | let from = "my span" ; |
| 116 | let span = tracing::span!( |
| 117 | Level::TRACE, |
| 118 | "foo" , |
| 119 | bar = format_args!("hello from {}" , from) |
| 120 | ); |
| 121 | span.in_scope(|| {}); |
| 122 | }); |
| 123 | |
| 124 | with_default(subscriber, || { |
| 125 | tracing::info!("hello from my event" ); |
| 126 | }); |
| 127 | |
| 128 | handle.assert_finished(); |
| 129 | } |
| 130 | |