Skip to content

Fix the Rails 7.1 unrestorable busy wait test - #81

Open
cardmagic wants to merge 1 commit into
mainfrom
fix/rails-71-busy-wait-test
Open

cardmagic wants to merge 1 commit into
mainfrom
fix/rails-71-busy-wait-test

Conversation

@cardmagic

Copy link
Copy Markdown
Owner

Summary

test_sync_leaves_an_unrestorable_busy_wait_alone failed on Rails 7.1 when it ran before any other test had touched its connection. CI run 35874660739 failed this way, and seed 11785 fails every time on main.

The test checks that a sync call leaves alone a busy wait that the adapter cannot read back. It stubs configured_busy_handler_timeout to nil, so the adapter reads PRAGMA busy_timeout. The test assumed that its connection already had a Ruby busy handler, which PRAGMA busy_timeout reads as 0:

Connection PRAGMA busy_timeout
New, Rails 7.1.6 5000 (SQLite's own wait)
New, Rails 8.1.3.1 0 (Ruby busy handler)
After busy_handler_timeout= 0

On a new Rails 7.1 connection, the adapter correctly took the restorable path and put back SQLite's own wait. That wait does not release the Ruby VM lock, so the releaser thread in write_while_write_lock_is_briefly_held could not release the write lock. The write raised SQLite3::BusyException after the full 5 s.

The test now installs the Ruby busy handler on its connection and asserts that PRAGMA busy_timeout reads 0. It checks the unrestorable path on every Rails version and in every test order. Only the test changes; the adapter behaved correctly.

Compatibility

Test-only change. No runtime, API, or migration effect. Not applicable to solid-objects-js, which has no Rails connection or Ruby VM lock.

Validation

  • Before the fix, Rails 7.1.6, test alone: ActiveRecord::StatementInvalid: SQLite3::BusyException: database is locked at write_while_write_lock_is_briefly_held after about 6 s.
  • Before the fix, Rails 7.1.6, bundle exec rake test TESTOPTS="--seed=11785": 797 runs, 1 error (this test, BusyException).
  • After the fix, Rails 7.1.6: the test passes alone. Seed 11785 and random seeds 38098 and 37363 each ran 797 tests with 0 failures/errors and 28 skips.
  • Reversal: removing return nil unless pragma_timeout.positive? from Sqlite#restorable_busy_wait makes the adapter overwrite the handler. The changed test then fails with SQLite3::BusyException on Rails 7.1.6 and 8.1.3.1.
  • Rails 8.1.3.1, bundle exec rake: 797 runs, 2,707 assertions, 0 failures/errors, 28 skips. Standard, RuboCop, RBS validation, Steep, and Brakeman passed.

Rails 7.1 runs used RAILS_VERSION=7.1 bundle lock --update --local, as the CI compatibility job does.

The unrestorable busy wait test assumed that its connection already had
a Ruby busy handler, which PRAGMA busy_timeout reads as 0. Rails 7.2
and later install that handler on each new connection, and an earlier
sync call installs it too. A new Rails 7.1 connection instead uses
SQLite's own busy_timeout, which PRAGMA reads as 5000.

When the test ran first on Rails 7.1, the adapter correctly took the
restorable path and put back SQLite's own wait. That wait holds the
Ruby VM lock, so the releaser thread could not release the write lock,
and the write raised SQLite3::BusyException after 5 s. Seed 11785
failed every time; CI run 35874660739 failed the same way.

Install the handler in the test and assert that PRAGMA reads 0, so the
test checks the unrestorable path on every Rails version and order.
@greptile-apps

greptile-apps Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Low risk] Fixes a test for Rails 7.1 compatibility.

The PR appears safe to merge.

Summary

The PR makes the SQLite synchronous-invocation test install a Ruby busy handler explicitly, then confirms that PRAGMA busy_timeout is zero before exercising the unrestorable-wait path. It changes only the test.

Reviews (1) · Last reviewed commit: "test: install the busy handler the test ..."

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