Skip to content

Commit c661a03

Browse files
committed
test: stop stripping the SQLite busy handler
The doctor and synchronous invocation suites each simulated immediate lock failure by writing PRAGMA busy_timeout back over itself, which left the pooled connection with no busy handler and made later concurrent tests fail with SQLite3::BusyException. Share one helper that suspends and correctly restores the configured busy wait.
1 parent e015c6a commit c661a03

3 files changed

Lines changed: 27 additions & 31 deletions

File tree

test/database_test_helper.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,31 @@ class ActiveSupport::TestCase
5656
SolidObjects::Process.delete_all
5757
SolidObjectsTestDomainRecord.delete_all
5858
end
59+
60+
def with_immediate_sqlite_lock_failure(&block)
61+
SolidObjects::Record.connection_pool.with_connection do |connection|
62+
suspend_sqlite_busy_wait(connection, &block)
63+
end
64+
end
65+
66+
def suspend_sqlite_busy_wait(connection)
67+
database_adapter = SolidObjects.database_adapter
68+
database_adapter.define_singleton_method(:configured_busy_handler_timeout) { |_connection| 0 }
69+
connection.raw_connection.busy_handler_timeout = 0
70+
yield
71+
ensure
72+
database_adapter.singleton_class.send(:remove_method, :configured_busy_handler_timeout)
73+
connection.raw_connection.busy_handler_timeout = configured_sqlite_busy_handler_timeout
74+
end
75+
76+
def configured_sqlite_busy_handler_timeout
77+
SolidObjects::Record
78+
.connection_pool
79+
.db_config
80+
.configuration_hash
81+
.fetch(:timeout, 5_000)
82+
.to_i
83+
end
5984
end
6085

6186
Minitest.after_run do

test/integration/doctor_test.rb

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class DoctorTest < ActiveSupport::TestCase
5252
skip unless SolidObjects::Record.connection.adapter_name.match?(/sqlite/i)
5353
lock = hold_sqlite_write_lock
5454

55-
report = without_sqlite_busy_wait { SolidObjects::Doctor.new.call }
55+
report = with_immediate_sqlite_lock_failure { SolidObjects::Doctor.new.call }
5656

5757
refute report.healthy?
5858
assert_equal :fail, report.check(:sync_round_trip).status
@@ -171,16 +171,6 @@ def hold_sqlite_write_lock
171171
[ thread, release ]
172172
end
173173

174-
def without_sqlite_busy_wait
175-
SolidObjects::Record.connection_pool.with_connection do |connection|
176-
previous_timeout = connection.select_value("PRAGMA busy_timeout").to_i
177-
connection.execute("PRAGMA busy_timeout = 0")
178-
yield
179-
ensure
180-
connection.execute("PRAGMA busy_timeout = #{previous_timeout}") if previous_timeout
181-
end
182-
end
183-
184174
def release_sqlite_write_lock(lock)
185175
thread, release = lock
186176
release << true

test/integration/synchronous_invocation_test.rb

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ def invoke_with_immediate_sqlite_lock_failure(message_reference)
806806
attempts += 1 if process_write?(event.payload)
807807
end
808808
SolidObjects::Record.connection_pool.with_connection do |connection|
809-
with_immediate_sqlite_lock_failure(connection) do
809+
suspend_sqlite_busy_wait(connection) do
810810
started_at = monotonic_now
811811
error = capture_exception do
812812
SolidObjects::SynchronousInvocation.new.call(message_reference, timeout: 0.1)
@@ -823,25 +823,6 @@ def invoke_with_immediate_sqlite_lock_failure(message_reference)
823823
captured
824824
end
825825

826-
def with_immediate_sqlite_lock_failure(connection)
827-
database_adapter = SolidObjects.database_adapter
828-
database_adapter.define_singleton_method(:configured_busy_handler_timeout) { |_connection| 0 }
829-
connection.raw_connection.busy_handler_timeout = 0
830-
yield
831-
ensure
832-
database_adapter.singleton_class.send(:remove_method, :configured_busy_handler_timeout)
833-
connection.raw_connection.busy_handler_timeout = configured_busy_handler_timeout
834-
end
835-
836-
def configured_busy_handler_timeout
837-
SolidObjects::Record
838-
.connection_pool
839-
.db_config
840-
.configuration_hash
841-
.fetch(:timeout, 5_000)
842-
.to_i
843-
end
844-
845826
def process_write?(payload)
846827
payload.fetch(:sql).match?(/\A(?:INSERT|UPDATE)/) &&
847828
payload.fetch(:sql).include?(SolidObjects::Process.table_name)

0 commit comments

Comments
 (0)