fix(core): serialise tuning env-var tests behind a lock
Without a lock, env_var_bypasses_clamps (set_var + remove_var) and matches_existing_clamp_when_no_clamps_apply (remove_var) race under cargo's parallel test runner. Task 2.2 will add another remove_var call, compounding the race. Adds a #[cfg(test)] static THREAD_ENV_LOCK and a closure-style with_thread_env_lock helper, mirroring power::with_override. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -63,24 +63,38 @@ pub fn inference_thread_count(_workload: Workload, _gpu_offloaded: bool) -> usiz
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
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<R>(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]
|
#[test]
|
||||||
fn matches_existing_clamp_when_no_clamps_apply() {
|
fn matches_existing_clamp_when_no_clamps_apply() {
|
||||||
// With no env override, no battery, no gpu_offload, helper
|
// With no env override, no battery, no gpu_offload, helper
|
||||||
// should return physical-core count clamped to [2, 8].
|
// should return physical-core count clamped to [2, 8].
|
||||||
// We can't pin physical exactly without mocking num_cpus; just
|
// We can't pin physical exactly without mocking num_cpus; just
|
||||||
// assert the result is in range.
|
// assert the result is in range.
|
||||||
std::env::remove_var("MAGNOTIA_INFERENCE_THREADS");
|
with_thread_env_lock(|| {
|
||||||
let n = inference_thread_count(Workload::Llm, false);
|
std::env::remove_var("MAGNOTIA_INFERENCE_THREADS");
|
||||||
assert!(n >= MIN_INFERENCE_THREADS && n <= MAX_INFERENCE_THREADS,
|
let n = inference_thread_count(Workload::Llm, false);
|
||||||
"got {n}, expected within [{MIN_INFERENCE_THREADS}, {MAX_INFERENCE_THREADS}]");
|
assert!(n >= MIN_INFERENCE_THREADS && n <= MAX_INFERENCE_THREADS,
|
||||||
|
"got {n}, expected within [{MIN_INFERENCE_THREADS}, {MAX_INFERENCE_THREADS}]");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn env_var_bypasses_clamps() {
|
fn env_var_bypasses_clamps() {
|
||||||
std::env::set_var("MAGNOTIA_INFERENCE_THREADS", "10");
|
with_thread_env_lock(|| {
|
||||||
let n = inference_thread_count(Workload::Llm, true);
|
std::env::set_var("MAGNOTIA_INFERENCE_THREADS", "10");
|
||||||
assert_eq!(n, 10);
|
let n = inference_thread_count(Workload::Llm, true);
|
||||||
std::env::remove_var("MAGNOTIA_INFERENCE_THREADS");
|
assert_eq!(n, 10);
|
||||||
|
std::env::remove_var("MAGNOTIA_INFERENCE_THREADS");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user