// 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 serde_json::json; use glean_core::metrics::*; use glean_core::storage::StorageManager; use glean_core::{CommonMetricData, Lifetime}; #[test] fn snapshot_returns_none_if_nothing_is_recorded_in_the_store() { let (glean, _t) = new_glean(None); assert!(StorageManager .snapshot(glean.storage(), "unknown_store", true) .is_none()) } #[test] fn can_snapshot() { let (glean, _t) = new_glean(None); let local_metric = StringMetric::new(CommonMetricData { name: "can_snapshot_local_metric".into(), category: "local".into(), send_in_pings: vec!["store1".into()], ..Default::default() }); local_metric.set_sync(&glean, "snapshot 42"); assert!(StorageManager .snapshot(glean.storage(), "store1", true) .is_some()) } #[test] fn snapshot_correctly_clears_the_stores() { let (glean, _t) = new_glean(None); let store_names: Vec = vec!["store1".into(), "store2".into()]; let metric = CounterMetric::new(CommonMetricData { name: "metric".into(), category: "telemetry".into(), send_in_pings: store_names, disabled: false, lifetime: Lifetime::Ping, ..Default::default() }); metric.add_sync(&glean, 1); // Get the snapshot from "store1" and clear it. let snapshot = StorageManager.snapshot(glean.storage(), "store1", true); assert!(snapshot.is_some()); // Check that getting a new snapshot for "store1" returns an empty store. assert!(StorageManager .snapshot(glean.storage(), "store1", false) .is_none()); // Check that we get the right data from both the stores. Clearing "store1" must // not clear "store2" as well. let snapshot2 = StorageManager.snapshot(glean.storage(), "store2", true); assert!(snapshot2.is_some()); } #[test] fn storage_is_thread_safe() { use std::sync::{Arc, Barrier, Mutex}; use std::thread; let (glean, _t) = new_glean(None); let glean = Arc::new(Mutex::new(glean)); let threadsafe_metric = CounterMetric::new(CommonMetricData { name: "threadsafe".into(), category: "global".into(), send_in_pings: vec!["store1".into(), "metrics".into()], ..Default::default() }); let threadsafe_metric = Arc::new(threadsafe_metric); let barrier = Arc::new(Barrier::new(2)); let c = barrier.clone(); let threadsafe_metric_clone = threadsafe_metric.clone(); let glean_clone = glean.clone(); let child = thread::spawn(move || { threadsafe_metric_clone.add_sync(&glean_clone.lock().unwrap(), 1); c.wait(); threadsafe_metric_clone.add_sync(&glean_clone.lock().unwrap(), 1); }); threadsafe_metric.add_sync(&glean.lock().unwrap(), 1); barrier.wait(); threadsafe_metric.add_sync(&glean.lock().unwrap(), 1); child.join().unwrap(); let snapshot = StorageManager .snapshot_as_json(glean.lock().unwrap().storage(), "store1", true) .unwrap(); assert_eq!(json!({"counter": { "global.threadsafe": 4 }}), snapshot); }