use std::time::UNIX_EPOCH;
use assert2::check;
use metrique::{
OnParentDrop, Slot,
timers::{EpochMicros, Timestamp, TimestampOnClose},
};
use metrique_macro::metrics;
use metrique_timesource::{TimeSource, set_time_source};
use metrique_writer::sink::DevNullSink;
#[metrics(rename_all = "PascalCase")]
#[derive(Default, Debug)]
struct Metrics {
a: usize,
#[metrics(flatten)]
b: Slot<Nested>,
#[metrics(flatten)]
c: Slot<AnotherNested>,
}
#[metrics(subfield_owned)]
#[derive(Default, Debug)]
struct Nested {
inner_value: usize,
timer: TimestampOnClose,
#[metrics(format = EpochMicros)]
formatted: Timestamp,
}
#[metrics(subfield)]
#[derive(Default, Clone, Debug)]
struct AnotherNested {
another_value: usize,
}
#[tokio::test(start_paused = true)]
async fn debug_slot_closed() {
let _mock_time = set_time_source(TimeSource::tokio(UNIX_EPOCH));
let mut metrics = Metrics {
a: 42,
b: Slot::new(Nested {
inner_value: 123,
timer: TimestampOnClose::default(),
formatted: Timestamp::default(),
}),
c: Slot::new(AnotherNested { another_value: 456 }),
};
check!(format!("{:?}", metrics.b) == "Slot { open: false, has_data: false, data: None }");
let mut guard = metrics.b.open(OnParentDrop::Discard).unwrap();
check!(format!("{:?}", metrics.b) == "Slot { open: true, has_data: false, data: None }");
guard.inner_value = 1000;
drop(guard);
check!(format!("{:?}", metrics.b) == "Slot { open: true, has_data: true, data: None }");
metrics.b.wait_for_data().await;
check!(
format!("{:?}", metrics.b)
== "Slot { open: true, has_data: true, data: Some(NestedEntry { inner_value: 1000, timer: TimestampValue { duration_since_epoch: 0ns }, formatted: TimestampValue { duration_since_epoch: 0ns } }) }"
);
}
#[test]
fn debug_slot_open() {
let _mock_time = set_time_source(TimeSource::tokio(UNIX_EPOCH));
let mut metrics = Metrics {
a: 99,
b: Slot::new(Nested {
inner_value: 200,
timer: TimestampOnClose::default(),
formatted: Timestamp::default(),
}),
c: Slot::new(AnotherNested { another_value: 300 }),
};
let _guard_b = metrics.b.open(OnParentDrop::Discard);
let _guard_c = metrics.c.open(OnParentDrop::Discard);
let debug_output = format!("{:?}", metrics);
check!(debug_output.contains("a: 99"));
check!(debug_output.contains("open: true"));
check!(
format!("{:?}", metrics.append_on_drop(DevNullSink::new()))
== "AppendAndCloseOnDrop { value: Metrics { a: 99, b: Slot { open: true, has_data: false, data: None }, c: Slot { open: true, has_data: false, data: None } }, sink: DevNullSink }"
);
}
#[tokio::test(start_paused = true)]
async fn debug_slot_guard() {
let _mock_time = set_time_source(TimeSource::tokio(UNIX_EPOCH));
let mut metrics = Metrics {
a: 1,
b: Slot::new(Nested {
inner_value: 777,
timer: TimestampOnClose::default(),
formatted: Timestamp::default(),
}),
c: Slot::new(AnotherNested { another_value: 888 }),
};
let guard_b = metrics.b.open(OnParentDrop::Discard).unwrap();
check!(
format!("{:?}", guard_b)
== "SlotGuard { value: Nested { inner_value: 777, timer: TimestampOnClose { time_source: TimeSource::Custom(...) }, formatted: Timestamp { time: SystemTime { tv_sec: 0, tv_nsec: 0 } } }, parent_is_closed: false, parent_drop_mode: Discard }"
);
drop(metrics);
check!(
format!("{:?}", guard_b)
== "SlotGuard { value: Nested { inner_value: 777, timer: TimestampOnClose { time_source: TimeSource::Custom(...) }, formatted: Timestamp { time: SystemTime { tv_sec: 0, tv_nsec: 0 } } }, parent_is_closed: true, parent_drop_mode: Discard }"
);
}