Skip to content

Commit

Permalink
add locking functionality to the TestMetrics struct
Browse files Browse the repository at this point in the history
  • Loading branch information
jeddai committed Oct 6, 2023
1 parent 1b8a408 commit 783ac66
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::tests::stateful::helpers::{reset_and_lock_glean, TestMetrics};
fn test_null_client() -> Result<()> {
use crate::NimbusClient;

let _guard = reset_and_lock_glean();
let metrics = TestMetrics::new();
let _ = env_logger::try_init();

let tmp_dir = tempfile::tempdir()?;
Expand All @@ -25,7 +25,7 @@ fn test_null_client() -> Result<()> {
tmp_dir.path(),
None,
aru,
Box::new(TestMetrics),
Box::new(metrics),
)?;
client.fetch_experiments()?;
client.apply_pending_experiments()?;
Expand Down
86 changes: 51 additions & 35 deletions components/nimbus/src/tests/stateful/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,46 +34,62 @@ impl GetExtraKey for RecordedEvent {

static METRICS_SINGLE_THREAD_MUTEX: Mutex<()> = Mutex::new(());

/// This method does two things:
/// 1. It resets Glean
/// 2. It locks a static Mutex and returns its guard
/// A Rust implementation of the MetricsHandler trait
/// Used to test recording of Glean metrics across the FFI within Rust
///
/// The purpose of the latter is so it can be used as such at the beginning of a test:
/// ```rust
/// let _guard = reset_and_lock_glean();
/// ```
/// and it will lock the Mutex so no other tests that use Glean can run at the same time.
pub fn reset_and_lock_glean<'a>() -> MutexGuard<'a, ()> {
let lock = match METRICS_SINGLE_THREAD_MUTEX.lock() {
Ok(l) => l,
Err(poisoned) => poisoned.into_inner(),
};
let dir = tempfile::tempdir().unwrap();
/// *NOTE: Use this struct's `new` method when instantiating it to lock the Glean store*
pub struct TestMetrics<'a> {
_lock: Option<MutexGuard<'a, ()>>,
}

impl<'a> TestMetrics<'a> {
/// This struct does two things on initialization:
/// 1. It resets Glean
/// 2. It locks a static Mutex and hold onto its guard
///
/// The purpose of the latter is so it can be used as such at the beginning of a test:
/// ```rust
/// let metrics = TestMetrics::new();
/// ```
/// and it will lock the Mutex so no other tests that use Glean can run at the same time.
///
/// *NOTE: Cloned copies of TestMetrics objects do not lock the Mutex*
pub fn new() -> Self {
let lock = match METRICS_SINGLE_THREAD_MUTEX.lock() {
Ok(l) => l,
Err(poisoned) => poisoned.into_inner(),
};
let dir = tempfile::tempdir().unwrap();

let cfg = glean::Configuration {
data_path: dir.path().clone().to_path_buf(),
application_id: "app-id".into(),
upload_enabled: true,
server_endpoint: Some("invalid-test-host".into()),
max_events: None,
delay_ping_lifetime_io: false,
uploader: None,
use_core_mps: false,
trim_data_to_registered_pings: false,
log_level: None,
rate_limit: None,
enable_event_timestamps: false,
};
let client_info = glean::ClientInfoMetrics::unknown();
glean::test_reset_glean(cfg, client_info, true);
Self { _lock: Some(lock) }
}
}

let cfg = glean::Configuration {
data_path: dir.path().clone().to_path_buf(),
application_id: "app-id".into(),
upload_enabled: true,
server_endpoint: Some("invalid-test-host".into()),
max_events: None,
delay_ping_lifetime_io: false,
uploader: None,
use_core_mps: false,
trim_data_to_registered_pings: false,
log_level: None,
rate_limit: None,
enable_event_timestamps: false,
};
let client_info = glean::ClientInfoMetrics::unknown();
glean::test_reset_glean(cfg, client_info, true);
lock
impl<'a> Clone for TestMetrics<'a> {
fn clone(&self) -> Self {
Self { _lock: None }
}
}

/// A Rust implementation of the MetricsHandler trait
/// Used to test recording of Glean metrics across the FFI within Rust
pub struct TestMetrics;
unsafe impl<'a> Send for TestMetrics<'a> {}

impl MetricsHandler for TestMetrics {
impl<'a> MetricsHandler for TestMetrics<'a> {
fn record_enrollment_statuses(&self, enrollment_status_extras: Vec<EnrollmentStatusExtraDef>) {
for extra in enrollment_status_extras {
enrollment_status.record(EnrollmentStatusExtra::from(extra));
Expand Down
Loading

0 comments on commit 783ac66

Please sign in to comment.