fix(core): cfg-gate test override + restore TEST_OVERRIDE on panic
TEST_OVERRIDE and test_get_override are now #[cfg(test)]-gated and the read in probe_power_state is wrapped in a #[cfg(test)] block, so test scaffolding doesn't compile into production builds. with_override now uses a drop-guard pattern so a panic inside body still resets TEST_OVERRIDE, preventing stale state from leaking into subsequent tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -64,6 +64,7 @@ fn read_trimmed(path: &Path) -> Option<String> {
|
||||
fs::read_to_string(path).ok().map(|s| s.trim().to_owned())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
use std::sync::Mutex;
|
||||
|
||||
/// Top-level power-state probe.
|
||||
@@ -80,6 +81,7 @@ use std::sync::Mutex;
|
||||
///
|
||||
/// (TTL cache is added in Task 1.4.)
|
||||
pub fn probe_power_state() -> PowerState {
|
||||
#[cfg(test)]
|
||||
if let Some(state) = test_get_override() {
|
||||
return state;
|
||||
}
|
||||
@@ -111,14 +113,29 @@ fn platform_probe() -> PowerState {
|
||||
|
||||
// In-process override slot. Tests must use `with_override` (below) to
|
||||
// set it; production code never writes to this. Read on every probe.
|
||||
#[cfg(test)]
|
||||
static TEST_OVERRIDE: Mutex<Option<PowerState>> = Mutex::new(None);
|
||||
|
||||
#[cfg(test)]
|
||||
fn test_get_override() -> Option<PowerState> {
|
||||
*TEST_OVERRIDE.lock().expect("power test override mutex poisoned")
|
||||
}
|
||||
|
||||
/// Drop-guard that resets `TEST_OVERRIDE` to `None` on drop (including on unwind).
|
||||
/// This prevents a panicking test body from leaking stale override state into
|
||||
/// subsequent tests.
|
||||
#[cfg(test)]
|
||||
struct OverrideGuard;
|
||||
|
||||
#[cfg(test)]
|
||||
impl Drop for OverrideGuard {
|
||||
fn drop(&mut self) {
|
||||
*TEST_OVERRIDE.lock().expect("power test override mutex poisoned") = None;
|
||||
}
|
||||
}
|
||||
|
||||
/// Run `body` with the in-process override set to `state`. Restores
|
||||
/// the previous override (always `None` in practice) on return.
|
||||
/// `TEST_OVERRIDE` to `None` on return, even if `body` panics.
|
||||
///
|
||||
/// Holds a dedicated `TEST_LOCK` mutex for the duration of the body,
|
||||
/// so override-using unit tests run serially with respect to each
|
||||
@@ -128,9 +145,8 @@ pub(crate) fn with_override<R>(state: Option<PowerState>, body: impl FnOnce() ->
|
||||
static TEST_LOCK: Mutex<()> = Mutex::new(());
|
||||
let _lock = TEST_LOCK.lock().expect("power TEST_LOCK poisoned");
|
||||
*TEST_OVERRIDE.lock().expect("power test override mutex poisoned") = state;
|
||||
let result = body();
|
||||
*TEST_OVERRIDE.lock().expect("power test override mutex poisoned") = None;
|
||||
result
|
||||
let _guard = OverrideGuard;
|
||||
body()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user