fix: share one language-test mutex; read the OFX marker via Win32 env

i18n: test_lock() and lang_test_lock() used to be TWO different static
mutexes, so the i18n tests and the ~30 app/actions/dialogs tests that
mutate the language global never excluded each other. Windows thread
scheduling exposed the race: tr_falls_back_to_english_then_the_key got
the English value because another test flipped the language mid-assert.
Both entry points now lock the same mutex.

oak_test_plugin.c: on Windows the plugin DLL has its own CRT
environment block, so getenv() never sees what the host's
std::env::set_var set via SetEnvironmentVariableW — the interact
lifecycle test's marker file stayed empty ("lifecycle actions
missing: []"). Read the marker path through GetEnvironmentVariableA
on _WIN32.
This commit is contained in:
2026-08-21 13:36:19 +08:00
parent d9dc16ec26
commit 3efdee5a10
2 changed files with 28 additions and 5 deletions
+6 -3
View File
@@ -425,11 +425,14 @@ mod tests {
/// Serializes tests that mutate the language global / HOME.
#[cfg(test)]
pub(crate) fn test_lock() -> std::sync::MutexGuard<'static, ()> {
static LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
LOCK.lock().unwrap_or_else(|e| e.into_inner())
lang_test_lock().lock().unwrap_or_else(|e| e.into_inner())
}
/// Compatibility alias used by the app/actions test modules.
/// Compatibility alias used by the app/actions test modules. Both entry
/// points MUST share the one static mutex: with two separate mutexes the
/// i18n tests and the app/actions tests do not exclude each other, and
/// the language global races (observed as a Windows-only CI failure
/// where `tr` returned the English value mid-test).
#[cfg(test)]
pub(crate) fn lang_test_lock() -> &'static std::sync::Mutex<()> {
static LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());