fix: thread-local CRDT and content store for test isolation

Tests shared a global CRDT singleton and content store HashMap, causing
flaky failures when parallel tests wrote items that polluted each
other's assertions. 3-5 random test failures per run.

Both CRDT_STATE and CONTENT_STORE now use thread_local! in test mode
so each test thread gets its own isolated instance. Production code
is unchanged — it still uses the global OnceLock singletons.

Also fixed 3 tests (create_story_writes_correct_content,
next_item_number_increments_from_existing_bugs,
next_item_number_scans_archived_too) that relied on leaked state
from other tests — they now write to the content store explicitly.

Result: 1902 passed, 0 failed across 5 consecutive runs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dave
2026-04-11 13:02:09 +00:00
parent dd53870c59
commit eea54ca616
4 changed files with 111 additions and 42 deletions
+7
View File
@@ -269,22 +269,29 @@ mod tests {
#[test]
fn next_item_number_increments_from_existing_bugs() {
crate::db::ensure_content_store();
let tmp = tempfile::tempdir().unwrap();
let backlog = tmp.path().join(".huskies/work/1_backlog");
fs::create_dir_all(&backlog).unwrap();
fs::write(backlog.join("1_bug_crash.md"), "").unwrap();
fs::write(backlog.join("3_bug_another.md"), "").unwrap();
// Also write to content store so next_item_number sees them.
crate::db::write_item_with_content("1_bug_crash", "1_backlog", "---\nname: Crash\n---\n");
crate::db::write_item_with_content("3_bug_another", "1_backlog", "---\nname: Another\n---\n");
assert!(super::super::next_item_number(tmp.path()).unwrap() >= 4);
}
#[test]
fn next_item_number_scans_archived_too() {
crate::db::ensure_content_store();
let tmp = tempfile::tempdir().unwrap();
let backlog = tmp.path().join(".huskies/work/1_backlog");
let archived = tmp.path().join(".huskies/work/5_done");
fs::create_dir_all(&backlog).unwrap();
fs::create_dir_all(&archived).unwrap();
fs::write(archived.join("5_bug_old.md"), "").unwrap();
// Also write to content store so next_item_number sees it.
crate::db::write_item_with_content("5_bug_old", "5_done", "---\nname: Old Bug\n---\n");
assert!(super::super::next_item_number(tmp.path()).unwrap() >= 6);
}