Merge pull request #44686 from nvasilevski/flunk-if-test-isnt-using-savepoint-transaction

[Tests only] Flunk if test is not using SavepointTransaction
This commit is contained in:
Matthew Draper 2022-03-30 15:54:08 +10:30 committed by GitHub
commit 89e3df569c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -52,7 +52,9 @@ class Bit < ActiveRecord::Base
thread = Thread.new do
with_warning_suppression do
Sample.transaction(isolation: :serializable, requires_new: false) do
make_parent_transaction_dirty
Sample.transaction(requires_new: true) do
assert_current_transaction_is_savepoint_transaction
before.wait
Sample.create value: Sample.sum(:value)
after.wait
@ -64,7 +66,9 @@ class Bit < ActiveRecord::Base
begin
with_warning_suppression do
Sample.transaction(isolation: :serializable, requires_new: false) do
make_parent_transaction_dirty
Sample.transaction(requires_new: true) do
assert_current_transaction_is_savepoint_transaction
before.wait
Sample.create value: Sample.sum(:value)
after.wait
@ -98,8 +102,10 @@ class Bit < ActiveRecord::Base
with_warning_suppression do
start_right.wait
Sample.transaction(isolation: :serializable, requires_new: false) do
make_parent_transaction_dirty
assert_raises(ActiveRecord::SerializationFailure) do
Sample.transaction(requires_new: true) do
assert_current_transaction_is_savepoint_transaction
Sample.create value: 3
commit_left.set
finish_right.wait(2)
@ -128,7 +134,9 @@ class Bit < ActiveRecord::Base
thread = Thread.new do
connections.add Sample.connection
Sample.transaction(requires_new: false) do
make_parent_transaction_dirty
Sample.transaction(requires_new: true) do
assert_current_transaction_is_savepoint_transaction
s1.lock!
barrier.wait
s2.update value: 1
@ -139,7 +147,9 @@ class Bit < ActiveRecord::Base
begin
connections.add Sample.connection
Sample.transaction(requires_new: false) do
make_parent_transaction_dirty
Sample.transaction(requires_new: true) do
assert_current_transaction_is_savepoint_transaction
s2.lock!
barrier.wait
s1.update value: 2
@ -163,8 +173,10 @@ class Bit < ActiveRecord::Base
thread = Thread.new do
Sample.transaction(requires_new: false) do
make_parent_transaction_dirty
begin
Sample.transaction(requires_new: true) do
assert_current_transaction_is_savepoint_transaction
s1.lock!
barrier.wait
s2.update value: 4
@ -178,8 +190,10 @@ class Bit < ActiveRecord::Base
begin
Sample.transaction(requires_new: false) do
make_parent_transaction_dirty
begin
Sample.transaction(requires_new: true) do
assert_current_transaction_is_savepoint_transaction
s2.lock!
barrier.wait
s1.update value: 3
@ -206,5 +220,19 @@ def with_warning_suppression
ActiveRecord::Base.clear_active_connections!
ActiveRecord::Base.connection.client_min_messages = log_level
end
# These tests are coordinating a controlled sequence of accesses to rows in `samples` table under serializable isolation.
# We need to run a query to dirty our transaction, but must avoid touching `samples` rows
# because otherwise our no-op query becomes an active participant of the test setup
def make_parent_transaction_dirty
Bit.take
end
def assert_current_transaction_is_savepoint_transaction
current_transaction = Sample.connection.current_transaction
unless current_transaction.is_a?(ActiveRecord::ConnectionAdapters::SavepointTransaction)
flunk("current transaction is not a savepoint transaction")
end
end
end
end