A different prefs::tests::put_prefs_* test fails on roughly every other full cargo test run (seen on master 79b339a and on the #155 / #156 branches):
thread 'prefs::tests::put_prefs_…' panicked at src/database/mod.rs:193:6:
set sqlite pragmas: … database is locked
Observed failing: put_prefs_requires_auth, put_prefs_owner_defaults_null_clears, put_prefs_valid_display_tz_persists, put_prefs_partial_update_leaves_omitted_fields_untouched, put_prefs_owner_defaults_set_and_persist. They always pass in isolation (cargo test --lib prefs::tests). Worse on a fresh auth.db (e.g. a new worktree). Because cargo stops at the first failing test binary, a flake also hides the integration tests unless --no-fail-fast is used.
The WAL switch needs a lock, but it runs beforebusy_timeout is set, so it uses SQLite's default timeout of 0 and fails immediately on any contention instead of waiting. AppState::test_state() opens ~10 DAO connections to the one shared DATABASE_URL file, and six test modules build it in parallel (files ×4, video ×5, ai::handlers ×3, prefs, memories, reels). ai::handlers::turn_replay_tests already works around this with a module-local DB_INIT mutex, which doesn't cover the other modules.
Fix direction
Set busy_timeout first in connect() (before journal_mode = WAL), so the switch waits out contention. That fixes it at the source for every test module (and for startup), and the DB_INIT workaround can probably go. If it doesn't fully fix it, fall back to a crate-wide init guard inside test_state() rather than per-module mutexes.
Acceptance
cargo test passes repeatedly (e.g. 10 consecutive full runs) with no set sqlite pragmas panic
Includes a fresh-DB run (delete the test auth.db first)
DB_INIT removed if the root fix makes it redundant
## Problem
A different `prefs::tests::put_prefs_*` test fails on roughly every other full `cargo test` run (seen on master `79b339a` and on the #155 / #156 branches):
thread 'prefs::tests::put_prefs_…' panicked at src/database/mod.rs:193:6:
set sqlite pragmas: … database is locked
Observed failing: `put_prefs_requires_auth`, `put_prefs_owner_defaults_null_clears`, `put_prefs_valid_display_tz_persists`, `put_prefs_partial_update_leaves_omitted_fields_untouched`, `put_prefs_owner_defaults_set_and_persist`. They always pass in isolation (`cargo test --lib prefs::tests`). Worse on a fresh `auth.db` (e.g. a new worktree). Because cargo stops at the first failing test binary, a flake also hides the integration tests unless `--no-fail-fast` is used.
## Likely cause (unverified)
`database::connect()` runs one batch:
PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 5000;
...
The WAL switch needs a lock, but it runs **before** `busy_timeout` is set, so it uses SQLite's default timeout of 0 and fails immediately on any contention instead of waiting. `AppState::test_state()` opens ~10 DAO connections to the one shared `DATABASE_URL` file, and six test modules build it in parallel (files ×4, video ×5, ai::handlers ×3, prefs, memories, reels). `ai::handlers::turn_replay_tests` already works around this with a module-local `DB_INIT` mutex, which doesn't cover the other modules.
## Fix direction
Set `busy_timeout` first in `connect()` (before `journal_mode = WAL`), so the switch waits out contention. That fixes it at the source for every test module (and for startup), and the `DB_INIT` workaround can probably go. If it doesn't fully fix it, fall back to a crate-wide init guard inside `test_state()` rather than per-module mutexes.
## Acceptance
- [ ] `cargo test` passes repeatedly (e.g. 10 consecutive full runs) with no `set sqlite pragmas` panic
- [ ] Includes a fresh-DB run (delete the test `auth.db` first)
- [ ] `DB_INIT` removed if the root fix makes it redundant
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
A different
prefs::tests::put_prefs_*test fails on roughly every other fullcargo testrun (seen on master79b339aand on the #155 / #156 branches):Observed failing:
put_prefs_requires_auth,put_prefs_owner_defaults_null_clears,put_prefs_valid_display_tz_persists,put_prefs_partial_update_leaves_omitted_fields_untouched,put_prefs_owner_defaults_set_and_persist. They always pass in isolation (cargo test --lib prefs::tests). Worse on a freshauth.db(e.g. a new worktree). Because cargo stops at the first failing test binary, a flake also hides the integration tests unless--no-fail-fastis used.Likely cause (unverified)
database::connect()runs one batch:The WAL switch needs a lock, but it runs before
busy_timeoutis set, so it uses SQLite's default timeout of 0 and fails immediately on any contention instead of waiting.AppState::test_state()opens ~10 DAO connections to the one sharedDATABASE_URLfile, and six test modules build it in parallel (files ×4, video ×5, ai::handlers ×3, prefs, memories, reels).ai::handlers::turn_replay_testsalready works around this with a module-localDB_INITmutex, which doesn't cover the other modules.Fix direction
Set
busy_timeoutfirst inconnect()(beforejournal_mode = WAL), so the switch waits out contention. That fixes it at the source for every test module (and for startup), and theDB_INITworkaround can probably go. If it doesn't fully fix it, fall back to a crate-wide init guard insidetest_state()rather than per-module mutexes.Acceptance
cargo testpasses repeatedly (e.g. 10 consecutive full runs) with noset sqlite pragmaspanicauth.dbfirst)DB_INITremoved if the root fix makes it redundant🤖 Generated with Claude Code