Skip to content

fix(tui): isolate i18n locale in tests to eliminate parallel flake#152

Merged
p1024k merged 1 commit into
developfrom
fix/i18n-test-locale-isolation
Jun 18, 2026
Merged

fix(tui): isolate i18n locale in tests to eliminate parallel flake#152
p1024k merged 1 commit into
developfrom
fix/i18n-test-locale-isolation

Conversation

@p1024k

@p1024k p1024k commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Problem

The process-global rust_i18n locale caused flaky failures under parallel test execution (e.g. render_expired_badge_in_list, sync_indicator_ascii_fallbacks). These tests held no locale guard, so they could read a locale mutated by a concurrent zh-CN guard holder and assert the wrong localized text.

Root cause

LocaleGuard serialized only guard holders via a std::sync::Mutex. Tests that depended on the locale without holding a guard raced against those that did — and the non-reentrant mutex made nesting (manual guard + helper guard) deadlock.

Fix

  • i18n: LOCALE_LOCKparking_lot::ReentrantMutex — guards can nest without deadlock; concurrent locale-sensitive tests still serialize across threads.
  • list tests: render_snapshot / render_buffer gain _locale variants that hold an internal LocaleGuard (default delegates to "en"). The two zh-CN timestamp tests migrate to render_buffer_locale(.., "zh-CN").
  • New tests: a deterministic concurrent-isolation test (en renders stay correct under concurrent zh-CN guard holders) + a localized-helper contract test (en Expired / zh-CN 已过期).
  • 85 locale-dependent tests across 14 files get LocaleGuard::en().

Verification (CI gate, all green)

  • cargo fmt --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test (2595 + all integration / snapshot / e2e) — run 3×, stable ✅
  • cargo build --release --bin ok
  • cargo audit — 0 vulnerabilities ✅ (1 pre-existing allowed aes yank via keepass, unrelated)

render_expired_badge_in_list and sync_indicator_ascii_fallbacks are now stable across runs.

Test-infrastructure only; not user-visible, so no version bump.

The process-global rust_i18n locale caused flaky failures under parallel
test execution. Tests such as render_expired_badge_in_list and
sync_indicator_ascii_fallbacks held no locale guard, so they could read
a locale mutated by a concurrent zh-CN guard holder and assert the wrong
localized text.

Root cause: LocaleGuard serialized only guard holders via a std::sync::Mutex.
Tests that depended on the locale without holding a guard raced against
those that did, and the non-reentrant mutex precluded nesting.

Changes:
- i18n: LOCALE_LOCK is now a parking_lot::ReentrantMutex so a manual
  LocaleGuard can nest inside a render-helper guard without deadlocking.
- list tests: render_snapshot/render_buffer gain _locale variants that
  hold an internal LocaleGuard (default delegates to "en"). The two zh-CN
  timestamp tests are migrated to render_buffer_locale(.., "zh-CN").
- Add a deterministic concurrent-isolation test (proves en renders stay
  correct under concurrent zh-CN guard holders) and a localized-helper
  contract test (en "Expired" / zh-CN "已过期").
- Add LocaleGuard::en() to 85 locale-dependent tests across 14 files that
  previously had no guard.

Verified: cargo fmt --check, cargo clippy --all-targets -- -D warnings,
cargo test (2595 + all integration/snapshot/e2e) run 3x, cargo build
--release --bin ok, cargo audit (0 vulnerabilities).
render_expired_badge_in_list and sync_indicator_ascii_fallbacks are now
stable across runs.
@p1024k p1024k merged commit c0b1e0a into develop Jun 18, 2026
1 check passed
@p1024k p1024k deleted the fix/i18n-test-locale-isolation branch June 18, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant