summaryrefslogtreecommitdiffstats
path: root/third_party/rust/tracing/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/tracing/tests
parentInitial commit. (diff)
downloadfirefox-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')
-rw-r--r--third_party/rust/tracing/tests/enabled.rs54
-rw-r--r--third_party/rust/tracing/tests/event.rs500
-rw-r--r--third_party/rust/tracing/tests/filter_caching_is_lexically_scoped.rs65
-rw-r--r--third_party/rust/tracing/tests/filters_are_not_reevaluated_for_the_same_span.rs70
-rw-r--r--third_party/rust/tracing/tests/filters_are_reevaluated_for_different_call_sites.rs80
-rw-r--r--third_party/rust/tracing/tests/filters_dont_leak.rs81
-rw-r--r--third_party/rust/tracing/tests/future_send.rs22
-rw-r--r--third_party/rust/tracing/tests/macro_imports.rs23
-rw-r--r--third_party/rust/tracing/tests/macros.rs963
-rw-r--r--third_party/rust/tracing/tests/macros_incompatible_concat.rs24
-rw-r--r--third_party/rust/tracing/tests/macros_redefined_core.rs18
-rw-r--r--third_party/rust/tracing/tests/max_level_hint.rs37
-rw-r--r--third_party/rust/tracing/tests/multiple_max_level_hints.rs69
-rw-r--r--third_party/rust/tracing/tests/no_subscriber.rs15
-rw-r--r--third_party/rust/tracing/tests/register_callsite_deadlock.rs47
-rw-r--r--third_party/rust/tracing/tests/scoped_clobbers_default.rs35
-rw-r--r--third_party/rust/tracing/tests/span.rs825
-rw-r--r--third_party/rust/tracing/tests/subscriber.rs130
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();
+}