diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/glean/tests | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/glean/tests')
-rw-r--r-- | third_party/rust/glean/tests/common/mod.rs | 51 | ||||
-rw-r--r-- | third_party/rust/glean/tests/init_fails.rs | 84 | ||||
-rw-r--r-- | third_party/rust/glean/tests/never_init.rs | 66 | ||||
-rw-r--r-- | third_party/rust/glean/tests/no_time_to_init.rs | 81 | ||||
-rw-r--r-- | third_party/rust/glean/tests/overflowing_preinit.rs | 95 | ||||
-rw-r--r-- | third_party/rust/glean/tests/persist_ping_lifetime.rs | 95 | ||||
-rw-r--r-- | third_party/rust/glean/tests/persist_ping_lifetime_nopanic.rs | 43 | ||||
-rw-r--r-- | third_party/rust/glean/tests/schema.rs | 180 | ||||
-rw-r--r-- | third_party/rust/glean/tests/simple.rs | 84 |
9 files changed, 779 insertions, 0 deletions
diff --git a/third_party/rust/glean/tests/common/mod.rs b/third_party/rust/glean/tests/common/mod.rs new file mode 100644 index 0000000000..cc02946d2c --- /dev/null +++ b/third_party/rust/glean/tests/common/mod.rs @@ -0,0 +1,51 @@ +// 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/. + +// #[allow(dead_code)] is required on this module as a workaround for +// https://github.com/rust-lang/rust/issues/46379 +#![allow(dead_code)] + +use std::{panic, process}; + +use glean::{ClientInfoMetrics, Configuration}; + +/// Initialize the env logger for a test environment. +/// +/// When testing we want all logs to go to stdout/stderr by default. +pub fn enable_test_logging() { + let _ = env_logger::builder().is_test(true).try_init(); +} + +/// Install a panic handler that exits the whole process when a panic occurs. +/// +/// This causes the process to exit even if a thread panics. +/// This is similar to the `panic=abort` configuration, but works in the default configuration +/// (as used by `cargo test`). +fn install_panic_handler() { + let orig_hook = panic::take_hook(); + panic::set_hook(Box::new(move |panic_info| { + // invoke the default handler and exit the process + orig_hook(panic_info); + process::exit(1); + })); +} + +/// Create a new instance of Glean. +pub fn initialize(cfg: Configuration) { + // Ensure panics in threads, such as the init thread or the dispatcher, cause the process to + // exit. + // + // Otherwise in case of a panic in a thread the integration test will just hang. + // CI will terminate it after a timeout, but why stick around if we know nothing is happening? + install_panic_handler(); + + // Use some default values to make our life easier a bit. + let client_info = ClientInfoMetrics { + app_build: "1.0.0".to_string(), + app_display_version: "1.0.0".to_string(), + channel: Some("testing".to_string()), + }; + + glean::initialize(cfg, client_info); +} diff --git a/third_party/rust/glean/tests/init_fails.rs b/third_party/rust/glean/tests/init_fails.rs new file mode 100644 index 0000000000..f696d78860 --- /dev/null +++ b/third_party/rust/glean/tests/init_fails.rs @@ -0,0 +1,84 @@ +// 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/. + +//! This integration test should model how the RLB is used when embedded in another Rust application +//! (e.g. FOG/Firefox Desktop). +//! +//! We write a single test scenario per file to avoid any state keeping across runs +//! (different files run as different processes). + +mod common; + +use std::{thread, time::Duration}; + +use glean::Configuration; + +/// Some user metrics. +mod metrics { + use glean::private::*; + use glean::{Lifetime, TimeUnit}; + use glean_core::CommonMetricData; + use once_cell::sync::Lazy; + + #[allow(non_upper_case_globals)] + pub static initialization: Lazy<TimespanMetric> = Lazy::new(|| { + TimespanMetric::new( + CommonMetricData { + name: "initialization".into(), + category: "sample".into(), + send_in_pings: vec!["validation".into()], + lifetime: Lifetime::Ping, + disabled: false, + ..Default::default() + }, + TimeUnit::Nanosecond, + ) + }); +} + +mod pings { + use glean::private::PingType; + use once_cell::sync::Lazy; + + #[allow(non_upper_case_globals)] + pub static validation: Lazy<PingType> = + Lazy::new(|| glean::private::PingType::new("validation", true, true, vec![])); +} + +/// Test scenario: Glean initialization fails. +/// +/// App tries to initialize Glean, but that somehow fails. +#[test] +fn init_fails() { + common::enable_test_logging(); + + metrics::initialization.start(); + + // Create a custom configuration to use a validating uploader. + let dir = tempfile::tempdir().unwrap(); + let tmpname = dir.path().to_path_buf(); + + let cfg = Configuration { + data_path: tmpname, + application_id: "".into(), // An empty application ID is invalid. + upload_enabled: true, + max_events: None, + delay_ping_lifetime_io: false, + server_endpoint: Some("invalid-test-host".into()), + uploader: None, + use_core_mps: false, + }; + common::initialize(cfg); + + metrics::initialization.stop(); + + pings::validation.submit(None); + + // We don't test for data here, as that would block on the dispatcher. + + // Give it a short amount of time to actually finish initialization. + thread::sleep(Duration::from_millis(500)); + + glean::shutdown(); +} diff --git a/third_party/rust/glean/tests/never_init.rs b/third_party/rust/glean/tests/never_init.rs new file mode 100644 index 0000000000..321662b327 --- /dev/null +++ b/third_party/rust/glean/tests/never_init.rs @@ -0,0 +1,66 @@ +// 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/. + +//! This integration test should model how the RLB is used when embedded in another Rust application +//! (e.g. FOG/Firefox Desktop). +//! +//! We write a single test scenario per file to avoid any state keeping across runs +//! (different files run as different processes). + +mod common; + +/// Some user metrics. +mod metrics { + use glean::private::*; + use glean::{Lifetime, TimeUnit}; + use glean_core::CommonMetricData; + use once_cell::sync::Lazy; + + #[allow(non_upper_case_globals)] + pub static initialization: Lazy<TimespanMetric> = Lazy::new(|| { + TimespanMetric::new( + CommonMetricData { + name: "initialization".into(), + category: "sample".into(), + send_in_pings: vec!["validation".into()], + lifetime: Lifetime::Ping, + disabled: false, + ..Default::default() + }, + TimeUnit::Nanosecond, + ) + }); +} + +mod pings { + use glean::private::PingType; + use once_cell::sync::Lazy; + + #[allow(non_upper_case_globals)] + pub static validation: Lazy<PingType> = + Lazy::new(|| glean::private::PingType::new("validation", true, true, vec![])); +} + +/// Test scenario: Glean is never initialized. +/// +/// Glean is never initialized. +/// Some data is recorded early on. +/// And later the whole process is shutdown. +#[test] +fn never_initialize() { + common::enable_test_logging(); + + metrics::initialization.start(); + + // NOT calling `initialize` here. + // In apps this might happen for several reasons: + // 1. Process doesn't run long enough for Glean to be initialized. + // 2. Getting some early data used for initialize fails + + pings::validation.submit(None); + + // We can't test for data either, as that would panic because init was never called. + + glean::shutdown(); +} diff --git a/third_party/rust/glean/tests/no_time_to_init.rs b/third_party/rust/glean/tests/no_time_to_init.rs new file mode 100644 index 0000000000..162e89df20 --- /dev/null +++ b/third_party/rust/glean/tests/no_time_to_init.rs @@ -0,0 +1,81 @@ +// 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/. + +//! This integration test should model how the RLB is used when embedded in another Rust application +//! (e.g. FOG/Firefox Desktop). +//! +//! We write a single test scenario per file to avoid any state keeping across runs +//! (different files run as different processes). + +mod common; + +use glean::Configuration; + +/// Some user metrics. +mod metrics { + use glean::private::*; + use glean::{Lifetime, TimeUnit}; + use glean_core::CommonMetricData; + use once_cell::sync::Lazy; + + #[allow(non_upper_case_globals)] + pub static initialization: Lazy<TimespanMetric> = Lazy::new(|| { + TimespanMetric::new( + CommonMetricData { + name: "initialization".into(), + category: "sample".into(), + send_in_pings: vec!["validation".into()], + lifetime: Lifetime::Ping, + disabled: false, + ..Default::default() + }, + TimeUnit::Nanosecond, + ) + }); +} + +mod pings { + use glean::private::PingType; + use once_cell::sync::Lazy; + + #[allow(non_upper_case_globals)] + pub static validation: Lazy<PingType> = + Lazy::new(|| glean::private::PingType::new("validation", true, true, vec![])); +} + +/// Test scenario: Glean initialization fails. +/// +/// The app tries to initializate Glean, but that somehow fails. +#[test] +fn init_fails() { + common::enable_test_logging(); + + metrics::initialization.start(); + + // Create a custom configuration to use a validating uploader. + let dir = tempfile::tempdir().unwrap(); + let tmpname = dir.path().to_path_buf(); + + let cfg = Configuration { + data_path: tmpname, + application_id: "firefox-desktop".into(), // An empty application ID is invalid. + upload_enabled: true, + max_events: None, + delay_ping_lifetime_io: false, + server_endpoint: Some("invalid-test-host".into()), + uploader: None, + use_core_mps: false, + }; + common::initialize(cfg); + + metrics::initialization.stop(); + + pings::validation.submit(None); + + // We don't test for data here, as that would block on the dispatcher. + + // Shut it down immediately; this might not be enough time to initialize. + + glean::shutdown(); +} diff --git a/third_party/rust/glean/tests/overflowing_preinit.rs b/third_party/rust/glean/tests/overflowing_preinit.rs new file mode 100644 index 0000000000..fe6b3eb2f9 --- /dev/null +++ b/third_party/rust/glean/tests/overflowing_preinit.rs @@ -0,0 +1,95 @@ +// 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/. + +//! This integration test should model how the RLB is used when embedded in another Rust application +//! (e.g. FOG/Firefox Desktop). +//! +//! We write a single test scenario per file to avoid any state keeping across runs +//! (different files run as different processes). + +mod common; + +use glean::Configuration; + +/// Some user metrics. +mod metrics { + use glean::private::*; + use glean::Lifetime; + use glean_core::CommonMetricData; + use once_cell::sync::Lazy; + + #[allow(non_upper_case_globals)] + pub static rapid_counting: Lazy<CounterMetric> = Lazy::new(|| { + CounterMetric::new(CommonMetricData { + name: "rapid_counting".into(), + category: "sample".into(), + send_in_pings: vec!["metrics".into()], + lifetime: Lifetime::Ping, + disabled: false, + ..Default::default() + }) + }); + + // This is a hack, but a good one: + // + // To avoid reaching into RLB internals we re-create the metric so we can look at it. + #[allow(non_upper_case_globals)] + pub static preinit_tasks_overflow: Lazy<CounterMetric> = Lazy::new(|| { + CounterMetric::new(CommonMetricData { + category: "glean.error".into(), + name: "preinit_tasks_overflow".into(), + send_in_pings: vec!["metrics".into()], + lifetime: Lifetime::Ping, + disabled: false, + ..Default::default() + }) + }); +} + +/// Test scenario: Lots of metric recordings before init. +/// +/// The app starts recording metrics before Glean is initialized. +/// Once initialized the recordings are processed and data is persisted. +/// The pre-init dispatcher queue records how many recordings over the limit it saw. +/// +/// This is an integration test to avoid dealing with resetting the dispatcher. +#[test] +fn overflowing_the_task_queue_records_telemetry() { + common::enable_test_logging(); + + // Create a custom configuration to use a validating uploader. + let dir = tempfile::tempdir().unwrap(); + let tmpname = dir.path().to_path_buf(); + + let cfg = Configuration { + data_path: tmpname, + application_id: "firefox-desktop".into(), + upload_enabled: true, + max_events: None, + delay_ping_lifetime_io: false, + server_endpoint: Some("invalid-test-host".into()), + uploader: None, + use_core_mps: false, + }; + + // Insert a bunch of tasks to overflow the queue. + for _ in 0..1010 { + metrics::rapid_counting.add(1); + } + + // Now initialize Glean + common::initialize(cfg); + + assert_eq!(Some(1000), metrics::rapid_counting.test_get_value(None)); + + // The metrics counts the total number of overflowing tasks, + // (and the count of tasks in the queue when we overflowed: bug 1764573) + // this might include Glean-internal tasks. + let val = metrics::preinit_tasks_overflow + .test_get_value(None) + .unwrap(); + assert!(val >= 10); + + glean::shutdown(); +} diff --git a/third_party/rust/glean/tests/persist_ping_lifetime.rs b/third_party/rust/glean/tests/persist_ping_lifetime.rs new file mode 100644 index 0000000000..1a98e3beab --- /dev/null +++ b/third_party/rust/glean/tests/persist_ping_lifetime.rs @@ -0,0 +1,95 @@ +// 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/. + +//! This integration test should model how the RLB is used when embedded in another Rust application +//! (e.g. FOG/Firefox Desktop). +//! +//! We write a single test scenario per file to avoid any state keeping across runs +//! (different files run as different processes). + +mod common; + +use glean::{ClientInfoMetrics, Configuration}; +use std::path::PathBuf; + +/// Some user metrics. +mod metrics { + use glean::private::*; + use glean::Lifetime; + use glean_core::CommonMetricData; + use once_cell::sync::Lazy; + + #[allow(non_upper_case_globals)] + pub static boo: Lazy<BooleanMetric> = Lazy::new(|| { + BooleanMetric::new(CommonMetricData { + name: "boo".into(), + category: "sample".into(), + send_in_pings: vec!["validation".into()], + lifetime: Lifetime::Ping, + disabled: false, + ..Default::default() + }) + }); +} + +fn cfg_new(tmpname: PathBuf) -> Configuration { + Configuration { + data_path: tmpname, + application_id: "firefox-desktop".into(), + upload_enabled: true, + max_events: None, + delay_ping_lifetime_io: true, + server_endpoint: Some("invalid-test-host".into()), + uploader: None, + use_core_mps: false, + } +} + +/// Test scenario: Are ping-lifetime data persisted on shutdown when delayed? +/// +/// delay_ping_lifetime_io: true has Glean put "ping"-lifetime data in-memory +/// instead of the db. Ensure that, on orderly shutdowns, we correctly persist +/// these in-memory data to the db. +#[test] +fn delayed_ping_data() { + common::enable_test_logging(); + + metrics::boo.set(true); + + // Create a custom configuration to delay ping-lifetime io + let dir = tempfile::tempdir().unwrap(); + let tmpname = dir.path().to_path_buf(); + + common::initialize(cfg_new(tmpname.clone())); + + assert!( + metrics::boo.test_get_value(None).unwrap(), + "Data should be present. Doesn't mean it's persisted, though." + ); + + glean::test_reset_glean( + cfg_new(tmpname.clone()), + ClientInfoMetrics::unknown(), + false, + ); + + assert_eq!( + None, + metrics::boo.test_get_value(None), + "Data should not have made it to disk on unclean shutdown." + ); + metrics::boo.set(true); // Let's try again + + // This time, let's shut down cleanly + glean::shutdown(); + + // Now when we init, we should get the persisted data + glean::test_reset_glean(cfg_new(tmpname), ClientInfoMetrics::unknown(), false); + assert!( + metrics::boo.test_get_value(None).unwrap(), + "Data must be persisted between clean shutdown and init!" + ); + + glean::shutdown(); // Cleanly shut down at the end of the test. +} diff --git a/third_party/rust/glean/tests/persist_ping_lifetime_nopanic.rs b/third_party/rust/glean/tests/persist_ping_lifetime_nopanic.rs new file mode 100644 index 0000000000..7300d4185a --- /dev/null +++ b/third_party/rust/glean/tests/persist_ping_lifetime_nopanic.rs @@ -0,0 +1,43 @@ +// 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/. + +//! This integration test should model how the RLB is used when embedded in another Rust application +//! (e.g. FOG/Firefox Desktop). +//! +//! We write a single test scenario per file to avoid any state keeping across runs +//! (different files run as different processes). + +mod common; + +use glean::Configuration; +use std::path::PathBuf; + +fn cfg_new(tmpname: PathBuf) -> Configuration { + Configuration { + data_path: tmpname, + application_id: "firefox-desktop".into(), + upload_enabled: true, + max_events: None, + delay_ping_lifetime_io: true, + server_endpoint: Some("invalid-test-host".into()), + uploader: None, + use_core_mps: false, + } +} + +/// Test scenario: `persist_ping_lifetime_data` called after shutdown. +#[test] +fn delayed_ping_data() { + common::enable_test_logging(); + + // Create a custom configuration to delay ping-lifetime io + let dir = tempfile::tempdir().unwrap(); + let tmpname = dir.path().to_path_buf(); + + common::initialize(cfg_new(tmpname)); + glean::persist_ping_lifetime_data(); + + glean::shutdown(); + glean::persist_ping_lifetime_data(); +} diff --git a/third_party/rust/glean/tests/schema.rs b/third_party/rust/glean/tests/schema.rs new file mode 100644 index 0000000000..92fb2a4751 --- /dev/null +++ b/third_party/rust/glean/tests/schema.rs @@ -0,0 +1,180 @@ +// 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/. + +use std::io::Read; + +use flate2::read::GzDecoder; +use jsonschema_valid::{self, schemas::Draft}; +use serde_json::Value; + +//use glean::private::{DenominatorMetric, NumeratorMetric, RateMetric}; +use glean::net::UploadResult; +use glean::{ClientInfoMetrics, Configuration}; + +const SCHEMA_JSON: &str = include_str!("../../../glean.1.schema.json"); + +fn load_schema() -> Value { + serde_json::from_str(SCHEMA_JSON).unwrap() +} + +const GLOBAL_APPLICATION_ID: &str = "org.mozilla.glean.test.app"; + +// Create a new instance of Glean with a temporary directory. +// We need to keep the `TempDir` alive, so that it's not deleted before we stop using it. +fn new_glean(configuration: Option<Configuration>) -> tempfile::TempDir { + let dir = tempfile::tempdir().unwrap(); + let tmpname = dir.path().to_path_buf(); + + let cfg = match configuration { + Some(c) => c, + None => Configuration { + data_path: tmpname, + application_id: GLOBAL_APPLICATION_ID.into(), + upload_enabled: true, + max_events: None, + delay_ping_lifetime_io: false, + server_endpoint: Some("invalid-test-host".into()), + uploader: None, + use_core_mps: false, + }, + }; + + let client_info = ClientInfoMetrics { + app_build: env!("CARGO_PKG_VERSION").to_string(), + app_display_version: env!("CARGO_PKG_VERSION").to_string(), + channel: Some("testing".to_string()), + }; + + glean::initialize(cfg, client_info); + + dir +} + +#[test] +fn validate_against_schema() { + let schema = load_schema(); + + let (s, r) = crossbeam_channel::bounded::<Vec<u8>>(1); + + // Define a fake uploader that reports back the submitted payload + // using a crossbeam channel. + #[derive(Debug)] + pub struct ValidatingUploader { + sender: crossbeam_channel::Sender<Vec<u8>>, + } + impl glean::net::PingUploader for ValidatingUploader { + fn upload( + &self, + _url: String, + body: Vec<u8>, + _headers: Vec<(String, String)>, + ) -> UploadResult { + self.sender.send(body).unwrap(); + UploadResult::http_status(200) + } + } + + // Create a custom configuration to use a validating uploader. + let dir = tempfile::tempdir().unwrap(); + let tmpname = dir.path().to_path_buf(); + + let cfg = Configuration { + data_path: tmpname, + application_id: GLOBAL_APPLICATION_ID.into(), + upload_enabled: true, + max_events: None, + delay_ping_lifetime_io: false, + server_endpoint: Some("invalid-test-host".into()), + uploader: Some(Box::new(ValidatingUploader { sender: s })), + use_core_mps: false, + }; + let _ = new_glean(Some(cfg)); + + const PING_NAME: &str = "test-ping"; + + // Test each of the metric types, just for basic smoke testing against the + // schema + + // TODO: 1695762 Test all of the metric types against the schema from Rust + + /* + let rate_metric: RateMetric = RateMetric::new(CommonMetricData { + category: "test".into(), + name: "rate".into(), + send_in_pings: vec![PING_NAME.into()], + ..Default::default() + }); + rate_metric.add_to_numerator(1); + rate_metric.add_to_denominator(1); + + let numerator_metric1: NumeratorMetric = NumeratorMetric::new(CommonMetricData { + category: "test".into(), + name: "num1".into(), + send_in_pings: vec![PING_NAME.into()], + ..Default::default() + }); + let numerator_metric2: NumeratorMetric = NumeratorMetric::new(CommonMetricData { + category: "test".into(), + name: "num2".into(), + send_in_pings: vec![PING_NAME.into()], + ..Default::default() + }); + let denominator_metric: DenominatorMetric = DenominatorMetric::new( + CommonMetricData { + category: "test".into(), + name: "den".into(), + send_in_pings: vec![PING_NAME.into()], + ..Default::default() + }, + vec![ + CommonMetricData { + category: "test".into(), + name: "num1".into(), + send_in_pings: vec![PING_NAME.into()], + ..Default::default() + }, + CommonMetricData { + category: "test".into(), + name: "num2".into(), + send_in_pings: vec![PING_NAME.into()], + ..Default::default() + }, + ], + ); + + numerator_metric1.add_to_numerator(1); + numerator_metric2.add_to_numerator(2); + denominator_metric.add(3); + */ + + // Define a new ping and submit it. + let custom_ping = glean::private::PingType::new(PING_NAME, true, true, vec![]); + custom_ping.submit(None); + + // Wait for the ping to arrive. + let raw_body = r.recv().unwrap(); + + // Decode the gzipped body. + let mut gzip_decoder = GzDecoder::new(&raw_body[..]); + let mut s = String::with_capacity(raw_body.len()); + + let data = gzip_decoder + .read_to_string(&mut s) + .ok() + .map(|_| &s[..]) + .or_else(|| std::str::from_utf8(&raw_body).ok()) + .and_then(|payload| serde_json::from_str(payload).ok()) + .unwrap(); + + // Now validate against the vendored schema + let cfg = jsonschema_valid::Config::from_schema(&schema, Some(Draft::Draft6)).unwrap(); + let validation = cfg.validate(&data); + match validation { + Ok(()) => {} + Err(e) => { + let errors = e.map(|e| format!("{}", e)).collect::<Vec<_>>(); + panic!("Data: {:#?}\nErrors: {:#?}", data, errors); + } + } +} diff --git a/third_party/rust/glean/tests/simple.rs b/third_party/rust/glean/tests/simple.rs new file mode 100644 index 0000000000..245e4d67a2 --- /dev/null +++ b/third_party/rust/glean/tests/simple.rs @@ -0,0 +1,84 @@ +// 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/. + +//! This integration test should model how the RLB is used when embedded in another Rust application +//! (e.g. FOG/Firefox Desktop). +//! +//! We write a single test scenario per file to avoid any state keeping across runs +//! (different files run as different processes). + +mod common; + +use glean::Configuration; + +/// Some user metrics. +mod metrics { + use glean::private::*; + use glean::{Lifetime, TimeUnit}; + use glean_core::CommonMetricData; + use once_cell::sync::Lazy; + + #[allow(non_upper_case_globals)] + pub static initialization: Lazy<TimespanMetric> = Lazy::new(|| { + TimespanMetric::new( + CommonMetricData { + name: "initialization".into(), + category: "sample".into(), + send_in_pings: vec!["validation".into()], + lifetime: Lifetime::Ping, + disabled: false, + ..Default::default() + }, + TimeUnit::Nanosecond, + ) + }); +} + +mod pings { + use glean::private::PingType; + use once_cell::sync::Lazy; + + #[allow(non_upper_case_globals)] + pub static validation: Lazy<PingType> = + Lazy::new(|| glean::private::PingType::new("validation", true, true, vec![])); +} + +/// Test scenario: A clean run +/// +/// The app is initialized, in turn Glean gets initialized without problems. +/// Some data is recorded (before and after initialization). +/// And later the whole process is shutdown. +#[test] +fn simple_lifecycle() { + common::enable_test_logging(); + + metrics::initialization.start(); + + // Create a custom configuration to use a validating uploader. + let dir = tempfile::tempdir().unwrap(); + let tmpname = dir.path().to_path_buf(); + + let cfg = Configuration { + data_path: tmpname, + application_id: "firefox-desktop".into(), + upload_enabled: true, + max_events: None, + delay_ping_lifetime_io: false, + server_endpoint: Some("invalid-test-host".into()), + uploader: None, + use_core_mps: false, + }; + common::initialize(cfg); + + metrics::initialization.stop(); + + // This would never be called outside of tests, + // but it's the only way we can really test it's working right now. + assert!(metrics::initialization.test_get_value(None).is_some()); + + pings::validation.submit(None); + assert!(metrics::initialization.test_get_value(None).is_none()); + + glean::shutdown(); +} |