Files
tokio/tokio-trace/tests/subscriber.rs
T

171 lines
5.5 KiB
Rust
Raw Normal View History

2019-02-19 12:15:01 -08:00
#[macro_use]
extern crate tokio_trace;
mod support;
use self::support::*;
use tokio_trace::{dispatcher, Dispatch};
use std::sync::{
atomic::{AtomicUsize, Ordering},
Arc,
};
#[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();
dispatcher::with_default(Dispatch::new(subscriber), move || {
// Enter "alice" and then "bob". The dispatcher expects to see "bob" but
// not "alice."
let mut alice = span!("alice");
let mut bob = alice.enter(|| {
let mut bob = span!("bob");
bob.enter(|| ());
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.enter(|| bob.enter(|| {}));
// 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.enter(|| {});
assert_eq!(alice_count.load(Ordering::Relaxed), 1);
assert_eq!(bob_count.load(Ordering::Relaxed), 1);
});
handle.assert_finished();
}
#[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();
dispatcher::with_default(Dispatch::new(subscriber), move || {
// Enter "charlie" and then "dave". The dispatcher expects to see "dave" but
// not "charlie."
let mut charlie = span!("charlie");
let mut dave = charlie.enter(|| {
let mut dave = span!("dave");
dave.enter(|| {});
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.enter(|| dave.enter(|| {}));
// 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 mut charlie2 = span!("charlie");
charlie.enter(|| {});
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.enter(|| span!("dave").enter(|| {}));
assert_eq!(charlie_count.load(Ordering::Relaxed), 2);
assert_eq!(dave_count.load(Ordering::Relaxed), 2);
});
}
#[test]
fn filter_caching_is_lexically_scoped() {
pub fn my_great_function() -> bool {
span!("emily").enter(|| true)
}
pub fn my_other_function() -> bool {
span!("frank").enter(|| 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();
dispatcher::with_default(Dispatch::new(subscriber), || {
// 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);
});
}