Revision control
Copy as Markdown
Other Tools
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
mod common;
use crate::common::*;
use glean_core::metrics::*;
use glean_core::CommonMetricData;
use glean_core::Glean;
use glean_core::Lifetime;
fn nofollows_ping(glean: &mut Glean) -> PingType {
// When `follows_collection_enabled=false` then by default `enabled=false`
let ping = PingType::new(
"nofollows",
/* include_client_id */ false,
/* send_if_empty */ true,
/* precise_timestamps */ true,
/* include_info_sections */ false,
/* enabled */ false,
vec![],
vec![],
/* follows_collection_enabled */ false,
);
glean.register_ping_type(&ping);
ping
}
fn manual_ping(glean: &mut Glean) -> PingType {
let ping = PingType::new(
"manual",
/* include_client_id */ true,
/* send_if_empty */ false,
/* precise_timestamps */ true,
/* include_info_sections */ true,
/* enabled */ true,
vec![],
vec![],
/* collection_enabled */ true,
);
glean.register_ping_type(&ping);
ping
}
#[test]
fn pings_with_follows_false_are_exempt() {
let (mut glean, _t) = new_glean(None);
let ping = nofollows_ping(&mut glean);
// We need to store a metric as an empty ping is not stored.
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
category: "local".into(),
send_in_pings: vec!["nofollows".into()],
..Default::default()
});
counter.add_sync(&glean, 1);
assert!(!ping.submit_sync(&glean, None));
glean.set_ping_enabled(&ping, true);
counter.add_sync(&glean, 2);
assert!(ping.submit_sync(&glean, None));
let mut queued_pings = get_queued_pings(glean.get_data_path()).unwrap();
assert_eq!(1, queued_pings.len());
let json = queued_pings.pop().unwrap().1;
let counter_val = json["metrics"]["counter"]["local.counter"]
.as_i64()
.unwrap();
assert_eq!(2, counter_val);
glean.set_upload_enabled(false);
assert_eq!(1, get_queued_pings(glean.get_data_path()).unwrap().len());
// Disabling upload generates a deletion ping
assert_eq!(1, get_deletion_pings(glean.get_data_path()).unwrap().len());
// Regardless, the `nofollows` ping is still enabled.
counter.add_sync(&glean, 10);
assert!(ping.submit_sync(&glean, None));
let queued_pings = get_queued_pings(glean.get_data_path()).unwrap();
// both `nofollows` pings remain in the queue
assert_eq!(2, queued_pings.len());
let mut values = vec![2, 10];
for ping in queued_pings {
let json = ping.1;
let counter_val = json["metrics"]["counter"]["local.counter"]
.as_i64()
.unwrap();
assert!(values.contains(&counter_val));
values.retain(|&x| x != counter_val);
}
}
#[test]
fn nofollows_ping_can_ride_along() {
let (mut glean, _t) = new_glean(None);
let nofollows_ping = nofollows_ping(&mut glean);
// Basically `manual_ping` but with a ride-along
let manual_ping = PingType::new(
"manual",
/* include_client_id */ true,
/* send_if_empty */ false,
/* precise_timestamps */ true,
/* include_info_sections */ true,
/* enabled */ true,
vec!["nofollows".to_string()],
vec![],
/* collection_enabled */ true,
);
glean.register_ping_type(&manual_ping);
// We need to store a metric as an empty ping is not stored.
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
category: "local".into(),
send_in_pings: vec!["manual".into(), "nofollows".into()],
lifetime: Lifetime::Application,
..Default::default()
});
// Trigger a ping with data.
counter.add_sync(&glean, 1);
assert!(manual_ping.submit_sync(&glean, None));
assert_eq!(1, get_queued_pings(glean.get_data_path()).unwrap().len());
// Enable one more ping, trigger it with more data
glean.set_ping_enabled(&nofollows_ping, true);
counter.add_sync(&glean, 2);
assert!(manual_ping.submit_sync(&glean, None));
// The previous one, plus 2 new ones
let queued_pings = get_queued_pings(glean.get_data_path()).unwrap();
assert_eq!(3, queued_pings.len());
for (_url, json, info) in queued_pings {
let Some(obj) = info else {
panic!("no ping info")
};
let counter_val = json["metrics"]["counter"]["local.counter"]
.as_i64()
.unwrap();
if obj["ping_name"].as_str().unwrap() == "nofollows" {
assert_eq!(2, counter_val, "{:?}", json);
} else {
let seq = json["ping_info"]["seq"].as_i64().unwrap();
match seq {
0 => assert_eq!(1, counter_val),
1 => assert_eq!(3, counter_val),
2 => assert_eq!(8, counter_val),
_ => panic!("unexpected sequence number: {}", seq),
}
}
}
// Disable it again
glean.set_ping_enabled(&nofollows_ping, false);
counter.add_sync(&glean, 5);
assert!(manual_ping.submit_sync(&glean, None));
let queued_pings = get_queued_pings(glean.get_data_path()).unwrap();
// The 2 previous `manual` pings, the `nofollows` was removed, plus the new `manual` one
assert_eq!(3, queued_pings.len());
// Check that all follows are as expected.
// We cannot guarantee order, so we need to look at some values
for (_url, json, info) in queued_pings {
let Some(obj) = info else {
panic!("no ping info")
};
let counter_val = json["metrics"]["counter"]["local.counter"]
.as_i64()
.unwrap();
assert_ne!("nofollows", obj["ping_name"].as_str().unwrap());
let seq = json["ping_info"]["seq"].as_i64().unwrap();
match seq {
0 => assert_eq!(1, counter_val),
1 => assert_eq!(3, counter_val),
2 => assert_eq!(8, counter_val),
_ => panic!("unexpected sequence number: {}", seq),
}
}
}
#[test]
fn queued_nofollows_pings_are_not_removed() {
let (mut glean, t) = new_glean(None);
let nofollows_ping = nofollows_ping(&mut glean);
let manual_ping = manual_ping(&mut glean);
glean.set_ping_enabled(&nofollows_ping, true);
// We need to store a metric as an empty ping is not stored.
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
category: "local".into(),
send_in_pings: vec!["manual".into(), "nofollows".into()],
lifetime: Lifetime::Application,
..Default::default()
});
// Trigger a ping with data.
counter.add_sync(&glean, 1);
assert!(manual_ping.submit_sync(&glean, None));
assert!(nofollows_ping.submit_sync(&glean, None));
assert_eq!(2, get_queued_pings(glean.get_data_path()).unwrap().len());
glean.set_upload_enabled(false);
assert_eq!(1, get_queued_pings(glean.get_data_path()).unwrap().len());
// Ping is still there after a Glean restart
let (glean, _t) = new_glean(Some(t));
assert_eq!(1, get_queued_pings(glean.get_data_path()).unwrap().len());
}