| use tracing::subscriber::with_default; |
| use tracing::Level; |
| use tracing_attributes::instrument; |
| use tracing_mock::*; |
| |
| // Reproduces a compile error when an instrumented function body contains inner |
| // attributes (https://github.com/tokio-rs/tracing/issues/2294). |
| #[deny(unused_variables)] |
| #[instrument] |
| fn repro_2294() { |
| #![allow(unused_variables)] |
| let i = 42; |
| } |
| |
| #[test] |
| fn override_everything() { |
| #[instrument(target = "my_target", level = "debug")] |
| fn my_fn() {} |
| |
| #[instrument(level = Level::DEBUG, target = "my_target")] |
| fn my_other_fn() {} |
| |
| let span = expect::span() |
| .named("my_fn") |
| .at_level(Level::DEBUG) |
| .with_target("my_target"); |
| let span2 = expect::span() |
| .named("my_other_fn") |
| .at_level(Level::DEBUG) |
| .with_target("my_target"); |
| let (subscriber, handle) = subscriber::mock() |
| .new_span(span.clone()) |
| .enter(span.clone()) |
| .exit(span.clone()) |
| .drop_span(span) |
| .new_span(span2.clone()) |
| .enter(span2.clone()) |
| .exit(span2.clone()) |
| .drop_span(span2) |
| .only() |
| .run_with_handle(); |
| |
| with_default(subscriber, || { |
| my_fn(); |
| my_other_fn(); |
| }); |
| |
| handle.assert_finished(); |
| } |
| |
| #[test] |
| fn fields() { |
| #[instrument(target = "my_target", level = "debug")] |
| fn my_fn(arg1: usize, arg2: bool) {} |
| |
| let span = expect::span() |
| .named("my_fn") |
| .at_level(Level::DEBUG) |
| .with_target("my_target"); |
| |
| let span2 = expect::span() |
| .named("my_fn") |
| .at_level(Level::DEBUG) |
| .with_target("my_target"); |
| let (subscriber, handle) = subscriber::mock() |
| .new_span( |
| span.clone().with_field( |
| expect::field("arg1") |
| .with_value(&2usize) |
| .and(expect::field("arg2").with_value(&false)) |
| .only(), |
| ), |
| ) |
| .enter(span.clone()) |
| .exit(span.clone()) |
| .drop_span(span) |
| .new_span( |
| span2.clone().with_field( |
| expect::field("arg1") |
| .with_value(&3usize) |
| .and(expect::field("arg2").with_value(&true)) |
| .only(), |
| ), |
| ) |
| .enter(span2.clone()) |
| .exit(span2.clone()) |
| .drop_span(span2) |
| .only() |
| .run_with_handle(); |
| |
| with_default(subscriber, || { |
| my_fn(2, false); |
| my_fn(3, true); |
| }); |
| |
| handle.assert_finished(); |
| } |
| |
| #[test] |
| fn skip() { |
| struct UnDebug(pub u32); |
| |
| #[instrument(target = "my_target", level = "debug", skip(_arg2, _arg3))] |
| fn my_fn(arg1: usize, _arg2: UnDebug, _arg3: UnDebug) {} |
| |
| #[instrument(target = "my_target", level = "debug", skip_all)] |
| fn my_fn2(_arg1: usize, _arg2: UnDebug, _arg3: UnDebug) {} |
| |
| let span = expect::span() |
| .named("my_fn") |
| .at_level(Level::DEBUG) |
| .with_target("my_target"); |
| |
| let span2 = expect::span() |
| .named("my_fn") |
| .at_level(Level::DEBUG) |
| .with_target("my_target"); |
| |
| let span3 = expect::span() |
| .named("my_fn2") |
| .at_level(Level::DEBUG) |
| .with_target("my_target"); |
| |
| let (subscriber, handle) = subscriber::mock() |
| .new_span( |
| span.clone() |
| .with_field(expect::field("arg1").with_value(&2usize).only()), |
| ) |
| .enter(span.clone()) |
| .exit(span.clone()) |
| .drop_span(span) |
| .new_span( |
| span2 |
| .clone() |
| .with_field(expect::field("arg1").with_value(&3usize).only()), |
| ) |
| .enter(span2.clone()) |
| .exit(span2.clone()) |
| .drop_span(span2) |
| .new_span(span3.clone()) |
| .enter(span3.clone()) |
| .exit(span3.clone()) |
| .drop_span(span3) |
| .only() |
| .run_with_handle(); |
| |
| with_default(subscriber, || { |
| my_fn(2, UnDebug(0), UnDebug(1)); |
| my_fn(3, UnDebug(0), UnDebug(1)); |
| my_fn2(2, UnDebug(0), UnDebug(1)); |
| }); |
| |
| handle.assert_finished(); |
| } |
| |
| #[test] |
| fn generics() { |
| #[derive(Debug)] |
| struct Foo; |
| |
| #[instrument] |
| fn my_fn<S, T: std::fmt::Debug>(arg1: S, arg2: T) |
| where |
| S: std::fmt::Debug, |
| { |
| } |
| |
| let span = expect::span().named("my_fn"); |
| |
| let (subscriber, handle) = subscriber::mock() |
| .new_span( |
| span.clone().with_field( |
| expect::field("arg1") |
| .with_value(&format_args!("Foo")) |
| .and(expect::field("arg2").with_value(&format_args!("false"))), |
| ), |
| ) |
| .enter(span.clone()) |
| .exit(span.clone()) |
| .drop_span(span) |
| .only() |
| .run_with_handle(); |
| |
| with_default(subscriber, || { |
| my_fn(Foo, false); |
| }); |
| |
| handle.assert_finished(); |
| } |
| |
| #[test] |
| fn methods() { |
| #[derive(Debug)] |
| struct Foo; |
| |
| impl Foo { |
| #[instrument] |
| fn my_fn(&self, arg1: usize) {} |
| } |
| |
| let span = expect::span().named("my_fn"); |
| |
| let (subscriber, handle) = subscriber::mock() |
| .new_span( |
| span.clone().with_field( |
| expect::field("self") |
| .with_value(&format_args!("Foo")) |
| .and(expect::field("arg1").with_value(&42usize)), |
| ), |
| ) |
| .enter(span.clone()) |
| .exit(span.clone()) |
| .drop_span(span) |
| .only() |
| .run_with_handle(); |
| |
| with_default(subscriber, || { |
| let foo = Foo; |
| foo.my_fn(42); |
| }); |
| |
| handle.assert_finished(); |
| } |
| |
| #[test] |
| fn impl_trait_return_type() { |
| #[instrument] |
| fn returns_impl_trait(x: usize) -> impl Iterator<Item = usize> { |
| 0..x |
| } |
| |
| let span = expect::span().named("returns_impl_trait"); |
| |
| let (subscriber, handle) = subscriber::mock() |
| .new_span( |
| span.clone() |
| .with_field(expect::field("x").with_value(&10usize).only()), |
| ) |
| .enter(span.clone()) |
| .exit(span.clone()) |
| .drop_span(span) |
| .only() |
| .run_with_handle(); |
| |
| with_default(subscriber, || { |
| for _ in returns_impl_trait(10) { |
| // nop |
| } |
| }); |
| |
| handle.assert_finished(); |
| } |