Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

54
vendor/tracing/tests/enabled.rs vendored Normal file
View File

@@ -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
}
})
.only()
.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
}
})
.only()
.run();
let _guard = tracing::subscriber::set_default(subscriber);
// Ensure that the `_event` and `_span` alternatives work correctly
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));
}

620
vendor/tracing/tests/event.rs vendored Normal file
View File

@@ -0,0 +1,620 @@
// 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(
expect::event().with_fields(
expect::field("answer")
.with_value(&42)
.and(
expect::field("to_question")
.with_value(&"life, the universe, and everything"),
)
.only(),
),
)
.only()
.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(
expect::event().with_fields(expect::field("message").with_value(
&tracing::field::debug(format_args!(
"hello from my tracing::event! yak shaved = {:?}",
true
)),
)),
)
.only()
.run_with_handle();
with_default(subscriber, || {
debug!("hello from my tracing::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(
expect::event().with_fields(
expect::field("answer")
.with_value(&42)
.and(
expect::field("question").with_value(&"life, the universe, and everything"),
)
.and(expect::msg(format_args!(
"hello from my event! tricky? {:?}!",
true
)))
.only(),
),
)
.only()
.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(
expect::event().with_fields(
expect::field("answer")
.with_value(&42)
.and(
expect::field("question").with_value(&"life, the universe, and everything"),
)
.and(expect::msg(format_args!("hello from my event")))
.only(),
),
)
.only()
.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(
expect::event()
.with_fields(
expect::field("message")
.with_value(&tracing::field::debug(format_args!(
"{:#x} make me one with{what:.>20}",
4_277_009_102u64,
what = "everything"
)))
.and(expect::field("foo").with_value(&666))
.and(expect::field("bar").with_value(&false))
.and(expect::field("like_a_butterfly").with_value(&42.0))
.only(),
)
.at_level(Level::ERROR)
.with_target("whatever"),
)
.only()
.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(
expect::event().with_fields(
expect::field("foo")
.with_value(&display("hello from my event"))
.only(),
),
)
.only()
.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(
expect::event().with_fields(
expect::field("foo.bar")
.with_value(&true)
.and(expect::field("foo.baz").with_value(&false))
.only(),
),
)
.only()
.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(
expect::event().with_fields(
expect::field("foo")
.with_value(&display("hello from my event"))
.only(),
),
)
.only()
.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(
expect::event().with_fields(
expect::field("x")
.with_value(&debug(3.234))
.and(expect::field("y").with_value(&debug(-1.223)))
.only(),
),
)
.event(expect::event().with_fields(expect::field("position").with_value(&debug(&pos))))
.only()
.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(
expect::event().with_fields(
expect::field("my_field")
.with_value(&display("hello world"))
.only(),
),
)
.only()
.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(
expect::event().with_fields(
expect::field("my_field")
.with_value(&debug("hello world"))
.only(),
),
)
.only()
.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(
expect::event().with_fields(
expect::field("display_field")
.with_value(&display("hello world"))
.and(expect::field("debug_field").with_value(&debug("hello world")))
.only(),
),
)
.only()
.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(expect::span().named("foo"))
.event(expect::event().with_ancestry(expect::has_explicit_parent("foo")))
.only()
.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(expect::span().named("foo"))
.event(expect::event().with_ancestry(expect::has_explicit_parent("foo")))
.event(expect::event().with_ancestry(expect::has_explicit_parent("foo")))
.event(expect::event().with_ancestry(expect::has_explicit_parent("foo")))
.event(expect::event().with_ancestry(expect::has_explicit_parent("foo")))
.event(expect::event().with_ancestry(expect::has_explicit_parent("foo")))
.only()
.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(
expect::event().with_fields(
expect::field("some_str")
.with_value(&"yes")
.and(expect::field("some_bool").with_value(&true))
.and(expect::field("some_u64").with_value(&42_u64))
.only(),
),
)
.only()
.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(
expect::event().with_fields(
expect::field("some_str")
.with_value(&"yes")
.and(expect::field("some_bool").with_value(&true))
.and(expect::field("some_u64").with_value(&42_u64))
.only(),
),
)
.only()
.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(
expect::event().with_fields(
expect::field("some_str")
.with_value(&"yes")
.and(expect::field("some_bool").with_value(&true))
.and(expect::field("some_u64").with_value(&42_u64))
.only(),
),
)
.only()
.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(expect::event().with_fields(expect::field("my_string").with_value(&"hello").only()))
.event(
expect::event().with_fields(
expect::field("my_string")
.with_value(&"hello world!")
.only(),
),
)
.only()
.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();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn constant_field_name() {
let expect_event = || {
expect::event().with_fields(
expect::field("foo")
.with_value(&"bar")
.and(expect::field("constant string").with_value(&"also works"))
.and(expect::field("foo.bar").with_value(&"baz"))
.and(expect::field("message").with_value(&debug(format_args!("quux"))))
.only(),
)
};
let (subscriber, handle) = subscriber::mock()
.event(expect_event())
.event(expect_event())
.event(expect_event())
.event(expect_event())
.event(expect_event())
.event(expect_event())
.event(expect_event())
.event(expect_event())
.only()
.run_with_handle();
with_default(subscriber, || {
const FOO: &str = "foo";
tracing::event!(
Level::INFO,
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
"quux"
);
tracing::event!(
Level::INFO,
{
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
},
"quux"
);
tracing::info!(
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
"quux"
);
tracing::info!(
{
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
},
"quux"
);
tracing::event!(
Level::INFO,
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
"{}",
"quux"
);
tracing::event!(
Level::INFO,
{
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
},
"{}",
"quux"
);
tracing::info!(
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
"{}",
"quux"
);
tracing::info!(
{
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
},
"{}",
"quux"
);
});
handle.assert_finished();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn keyword_ident_in_field_name() {
let (subscriber, handle) = subscriber::mock()
.event(expect::event().with_fields(expect::field("crate").with_value(&"tracing")))
.only()
.run_with_handle();
with_default(subscriber, || error!(crate = "tracing", "message"));
handle.assert_finished();
}

View File

@@ -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);
}

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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)
.only()
.run_with_handle();
let _guard = tracing::subscriber::set_default(subscriber);
do_span();
let alice = expect::span().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)
.only()
.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)
.only()
.run_with_handle();
let _guard = tracing::subscriber::set_default(subscriber);
do_event();
let (subscriber2, handle2) = subscriber::mock()
.named("events/subscriber2")
.with_filter(|_| true)
.event(expect::event())
.only()
.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();
}

22
vendor/tracing/tests/future_send.rs vendored Normal file
View File

@@ -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) {}

68
vendor/tracing/tests/instrument.rs vendored Normal file
View File

@@ -0,0 +1,68 @@
// 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::{future::Future, pin::Pin, task};
use futures::FutureExt as _;
use tracing::{subscriber::with_default, Instrument as _, Level};
use tracing_mock::*;
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn span_on_drop() {
#[derive(Clone, Debug)]
struct AssertSpanOnDrop;
impl Drop for AssertSpanOnDrop {
fn drop(&mut self) {
tracing::info!("Drop");
}
}
#[allow(dead_code)] // Field not used, but logs on `Drop`
struct Fut(Option<AssertSpanOnDrop>);
impl Future for Fut {
type Output = ();
fn poll(mut self: Pin<&mut Self>, _: &mut task::Context<'_>) -> task::Poll<Self::Output> {
self.set(Fut(None));
task::Poll::Ready(())
}
}
let subscriber = subscriber::mock()
.enter(expect::span().named("foo"))
.event(
expect::event()
.with_ancestry(expect::has_contextual_parent("foo"))
.at_level(Level::INFO),
)
.exit(expect::span().named("foo"))
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.enter(expect::span().named("bar"))
.event(
expect::event()
.with_ancestry(expect::has_contextual_parent("bar"))
.at_level(Level::INFO),
)
.exit(expect::span().named("bar"))
.drop_span(expect::span().named("bar"))
.only()
.run();
with_default(subscriber, || {
// polled once
Fut(Some(AssertSpanOnDrop))
.instrument(tracing::span!(Level::TRACE, "foo"))
.now_or_never()
.unwrap();
// never polled
drop(Fut(Some(AssertSpanOnDrop)).instrument(tracing::span!(Level::TRACE, "bar")));
});
}

23
vendor/tracing/tests/macro_imports.rs vendored Normal file
View File

@@ -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");
}

1387
vendor/tracing/tests/macros.rs vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}

37
vendor/tracing/tests/max_level_hint.rs vendored Normal file
View File

@@ -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(expect::event().at_level(Level::INFO))
.event(expect::event().at_level(Level::WARN))
.event(expect::event().at_level(Level::ERROR))
.only()
.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();
}

View File

@@ -0,0 +1,109 @@
use std::{
ptr,
sync::atomic::{AtomicPtr, Ordering},
thread::{self, JoinHandle},
time::Duration,
};
use tracing::Subscriber;
use tracing_core::{span, Metadata};
struct TestSubscriber {
creator_thread: String,
sleep: Duration,
callsite: AtomicPtr<Metadata<'static>>,
}
impl TestSubscriber {
fn new(sleep_micros: u64) -> Self {
let creator_thread = thread::current()
.name()
.unwrap_or("<unknown thread>")
.to_owned();
Self {
creator_thread,
sleep: Duration::from_micros(sleep_micros),
callsite: AtomicPtr::new(ptr::null_mut()),
}
}
}
impl Subscriber for TestSubscriber {
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> tracing_core::Interest {
if !self.sleep.is_zero() {
thread::sleep(self.sleep);
}
self.callsite
.store(metadata as *const _ as *mut _, Ordering::SeqCst);
println!(
"{creator} from {thread:?}: register_callsite: {callsite:#?}",
creator = self.creator_thread,
callsite = metadata as *const _,
thread = thread::current().name(),
);
tracing_core::Interest::always()
}
fn event(&self, event: &tracing_core::Event<'_>) {
let stored_callsite = self.callsite.load(Ordering::SeqCst);
let event_callsite: *mut Metadata<'static> = event.metadata() as *const _ as *mut _;
println!(
"{creator} from {thread:?}: event (with callsite): {event_callsite:#?} (stored callsite: {stored_callsite:#?})",
creator = self.creator_thread,
thread = thread::current().name(),
);
// This assert is the actual test.
assert_eq!(
stored_callsite, event_callsite,
"stored callsite: {stored_callsite:#?} does not match event \
callsite: {event_callsite:#?}. Was `event` called before \
`register_callsite`?"
);
}
fn enabled(&self, _metadata: &Metadata<'_>) -> bool {
true
}
fn new_span(&self, _span: &span::Attributes<'_>) -> span::Id {
span::Id::from_u64(0)
}
fn record(&self, _span: &span::Id, _values: &span::Record<'_>) {}
fn record_follows_from(&self, _span: &span::Id, _follows: &span::Id) {}
fn enter(&self, _span: &tracing_core::span::Id) {}
fn exit(&self, _span: &tracing_core::span::Id) {}
}
fn subscriber_thread(idx: usize, register_sleep_micros: u64) -> JoinHandle<()> {
thread::Builder::new()
.name(format!("subscriber-{idx}"))
.spawn(move || {
// We use a sleep to ensure the starting order of the 2 threads.
let subscriber = TestSubscriber::new(register_sleep_micros);
let _subscriber_guard = tracing::subscriber::set_default(subscriber);
tracing::info!("event-from-{idx}", idx = idx);
// Wait a bit for everything to end (we don't want to remove the subscriber
// immediately because that will mix up the test).
thread::sleep(Duration::from_millis(100));
})
.expect("failed to spawn thread")
}
#[test]
fn event_before_register() {
let subscriber_1_register_sleep_micros = 100;
let subscriber_2_register_sleep_micros = 0;
let jh1 = subscriber_thread(1, subscriber_1_register_sleep_micros);
// This delay ensures that the event!() in the first thread is executed first.
thread::sleep(Duration::from_micros(50));
let jh2 = subscriber_thread(2, subscriber_2_register_sleep_micros);
jh1.join().expect("failed to join thread");
jh2.join().expect("failed to join thread");
}

View File

@@ -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(expect::event().at_level(Level::INFO))
.event(expect::event().at_level(Level::WARN))
.event(expect::event().at_level(Level::ERROR))
.only()
.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(expect::event().at_level(Level::INFO))
.event(expect::event().at_level(Level::DEBUG))
.event(expect::event().at_level(Level::WARN))
.event(expect::event().at_level(Level::ERROR))
.only()
.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();
}

16
vendor/tracing/tests/no_subscriber.rs vendored Normal file
View File

@@ -0,0 +1,16 @@
#![cfg(feature = "std")]
use tracing_mock::subscriber;
#[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) = subscriber::mock().only().run_with_handle();
tracing::subscriber::set_global_default(subscriber)
.expect("setting global default must succeed");
tracing::subscriber::with_default(tracing::subscriber::NoSubscriber::default(), || {
tracing::info!("this should not be recorded");
});
handle.assert_finished();
}

View File

@@ -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");
}

View File

@@ -0,0 +1,35 @@
#![cfg(feature = "std")]
use tracing_mock::{expect, subscriber};
#[test]
fn scoped_clobbers_global() {
// Reproduces https://github.com/tokio-rs/tracing/issues/2050
let (scoped, scoped_handle) = subscriber::mock()
.event(expect::event().with_fields(expect::msg("before global")))
.event(expect::event().with_fields(expect::msg("before drop")))
.only()
.run_with_handle();
let (global, global_handle) = subscriber::mock()
.event(expect::event().with_fields(expect::msg("after drop")))
.only()
.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();
}

918
vendor/tracing/tests/span.rs vendored Normal file
View File

@@ -0,0 +1,918 @@
// 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::{
error_span,
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");
// The purpose of this test is to assert that two clones of the same
// span are equal, so the clone here is kind of the whole point :)
#[allow(clippy::redundant_clone)]
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(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(expect::span().named("foo"))
.event(expect::event())
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(expect::span().named("foo"))
.event(expect::event())
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.enter(expect::span().named("bar"))
.exit(expect::span().named("bar"))
.drop_span(expect::span().named("bar"))
.only()
.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(expect::event())
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(expect::span().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(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.drop_span(expect::span().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(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.clone_span(expect::span().named("foo"))
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.run_with_handle();
let subscriber2 = subscriber::mock().only().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(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(expect::span().named("foo"))
.event(expect::event())
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(expect::span().named("foo"))
.event(expect::event())
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(expect::span().named("foo"))
.event(expect::event())
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(
expect::span().named("foo").with_fields(
expect::field("bar")
.with_value(&display("hello from my span"))
.only(),
),
)
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(
expect::span()
.named("foo")
.with_fields(expect::field("fields.bar").with_value(&true).only()),
)
.only()
.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(
expect::span().named("foo").with_fields(
expect::field("bar")
.with_value(&display("hello from my span"))
.only(),
),
)
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(
expect::span().named("foo").with_fields(
expect::field("x")
.with_value(&debug(3.234))
.and(expect::field("y").with_value(&debug(-1.223)))
.only(),
),
)
.new_span(
expect::span()
.named("bar")
.with_fields(expect::field("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(
expect::span().named("foo").with_fields(
expect::field("x")
.with_value(&3.234)
.and(expect::field("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(
expect::span()
.named("foo")
.with_fields(expect::field("bar").with_value(&5)
.and(expect::field("baz").with_value).only()),
)
.record(
expect::span().named("foo"),
field::expect("baz").with_value(&true).only(),
)
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(expect::span().named("foo"))
.record(
expect::span().named("foo"),
field::expect("bar").with_value(&5).only(),
)
.record(
expect::span().named("foo"),
field::expect("baz").with_value(&true).only(),
)
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(
expect::span().named("foo").with_fields(
expect::field("bar")
.with_value(&5)
.and(expect::field("baz").with_value(&false))
.only(),
),
)
.record(
expect::span().named("foo"),
expect::field("baz").with_value(&true).only(),
)
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(
expect::span().named("foo").with_fields(
expect::field("bar")
.with_value(&4)
.and(expect::field("baz").with_value(&false))
.only(),
),
)
.record(
expect::span().named("foo"),
expect::field("bar").with_value(&5).only(),
)
.record(
expect::span().named("foo"),
expect::field("baz").with_value(&true).only(),
)
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(
expect::span()
.named("foo")
.with_target("app_span")
.at_level(Level::DEBUG),
)
.only()
.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(
expect::span()
.named("foo")
.with_ancestry(expect::is_explicit_root()),
)
.only()
.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(expect::span().named("foo"))
.enter(expect::span().named("foo"))
.new_span(
expect::span()
.named("bar")
.with_ancestry(expect::is_explicit_root()),
)
.exit(expect::span().named("foo"))
.only()
.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(expect::span().named("foo"))
.new_span(
expect::span()
.named("bar")
.with_ancestry(expect::has_explicit_parent("foo")),
)
.only()
.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(expect::span().named("foo"))
.new_span(
expect::span()
.named("a")
.with_ancestry(expect::has_explicit_parent("foo")),
)
.new_span(
expect::span()
.named("b")
.with_ancestry(expect::has_explicit_parent("foo")),
)
.new_span(
expect::span()
.named("c")
.with_ancestry(expect::has_explicit_parent("foo")),
)
.new_span(
expect::span()
.named("d")
.with_ancestry(expect::has_explicit_parent("foo")),
)
.new_span(
expect::span()
.named("e")
.with_ancestry(expect::has_explicit_parent("foo")),
)
.only()
.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(expect::span().named("foo"))
.new_span(expect::span().named("bar"))
.enter(expect::span().named("bar"))
.new_span(
expect::span()
.named("baz")
.with_ancestry(expect::has_explicit_parent("foo")),
)
.exit(expect::span().named("bar"))
.only()
.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(
expect::span()
.named("foo")
.with_ancestry(expect::is_contextual_root()),
)
.only()
.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(expect::span().named("foo"))
.enter(expect::span().named("foo"))
.new_span(
expect::span()
.named("bar")
.with_ancestry(expect::has_contextual_parent("foo")),
)
.exit(expect::span().named("foo"))
.only()
.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(
expect::span().named("my_span").with_fields(
expect::field("my_field")
.with_value(&display("hello world"))
.only(),
),
)
.only()
.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(
expect::span().named("my_span").with_fields(
expect::field("my_field")
.with_value(&debug("hello world"))
.only(),
),
)
.only()
.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(
expect::span().named("my_span").with_fields(
expect::field("display_field")
.with_value(&display("hello world"))
.and(expect::field("debug_field").with_value(&debug("hello world")))
.only(),
),
)
.only()
.run_with_handle();
with_default(subscriber, || {
tracing::span!(Level::TRACE, "my_span", display_field = %"hello world", debug_field = ?"hello world");
});
handle.assert_finished();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn constant_field_name() {
let (subscriber, handle) = subscriber::mock()
.new_span(
expect::span().named("my_span").with_fields(
expect::field("foo")
.with_value(&"bar")
.and(expect::field("constant string").with_value(&"also works"))
.and(expect::field("foo.bar").with_value(&"baz"))
.only(),
),
)
.only()
.run_with_handle();
with_default(subscriber, || {
const FOO: &str = "foo";
tracing::span!(
Level::TRACE,
"my_span",
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
);
});
handle.assert_finished();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn keyword_ident_in_field_name_span_macro() {
#[derive(Debug)]
struct Foo;
let (subscriber, handle) = subscriber::mock()
.new_span(expect::span().with_fields(expect::field("self").with_value(&debug(Foo)).only()))
.only()
.run_with_handle();
with_default(subscriber, || {
error_span!("span", self = ?Foo);
});
handle.assert_finished();
}

129
vendor/tracing/tests/subscriber.rs vendored Normal file
View File

@@ -0,0 +1,129 @@
// 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::{expect, subscriber};
#[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(
expect::span().named("foo").with_fields(
expect::field("bar")
.with_value(&display("hello from my span"))
.only(),
),
)
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.only()
.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(
expect::span().named("foo").with_fields(
expect::field("bar")
.with_value(&display("hello from my span"))
.only(),
),
)
.enter(expect::span().named("foo"))
.exit(expect::span().named("foo"))
.drop_span(expect::span().named("foo"))
.event(
expect::event()
.with_fields(expect::field("message").with_value(&display("hello from my event"))),
)
.only()
.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();
}