in glean-core/src/event_database/mod.rs [965:1089]
fn normalize_store_multi_run_timestamp_math() {
// With multiple runs of events (separated by `glean.restarted`),
// ensure the timestamp math works.
// (( works = Initial event gets to be 0, subsequent events get normalized to that 0.
// Subsequent runs figure it out via glean.restarted.date and ping_info.start_time ))
let (glean, _dir) = new_glean(None);
let store_name = "store-name";
let glean_restarted = StoredEvent {
event: RecordedEvent {
category: "glean".into(),
name: "restarted".into(),
..Default::default()
},
execution_counter: None,
};
let not_glean_restarted = StoredEvent {
event: RecordedEvent {
category: "category".into(),
name: "name".into(),
..Default::default()
},
execution_counter: None,
};
// This scenario represents a run of three events followed by an hour between runs,
// followed by one final event.
let timestamps = [20, 40, 200, 12];
let ecs = [0, 1];
let some_hour = 16;
let startup_date = FixedOffset::east(0)
.ymd(2022, 11, 24)
.and_hms(some_hour, 29, 0); // TimeUnit::Minute -- don't put seconds
let glean_start_time = startup_date.with_hour(some_hour - 1);
let restarted_ts = 2;
let mut store = vec![
StoredEvent {
event: RecordedEvent {
timestamp: timestamps[0],
..not_glean_restarted.event.clone()
},
execution_counter: Some(ecs[0]),
},
StoredEvent {
event: RecordedEvent {
timestamp: timestamps[1],
..not_glean_restarted.event.clone()
},
execution_counter: Some(ecs[0]),
},
StoredEvent {
event: RecordedEvent {
timestamp: timestamps[2],
..not_glean_restarted.event.clone()
},
execution_counter: Some(ecs[0]),
},
StoredEvent {
event: RecordedEvent {
extra: Some(
[(
"glean.startup.date".into(),
get_iso_time_string(startup_date, TimeUnit::Minute),
)]
.into(),
),
timestamp: restarted_ts,
..glean_restarted.event.clone()
},
execution_counter: Some(ecs[1]),
},
StoredEvent {
event: RecordedEvent {
timestamp: timestamps[3],
..not_glean_restarted.event.clone()
},
execution_counter: Some(ecs[1]),
},
];
glean.event_storage().normalize_store(
&glean,
store_name,
&mut store,
glean_start_time.unwrap(),
);
assert_eq!(5, store.len()); // 4 "real" events plus 1 `glean.restarted`
// Let's check the first three.
for (timestamp, event) in timestamps[..timestamps.len() - 1].iter().zip(store.clone()) {
assert_eq!(
StoredEvent {
event: RecordedEvent {
timestamp: timestamp - timestamps[0],
..not_glean_restarted.event.clone()
},
execution_counter: None,
},
event
);
}
// The fourth should be a glean.restarted and have a realtime-based timestamp.
let hour_in_millis = 3600000;
assert_eq!(
store[3],
StoredEvent {
event: RecordedEvent {
timestamp: hour_in_millis,
..glean_restarted.event
},
execution_counter: None,
}
);
// The fifth should have a timestamp based on the new origin.
assert_eq!(
store[4],
StoredEvent {
event: RecordedEvent {
timestamp: hour_in_millis + timestamps[3] - restarted_ts,
..not_glean_restarted.event
},
execution_counter: None,
}
);
}