Skip to content

Commit edce38b

Browse files
committed
Share test env lock across modules
1 parent 1f88221 commit edce38b

3 files changed

Lines changed: 58 additions & 104 deletions

File tree

src/main.rs

Lines changed: 3 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ mod external_events;
66
mod output;
77
mod processes;
88
mod state;
9+
#[cfg(test)]
10+
mod test_support;
911

1012
use std::path::PathBuf;
1113

@@ -346,59 +348,8 @@ mod tests {
346348
use crate::output::{
347349
format_output_prefix, normalize_internal_log_label, normalize_source_label,
348350
};
351+
use crate::test_support::RustLogGuard;
349352
use clap::Parser;
350-
use std::ffi::OsString;
351-
use std::sync::{Mutex, MutexGuard, OnceLock};
352-
353-
fn rust_log_lock() -> &'static Mutex<()> {
354-
static LOCK: OnceLock<Mutex<()>> = OnceLock::new();
355-
LOCK.get_or_init(|| Mutex::new(()))
356-
}
357-
358-
struct RustLogGuard {
359-
_lock: MutexGuard<'static, ()>,
360-
original: Option<OsString>,
361-
}
362-
363-
impl RustLogGuard {
364-
fn set(value: Option<&str>) -> Self {
365-
let lock = rust_log_lock().lock().expect("lock RUST_LOG test mutex");
366-
let original = std::env::var_os("RUST_LOG");
367-
match value {
368-
Some(value) => set_test_env_var("RUST_LOG", value),
369-
None => remove_test_env_var("RUST_LOG"),
370-
}
371-
Self {
372-
_lock: lock,
373-
original,
374-
}
375-
}
376-
}
377-
378-
impl Drop for RustLogGuard {
379-
fn drop(&mut self) {
380-
match &self.original {
381-
Some(value) => set_test_env_var("RUST_LOG", value),
382-
None => remove_test_env_var("RUST_LOG"),
383-
}
384-
}
385-
}
386-
387-
fn set_test_env_var(key: &str, value: impl AsRef<std::ffi::OsStr>) {
388-
// SAFETY: tests serialize all RUST_LOG mutation through `rust_log_lock`,
389-
// so no concurrent test can observe partially updated process-global state.
390-
unsafe {
391-
std::env::set_var(key, value);
392-
}
393-
}
394-
395-
fn remove_test_env_var(key: &str) {
396-
// SAFETY: tests serialize all RUST_LOG mutation through `rust_log_lock`,
397-
// so removing the variable cannot race with other tests here.
398-
unsafe {
399-
std::env::remove_var(key);
400-
}
401-
}
402353

403354
#[test]
404355
fn default_rust_log_uses_info_when_unset() {

src/processes.rs

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -984,64 +984,13 @@ fn timeout_error(name: &str, probe: &ProbeSpec) -> anyhow::Error {
984984
mod tests {
985985
use super::*;
986986
use crate::config::{OutputExtract, ProbeSpec};
987+
use crate::test_support::RustLogGuard;
987988
use serde_json::Value;
988-
use std::ffi::OsString;
989989
use std::sync::Arc;
990-
use std::sync::{Mutex as StdMutex, MutexGuard, OnceLock};
991990
use std::time::{SystemTime, UNIX_EPOCH};
992991
use tokio::io::AsyncReadExt;
993992
use tokio::sync::Mutex;
994993

995-
fn rust_log_lock() -> &'static StdMutex<()> {
996-
static LOCK: OnceLock<StdMutex<()>> = OnceLock::new();
997-
LOCK.get_or_init(|| StdMutex::new(()))
998-
}
999-
1000-
struct RustLogGuard {
1001-
_lock: MutexGuard<'static, ()>,
1002-
original: Option<OsString>,
1003-
}
1004-
1005-
impl RustLogGuard {
1006-
fn set(value: Option<&str>) -> Self {
1007-
let lock = rust_log_lock().lock().expect("lock RUST_LOG test mutex");
1008-
let original = std::env::var_os("RUST_LOG");
1009-
match value {
1010-
Some(value) => set_test_env_var("RUST_LOG", value),
1011-
None => remove_test_env_var("RUST_LOG"),
1012-
}
1013-
Self {
1014-
_lock: lock,
1015-
original,
1016-
}
1017-
}
1018-
}
1019-
1020-
impl Drop for RustLogGuard {
1021-
fn drop(&mut self) {
1022-
match &self.original {
1023-
Some(value) => set_test_env_var("RUST_LOG", value),
1024-
None => remove_test_env_var("RUST_LOG"),
1025-
}
1026-
}
1027-
}
1028-
1029-
fn set_test_env_var(key: &str, value: impl AsRef<std::ffi::OsStr>) {
1030-
// SAFETY: these tests serialize process-global env mutation through
1031-
// `rust_log_lock`, so no concurrent test observes a torn update.
1032-
unsafe {
1033-
std::env::set_var(key, value);
1034-
}
1035-
}
1036-
1037-
fn remove_test_env_var(key: &str) {
1038-
// SAFETY: these tests serialize process-global env mutation through
1039-
// `rust_log_lock`, so removing the variable does not race here.
1040-
unsafe {
1041-
std::env::remove_var(key);
1042-
}
1043-
}
1044-
1045994
fn unique_state_path() -> PathBuf {
1046995
let unique = SystemTime::now()
1047996
.duration_since(UNIX_EPOCH)

src/test_support.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use std::ffi::{OsStr, OsString};
2+
use std::sync::{Mutex, MutexGuard, OnceLock};
3+
4+
fn rust_log_lock() -> &'static Mutex<()> {
5+
static LOCK: OnceLock<Mutex<()>> = OnceLock::new();
6+
LOCK.get_or_init(|| Mutex::new(()))
7+
}
8+
9+
pub(crate) struct RustLogGuard {
10+
_lock: MutexGuard<'static, ()>,
11+
original: Option<OsString>,
12+
}
13+
14+
impl RustLogGuard {
15+
pub(crate) fn set(value: Option<&str>) -> Self {
16+
let lock = rust_log_lock().lock().expect("lock RUST_LOG test mutex");
17+
let original = std::env::var_os("RUST_LOG");
18+
match value {
19+
Some(value) => set_test_env_var("RUST_LOG", value),
20+
None => remove_test_env_var("RUST_LOG"),
21+
}
22+
Self {
23+
_lock: lock,
24+
original,
25+
}
26+
}
27+
}
28+
29+
impl Drop for RustLogGuard {
30+
fn drop(&mut self) {
31+
match &self.original {
32+
Some(value) => set_test_env_var("RUST_LOG", value),
33+
None => remove_test_env_var("RUST_LOG"),
34+
}
35+
}
36+
}
37+
38+
fn set_test_env_var(key: &str, value: impl AsRef<OsStr>) {
39+
// SAFETY: all test-time RUST_LOG mutation goes through the shared
40+
// `rust_log_lock`, so no concurrent unit test can race on this
41+
// process-global environment state.
42+
unsafe {
43+
std::env::set_var(key, value);
44+
}
45+
}
46+
47+
fn remove_test_env_var(key: &str) {
48+
// SAFETY: all test-time RUST_LOG mutation goes through the shared
49+
// `rust_log_lock`, so removing the variable cannot race with another
50+
// unit test in this process.
51+
unsafe {
52+
std::env::remove_var(key);
53+
}
54+
}

0 commit comments

Comments
 (0)