summaryrefslogtreecommitdiffstats
path: root/third_party/rust/glean-core/tests/ping_maker.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/glean-core/tests/ping_maker.rs')
-rw-r--r--third_party/rust/glean-core/tests/ping_maker.rs301
1 files changed, 301 insertions, 0 deletions
diff --git a/third_party/rust/glean-core/tests/ping_maker.rs b/third_party/rust/glean-core/tests/ping_maker.rs
new file mode 100644
index 0000000000..29b6bccaca
--- /dev/null
+++ b/third_party/rust/glean-core/tests/ping_maker.rs
@@ -0,0 +1,301 @@
+// 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
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+mod common;
+use crate::common::*;
+
+use glean_core::metrics::*;
+use glean_core::ping::PingMaker;
+use glean_core::{CommonMetricData, Glean, Lifetime};
+
+fn set_up_basic_ping() -> (Glean, PingMaker, PingType, tempfile::TempDir) {
+ let (tempdir, _) = tempdir();
+ let (mut glean, t) = new_glean(Some(tempdir));
+ let ping_maker = PingMaker::new();
+ let ping_type = PingType::new("store1", true, false, true, vec![]);
+ glean.register_ping_type(&ping_type);
+
+ // Record something, so the ping will have data
+ let metric = BooleanMetric::new(CommonMetricData {
+ name: "boolean_metric".into(),
+ category: "telemetry".into(),
+ send_in_pings: vec!["store1".into()],
+ disabled: false,
+ lifetime: Lifetime::User,
+ ..Default::default()
+ });
+ metric.set_sync(&glean, true);
+
+ (glean, ping_maker, ping_type, t)
+}
+
+#[test]
+fn ping_info_must_contain_a_nonempty_start_and_end_time() {
+ let (glean, ping_maker, ping_type, _t) = set_up_basic_ping();
+
+ let ping = ping_maker
+ .collect(&glean, &ping_type, None, "", "")
+ .unwrap();
+ let ping_info = ping.content["ping_info"].as_object().unwrap();
+
+ let start_time_str = ping_info["start_time"].as_str().unwrap();
+ let start_time_date = iso8601_to_chrono(&iso8601::datetime(start_time_str).unwrap());
+
+ let end_time_str = ping_info["end_time"].as_str().unwrap();
+ let end_time_date = iso8601_to_chrono(&iso8601::datetime(end_time_str).unwrap());
+
+ assert!(start_time_date <= end_time_date);
+}
+
+#[test]
+fn get_ping_info_must_report_all_the_required_fields() {
+ let (glean, ping_maker, ping_type, _t) = set_up_basic_ping();
+
+ let ping = ping_maker
+ .collect(&glean, &ping_type, None, "", "")
+ .unwrap();
+ let ping_info = ping.content["ping_info"].as_object().unwrap();
+
+ assert!(ping_info.get("start_time").is_some());
+ assert!(ping_info.get("end_time").is_some());
+ assert!(ping_info.get("seq").is_some());
+}
+
+#[test]
+fn get_client_info_must_report_all_the_available_data() {
+ let (glean, ping_maker, ping_type, _t) = set_up_basic_ping();
+
+ let ping = ping_maker
+ .collect(&glean, &ping_type, None, "", "")
+ .unwrap();
+ let client_info = ping.content["client_info"].as_object().unwrap();
+
+ client_info["telemetry_sdk_build"].as_str().unwrap();
+}
+
+#[test]
+fn test_metrics_must_report_experimentation_id() {
+ let (tempdir, _) = tempdir();
+ let mut glean = Glean::new(glean_core::InternalConfiguration {
+ data_path: tempdir.path().display().to_string(),
+ application_id: GLOBAL_APPLICATION_ID.into(),
+ language_binding_name: "Rust".into(),
+ upload_enabled: true,
+ max_events: None,
+ delay_ping_lifetime_io: false,
+ app_build: "Unknown".into(),
+ use_core_mps: false,
+ trim_data_to_registered_pings: false,
+ log_level: None,
+ rate_limit: None,
+ enable_event_timestamps: false,
+ experimentation_id: Some("test-experimentation-id".to_string()),
+ })
+ .unwrap();
+ let ping_maker = PingMaker::new();
+ let ping_type = PingType::new("store1", true, false, true, vec![]);
+ glean.register_ping_type(&ping_type);
+
+ // Record something, so the ping will have data
+ let metric = BooleanMetric::new(CommonMetricData {
+ name: "boolean_metric".into(),
+ category: "telemetry".into(),
+ send_in_pings: vec!["store1".into()],
+ disabled: false,
+ lifetime: Lifetime::User,
+ ..Default::default()
+ });
+ metric.set_sync(&glean, true);
+
+ let ping = ping_maker
+ .collect(&glean, &ping_type, None, "", "")
+ .unwrap();
+ let metrics = ping.content["metrics"].as_object().unwrap();
+ println!("TLDEBUG Metrics:\n{:?}", metrics);
+
+ let strings = metrics["string"].as_object().unwrap();
+ assert_eq!(
+ strings["glean.client.annotation.experimentation_id"]
+ .as_str()
+ .unwrap(),
+ "test-experimentation-id",
+ "experimentation ids must match"
+ );
+}
+
+#[test]
+fn experimentation_id_is_removed_if_send_if_empty_is_false() {
+ // Initialize Glean with an experimentation id, it should be removed if the ping is empty
+ // and send_if_empty is false.
+ let (tempdir, _) = tempdir();
+ let mut glean = Glean::new(glean_core::InternalConfiguration {
+ data_path: tempdir.path().display().to_string(),
+ application_id: GLOBAL_APPLICATION_ID.into(),
+ language_binding_name: "Rust".into(),
+ upload_enabled: true,
+ max_events: None,
+ delay_ping_lifetime_io: false,
+ app_build: "Unknown".into(),
+ use_core_mps: false,
+ trim_data_to_registered_pings: false,
+ log_level: None,
+ rate_limit: None,
+ enable_event_timestamps: false,
+ experimentation_id: Some("test-experimentation-id".to_string()),
+ })
+ .unwrap();
+ let ping_maker = PingMaker::new();
+
+ let unknown_ping_type = PingType::new("unknown", true, false, true, vec![]);
+ glean.register_ping_type(&unknown_ping_type);
+
+ assert!(ping_maker
+ .collect(&glean, &unknown_ping_type, None, "", "")
+ .is_none());
+}
+
+#[test]
+fn collect_must_report_none_when_no_data_is_stored() {
+ // NOTE: This is a behavior change from glean-ac which returned an empty
+ // string in this case. As this is an implementation detail and not part of
+ // the public API, it's safe to change this.
+
+ let (mut glean, ping_maker, ping_type, _t) = set_up_basic_ping();
+
+ let unknown_ping_type = PingType::new("unknown", true, false, true, vec![]);
+ glean.register_ping_type(&ping_type);
+
+ assert!(ping_maker
+ .collect(&glean, &unknown_ping_type, None, "", "")
+ .is_none());
+}
+
+#[test]
+fn seq_number_must_be_sequential() {
+ let (glean, ping_maker, _ping_type, _t) = set_up_basic_ping();
+
+ let metric = BooleanMetric::new(CommonMetricData {
+ name: "boolean_metric".into(),
+ category: "telemetry".into(),
+ send_in_pings: vec!["store2".into()],
+ disabled: false,
+ lifetime: Lifetime::User,
+ ..Default::default()
+ });
+ metric.set_sync(&glean, true);
+
+ for i in 0..=1 {
+ for ping_name in ["store1", "store2"].iter() {
+ let ping_type = PingType::new(*ping_name, true, false, true, vec![]);
+ let ping = ping_maker
+ .collect(&glean, &ping_type, None, "", "")
+ .unwrap();
+ let seq_num = ping.content["ping_info"]["seq"].as_i64().unwrap();
+ // Ensure sequence numbers in different stores are independent of
+ // each other
+ assert_eq!(i, seq_num);
+ }
+ }
+
+ // Test that ping sequence numbers increase independently.
+ {
+ let ping_type = PingType::new("store1", true, false, true, vec![]);
+
+ // 3rd ping of store1
+ let ping = ping_maker
+ .collect(&glean, &ping_type, None, "", "")
+ .unwrap();
+ let seq_num = ping.content["ping_info"]["seq"].as_i64().unwrap();
+ assert_eq!(2, seq_num);
+
+ // 4th ping of store1
+ let ping = ping_maker
+ .collect(&glean, &ping_type, None, "", "")
+ .unwrap();
+ let seq_num = ping.content["ping_info"]["seq"].as_i64().unwrap();
+ assert_eq!(3, seq_num);
+ }
+
+ {
+ let ping_type = PingType::new("store2", true, false, true, vec![]);
+
+ // 3rd ping of store2
+ let ping = ping_maker
+ .collect(&glean, &ping_type, None, "", "")
+ .unwrap();
+ let seq_num = ping.content["ping_info"]["seq"].as_i64().unwrap();
+ assert_eq!(2, seq_num);
+ }
+
+ {
+ let ping_type = PingType::new("store1", true, false, true, vec![]);
+
+ // 5th ping of store1
+ let ping = ping_maker
+ .collect(&glean, &ping_type, None, "", "")
+ .unwrap();
+ let seq_num = ping.content["ping_info"]["seq"].as_i64().unwrap();
+ assert_eq!(4, seq_num);
+ }
+}
+
+#[test]
+fn clear_pending_pings() {
+ let (mut glean, _t) = new_glean(None);
+ let ping_maker = PingMaker::new();
+ let ping_type = PingType::new("store1", true, false, true, vec![]);
+ glean.register_ping_type(&ping_type);
+
+ // Record something, so the ping will have data
+ let metric = BooleanMetric::new(CommonMetricData {
+ name: "boolean_metric".into(),
+ category: "telemetry".into(),
+ send_in_pings: vec!["store1".into()],
+ disabled: false,
+ lifetime: Lifetime::User,
+ ..Default::default()
+ });
+ metric.set_sync(&glean, true);
+
+ assert!(ping_type.submit_sync(&glean, None));
+ assert_eq!(1, get_queued_pings(glean.get_data_path()).unwrap().len());
+
+ assert!(ping_maker
+ .clear_pending_pings(glean.get_data_path())
+ .is_ok());
+ assert_eq!(0, get_queued_pings(glean.get_data_path()).unwrap().len());
+}
+
+#[test]
+fn no_pings_submitted_if_upload_disabled() {
+ // Regression test, bug 1603571
+
+ let (mut glean, _t) = new_glean(None);
+ let ping_type = PingType::new("store1", true, true, true, vec![]);
+ glean.register_ping_type(&ping_type);
+
+ assert!(ping_type.submit_sync(&glean, None));
+ assert_eq!(1, get_queued_pings(glean.get_data_path()).unwrap().len());
+
+ // Disable upload, then try to sumbit
+ glean.set_upload_enabled(false);
+
+ // Test again through the direct call
+ assert!(!ping_type.submit_sync(&glean, None));
+ assert_eq!(0, get_queued_pings(glean.get_data_path()).unwrap().len());
+}
+
+#[test]
+fn metadata_is_correctly_added_when_necessary() {
+ let (mut glean, _t) = new_glean(None);
+ glean.set_debug_view_tag("valid-tag");
+ let ping_type = PingType::new("store1", true, true, true, vec![]);
+ glean.register_ping_type(&ping_type);
+
+ assert!(ping_type.submit_sync(&glean, None));
+
+ let (_, _, metadata) = &get_queued_pings(glean.get_data_path()).unwrap()[0];
+ let headers = metadata.as_ref().unwrap().get("headers").unwrap();
+ assert_eq!(headers.get("X-Debug-ID").unwrap(), "valid-tag");
+}