Revision control
Copy as Markdown
// 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 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<String> = 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);
}