diff --git a/crates/core/src/tuning.rs b/crates/core/src/tuning.rs index dd2b742..70ec908 100644 --- a/crates/core/src/tuning.rs +++ b/crates/core/src/tuning.rs @@ -63,24 +63,38 @@ pub fn inference_thread_count(_workload: Workload, _gpu_offloaded: bool) -> usiz mod tests { use super::*; + /// Serialises tests that read/write `MAGNOTIA_INFERENCE_THREADS` so + /// they don't race under cargo's parallel test runner. + /// Mirrors the pattern used by `power::with_override`. + fn with_thread_env_lock(body: impl FnOnce() -> R) -> R { + use std::sync::Mutex; + static THREAD_ENV_LOCK: Mutex<()> = Mutex::new(()); + let _lock = THREAD_ENV_LOCK.lock().expect("tuning thread-env lock poisoned"); + body() + } + #[test] fn matches_existing_clamp_when_no_clamps_apply() { // With no env override, no battery, no gpu_offload, helper // should return physical-core count clamped to [2, 8]. // We can't pin physical exactly without mocking num_cpus; just // assert the result is in range. - std::env::remove_var("MAGNOTIA_INFERENCE_THREADS"); - let n = inference_thread_count(Workload::Llm, false); - assert!(n >= MIN_INFERENCE_THREADS && n <= MAX_INFERENCE_THREADS, - "got {n}, expected within [{MIN_INFERENCE_THREADS}, {MAX_INFERENCE_THREADS}]"); + with_thread_env_lock(|| { + std::env::remove_var("MAGNOTIA_INFERENCE_THREADS"); + let n = inference_thread_count(Workload::Llm, false); + assert!(n >= MIN_INFERENCE_THREADS && n <= MAX_INFERENCE_THREADS, + "got {n}, expected within [{MIN_INFERENCE_THREADS}, {MAX_INFERENCE_THREADS}]"); + }); } #[test] fn env_var_bypasses_clamps() { - std::env::set_var("MAGNOTIA_INFERENCE_THREADS", "10"); - let n = inference_thread_count(Workload::Llm, true); - assert_eq!(n, 10); - std::env::remove_var("MAGNOTIA_INFERENCE_THREADS"); + with_thread_env_lock(|| { + std::env::set_var("MAGNOTIA_INFERENCE_THREADS", "10"); + let n = inference_thread_count(Workload::Llm, true); + assert_eq!(n, 10); + std::env::remove_var("MAGNOTIA_INFERENCE_THREADS"); + }); } #[test]