fix(desktop): two independent CI flakes in the Rust suite - #19
Conversation
…sphrases The EFF short wordlist 2.0 holds one entry containing a hyphen (`yo-yo`). Drawn into a `-`-joined phrase it hides a word boundary: the phrase reads as one more word than it has, to a human retyping it and to anything counting the parts. That is what turned `Windows Rust` red on 3cabe10 — `generated_passphrase_clamps_word_count` saw 11 parts where it asked for 10. Both that test and `generated_passphrase_respects_word_count_and_separator` draw against real entropy, so it fires roughly one CI run in a hundred on any platform, not just Windows. Fixed in the generator rather than in the assertions: the draw loop now skips words containing the separator, so no caller can be handed a phrase whose separator count disagrees with its word count. Cost is ~0.001 bits per word. An empty separator delimits nothing, so nothing is excluded — without that guard the loop would spin forever, since `"".contains("")`.
|
User-visible too, not just a test artifact: the backup-password generator popover ( |
`relay::tests::oversized_hint_is_capped_in_relay_error_message_string`
drives a real 429 through `relay_error_message`, which arms the
process-wide `GATE_EXPIRY` for the 300s cap. It took neither the serial
lock the `relay_admission` tests use nor reset the gate afterwards, and
Rust runs tests in parallel threads.
A waiter parked on its own 2s expiry re-reads the static when it wakes,
so it adopted the 300s window:
concurrent_429_extends_the_window_for_parked_waiters
assertion `left == right` failed: waiter must respect the extension
armed mid-sleep (1s + 4s)
left: 300.001s
right: 5s
Fixed the contract rather than that one test: `test_support::lock_gate()`
returns an RAII guard that holds the lock and clears the gate on both
acquire and drop. A test can now neither inherit another's armed window
nor bequeath its own, and the "remember to reset at the end" step several
gate tests already skipped is gone.
Second, unrelated flake in the same suiteThe first CI run on this branch went red — but on a different test, and the passphrase tests passed ( 300s is
Fixed the contract, not the one offender:
|
What broke
Windows Rust (x86_64-pc-windows-msvc)failed on main @3cabe1078:Nothing platform-specific about it — the job just happened to lose the coin flip.
Root cause
The EFF short wordlist 2.0 has exactly one entry containing a hyphen:
generate_passphrase(n, "-")joins its draws with-, so a phrase holdingyo-yosplits inton + 1parts. Two tests assertphrase.split(separator).count() == count, and both draw from real OS entropy — combined odds ≈ 1% per CI run (~0.77% from the 10-word draw, ~0.23% from the 3-word one). It has nothing to do with the desktop change that commit carried.Fix
At the shared function, not at the assertions: the rejection-sampling draw loop skips any word containing the separator, so no caller can be handed a phrase whose separator count disagrees with its word count — including the human retyping it. Dropping 1 of 1296 words costs ~0.001 bits per word.
An empty separator delimits nothing and is explicitly exercised by the existing tests, so it excludes nothing — load-bearing, since
"".contains("")istrueand thewhile chosen.len() < word_countloop would otherwise never terminate.Test plan
hyphenated_wordlist_entry_is_excluded_from_hyphen_joined_phrases— pins the behaviour per separator and asserts the wordlist's hyphenated set is exactly["yo-yo"], so a future entry fails loudly instead of resurrecting the flake.generated_phrases_never_hide_a_word_boundary— 512 × 10-word draws through the real generator. Verified red against the unfixed draw loop (left: 11, right: 10), green with it.cargo test --lib key_backupfromdesktop/src-tauri: 30 passed, 0 failed.cargo fmt --checkclean;cargo clippy --lib --all-targets -- -D warningsclean.