diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/tracing/tests | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/tracing/tests')
18 files changed, 3058 insertions, 0 deletions
diff --git a/third_party/rust/tracing/tests/enabled.rs b/third_party/rust/tracing/tests/enabled.rs new file mode 100644 index 0000000000..ea1c69804d --- /dev/null +++ b/third_party/rust/tracing/tests/enabled.rs @@ -0,0 +1,54 @@ +#![cfg(feature = "std")] +use tracing::Level; +use tracing_mock::*; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn level_and_target() { + let subscriber = subscriber::mock() + .with_filter(|meta| { + if meta.target() == "debug_module" { + meta.level() <= &Level::DEBUG + } else { + meta.level() <= &Level::INFO + } + }) + .done() + .run(); + + let _guard = tracing::subscriber::set_default(subscriber); + + assert!(tracing::enabled!(target: "debug_module", Level::DEBUG)); + assert!(tracing::enabled!(Level::ERROR)); + assert!(!tracing::enabled!(Level::DEBUG)); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn span_and_event() { + let subscriber = subscriber::mock() + .with_filter(|meta| { + if meta.target() == "debug_module" { + meta.level() <= &Level::DEBUG + } else if meta.is_span() { + meta.level() <= &Level::TRACE + } else if meta.is_event() { + meta.level() <= &Level::DEBUG + } else { + meta.level() <= &Level::INFO + } + }) + .done() + .run(); + + let _guard = tracing::subscriber::set_default(subscriber); + + // Ensure that the `_event` and `_span` alternatives work corretly + assert!(!tracing::event_enabled!(Level::TRACE)); + assert!(tracing::event_enabled!(Level::DEBUG)); + assert!(tracing::span_enabled!(Level::TRACE)); + + // target variants + assert!(tracing::span_enabled!(target: "debug_module", Level::DEBUG)); + assert!(tracing::event_enabled!(target: "debug_module", Level::DEBUG)); +} diff --git a/third_party/rust/tracing/tests/event.rs b/third_party/rust/tracing/tests/event.rs new file mode 100644 index 0000000000..61df19ad3c --- /dev/null +++ b/third_party/rust/tracing/tests/event.rs @@ -0,0 +1,500 @@ +// These tests require the thread-local scoped dispatcher, which only works when +// we have a standard library. The behaviour being tested should be the same +// with the standard lib disabled. +// +// The alternative would be for each of these tests to be defined in a separate +// file, which is :( +#![cfg(feature = "std")] + +use tracing::{ + debug, error, + field::{debug, display}, + info, + subscriber::with_default, + trace, warn, Level, +}; +use tracing_mock::*; + +macro_rules! event_without_message { + ($name:ident: $e:expr) => { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] + #[test] + fn $name() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("answer") + .with_value(&42) + .and( + field::mock("to_question") + .with_value(&"life, the universe, and everything"), + ) + .only(), + ), + ) + .done() + .run_with_handle(); + + with_default(subscriber, || { + info!( + answer = $e, + to_question = "life, the universe, and everything" + ); + }); + + handle.assert_finished(); + } + }; +} + +event_without_message! {event_without_message: 42} +event_without_message! {wrapping_event_without_message: std::num::Wrapping(42)} +event_without_message! {nonzeroi32_event_without_message: std::num::NonZeroI32::new(42).unwrap()} +// needs API breakage +//event_without_message!{nonzerou128_event_without_message: std::num::NonZeroU128::new(42).unwrap()} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn event_with_message() { + let (subscriber, handle) = subscriber::mock() + .event(event::msg(format_args!( + "hello from my event! yak shaved = {:?}", + true + ))) + .done() + .run_with_handle(); + + with_default(subscriber, || { + debug!("hello from my event! yak shaved = {:?}", true); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn message_without_delims() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("answer") + .with_value(&42) + .and(field::mock("question").with_value(&"life, the universe, and everything")) + .and(field::msg(format_args!( + "hello from my event! tricky? {:?}!", + true + ))) + .only(), + ), + ) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let question = "life, the universe, and everything"; + debug!(answer = 42, question, "hello from {where}! tricky? {:?}!", true, where = "my event"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn string_message_without_delims() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("answer") + .with_value(&42) + .and(field::mock("question").with_value(&"life, the universe, and everything")) + .and(field::msg(format_args!("hello from my event"))) + .only(), + ), + ) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let question = "life, the universe, and everything"; + debug!(answer = 42, question, "hello from my event"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn one_with_everything() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock() + .with_fields( + field::mock("message") + .with_value(&tracing::field::debug(format_args!( + "{:#x} make me one with{what:.>20}", + 4_277_009_102u64, + what = "everything" + ))) + .and(field::mock("foo").with_value(&666)) + .and(field::mock("bar").with_value(&false)) + .and(field::mock("like_a_butterfly").with_value(&42.0)) + .only(), + ) + .at_level(Level::ERROR) + .with_target("whatever"), + ) + .done() + .run_with_handle(); + + with_default(subscriber, || { + tracing::event!( + target: "whatever", + Level::ERROR, + { foo = 666, bar = false, like_a_butterfly = 42.0 }, + "{:#x} make me one with{what:.>20}", 4_277_009_102u64, what = "everything" + ); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn moved_field() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("foo") + .with_value(&display("hello from my event")) + .only(), + ), + ) + .done() + .run_with_handle(); + with_default(subscriber, || { + let from = "my event"; + tracing::event!(Level::INFO, foo = display(format!("hello from {}", from))) + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn dotted_field_name() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("foo.bar") + .with_value(&true) + .and(field::mock("foo.baz").with_value(&false)) + .only(), + ), + ) + .done() + .run_with_handle(); + with_default(subscriber, || { + tracing::event!(Level::INFO, foo.bar = true, foo.baz = false); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn borrowed_field() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("foo") + .with_value(&display("hello from my event")) + .only(), + ), + ) + .done() + .run_with_handle(); + with_default(subscriber, || { + let from = "my event"; + let mut message = format!("hello from {}", from); + tracing::event!(Level::INFO, foo = display(&message)); + message.push_str(", which happened!"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +// If emitting log instrumentation, this gets moved anyway, breaking the test. +#[cfg(not(feature = "log"))] +fn move_field_out_of_struct() { + use tracing::field::debug; + + #[derive(Debug)] + struct Position { + x: f32, + y: f32, + } + + let pos = Position { + x: 3.234, + y: -1.223, + }; + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("x") + .with_value(&debug(3.234)) + .and(field::mock("y").with_value(&debug(-1.223))) + .only(), + ), + ) + .event(event::mock().with_fields(field::mock("position").with_value(&debug(&pos)))) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let pos = Position { + x: 3.234, + y: -1.223, + }; + debug!(x = debug(pos.x), y = debug(pos.y)); + debug!(target: "app_events", { position = debug(pos) }, "New position"); + }); + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn display_shorthand() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("my_field") + .with_value(&display("hello world")) + .only(), + ), + ) + .done() + .run_with_handle(); + with_default(subscriber, || { + tracing::event!(Level::TRACE, my_field = %"hello world"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn debug_shorthand() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("my_field") + .with_value(&debug("hello world")) + .only(), + ), + ) + .done() + .run_with_handle(); + with_default(subscriber, || { + tracing::event!(Level::TRACE, my_field = ?"hello world"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn both_shorthands() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("display_field") + .with_value(&display("hello world")) + .and(field::mock("debug_field").with_value(&debug("hello world"))) + .only(), + ), + ) + .done() + .run_with_handle(); + with_default(subscriber, || { + tracing::event!(Level::TRACE, display_field = %"hello world", debug_field = ?"hello world"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn explicit_child() { + let (subscriber, handle) = subscriber::mock() + .new_span(span::mock().named("foo")) + .event(event::mock().with_explicit_parent(Some("foo"))) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let foo = tracing::span!(Level::TRACE, "foo"); + tracing::event!(parent: foo.id(), Level::TRACE, "bar"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn explicit_child_at_levels() { + let (subscriber, handle) = subscriber::mock() + .new_span(span::mock().named("foo")) + .event(event::mock().with_explicit_parent(Some("foo"))) + .event(event::mock().with_explicit_parent(Some("foo"))) + .event(event::mock().with_explicit_parent(Some("foo"))) + .event(event::mock().with_explicit_parent(Some("foo"))) + .event(event::mock().with_explicit_parent(Some("foo"))) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let foo = tracing::span!(Level::TRACE, "foo"); + trace!(parent: foo.id(), "a"); + debug!(parent: foo.id(), "b"); + info!(parent: foo.id(), "c"); + warn!(parent: foo.id(), "d"); + error!(parent: foo.id(), "e"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn option_values() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("some_str") + .with_value(&"yes") + .and(field::mock("some_bool").with_value(&true)) + .and(field::mock("some_u64").with_value(&42_u64)) + .only(), + ), + ) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let some_str = Some("yes"); + let none_str: Option<&'static str> = None; + let some_bool = Some(true); + let none_bool: Option<bool> = None; + let some_u64 = Some(42_u64); + let none_u64: Option<u64> = None; + trace!( + some_str = some_str, + none_str = none_str, + some_bool = some_bool, + none_bool = none_bool, + some_u64 = some_u64, + none_u64 = none_u64 + ); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn option_ref_values() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("some_str") + .with_value(&"yes") + .and(field::mock("some_bool").with_value(&true)) + .and(field::mock("some_u64").with_value(&42_u64)) + .only(), + ), + ) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let some_str = &Some("yes"); + let none_str: &Option<&'static str> = &None; + let some_bool = &Some(true); + let none_bool: &Option<bool> = &None; + let some_u64 = &Some(42_u64); + let none_u64: &Option<u64> = &None; + trace!( + some_str = some_str, + none_str = none_str, + some_bool = some_bool, + none_bool = none_bool, + some_u64 = some_u64, + none_u64 = none_u64 + ); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn option_ref_mut_values() { + let (subscriber, handle) = subscriber::mock() + .event( + event::mock().with_fields( + field::mock("some_str") + .with_value(&"yes") + .and(field::mock("some_bool").with_value(&true)) + .and(field::mock("some_u64").with_value(&42_u64)) + .only(), + ), + ) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let some_str = &mut Some("yes"); + let none_str: &mut Option<&'static str> = &mut None; + let some_bool = &mut Some(true); + let none_bool: &mut Option<bool> = &mut None; + let some_u64 = &mut Some(42_u64); + let none_u64: &mut Option<u64> = &mut None; + trace!( + some_str = some_str, + none_str = none_str, + some_bool = some_bool, + none_bool = none_bool, + some_u64 = some_u64, + none_u64 = none_u64 + ); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn string_field() { + let (subscriber, handle) = subscriber::mock() + .event(event::mock().with_fields(field::mock("my_string").with_value(&"hello").only())) + .event( + event::mock().with_fields(field::mock("my_string").with_value(&"hello world!").only()), + ) + .done() + .run_with_handle(); + with_default(subscriber, || { + let mut my_string = String::from("hello"); + + tracing::event!(Level::INFO, my_string); + + // the string is not moved by using it as a field! + my_string.push_str(" world!"); + + tracing::event!(Level::INFO, my_string); + }); + + handle.assert_finished(); +} diff --git a/third_party/rust/tracing/tests/filter_caching_is_lexically_scoped.rs b/third_party/rust/tracing/tests/filter_caching_is_lexically_scoped.rs new file mode 100644 index 0000000000..e291103d75 --- /dev/null +++ b/third_party/rust/tracing/tests/filter_caching_is_lexically_scoped.rs @@ -0,0 +1,65 @@ +// Tests that depend on a count of the number of times their filter is evaluated +// can't exist in the same file with other tests that add subscribers to the +// registry. The registry was changed so that each time a new dispatcher is +// added all filters are re-evaluated. The tests being run only in separate +// threads with shared global state lets them interfere with each other + +#[cfg(not(feature = "std"))] +extern crate std; + +use tracing::{span, Level}; +use tracing_mock::*; + +use std::sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, +}; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn filter_caching_is_lexically_scoped() { + pub fn my_great_function() -> bool { + span!(Level::TRACE, "emily").in_scope(|| true) + } + + pub fn my_other_function() -> bool { + span!(Level::TRACE, "frank").in_scope(|| true) + } + + let count = Arc::new(AtomicUsize::new(0)); + let count2 = count.clone(); + + let subscriber = subscriber::mock() + .with_filter(move |meta| match meta.name() { + "emily" | "frank" => { + count2.fetch_add(1, Ordering::Relaxed); + true + } + _ => false, + }) + .run(); + + // Since this test is in its own file anyway, we can do this. Thus, this + // test will work even with no-std. + tracing::subscriber::set_global_default(subscriber).unwrap(); + + // Call the function once. The filter should be re-evaluated. + assert!(my_great_function()); + assert_eq!(count.load(Ordering::Relaxed), 1); + + // Call the function again. The cached result should be used. + assert!(my_great_function()); + assert_eq!(count.load(Ordering::Relaxed), 1); + + assert!(my_other_function()); + assert_eq!(count.load(Ordering::Relaxed), 2); + + assert!(my_great_function()); + assert_eq!(count.load(Ordering::Relaxed), 2); + + assert!(my_other_function()); + assert_eq!(count.load(Ordering::Relaxed), 2); + + assert!(my_great_function()); + assert_eq!(count.load(Ordering::Relaxed), 2); +} diff --git a/third_party/rust/tracing/tests/filters_are_not_reevaluated_for_the_same_span.rs b/third_party/rust/tracing/tests/filters_are_not_reevaluated_for_the_same_span.rs new file mode 100644 index 0000000000..e9b2529b8f --- /dev/null +++ b/third_party/rust/tracing/tests/filters_are_not_reevaluated_for_the_same_span.rs @@ -0,0 +1,70 @@ +// Tests that depend on a count of the number of times their filter is evaluated +// cant exist in the same file with other tests that add subscribers to the +// registry. The registry was changed so that each time a new dispatcher is +// added all filters are re-evaluated. The tests being run only in separate +// threads with shared global state lets them interfere with each other +#[cfg(not(feature = "std"))] +extern crate std; + +use tracing::{span, Level}; +use tracing_mock::*; + +use std::sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, +}; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn filters_are_not_reevaluated_for_the_same_span() { + // Asserts that the `span!` macro caches the result of calling + // `Subscriber::enabled` for each span. + let alice_count = Arc::new(AtomicUsize::new(0)); + let bob_count = Arc::new(AtomicUsize::new(0)); + let alice_count2 = alice_count.clone(); + let bob_count2 = bob_count.clone(); + + let (subscriber, handle) = subscriber::mock() + .with_filter(move |meta| match meta.name() { + "alice" => { + alice_count2.fetch_add(1, Ordering::Relaxed); + false + } + "bob" => { + bob_count2.fetch_add(1, Ordering::Relaxed); + true + } + _ => false, + }) + .run_with_handle(); + + // Since this test is in its own file anyway, we can do this. Thus, this + // test will work even with no-std. + tracing::subscriber::set_global_default(subscriber).unwrap(); + + // Enter "alice" and then "bob". The dispatcher expects to see "bob" but + // not "alice." + let alice = span!(Level::TRACE, "alice"); + let bob = alice.in_scope(|| { + let bob = span!(Level::TRACE, "bob"); + bob.in_scope(|| ()); + bob + }); + + // The filter should have seen each span a single time. + assert_eq!(alice_count.load(Ordering::Relaxed), 1); + assert_eq!(bob_count.load(Ordering::Relaxed), 1); + + alice.in_scope(|| bob.in_scope(|| {})); + + // The subscriber should see "bob" again, but the filter should not have + // been called. + assert_eq!(alice_count.load(Ordering::Relaxed), 1); + assert_eq!(bob_count.load(Ordering::Relaxed), 1); + + bob.in_scope(|| {}); + assert_eq!(alice_count.load(Ordering::Relaxed), 1); + assert_eq!(bob_count.load(Ordering::Relaxed), 1); + + handle.assert_finished(); +} diff --git a/third_party/rust/tracing/tests/filters_are_reevaluated_for_different_call_sites.rs b/third_party/rust/tracing/tests/filters_are_reevaluated_for_different_call_sites.rs new file mode 100644 index 0000000000..265d4a8865 --- /dev/null +++ b/third_party/rust/tracing/tests/filters_are_reevaluated_for_different_call_sites.rs @@ -0,0 +1,80 @@ +// Tests that depend on a count of the number of times their filter is evaluated +// cant exist in the same file with other tests that add subscribers to the +// registry. The registry was changed so that each time a new dispatcher is +// added all filters are re-evaluated. The tests being run only in separate +// threads with shared global state lets them interfere with each other +#[cfg(not(feature = "std"))] +extern crate std; + +use tracing::{span, Level}; +use tracing_mock::*; + +use std::sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, +}; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn filters_are_reevaluated_for_different_call_sites() { + // Asserts that the `span!` macro caches the result of calling + // `Subscriber::enabled` for each span. + let charlie_count = Arc::new(AtomicUsize::new(0)); + let dave_count = Arc::new(AtomicUsize::new(0)); + let charlie_count2 = charlie_count.clone(); + let dave_count2 = dave_count.clone(); + + let subscriber = subscriber::mock() + .with_filter(move |meta| { + println!("Filter: {:?}", meta.name()); + match meta.name() { + "charlie" => { + charlie_count2.fetch_add(1, Ordering::Relaxed); + false + } + "dave" => { + dave_count2.fetch_add(1, Ordering::Relaxed); + true + } + _ => false, + } + }) + .run(); + + // Since this test is in its own file anyway, we can do this. Thus, this + // test will work even with no-std. + tracing::subscriber::set_global_default(subscriber).unwrap(); + + // Enter "charlie" and then "dave". The dispatcher expects to see "dave" but + // not "charlie." + let charlie = span!(Level::TRACE, "charlie"); + let dave = charlie.in_scope(|| { + let dave = span!(Level::TRACE, "dave"); + dave.in_scope(|| {}); + dave + }); + + // The filter should have seen each span a single time. + assert_eq!(charlie_count.load(Ordering::Relaxed), 1); + assert_eq!(dave_count.load(Ordering::Relaxed), 1); + + charlie.in_scope(|| dave.in_scope(|| {})); + + // The subscriber should see "dave" again, but the filter should not have + // been called. + assert_eq!(charlie_count.load(Ordering::Relaxed), 1); + assert_eq!(dave_count.load(Ordering::Relaxed), 1); + + // A different span with the same name has a different call site, so it + // should cause the filter to be reapplied. + let charlie2 = span!(Level::TRACE, "charlie"); + charlie.in_scope(|| {}); + assert_eq!(charlie_count.load(Ordering::Relaxed), 2); + assert_eq!(dave_count.load(Ordering::Relaxed), 1); + + // But, the filter should not be re-evaluated for the new "charlie" span + // when it is re-entered. + charlie2.in_scope(|| span!(Level::TRACE, "dave").in_scope(|| {})); + assert_eq!(charlie_count.load(Ordering::Relaxed), 2); + assert_eq!(dave_count.load(Ordering::Relaxed), 2); +} diff --git a/third_party/rust/tracing/tests/filters_dont_leak.rs b/third_party/rust/tracing/tests/filters_dont_leak.rs new file mode 100644 index 0000000000..2ef1c9c701 --- /dev/null +++ b/third_party/rust/tracing/tests/filters_dont_leak.rs @@ -0,0 +1,81 @@ +#![cfg(feature = "std")] + +use tracing_mock::*; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn spans_dont_leak() { + fn do_span() { + let span = tracing::debug_span!("alice"); + let _e = span.enter(); + } + + let (subscriber, handle) = subscriber::mock() + .named("spans/subscriber1") + .with_filter(|_| false) + .done() + .run_with_handle(); + + let _guard = tracing::subscriber::set_default(subscriber); + + do_span(); + + let alice = span::mock().named("alice"); + let (subscriber2, handle2) = subscriber::mock() + .named("spans/subscriber2") + .with_filter(|_| true) + .new_span(alice.clone()) + .enter(alice.clone()) + .exit(alice.clone()) + .drop_span(alice) + .done() + .run_with_handle(); + + tracing::subscriber::with_default(subscriber2, || { + println!("--- subscriber 2 is default ---"); + do_span() + }); + + println!("--- subscriber 1 is default ---"); + do_span(); + + handle.assert_finished(); + handle2.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn events_dont_leak() { + fn do_event() { + tracing::debug!("alice"); + } + + let (subscriber, handle) = subscriber::mock() + .named("events/subscriber1") + .with_filter(|_| false) + .done() + .run_with_handle(); + + let _guard = tracing::subscriber::set_default(subscriber); + + do_event(); + + let (subscriber2, handle2) = subscriber::mock() + .named("events/subscriber2") + .with_filter(|_| true) + .event(event::mock()) + .done() + .run_with_handle(); + + tracing::subscriber::with_default(subscriber2, || { + println!("--- subscriber 2 is default ---"); + do_event() + }); + + println!("--- subscriber 1 is default ---"); + + do_event(); + + handle.assert_finished(); + handle2.assert_finished(); +} diff --git a/third_party/rust/tracing/tests/future_send.rs b/third_party/rust/tracing/tests/future_send.rs new file mode 100644 index 0000000000..5e5f9f18bc --- /dev/null +++ b/third_party/rust/tracing/tests/future_send.rs @@ -0,0 +1,22 @@ +// These tests reproduce the following issues: +// - https://github.com/tokio-rs/tracing/issues/1487 +// - https://github.com/tokio-rs/tracing/issues/1793 + +use core::future::{self, Future}; +#[test] +fn async_fn_is_send() { + async fn some_async_fn() { + tracing::info!("{}", future::ready("test").await); + } + + assert_send(some_async_fn()) +} + +#[test] +fn async_block_is_send() { + assert_send(async { + tracing::info!("{}", future::ready("test").await); + }) +} + +fn assert_send<F: Future + Send>(_f: F) {} diff --git a/third_party/rust/tracing/tests/macro_imports.rs b/third_party/rust/tracing/tests/macro_imports.rs new file mode 100644 index 0000000000..2d0a9d6528 --- /dev/null +++ b/third_party/rust/tracing/tests/macro_imports.rs @@ -0,0 +1,23 @@ +use tracing::Level; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn prefixed_span_macros() { + tracing::span!(Level::DEBUG, "foo"); + tracing::trace_span!("foo"); + tracing::debug_span!("foo"); + tracing::info_span!("foo"); + tracing::warn_span!("foo"); + tracing::error_span!("foo"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn prefixed_event_macros() { + tracing::event!(Level::DEBUG, "foo"); + tracing::trace!("foo"); + tracing::debug!("foo"); + tracing::info!("foo"); + tracing::warn!("foo"); + tracing::error!("foo"); +} diff --git a/third_party/rust/tracing/tests/macros.rs b/third_party/rust/tracing/tests/macros.rs new file mode 100644 index 0000000000..a9679a3e94 --- /dev/null +++ b/third_party/rust/tracing/tests/macros.rs @@ -0,0 +1,963 @@ +#![deny(warnings)] +use tracing::{ + callsite, debug, debug_span, enabled, error, error_span, event, event_enabled, info, info_span, + span, span_enabled, trace, trace_span, warn, warn_span, Level, +}; + +// Tests that macros work across various invocation syntax. +// +// These are quite repetitive, and _could_ be generated by a macro. However, +// they're compile-time tests, so I want to get line numbers etc out of +// failures, and producing them with a macro would muddy the waters a bit. + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn span() { + span!(target: "foo_events", Level::DEBUG, "foo", bar.baz = ?2, quux = %3, quuux = 4); + span!(target: "foo_events", Level::DEBUG, "foo", bar.baz = 2, quux = 3); + span!(target: "foo_events", Level::DEBUG, "foo", bar.baz = 2, quux = 4,); + span!(target: "foo_events", Level::DEBUG, "foo"); + span!(target: "foo_events", Level::DEBUG, "bar",); + span!(Level::DEBUG, "foo", bar.baz = 2, quux = 3); + span!(Level::DEBUG, "foo", bar.baz = 2, quux = 4,); + span!(Level::DEBUG, "foo", bar.baz = 2, quux = 3); + span!(Level::DEBUG, "foo", bar.baz = 2, quux = 4,); + span!(Level::DEBUG, "foo", bar.baz = ?2); + span!(Level::DEBUG, "foo", bar.baz = %2); + span!(Level::DEBUG, "foo"); + span!(Level::DEBUG, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn trace_span() { + trace_span!(target: "foo_events", "foo", bar.baz = ?2, quux = %3, quuux = 4); + trace_span!(target: "foo_events", "foo", bar.baz = 2, quux = 3); + trace_span!(target: "foo_events", "foo", bar.baz = 2, quux = 4,); + trace_span!(target: "foo_events", "foo"); + trace_span!(target: "foo_events", "bar",); + trace_span!("foo", bar.baz = 2, quux = 3); + trace_span!("foo", bar.baz = 2, quux = 4,); + trace_span!("foo", bar.baz = ?2); + trace_span!("foo", bar.baz = %2); + trace_span!("bar"); + trace_span!("bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn debug_span() { + debug_span!(target: "foo_events", "foo", bar.baz = ?2, quux = %3, quuux = 4); + debug_span!(target: "foo_events", "foo", bar.baz = 2, quux = 3); + debug_span!(target: "foo_events", "foo", bar.baz = 2, quux = 4,); + debug_span!(target: "foo_events", "foo"); + debug_span!(target: "foo_events", "bar",); + debug_span!("foo", bar.baz = 2, quux = 3); + debug_span!("foo", bar.baz = 2, quux = 4,); + debug_span!("foo", bar.baz = ?2); + debug_span!("foo", bar.baz = %2); + debug_span!("bar"); + debug_span!("bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn info_span() { + info_span!(target: "foo_events", "foo", bar.baz = ?2, quux = %3, quuux = 4); + info_span!(target: "foo_events", "foo", bar.baz = 2, quux = 3); + info_span!(target: "foo_events", "foo", bar.baz = 2, quux = 4,); + info_span!(target: "foo_events", "foo"); + info_span!(target: "foo_events", "bar",); + info_span!("foo", bar.baz = 2, quux = 3); + info_span!("foo", bar.baz = 2, quux = 4,); + info_span!("foo", bar.baz = ?2); + info_span!("foo", bar.baz = %2); + info_span!("bar"); + info_span!("bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn warn_span() { + warn_span!(target: "foo_events", "foo", bar.baz = ?2, quux = %3, quuux = 4); + warn_span!(target: "foo_events", "foo", bar.baz = 2, quux = 3); + warn_span!(target: "foo_events", "foo", bar.baz = 2, quux = 4,); + warn_span!(target: "foo_events", "foo"); + warn_span!(target: "foo_events", "bar",); + warn_span!("foo", bar.baz = 2, quux = 3); + warn_span!("foo", bar.baz = 2, quux = 4,); + warn_span!("foo", bar.baz = ?2); + warn_span!("foo", bar.baz = %2); + warn_span!("bar"); + warn_span!("bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn error_span() { + error_span!(target: "foo_events", "foo", bar.baz = ?2, quux = %3, quuux = 4); + error_span!(target: "foo_events", "foo", bar.baz = 2, quux = 3); + error_span!(target: "foo_events", "foo", bar.baz = 2, quux = 4,); + error_span!(target: "foo_events", "foo"); + error_span!(target: "foo_events", "bar",); + error_span!("foo", bar.baz = 2, quux = 3); + error_span!("foo", bar.baz = 2, quux = 4,); + error_span!("foo", bar.baz = ?2); + error_span!("foo", bar.baz = %2); + error_span!("bar"); + error_span!("bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn span_root() { + span!(target: "foo_events", parent: None, Level::TRACE, "foo", bar.baz = 2, quux = 3); + span!(target: "foo_events", parent: None, Level::TRACE, "foo", bar.baz = 2, quux = 3); + span!(target: "foo_events", parent: None, Level::TRACE, "foo", bar.baz = 2, quux = 4,); + span!(target: "foo_events", parent: None, Level::TRACE, "foo"); + span!(target: "foo_events", parent: None, Level::TRACE, "bar",); + span!(parent: None, Level::DEBUG, "foo", bar.baz = 2, quux = 3); + span!(parent: None, Level::DEBUG, "foo", bar.baz = 2, quux = 4,); + span!(parent: None, Level::DEBUG, "foo"); + span!(parent: None, Level::DEBUG, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn trace_span_root() { + trace_span!(target: "foo_events", parent: None, "foo", bar.baz = 2, quux = 3); + trace_span!(target: "foo_events", parent: None, "foo", bar.baz = 2, quux = 4,); + trace_span!(target: "foo_events", parent: None, "foo"); + trace_span!(target: "foo_events", parent: None, "bar",); + trace_span!(parent: None, "foo", bar.baz = 2, quux = 3); + trace_span!(parent: None, "foo", bar.baz = 2, quux = 4,); + trace_span!(parent: None, "foo"); + trace_span!(parent: None, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn debug_span_root() { + debug_span!(target: "foo_events", parent: None, "foo", bar.baz = 2, quux = 3); + debug_span!(target: "foo_events", parent: None, "foo", bar.baz = 2, quux = 4,); + debug_span!(target: "foo_events", parent: None, "foo"); + debug_span!(target: "foo_events", parent: None, "bar",); + debug_span!(parent: None, "foo", bar.baz = 2, quux = 3); + debug_span!(parent: None, "foo", bar.baz = 2, quux = 4,); + debug_span!(parent: None, "foo"); + debug_span!(parent: None, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn info_span_root() { + info_span!(target: "foo_events", parent: None, "foo", bar.baz = 2, quux = 3); + info_span!(target: "foo_events", parent: None, "foo", bar.baz = 2, quux = 4,); + info_span!(target: "foo_events", parent: None, "foo"); + info_span!(target: "foo_events", parent: None, "bar",); + info_span!(parent: None, "foo", bar.baz = 2, quux = 3); + info_span!(parent: None, "foo", bar.baz = 2, quux = 4,); + info_span!(parent: None, "foo"); + info_span!(parent: None, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn warn_span_root() { + warn_span!(target: "foo_events", parent: None, "foo", bar.baz = 2, quux = 3); + warn_span!(target: "foo_events", parent: None, "foo", bar.baz = 2, quux = 4,); + warn_span!(target: "foo_events", parent: None, "foo"); + warn_span!(target: "foo_events", parent: None, "bar",); + warn_span!(parent: None, "foo", bar.baz = 2, quux = 3); + warn_span!(parent: None, "foo", bar.baz = 2, quux = 4,); + warn_span!(parent: None, "foo"); + warn_span!(parent: None, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn error_span_root() { + error_span!(target: "foo_events", parent: None, "foo", bar.baz = 2, quux = 3); + error_span!(target: "foo_events", parent: None, "foo", bar.baz = 2, quux = 4,); + error_span!(target: "foo_events", parent: None, "foo"); + error_span!(target: "foo_events", parent: None, "bar",); + error_span!(parent: None, "foo", bar.baz = 2, quux = 3); + error_span!(parent: None, "foo", bar.baz = 2, quux = 4,); + error_span!(parent: None, "foo"); + error_span!(parent: None, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn span_with_parent() { + let p = span!(Level::TRACE, "im_a_parent!"); + span!(target: "foo_events", parent: &p, Level::TRACE, "foo", bar.baz = 2, quux = 3); + span!(target: "foo_events", parent: &p, Level::TRACE, "foo", bar.baz = 2, quux = 4,); + span!(target: "foo_events", parent: &p, Level::TRACE, "foo"); + span!(target: "foo_events", parent: &p, Level::TRACE, "bar",); + span!(parent: &p, Level::DEBUG, "foo", bar.baz = 2, quux = 3); + span!(parent: &p, Level::DEBUG, "foo", bar.baz = 2, quux = 4,); + span!(parent: &p, Level::DEBUG, "foo"); + span!(parent: &p, Level::DEBUG, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn trace_span_with_parent() { + let p = span!(Level::TRACE, "im_a_parent!"); + trace_span!(target: "foo_events", parent: &p, "foo", bar.baz = 2, quux = 3); + trace_span!(target: "foo_events", parent: &p, "foo", bar.baz = 2, quux = 4,); + trace_span!(target: "foo_events", parent: &p, "foo"); + trace_span!(target: "foo_events", parent: &p, "bar",); + + trace_span!(parent: &p, "foo", bar.baz = 2, quux = 3); + trace_span!(parent: &p, "foo", bar.baz = 2, quux = 4,); + + trace_span!(parent: &p, "foo"); + trace_span!(parent: &p, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn debug_span_with_parent() { + let p = span!(Level::TRACE, "im_a_parent!"); + debug_span!(target: "foo_events", parent: &p, "foo", bar.baz = 2, quux = 3); + debug_span!(target: "foo_events", parent: &p, "foo", bar.baz = 2, quux = 4,); + debug_span!(target: "foo_events", parent: &p, "foo"); + debug_span!(target: "foo_events", parent: &p, "bar",); + + debug_span!(parent: &p, "foo", bar.baz = 2, quux = 3); + debug_span!(parent: &p, "foo", bar.baz = 2, quux = 4,); + + debug_span!(parent: &p, "foo"); + debug_span!(parent: &p, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn info_span_with_parent() { + let p = span!(Level::TRACE, "im_a_parent!"); + info_span!(target: "foo_events", parent: &p, "foo", bar.baz = 2, quux = 3); + info_span!(target: "foo_events", parent: &p, "foo", bar.baz = 2, quux = 4,); + info_span!(target: "foo_events", parent: &p, "foo"); + info_span!(target: "foo_events", parent: &p, "bar",); + + info_span!(parent: &p, "foo", bar.baz = 2, quux = 3); + info_span!(parent: &p, "foo", bar.baz = 2, quux = 4,); + + info_span!(parent: &p, "foo"); + info_span!(parent: &p, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn warn_span_with_parent() { + let p = span!(Level::TRACE, "im_a_parent!"); + warn_span!(target: "foo_events", parent: &p, "foo", bar.baz = 2, quux = 3); + warn_span!(target: "foo_events", parent: &p, "foo", bar.baz = 2, quux = 4,); + warn_span!(target: "foo_events", parent: &p, "foo"); + warn_span!(target: "foo_events", parent: &p, "bar",); + + warn_span!(parent: &p, "foo", bar.baz = 2, quux = 3); + warn_span!(parent: &p, "foo", bar.baz = 2, quux = 4,); + + warn_span!(parent: &p, "foo"); + warn_span!(parent: &p, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn error_span_with_parent() { + let p = span!(Level::TRACE, "im_a_parent!"); + error_span!(target: "foo_events", parent: &p, "foo", bar.baz = 2, quux = 3); + error_span!(target: "foo_events", parent: &p, "foo", bar.baz = 2, quux = 4,); + error_span!(target: "foo_events", parent: &p, "foo"); + error_span!(target: "foo_events", parent: &p, "bar",); + + error_span!(parent: &p, "foo", bar.baz = 2, quux = 3); + error_span!(parent: &p, "foo", bar.baz = 2, quux = 4,); + + error_span!(parent: &p, "foo"); + error_span!(parent: &p, "bar",); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn span_with_non_rust_symbol() { + span!(Level::TRACE, "non-rust", "guid:x-request-id" = ?"abcdef", "more {}", 42); + span!(Level::TRACE, "non-rust", "guid:x-request-id" = %"abcdef", "more {}", 51); + span!( + Level::TRACE, + "non-rust", + "guid:x-request-id" = "abcdef", + "more {}", + 60 + ); + span!(Level::TRACE, "non-rust", "guid:x-request-id" = ?"abcdef"); + span!(Level::TRACE, "non-rust", "guid:x-request-id" = %"abcdef"); + span!(Level::TRACE, "non-rust", "guid:x-request-id" = "abcdef"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn event() { + event!(Level::DEBUG, foo = ?3, bar.baz = %2, quux = false); + event!(Level::DEBUG, foo = 3, bar.baz = 2, quux = false); + event!(Level::DEBUG, foo = 3, bar.baz = 3,); + event!(Level::DEBUG, "foo"); + event!(Level::DEBUG, "foo: {}", 3); + event!(Level::INFO, foo = ?3, bar.baz = %2, quux = false, "hello world {:?}", 42); + event!( + Level::INFO, + foo = 3, + bar.baz = 2, + quux = false, + "hello world {:?}", + 42 + ); + event!(Level::INFO, foo = 3, bar.baz = 3, "hello world {:?}", 42,); + event!(Level::DEBUG, { foo = 3, bar.baz = 80 }, "quux"); + event!(Level::DEBUG, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + event!(Level::DEBUG, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + event!(Level::DEBUG, { foo = ?2, bar.baz = %78 }, "quux"); + event!(target: "foo_events", Level::DEBUG, foo = 3, bar.baz = 2, quux = false); + event!(target: "foo_events", Level::DEBUG, foo = 3, bar.baz = 3,); + event!(target: "foo_events", Level::DEBUG, "foo"); + event!(target: "foo_events", Level::DEBUG, "foo: {}", 3); + event!(target: "foo_events", Level::DEBUG, { foo = 3, bar.baz = 80 }, "quux"); + event!(target: "foo_events", Level::DEBUG, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + event!(target: "foo_events", Level::DEBUG, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + event!(target: "foo_events", Level::DEBUG, { foo = 2, bar.baz = 78, }, "quux"); + let foo = 1; + event!(Level::DEBUG, ?foo); + event!(Level::DEBUG, %foo); + event!(Level::DEBUG, foo); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn enabled() { + enabled!(Level::DEBUG, foo, bar.baz, quux,); + enabled!(Level::DEBUG, message); + enabled!(Level::INFO, foo, bar.baz, quux, message,); + enabled!(Level::INFO, foo, bar., message,); + enabled!(Level::DEBUG, foo); + + enabled!(Level::DEBUG); + enabled!(target: "rando", Level::DEBUG); + enabled!(target: "rando", Level::DEBUG, field); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn span_enabled() { + span_enabled!(Level::DEBUG, foo, bar.baz, quux,); + span_enabled!(Level::DEBUG, message); + span_enabled!(Level::INFO, foo, bar.baz, quux, message,); + span_enabled!(Level::INFO, foo, bar., message,); + span_enabled!(Level::DEBUG, foo); + + span_enabled!(Level::DEBUG); + span_enabled!(target: "rando", Level::DEBUG); + span_enabled!(target: "rando", Level::DEBUG, field); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn event_enabled() { + event_enabled!(Level::DEBUG, foo, bar.baz, quux,); + event_enabled!(Level::DEBUG, message); + event_enabled!(Level::INFO, foo, bar.baz, quux, message,); + event_enabled!(Level::INFO, foo, bar., message,); + event_enabled!(Level::DEBUG, foo); + + event_enabled!(Level::DEBUG); + event_enabled!(target: "rando", Level::DEBUG); + event_enabled!(target: "rando", Level::DEBUG, field); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn locals_with_message() { + let data = (42, "forty-two"); + let private_data = "private"; + let error = "a bad error"; + event!(Level::ERROR, %error, "Received error"); + event!( + target: "app_events", + Level::WARN, + private_data, + ?data, + "App warning: {}", + error + ); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn locals_no_message() { + let data = (42, "forty-two"); + let private_data = "private"; + let error = "a bad error"; + event!( + target: "app_events", + Level::WARN, + private_data, + ?data, + ); + event!( + target: "app_events", + Level::WARN, + private_data, + ?data, + error, + ); + event!( + target: "app_events", + Level::WARN, + private_data, + ?data, + error + ); + event!(Level::WARN, private_data, ?data, error,); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn trace() { + trace!(foo = ?3, bar.baz = %2, quux = false); + trace!(foo = 3, bar.baz = 2, quux = false); + trace!(foo = 3, bar.baz = 3,); + trace!("foo"); + trace!("foo: {}", 3); + trace!(foo = ?3, bar.baz = %2, quux = false, "hello world {:?}", 42); + trace!(foo = 3, bar.baz = 2, quux = false, "hello world {:?}", 42); + trace!(foo = 3, bar.baz = 3, "hello world {:?}", 42,); + trace!({ foo = 3, bar.baz = 80 }, "quux"); + trace!({ foo = 2, bar.baz = 79 }, "quux {:?}", true); + trace!({ foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + trace!({ foo = 2, bar.baz = 78 }, "quux"); + trace!({ foo = ?2, bar.baz = %78 }, "quux"); + trace!(target: "foo_events", foo = 3, bar.baz = 2, quux = false); + trace!(target: "foo_events", foo = 3, bar.baz = 3,); + trace!(target: "foo_events", "foo"); + trace!(target: "foo_events", "foo: {}", 3); + trace!(target: "foo_events", { foo = 3, bar.baz = 80 }, "quux"); + trace!(target: "foo_events", { foo = 2, bar.baz = 79 }, "quux {:?}", true); + trace!(target: "foo_events", { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + trace!(target: "foo_events", { foo = 2, bar.baz = 78, }, "quux"); + let foo = 1; + trace!(?foo); + trace!(%foo); + trace!(foo); + trace!(target: "foo_events", ?foo); + trace!(target: "foo_events", %foo); + trace!(target: "foo_events", foo); + trace!(target: "foo_events", ?foo, true, "message"); + trace!(target: "foo_events", %foo, true, "message"); + trace!(target: "foo_events", foo, true, "message"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn debug() { + debug!(foo = ?3, bar.baz = %2, quux = false); + debug!(foo = 3, bar.baz = 2, quux = false); + debug!(foo = 3, bar.baz = 3,); + debug!("foo"); + debug!("foo: {}", 3); + debug!(foo = ?3, bar.baz = %2, quux = false, "hello world {:?}", 42); + debug!(foo = 3, bar.baz = 2, quux = false, "hello world {:?}", 42); + debug!(foo = 3, bar.baz = 3, "hello world {:?}", 42,); + debug!({ foo = 3, bar.baz = 80 }, "quux"); + debug!({ foo = 2, bar.baz = 79 }, "quux {:?}", true); + debug!({ foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + debug!({ foo = 2, bar.baz = 78 }, "quux"); + debug!({ foo = ?2, bar.baz = %78 }, "quux"); + debug!(target: "foo_events", foo = 3, bar.baz = 2, quux = false); + debug!(target: "foo_events", foo = 3, bar.baz = 3,); + debug!(target: "foo_events", "foo"); + debug!(target: "foo_events", "foo: {}", 3); + debug!(target: "foo_events", { foo = 3, bar.baz = 80 }, "quux"); + debug!(target: "foo_events", { foo = 2, bar.baz = 79 }, "quux {:?}", true); + debug!(target: "foo_events", { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + debug!(target: "foo_events", { foo = 2, bar.baz = 78, }, "quux"); + let foo = 1; + debug!(?foo); + debug!(%foo); + debug!(foo); + debug!(target: "foo_events", ?foo); + debug!(target: "foo_events", %foo); + debug!(target: "foo_events", foo); + debug!(target: "foo_events", ?foo, true, "message"); + debug!(target: "foo_events", %foo, true, "message"); + debug!(target: "foo_events", foo, true, "message"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn info() { + info!(foo = ?3, bar.baz = %2, quux = false); + info!(foo = 3, bar.baz = 2, quux = false); + info!(foo = 3, bar.baz = 3,); + info!("foo"); + info!("foo: {}", 3); + info!(foo = ?3, bar.baz = %2, quux = false, "hello world {:?}", 42); + info!(foo = 3, bar.baz = 2, quux = false, "hello world {:?}", 42); + info!(foo = 3, bar.baz = 3, "hello world {:?}", 42,); + info!({ foo = 3, bar.baz = 80 }, "quux"); + info!({ foo = 2, bar.baz = 79 }, "quux {:?}", true); + info!({ foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + info!({ foo = 2, bar.baz = 78 }, "quux"); + info!({ foo = ?2, bar.baz = %78 }, "quux"); + info!(target: "foo_events", foo = 3, bar.baz = 2, quux = false); + info!(target: "foo_events", foo = 3, bar.baz = 3,); + info!(target: "foo_events", "foo"); + info!(target: "foo_events", "foo: {}", 3); + info!(target: "foo_events", { foo = 3, bar.baz = 80 }, "quux"); + info!(target: "foo_events", { foo = 2, bar.baz = 79 }, "quux {:?}", true); + info!(target: "foo_events", { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + info!(target: "foo_events", { foo = 2, bar.baz = 78, }, "quux"); + let foo = 1; + info!(?foo); + info!(%foo); + info!(foo); + info!(target: "foo_events", ?foo); + info!(target: "foo_events", %foo); + info!(target: "foo_events", foo); + info!(target: "foo_events", ?foo, true, "message"); + info!(target: "foo_events", %foo, true, "message"); + info!(target: "foo_events", foo, true, "message"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn warn() { + warn!(foo = ?3, bar.baz = %2, quux = false); + warn!(foo = 3, bar.baz = 2, quux = false); + warn!(foo = 3, bar.baz = 3,); + warn!("foo"); + warn!("foo: {}", 3); + warn!(foo = ?3, bar.baz = %2, quux = false, "hello world {:?}", 42); + warn!(foo = 3, bar.baz = 2, quux = false, "hello world {:?}", 42); + warn!(foo = 3, bar.baz = 3, "hello world {:?}", 42,); + warn!({ foo = 3, bar.baz = 80 }, "quux"); + warn!({ foo = 2, bar.baz = 79 }, "quux {:?}", true); + warn!({ foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + warn!({ foo = 2, bar.baz = 78 }, "quux"); + warn!({ foo = ?2, bar.baz = %78 }, "quux"); + warn!(target: "foo_events", foo = 3, bar.baz = 2, quux = false); + warn!(target: "foo_events", foo = 3, bar.baz = 3,); + warn!(target: "foo_events", "foo"); + warn!(target: "foo_events", "foo: {}", 3); + warn!(target: "foo_events", { foo = 3, bar.baz = 80 }, "quux"); + warn!(target: "foo_events", { foo = 2, bar.baz = 79 }, "quux {:?}", true); + warn!(target: "foo_events", { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + warn!(target: "foo_events", { foo = 2, bar.baz = 78, }, "quux"); + let foo = 1; + warn!(?foo); + warn!(%foo); + warn!(foo); + warn!(target: "foo_events", ?foo); + warn!(target: "foo_events", %foo); + warn!(target: "foo_events", foo); + warn!(target: "foo_events", ?foo, true, "message"); + warn!(target: "foo_events", %foo, true, "message"); + warn!(target: "foo_events", foo, true, "message"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn error() { + error!(foo = ?3, bar.baz = %2, quux = false); + error!(foo = 3, bar.baz = 2, quux = false); + error!(foo = 3, bar.baz = 3,); + error!("foo"); + error!("foo: {}", 3); + error!(foo = ?3, bar.baz = %2, quux = false, "hello world {:?}", 42); + error!(foo = 3, bar.baz = 2, quux = false, "hello world {:?}", 42); + error!(foo = 3, bar.baz = 3, "hello world {:?}", 42,); + error!({ foo = 3, bar.baz = 80 }, "quux"); + error!({ foo = 2, bar.baz = 79 }, "quux {:?}", true); + error!({ foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + error!({ foo = 2, bar.baz = 78, }, "quux"); + error!({ foo = ?2, bar.baz = %78 }, "quux"); + error!(target: "foo_events", foo = 3, bar.baz = 2, quux = false); + error!(target: "foo_events", foo = 3, bar.baz = 3,); + error!(target: "foo_events", "foo"); + error!(target: "foo_events", "foo: {}", 3); + error!(target: "foo_events", { foo = 3, bar.baz = 80 }, "quux"); + error!(target: "foo_events", { foo = 2, bar.baz = 79 }, "quux {:?}", true); + error!(target: "foo_events", { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + error!(target: "foo_events", { foo = 2, bar.baz = 78, }, "quux"); + let foo = 1; + error!(?foo); + error!(%foo); + error!(foo); + error!(target: "foo_events", ?foo); + error!(target: "foo_events", %foo); + error!(target: "foo_events", foo); + error!(target: "foo_events", ?foo, true, "message"); + error!(target: "foo_events", %foo, true, "message"); + error!(target: "foo_events", foo, true, "message"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn event_root() { + event!(parent: None, Level::DEBUG, foo = ?3, bar.baz = %2, quux = false); + event!( + parent: None, + Level::DEBUG, + foo = 3, + bar.baz = 2, + quux = false + ); + event!(parent: None, Level::DEBUG, foo = 3, bar.baz = 3,); + event!(parent: None, Level::DEBUG, "foo"); + event!(parent: None, Level::DEBUG, "foo: {}", 3); + event!(parent: None, Level::DEBUG, { foo = 3, bar.baz = 80 }, "quux"); + event!(parent: None, Level::DEBUG, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + event!(parent: None, Level::DEBUG, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + event!(parent: None, Level::DEBUG, { foo = ?2, bar.baz = %78 }, "quux"); + event!(target: "foo_events", parent: None, Level::DEBUG, foo = 3, bar.baz = 2, quux = false); + event!(target: "foo_events", parent: None, Level::DEBUG, foo = 3, bar.baz = 3,); + event!(target: "foo_events", parent: None, Level::DEBUG, "foo"); + event!(target: "foo_events", parent: None, Level::DEBUG, "foo: {}", 3); + event!(target: "foo_events", parent: None, Level::DEBUG, { foo = 3, bar.baz = 80 }, "quux"); + event!(target: "foo_events", parent: None, Level::DEBUG, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + event!(target: "foo_events", parent: None, Level::DEBUG, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + event!(target: "foo_events", parent: None, Level::DEBUG, { foo = 2, bar.baz = 78, }, "quux"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn trace_root() { + trace!(parent: None, foo = ?3, bar.baz = %2, quux = false); + trace!(parent: None, foo = 3, bar.baz = 2, quux = false); + trace!(parent: None, foo = 3, bar.baz = 3,); + trace!(parent: None, "foo"); + trace!(parent: None, "foo: {}", 3); + trace!(parent: None, { foo = 3, bar.baz = 80 }, "quux"); + trace!(parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + trace!(parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + trace!(parent: None, { foo = 2, bar.baz = 78 }, "quux"); + trace!(parent: None, { foo = ?2, bar.baz = %78 }, "quux"); + trace!(target: "foo_events", parent: None, foo = 3, bar.baz = 2, quux = false); + trace!(target: "foo_events", parent: None, foo = 3, bar.baz = 3,); + trace!(target: "foo_events", parent: None, "foo"); + trace!(target: "foo_events", parent: None, "foo: {}", 3); + trace!(target: "foo_events", parent: None, { foo = 3, bar.baz = 80 }, "quux"); + trace!(target: "foo_events", parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + trace!(target: "foo_events", parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + trace!(target: "foo_events", parent: None, { foo = 2, bar.baz = 78, }, "quux"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn debug_root() { + debug!(parent: None, foo = ?3, bar.baz = %2, quux = false); + debug!(parent: None, foo = 3, bar.baz = 2, quux = false); + debug!(parent: None, foo = 3, bar.baz = 3,); + debug!(parent: None, "foo"); + debug!(parent: None, "foo: {}", 3); + debug!(parent: None, { foo = 3, bar.baz = 80 }, "quux"); + debug!(parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + debug!(parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + debug!(parent: None, { foo = 2, bar.baz = 78 }, "quux"); + debug!(parent: None, { foo = ?2, bar.baz = %78 }, "quux"); + debug!(target: "foo_events", parent: None, foo = 3, bar.baz = 2, quux = false); + debug!(target: "foo_events", parent: None, foo = 3, bar.baz = 3,); + debug!(target: "foo_events", parent: None, "foo"); + debug!(target: "foo_events", parent: None, "foo: {}", 3); + debug!(target: "foo_events", parent: None, { foo = 3, bar.baz = 80 }, "quux"); + debug!(target: "foo_events", parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + debug!(target: "foo_events", parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + debug!(target: "foo_events", parent: None, { foo = 2, bar.baz = 78, }, "quux"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn info_root() { + info!(parent: None, foo = ?3, bar.baz = %2, quux = false); + info!(parent: None, foo = 3, bar.baz = 2, quux = false); + info!(parent: None, foo = 3, bar.baz = 3,); + info!(parent: None, "foo"); + info!(parent: None, "foo: {}", 3); + info!(parent: None, { foo = 3, bar.baz = 80 }, "quux"); + info!(parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + info!(parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + info!(parent: None, { foo = 2, bar.baz = 78 }, "quux"); + info!(parent: None, { foo = ?2, bar.baz = %78 }, "quux"); + info!(target: "foo_events", parent: None, foo = 3, bar.baz = 2, quux = false); + info!(target: "foo_events", parent: None, foo = 3, bar.baz = 3,); + info!(target: "foo_events", parent: None, "foo"); + info!(target: "foo_events", parent: None, "foo: {}", 3); + info!(target: "foo_events", parent: None, { foo = 3, bar.baz = 80 }, "quux"); + info!(target: "foo_events", parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + info!(target: "foo_events", parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + info!(target: "foo_events", parent: None, { foo = 2, bar.baz = 78, }, "quux"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn warn_root() { + warn!(parent: None, foo = ?3, bar.baz = %2, quux = false); + warn!(parent: None, foo = 3, bar.baz = 2, quux = false); + warn!(parent: None, foo = 3, bar.baz = 3,); + warn!(parent: None, "foo"); + warn!(parent: None, "foo: {}", 3); + warn!(parent: None, { foo = 3, bar.baz = 80 }, "quux"); + warn!(parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + warn!(parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + warn!(parent: None, { foo = 2, bar.baz = 78 }, "quux"); + warn!(parent: None, { foo = ?2, bar.baz = %78 }, "quux"); + warn!(target: "foo_events", parent: None, foo = 3, bar.baz = 2, quux = false); + warn!(target: "foo_events", parent: None, foo = 3, bar.baz = 3,); + warn!(target: "foo_events", parent: None, "foo"); + warn!(target: "foo_events", parent: None, "foo: {}", 3); + warn!(target: "foo_events", parent: None, { foo = 3, bar.baz = 80 }, "quux"); + warn!(target: "foo_events", parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + warn!(target: "foo_events", parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + warn!(target: "foo_events", parent: None, { foo = 2, bar.baz = 78, }, "quux"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn error_root() { + error!(parent: None, foo = ?3, bar.baz = %2, quux = false); + error!(parent: None, foo = 3, bar.baz = 2, quux = false); + error!(parent: None, foo = 3, bar.baz = 3,); + error!(parent: None, "foo"); + error!(parent: None, "foo: {}", 3); + error!(parent: None, { foo = 3, bar.baz = 80 }, "quux"); + error!(parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + error!(parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + error!(parent: None, { foo = 2, bar.baz = 78 }, "quux"); + error!(parent: None, { foo = ?2, bar.baz = %78 }, "quux"); + error!(target: "foo_events", parent: None, foo = 3, bar.baz = 2, quux = false); + error!(target: "foo_events", parent: None, foo = 3, bar.baz = 3,); + error!(target: "foo_events", parent: None, "foo"); + error!(target: "foo_events", parent: None, "foo: {}", 3); + error!(target: "foo_events", parent: None, { foo = 3, bar.baz = 80 }, "quux"); + error!(target: "foo_events", parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + error!(target: "foo_events", parent: None, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + error!(target: "foo_events", parent: None, { foo = 2, bar.baz = 78, }, "quux"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn event_with_parent() { + let p = span!(Level::TRACE, "im_a_parent!"); + event!(parent: &p, Level::DEBUG, foo = ?3, bar.baz = %2, quux = false); + event!(parent: &p, Level::DEBUG, foo = 3, bar.baz = 2, quux = false); + event!(parent: &p, Level::DEBUG, foo = 3, bar.baz = 3,); + event!(parent: &p, Level::DEBUG, "foo"); + event!(parent: &p, Level::DEBUG, "foo: {}", 3); + event!(parent: &p, Level::DEBUG, { foo = 3, bar.baz = 80 }, "quux"); + event!(parent: &p, Level::DEBUG, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + event!(parent: &p, Level::DEBUG, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + event!(parent: &p, Level::DEBUG, { foo = ?2, bar.baz = %78 }, "quux"); + event!(target: "foo_events", parent: &p, Level::DEBUG, foo = 3, bar.baz = 2, quux = false); + event!(target: "foo_events", parent: &p, Level::DEBUG, foo = 3, bar.baz = 3,); + event!(target: "foo_events", parent: &p, Level::DEBUG, "foo"); + event!(target: "foo_events", parent: &p, Level::DEBUG, "foo: {}", 3); + event!(target: "foo_events", parent: &p, Level::DEBUG, { foo = 3, bar.baz = 80 }, "quux"); + event!(target: "foo_events", parent: &p, Level::DEBUG, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + event!(target: "foo_events", parent: &p, Level::DEBUG, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + event!(target: "foo_events", parent: &p, Level::DEBUG, { foo = 2, bar.baz = 78, }, "quux"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn trace_with_parent() { + let p = span!(Level::TRACE, "im_a_parent!"); + trace!(parent: &p, foo = ?3, bar.baz = %2, quux = false); + trace!(parent: &p, foo = 3, bar.baz = 2, quux = false); + trace!(parent: &p, foo = 3, bar.baz = 3,); + trace!(parent: &p, "foo"); + trace!(parent: &p, "foo: {}", 3); + trace!(parent: &p, { foo = 3, bar.baz = 80 }, "quux"); + trace!(parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + trace!(parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + trace!(parent: &p, { foo = 2, bar.baz = 78 }, "quux"); + trace!(parent: &p, { foo = ?2, bar.baz = %78 }, "quux"); + trace!(target: "foo_events", parent: &p, foo = 3, bar.baz = 2, quux = false); + trace!(target: "foo_events", parent: &p, foo = 3, bar.baz = 3,); + trace!(target: "foo_events", parent: &p, "foo"); + trace!(target: "foo_events", parent: &p, "foo: {}", 3); + trace!(target: "foo_events", parent: &p, { foo = 3, bar.baz = 80 }, "quux"); + trace!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + trace!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + trace!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 78, }, "quux"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn debug_with_parent() { + let p = span!(Level::TRACE, "im_a_parent!"); + debug!(parent: &p, foo = ?3, bar.baz = %2, quux = false); + debug!(parent: &p, foo = 3, bar.baz = 2, quux = false); + debug!(parent: &p, foo = 3, bar.baz = 3,); + debug!(parent: &p, "foo"); + debug!(parent: &p, "foo: {}", 3); + debug!(parent: &p, { foo = 3, bar.baz = 80 }, "quux"); + debug!(parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + debug!(parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + debug!(parent: &p, { foo = 2, bar.baz = 78 }, "quux"); + debug!(parent: &p, { foo = ?2, bar.baz = %78 }, "quux"); + debug!(target: "foo_events", parent: &p, foo = 3, bar.baz = 2, quux = false); + debug!(target: "foo_events", parent: &p, foo = 3, bar.baz = 3,); + debug!(target: "foo_events", parent: &p, "foo"); + debug!(target: "foo_events", parent: &p, "foo: {}", 3); + debug!(target: "foo_events", parent: &p, { foo = 3, bar.baz = 80 }, "quux"); + debug!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + debug!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + debug!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 78, }, "quux"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn info_with_parent() { + let p = span!(Level::TRACE, "im_a_parent!"); + info!(parent: &p, foo = ?3, bar.baz = %2, quux = false); + info!(parent: &p, foo = 3, bar.baz = 2, quux = false); + info!(parent: &p, foo = 3, bar.baz = 3,); + info!(parent: &p, "foo"); + info!(parent: &p, "foo: {}", 3); + info!(parent: &p, { foo = 3, bar.baz = 80 }, "quux"); + info!(parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + info!(parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + info!(parent: &p, { foo = 2, bar.baz = 78 }, "quux"); + info!(parent: &p, { foo = ?2, bar.baz = %78 }, "quux"); + info!(target: "foo_events", parent: &p, foo = 3, bar.baz = 2, quux = false); + info!(target: "foo_events", parent: &p, foo = 3, bar.baz = 3,); + info!(target: "foo_events", parent: &p, "foo"); + info!(target: "foo_events", parent: &p, "foo: {}", 3); + info!(target: "foo_events", parent: &p, { foo = 3, bar.baz = 80 }, "quux"); + info!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + info!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + info!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 78, }, "quux"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn warn_with_parent() { + let p = span!(Level::TRACE, "im_a_parent!"); + warn!(parent: &p, foo = ?3, bar.baz = %2, quux = false); + warn!(parent: &p, foo = 3, bar.baz = 2, quux = false); + warn!(parent: &p, foo = 3, bar.baz = 3,); + warn!(parent: &p, "foo"); + warn!(parent: &p, "foo: {}", 3); + warn!(parent: &p, { foo = 3, bar.baz = 80 }, "quux"); + warn!(parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + warn!(parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + warn!(parent: &p, { foo = 2, bar.baz = 78 }, "quux"); + warn!(parent: &p, { foo = ?2, bar.baz = %78 }, "quux"); + warn!(target: "foo_events", parent: &p, foo = 3, bar.baz = 2, quux = false); + warn!(target: "foo_events", parent: &p, foo = 3, bar.baz = 3,); + warn!(target: "foo_events", parent: &p, "foo"); + warn!(target: "foo_events", parent: &p, "foo: {}", 3); + warn!(target: "foo_events", parent: &p, { foo = 3, bar.baz = 80 }, "quux"); + warn!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + warn!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + warn!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 78, }, "quux"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn error_with_parent() { + let p = span!(Level::TRACE, "im_a_parent!"); + error!(parent: &p, foo = ?3, bar.baz = %2, quux = false); + error!(parent: &p, foo = 3, bar.baz = 2, quux = false); + error!(parent: &p, foo = 3, bar.baz = 3,); + error!(parent: &p, "foo"); + error!(parent: &p, "foo: {}", 3); + error!(parent: &p, { foo = 3, bar.baz = 80 }, "quux"); + error!(parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + error!(parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + error!(parent: &p, { foo = 2, bar.baz = 78 }, "quux"); + error!(parent: &p, { foo = ?2, bar.baz = %78 }, "quux"); + error!(target: "foo_events", parent: &p, foo = 3, bar.baz = 2, quux = false); + error!(target: "foo_events", parent: &p, foo = 3, bar.baz = 3,); + error!(target: "foo_events", parent: &p, "foo"); + error!(target: "foo_events", parent: &p, "foo: {}", 3); + error!(target: "foo_events", parent: &p, { foo = 3, bar.baz = 80 }, "quux"); + error!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}", true); + error!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 79 }, "quux {:?}, {quux}", true, quux = false); + error!(target: "foo_events", parent: &p, { foo = 2, bar.baz = 78, }, "quux"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn field_shorthand_only() { + #[derive(Debug)] + struct Position { + x: f32, + y: f32, + } + let pos = Position { + x: 3.234, + y: -1.223, + }; + + trace!(?pos.x, ?pos.y); + debug!(?pos.x, ?pos.y); + info!(?pos.x, ?pos.y); + warn!(?pos.x, ?pos.y); + error!(?pos.x, ?pos.y); + event!(Level::TRACE, ?pos.x, ?pos.y); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn borrow_val_events() { + // Reproduces https://github.com/tokio-rs/tracing/issues/954 + let mut foo = (String::new(), String::new()); + let zero = &mut foo.0; + trace!(one = ?foo.1); + debug!(one = ?foo.1); + info!(one = ?foo.1); + warn!(one = ?foo.1); + error!(one = ?foo.1); + zero.push_str("hello world"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn borrow_val_spans() { + // Reproduces https://github.com/tokio-rs/tracing/issues/954 + let mut foo = (String::new(), String::new()); + let zero = &mut foo.0; + let _span = trace_span!("span", one = ?foo.1); + let _span = debug_span!("span", one = ?foo.1); + let _span = info_span!("span", one = ?foo.1); + let _span = warn_span!("span", one = ?foo.1); + let _span = error_span!("span", one = ?foo.1); + zero.push_str("hello world"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn callsite_macro_api() { + // This test should catch any inadvertent breaking changes + // caused by changes to the macro. + let _callsite = callsite! { + name: "test callsite", + kind: tracing::metadata::Kind::EVENT, + target: "test target", + level: tracing::Level::TRACE, + fields: foo, bar, + }; + let _callsite = callsite! { + name: "test callsite", + kind: tracing::metadata::Kind::SPAN, + level: tracing::Level::TRACE, + fields: foo, + }; + let _callsite = callsite! { + name: "test callsite", + kind: tracing::metadata::Kind::SPAN, + fields: foo, + }; +} diff --git a/third_party/rust/tracing/tests/macros_incompatible_concat.rs b/third_party/rust/tracing/tests/macros_incompatible_concat.rs new file mode 100644 index 0000000000..bda6b964fa --- /dev/null +++ b/third_party/rust/tracing/tests/macros_incompatible_concat.rs @@ -0,0 +1,24 @@ +use tracing::{enabled, event, span, Level}; + +#[macro_export] +macro_rules! concat { + () => {}; +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn span() { + span!(Level::DEBUG, "foo"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn event() { + event!(Level::DEBUG, "foo"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn enabled() { + enabled!(Level::DEBUG); +} diff --git a/third_party/rust/tracing/tests/macros_redefined_core.rs b/third_party/rust/tracing/tests/macros_redefined_core.rs new file mode 100644 index 0000000000..d830dcdb02 --- /dev/null +++ b/third_party/rust/tracing/tests/macros_redefined_core.rs @@ -0,0 +1,18 @@ +extern crate self as core; + +use tracing::{enabled, event, span, Level}; + +#[test] +fn span() { + span!(Level::DEBUG, "foo"); +} + +#[test] +fn event() { + event!(Level::DEBUG, "foo"); +} + +#[test] +fn enabled() { + enabled!(Level::DEBUG); +} diff --git a/third_party/rust/tracing/tests/max_level_hint.rs b/third_party/rust/tracing/tests/max_level_hint.rs new file mode 100644 index 0000000000..63d3af6357 --- /dev/null +++ b/third_party/rust/tracing/tests/max_level_hint.rs @@ -0,0 +1,37 @@ +use tracing::Level; +use tracing_mock::*; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn max_level_hints() { + // This test asserts that when a subscriber provides us with the global + // maximum level that it will enable (by implementing the + // `Subscriber::max_level_hint` method), we will never call + // `Subscriber::enabled` for events above that maximum level. + // + // In this case, we test that by making the `enabled` method assert that no + // `Metadata` for spans or events at the `TRACE` or `DEBUG` levels. + let (subscriber, handle) = subscriber::mock() + .with_max_level_hint(Level::INFO) + .with_filter(|meta| { + assert!( + dbg!(meta).level() <= &Level::INFO, + "a TRACE or DEBUG event was dynamically filtered: " + ); + true + }) + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle(); + + tracing::subscriber::set_global_default(subscriber).unwrap(); + + tracing::info!("doing a thing that you might care about"); + tracing::debug!("charging turboencabulator with interocitor"); + tracing::warn!("extremely serious warning, pay attention"); + tracing::trace!("interocitor charge level is 10%"); + tracing::error!("everything is on fire"); + handle.assert_finished(); +} diff --git a/third_party/rust/tracing/tests/multiple_max_level_hints.rs b/third_party/rust/tracing/tests/multiple_max_level_hints.rs new file mode 100644 index 0000000000..dd50a193b5 --- /dev/null +++ b/third_party/rust/tracing/tests/multiple_max_level_hints.rs @@ -0,0 +1,69 @@ +#![cfg(feature = "std")] + +use tracing::Level; +use tracing_mock::*; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn multiple_max_level_hints() { + // This test ensures that when multiple subscribers are active, their max + // level hints are handled correctly. The global max level should be the + // maximum of the level filters returned by the two `Subscriber`'s + // `max_level_hint` method. + // + // In this test, we create a subscriber whose max level is `INFO`, and + // another whose max level is `DEBUG`. We then add an assertion to both of + // those subscribers' `enabled` method that no metadata for `TRACE` spans or + // events are filtered, since they are disabled by the global max filter. + + fn do_events() { + tracing::info!("doing a thing that you might care about"); + tracing::debug!("charging turboencabulator with interocitor"); + tracing::warn!("extremely serious warning, pay attention"); + tracing::trace!("interocitor charge level is 10%"); + tracing::error!("everything is on fire"); + } + + let (subscriber1, handle1) = subscriber::mock() + .named("subscriber1") + .with_max_level_hint(Level::INFO) + .with_filter(|meta| { + let level = dbg!(meta.level()); + assert!( + level <= &Level::DEBUG, + "a TRACE event was dynamically filtered by subscriber1" + ); + level <= &Level::INFO + }) + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle(); + let (subscriber2, handle2) = subscriber::mock() + .named("subscriber2") + .with_max_level_hint(Level::DEBUG) + .with_filter(|meta| { + let level = dbg!(meta.level()); + assert!( + level <= &Level::DEBUG, + "a TRACE event was dynamically filtered by subscriber2" + ); + level <= &Level::DEBUG + }) + .event(event::mock().at_level(Level::INFO)) + .event(event::mock().at_level(Level::DEBUG)) + .event(event::mock().at_level(Level::WARN)) + .event(event::mock().at_level(Level::ERROR)) + .done() + .run_with_handle(); + + let dispatch1 = tracing::Dispatch::new(subscriber1); + + tracing::dispatcher::with_default(&dispatch1, do_events); + handle1.assert_finished(); + + let dispatch2 = tracing::Dispatch::new(subscriber2); + tracing::dispatcher::with_default(&dispatch2, do_events); + handle2.assert_finished(); +} diff --git a/third_party/rust/tracing/tests/no_subscriber.rs b/third_party/rust/tracing/tests/no_subscriber.rs new file mode 100644 index 0000000000..5f927c1dee --- /dev/null +++ b/third_party/rust/tracing/tests/no_subscriber.rs @@ -0,0 +1,15 @@ +#![cfg(feature = "std")] + +use tracing::subscriber::{self, NoSubscriber}; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn no_subscriber_disables_global() { + // Reproduces https://github.com/tokio-rs/tracing/issues/1999 + let (subscriber, handle) = tracing_mock::subscriber::mock().done().run_with_handle(); + subscriber::set_global_default(subscriber).expect("setting global default must succeed"); + subscriber::with_default(NoSubscriber::default(), || { + tracing::info!("this should not be recorded"); + }); + handle.assert_finished(); +} diff --git a/third_party/rust/tracing/tests/register_callsite_deadlock.rs b/third_party/rust/tracing/tests/register_callsite_deadlock.rs new file mode 100644 index 0000000000..e4c116c75f --- /dev/null +++ b/third_party/rust/tracing/tests/register_callsite_deadlock.rs @@ -0,0 +1,47 @@ +use std::{sync::mpsc, thread, time::Duration}; +use tracing::{ + metadata::Metadata, + span, + subscriber::{self, Interest, Subscriber}, + Event, +}; + +#[test] +fn register_callsite_doesnt_deadlock() { + pub struct EvilSubscriber; + + impl Subscriber for EvilSubscriber { + fn register_callsite(&self, meta: &'static Metadata<'static>) -> Interest { + tracing::info!(?meta, "registered a callsite"); + Interest::always() + } + + fn enabled(&self, _: &Metadata<'_>) -> bool { + true + } + fn new_span(&self, _: &span::Attributes<'_>) -> span::Id { + span::Id::from_u64(1) + } + fn record(&self, _: &span::Id, _: &span::Record<'_>) {} + fn record_follows_from(&self, _: &span::Id, _: &span::Id) {} + fn event(&self, _: &Event<'_>) {} + fn enter(&self, _: &span::Id) {} + fn exit(&self, _: &span::Id) {} + } + + subscriber::set_global_default(EvilSubscriber).unwrap(); + + // spawn a thread, and assert it doesn't hang... + let (tx, didnt_hang) = mpsc::channel(); + let th = thread::spawn(move || { + tracing::info!("hello world!"); + tx.send(()).unwrap(); + }); + + didnt_hang + // Note: 60 seconds is *way* more than enough, but let's be generous in + // case of e.g. slow CI machines. + .recv_timeout(Duration::from_secs(60)) + .expect("the thread must not have hung!"); + th.join().expect("thread should join successfully"); +} diff --git a/third_party/rust/tracing/tests/scoped_clobbers_default.rs b/third_party/rust/tracing/tests/scoped_clobbers_default.rs new file mode 100644 index 0000000000..362d34a82c --- /dev/null +++ b/third_party/rust/tracing/tests/scoped_clobbers_default.rs @@ -0,0 +1,35 @@ +#![cfg(feature = "std")] +use tracing_mock::*; + +#[test] +fn scoped_clobbers_global() { + // Reproduces https://github.com/tokio-rs/tracing/issues/2050 + + let (scoped, scoped_handle) = subscriber::mock() + .event(event::msg("before global")) + .event(event::msg("before drop")) + .done() + .run_with_handle(); + + let (global, global_handle) = subscriber::mock() + .event(event::msg("after drop")) + .done() + .run_with_handle(); + + // Set a scoped default subscriber, returning a guard. + let guard = tracing::subscriber::set_default(scoped); + tracing::info!("before global"); + + // Now, set the global default. + tracing::subscriber::set_global_default(global) + .expect("global default should not already be set"); + // This event should still be collected by the scoped default. + tracing::info!("before drop"); + + // Drop the guard. Now, the global default subscriber should be used. + drop(guard); + tracing::info!("after drop"); + + scoped_handle.assert_finished(); + global_handle.assert_finished(); +} diff --git a/third_party/rust/tracing/tests/span.rs b/third_party/rust/tracing/tests/span.rs new file mode 100644 index 0000000000..4ed6500235 --- /dev/null +++ b/third_party/rust/tracing/tests/span.rs @@ -0,0 +1,825 @@ +// These tests require the thread-local scoped dispatcher, which only works when +// we have a standard library. The behaviour being tested should be the same +// with the standard lib disabled. +#![cfg(feature = "std")] + +use std::thread; + +use tracing::{ + field::{debug, display}, + subscriber::with_default, + Level, Span, +}; +use tracing_mock::*; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn handles_to_the_same_span_are_equal() { + // Create a mock subscriber that will return `true` on calls to + // `Subscriber::enabled`, so that the spans will be constructed. We + // won't enter any spans in this test, so the subscriber won't actually + // expect to see any spans. + with_default(subscriber::mock().run(), || { + let foo1 = tracing::span!(Level::TRACE, "foo"); + let foo2 = foo1.clone(); + // Two handles that point to the same span are equal. + assert_eq!(foo1, foo2); + }); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn handles_to_different_spans_are_not_equal() { + with_default(subscriber::mock().run(), || { + // Even though these spans have the same name and fields, they will have + // differing metadata, since they were created on different lines. + let foo1 = tracing::span!(Level::TRACE, "foo", bar = 1u64, baz = false); + let foo2 = tracing::span!(Level::TRACE, "foo", bar = 1u64, baz = false); + + assert_ne!(foo1, foo2); + }); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn handles_to_different_spans_with_the_same_metadata_are_not_equal() { + // Every time time this function is called, it will return a _new + // instance_ of a span with the same metadata, name, and fields. + fn make_span() -> Span { + tracing::span!(Level::TRACE, "foo", bar = 1u64, baz = false) + } + + with_default(subscriber::mock().run(), || { + let foo1 = make_span(); + let foo2 = make_span(); + + assert_ne!(foo1, foo2); + // assert_ne!(foo1.data(), foo2.data()); + }); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn spans_always_go_to_the_subscriber_that_tagged_them() { + let subscriber1 = subscriber::mock() + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run(); + let subscriber2 = subscriber::mock().run(); + + let foo = with_default(subscriber1, || { + let foo = tracing::span!(Level::TRACE, "foo"); + foo.in_scope(|| {}); + foo + }); + // Even though we enter subscriber 2's context, the subscriber that + // tagged the span should see the enter/exit. + with_default(subscriber2, move || foo.in_scope(|| {})); +} + +// This gets exempt from testing in wasm because of: `thread::spawn` which is +// not yet possible to do in WASM. There is work going on see: +// <https://rustwasm.github.io/2018/10/24/multithreading-rust-and-wasm.html> +// +// But for now since it's not possible we don't need to test for it :) +#[test] +fn spans_always_go_to_the_subscriber_that_tagged_them_even_across_threads() { + let subscriber1 = subscriber::mock() + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run(); + let foo = with_default(subscriber1, || { + let foo = tracing::span!(Level::TRACE, "foo"); + foo.in_scope(|| {}); + foo + }); + + // Even though we enter subscriber 2's context, the subscriber that + // tagged the span should see the enter/exit. + thread::spawn(move || { + with_default(subscriber::mock().run(), || { + foo.in_scope(|| {}); + }) + }) + .join() + .unwrap(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn dropping_a_span_calls_drop_span() { + let (subscriber, handle) = subscriber::mock() + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + with_default(subscriber, || { + let span = tracing::span!(Level::TRACE, "foo"); + span.in_scope(|| {}); + drop(span); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn span_closes_after_event() { + let (subscriber, handle) = subscriber::mock() + .enter(span::mock().named("foo")) + .event(event::mock()) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + with_default(subscriber, || { + tracing::span!(Level::TRACE, "foo").in_scope(|| { + tracing::event!(Level::DEBUG, {}, "my tracing::event!"); + }); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn new_span_after_event() { + let (subscriber, handle) = subscriber::mock() + .enter(span::mock().named("foo")) + .event(event::mock()) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .enter(span::mock().named("bar")) + .exit(span::mock().named("bar")) + .drop_span(span::mock().named("bar")) + .done() + .run_with_handle(); + with_default(subscriber, || { + tracing::span!(Level::TRACE, "foo").in_scope(|| { + tracing::event!(Level::DEBUG, {}, "my tracing::event!"); + }); + tracing::span!(Level::TRACE, "bar").in_scope(|| {}); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn event_outside_of_span() { + let (subscriber, handle) = subscriber::mock() + .event(event::mock()) + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + with_default(subscriber, || { + tracing::debug!("my tracing::event!"); + tracing::span!(Level::TRACE, "foo").in_scope(|| {}); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn cloning_a_span_calls_clone_span() { + let (subscriber, handle) = subscriber::mock() + .clone_span(span::mock().named("foo")) + .run_with_handle(); + with_default(subscriber, || { + let span = tracing::span!(Level::TRACE, "foo"); + // Allow the "redundant" `.clone` since it is used to call into the `.clone_span` hook. + #[allow(clippy::redundant_clone)] + let _span2 = span.clone(); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn drop_span_when_exiting_dispatchers_context() { + let (subscriber, handle) = subscriber::mock() + .clone_span(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .run_with_handle(); + with_default(subscriber, || { + let span = tracing::span!(Level::TRACE, "foo"); + let _span2 = span.clone(); + drop(span); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn clone_and_drop_span_always_go_to_the_subscriber_that_tagged_the_span() { + let (subscriber1, handle1) = subscriber::mock() + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .clone_span(span::mock().named("foo")) + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .run_with_handle(); + let subscriber2 = subscriber::mock().done().run(); + + let foo = with_default(subscriber1, || { + let foo = tracing::span!(Level::TRACE, "foo"); + foo.in_scope(|| {}); + foo + }); + // Even though we enter subscriber 2's context, the subscriber that + // tagged the span should see the enter/exit. + with_default(subscriber2, move || { + let foo2 = foo.clone(); + foo.in_scope(|| {}); + drop(foo); + drop(foo2); + }); + + handle1.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn span_closes_when_exited() { + let (subscriber, handle) = subscriber::mock() + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + with_default(subscriber, || { + let foo = tracing::span!(Level::TRACE, "foo"); + + foo.in_scope(|| {}); + + drop(foo); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn enter() { + let (subscriber, handle) = subscriber::mock() + .enter(span::mock().named("foo")) + .event(event::mock()) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + with_default(subscriber, || { + let foo = tracing::span!(Level::TRACE, "foo"); + let _enter = foo.enter(); + tracing::debug!("dropping guard..."); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn entered() { + let (subscriber, handle) = subscriber::mock() + .enter(span::mock().named("foo")) + .event(event::mock()) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + with_default(subscriber, || { + let _span = tracing::span!(Level::TRACE, "foo").entered(); + tracing::debug!("dropping guard..."); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn entered_api() { + let (subscriber, handle) = subscriber::mock() + .enter(span::mock().named("foo")) + .event(event::mock()) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + with_default(subscriber, || { + let span = tracing::span!(Level::TRACE, "foo").entered(); + let _derefs_to_span = span.id(); + tracing::debug!("exiting span..."); + let _: Span = span.exit(); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn moved_field() { + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock().named("foo").with_field( + field::mock("bar") + .with_value(&display("hello from my span")) + .only(), + ), + ) + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + with_default(subscriber, || { + let from = "my span"; + let span = tracing::span!( + Level::TRACE, + "foo", + bar = display(format!("hello from {}", from)) + ); + span.in_scope(|| {}); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn dotted_field_name() { + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock() + .named("foo") + .with_field(field::mock("fields.bar").with_value(&true).only()), + ) + .done() + .run_with_handle(); + with_default(subscriber, || { + tracing::span!(Level::TRACE, "foo", fields.bar = true); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn borrowed_field() { + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock().named("foo").with_field( + field::mock("bar") + .with_value(&display("hello from my span")) + .only(), + ), + ) + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let from = "my span"; + let mut message = format!("hello from {}", from); + let span = tracing::span!(Level::TRACE, "foo", bar = display(&message)); + span.in_scope(|| { + message.insert_str(10, " inside"); + }); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +// If emitting log instrumentation, this gets moved anyway, breaking the test. +#[cfg(not(feature = "log"))] +fn move_field_out_of_struct() { + use tracing::field::debug; + + #[derive(Debug)] + struct Position { + x: f32, + y: f32, + } + + let pos = Position { + x: 3.234, + y: -1.223, + }; + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock().named("foo").with_field( + field::mock("x") + .with_value(&debug(3.234)) + .and(field::mock("y").with_value(&debug(-1.223))) + .only(), + ), + ) + .new_span( + span::mock() + .named("bar") + .with_field(field::mock("position").with_value(&debug(&pos)).only()), + ) + .run_with_handle(); + + with_default(subscriber, || { + let pos = Position { + x: 3.234, + y: -1.223, + }; + let foo = tracing::span!(Level::TRACE, "foo", x = debug(pos.x), y = debug(pos.y)); + let bar = tracing::span!(Level::TRACE, "bar", position = debug(pos)); + foo.in_scope(|| {}); + bar.in_scope(|| {}); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn float_values() { + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock().named("foo").with_field( + field::mock("x") + .with_value(&3.234) + .and(field::mock("y").with_value(&-1.223)) + .only(), + ), + ) + .run_with_handle(); + + with_default(subscriber, || { + let foo = tracing::span!(Level::TRACE, "foo", x = 3.234, y = -1.223); + foo.in_scope(|| {}); + }); + + handle.assert_finished(); +} + +// TODO(#1138): determine a new syntax for uninitialized span fields, and +// re-enable these. +/* +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn add_field_after_new_span() { + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock() + .named("foo") + .with_field(field::mock("bar").with_value(&5) + .and(field::mock("baz").with_value).only()), + ) + .record( + span::mock().named("foo"), + field::mock("baz").with_value(&true).only(), + ) + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let span = tracing::span!(Level::TRACE, "foo", bar = 5, baz = false); + span.record("baz", &true); + span.in_scope(|| {}) + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn add_fields_only_after_new_span() { + let (subscriber, handle) = subscriber::mock() + .new_span(span::mock().named("foo")) + .record( + span::mock().named("foo"), + field::mock("bar").with_value(&5).only(), + ) + .record( + span::mock().named("foo"), + field::mock("baz").with_value(&true).only(), + ) + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let span = tracing::span!(Level::TRACE, "foo", bar = _, baz = _); + span.record("bar", &5); + span.record("baz", &true); + span.in_scope(|| {}) + }); + + handle.assert_finished(); +} +*/ + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn record_new_value_for_field() { + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock().named("foo").with_field( + field::mock("bar") + .with_value(&5) + .and(field::mock("baz").with_value(&false)) + .only(), + ), + ) + .record( + span::mock().named("foo"), + field::mock("baz").with_value(&true).only(), + ) + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let span = tracing::span!(Level::TRACE, "foo", bar = 5, baz = false); + span.record("baz", &true); + span.in_scope(|| {}) + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn record_new_values_for_fields() { + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock().named("foo").with_field( + field::mock("bar") + .with_value(&4) + .and(field::mock("baz").with_value(&false)) + .only(), + ), + ) + .record( + span::mock().named("foo"), + field::mock("bar").with_value(&5).only(), + ) + .record( + span::mock().named("foo"), + field::mock("baz").with_value(&true).only(), + ) + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let span = tracing::span!(Level::TRACE, "foo", bar = 4, baz = false); + span.record("bar", &5); + span.record("baz", &true); + span.in_scope(|| {}) + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn new_span_with_target_and_log_level() { + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock() + .named("foo") + .with_target("app_span") + .at_level(Level::DEBUG), + ) + .done() + .run_with_handle(); + + with_default(subscriber, || { + tracing::span!(target: "app_span", Level::DEBUG, "foo"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn explicit_root_span_is_root() { + let (subscriber, handle) = subscriber::mock() + .new_span(span::mock().named("foo").with_explicit_parent(None)) + .done() + .run_with_handle(); + + with_default(subscriber, || { + tracing::span!(parent: None, Level::TRACE, "foo"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn explicit_root_span_is_root_regardless_of_ctx() { + let (subscriber, handle) = subscriber::mock() + .new_span(span::mock().named("foo")) + .enter(span::mock().named("foo")) + .new_span(span::mock().named("bar").with_explicit_parent(None)) + .exit(span::mock().named("foo")) + .done() + .run_with_handle(); + + with_default(subscriber, || { + tracing::span!(Level::TRACE, "foo").in_scope(|| { + tracing::span!(parent: None, Level::TRACE, "bar"); + }) + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn explicit_child() { + let (subscriber, handle) = subscriber::mock() + .new_span(span::mock().named("foo")) + .new_span(span::mock().named("bar").with_explicit_parent(Some("foo"))) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let foo = tracing::span!(Level::TRACE, "foo"); + tracing::span!(parent: foo.id(), Level::TRACE, "bar"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn explicit_child_at_levels() { + let (subscriber, handle) = subscriber::mock() + .new_span(span::mock().named("foo")) + .new_span(span::mock().named("a").with_explicit_parent(Some("foo"))) + .new_span(span::mock().named("b").with_explicit_parent(Some("foo"))) + .new_span(span::mock().named("c").with_explicit_parent(Some("foo"))) + .new_span(span::mock().named("d").with_explicit_parent(Some("foo"))) + .new_span(span::mock().named("e").with_explicit_parent(Some("foo"))) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let foo = tracing::span!(Level::TRACE, "foo"); + tracing::trace_span!(parent: foo.id(), "a"); + tracing::debug_span!(parent: foo.id(), "b"); + tracing::info_span!(parent: foo.id(), "c"); + tracing::warn_span!(parent: foo.id(), "d"); + tracing::error_span!(parent: foo.id(), "e"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn explicit_child_regardless_of_ctx() { + let (subscriber, handle) = subscriber::mock() + .new_span(span::mock().named("foo")) + .new_span(span::mock().named("bar")) + .enter(span::mock().named("bar")) + .new_span(span::mock().named("baz").with_explicit_parent(Some("foo"))) + .exit(span::mock().named("bar")) + .done() + .run_with_handle(); + + with_default(subscriber, || { + let foo = tracing::span!(Level::TRACE, "foo"); + tracing::span!(Level::TRACE, "bar") + .in_scope(|| tracing::span!(parent: foo.id(), Level::TRACE, "baz")) + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn contextual_root() { + let (subscriber, handle) = subscriber::mock() + .new_span(span::mock().named("foo").with_contextual_parent(None)) + .done() + .run_with_handle(); + + with_default(subscriber, || { + tracing::span!(Level::TRACE, "foo"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn contextual_child() { + let (subscriber, handle) = subscriber::mock() + .new_span(span::mock().named("foo")) + .enter(span::mock().named("foo")) + .new_span( + span::mock() + .named("bar") + .with_contextual_parent(Some("foo")), + ) + .exit(span::mock().named("foo")) + .done() + .run_with_handle(); + + with_default(subscriber, || { + tracing::span!(Level::TRACE, "foo").in_scope(|| { + tracing::span!(Level::TRACE, "bar"); + }) + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn display_shorthand() { + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock().named("my_span").with_field( + field::mock("my_field") + .with_value(&display("hello world")) + .only(), + ), + ) + .done() + .run_with_handle(); + with_default(subscriber, || { + tracing::span!(Level::TRACE, "my_span", my_field = %"hello world"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn debug_shorthand() { + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock().named("my_span").with_field( + field::mock("my_field") + .with_value(&debug("hello world")) + .only(), + ), + ) + .done() + .run_with_handle(); + with_default(subscriber, || { + tracing::span!(Level::TRACE, "my_span", my_field = ?"hello world"); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn both_shorthands() { + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock().named("my_span").with_field( + field::mock("display_field") + .with_value(&display("hello world")) + .and(field::mock("debug_field").with_value(&debug("hello world"))) + .only(), + ), + ) + .done() + .run_with_handle(); + with_default(subscriber, || { + tracing::span!(Level::TRACE, "my_span", display_field = %"hello world", debug_field = ?"hello world"); + }); + + handle.assert_finished(); +} diff --git a/third_party/rust/tracing/tests/subscriber.rs b/third_party/rust/tracing/tests/subscriber.rs new file mode 100644 index 0000000000..15557c107f --- /dev/null +++ b/third_party/rust/tracing/tests/subscriber.rs @@ -0,0 +1,130 @@ +// These tests require the thread-local scoped dispatcher, which only works when +// we have a standard library. The behaviour being tested should be the same +// with the standard lib disabled. +// +// The alternative would be for each of these tests to be defined in a separate +// file, which is :( +#![cfg(feature = "std")] +use tracing::{ + field::display, + span::{Attributes, Id, Record}, + subscriber::{with_default, Interest, Subscriber}, + Event, Level, Metadata, +}; + +use tracing_mock::*; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn event_macros_dont_infinite_loop() { + // This test ensures that an event macro within a subscriber + // won't cause an infinite loop of events. + struct TestSubscriber; + impl Subscriber for TestSubscriber { + fn register_callsite(&self, _: &Metadata<'_>) -> Interest { + // Always return sometimes so that `enabled` will be called + // (which can loop). + Interest::sometimes() + } + + fn enabled(&self, meta: &Metadata<'_>) -> bool { + assert!(meta.fields().iter().any(|f| f.name() == "foo")); + tracing::event!(Level::TRACE, bar = false); + true + } + + fn new_span(&self, _: &Attributes<'_>) -> Id { + Id::from_u64(0xAAAA) + } + + fn record(&self, _: &Id, _: &Record<'_>) {} + + fn record_follows_from(&self, _: &Id, _: &Id) {} + + fn event(&self, event: &Event<'_>) { + assert!(event.metadata().fields().iter().any(|f| f.name() == "foo")); + tracing::event!(Level::TRACE, baz = false); + } + + fn enter(&self, _: &Id) {} + + fn exit(&self, _: &Id) {} + } + + with_default(TestSubscriber, || { + tracing::event!(Level::TRACE, foo = false); + }) +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn boxed_subscriber() { + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock().named("foo").with_field( + field::mock("bar") + .with_value(&display("hello from my span")) + .only(), + ), + ) + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .done() + .run_with_handle(); + let subscriber: Box<dyn Subscriber + Send + Sync + 'static> = Box::new(subscriber); + + with_default(subscriber, || { + let from = "my span"; + let span = tracing::span!( + Level::TRACE, + "foo", + bar = format_args!("hello from {}", from) + ); + span.in_scope(|| {}); + }); + + handle.assert_finished(); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] +#[test] +fn arced_subscriber() { + use std::sync::Arc; + + let (subscriber, handle) = subscriber::mock() + .new_span( + span::mock().named("foo").with_field( + field::mock("bar") + .with_value(&display("hello from my span")) + .only(), + ), + ) + .enter(span::mock().named("foo")) + .exit(span::mock().named("foo")) + .drop_span(span::mock().named("foo")) + .event( + event::mock() + .with_fields(field::mock("message").with_value(&display("hello from my event"))), + ) + .done() + .run_with_handle(); + let subscriber: Arc<dyn Subscriber + Send + Sync + 'static> = Arc::new(subscriber); + + // Test using a clone of the `Arc`ed subscriber + with_default(subscriber.clone(), || { + let from = "my span"; + let span = tracing::span!( + Level::TRACE, + "foo", + bar = format_args!("hello from {}", from) + ); + span.in_scope(|| {}); + }); + + with_default(subscriber, || { + tracing::info!("hello from my event"); + }); + + handle.assert_finished(); +} |