Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3038d44

Browse files
committedNov 17, 2023
more re-entrancy tests / expectations
1 parent 398c30e commit 3038d44

File tree

1 file changed

+71
-2
lines changed

1 file changed

+71
-2
lines changed
 

‎spec/safe_statements_spec.rb

+71-2
Original file line numberDiff line numberDiff line change
@@ -3918,10 +3918,76 @@ def up
39183918
it "allows re-entrancy" do
39193919
migration.safely_acquire_lock_for_table(table_name) do
39203920
migration.safely_acquire_lock_for_table(table_name) do
3921-
expect(locks_for_table(table_name, connection: alternate_connection)).not_to be_empty
3921+
expect(locks_for_table(table_name, connection: alternate_connection)).to contain_exactly(
3922+
having_attributes(
3923+
table: "bogus_table",
3924+
lock_type: "AccessExclusiveLock",
3925+
granted: true,
3926+
pid: kind_of(Integer),
3927+
),
3928+
)
39223929
end
3923-
expect(locks_for_table(table_name, connection: alternate_connection)).not_to be_empty
3930+
3931+
expect(locks_for_table(table_name, connection: alternate_connection)).to contain_exactly(
3932+
having_attributes(
3933+
table: "bogus_table",
3934+
lock_type: "AccessExclusiveLock",
3935+
granted: true,
3936+
pid: kind_of(Integer),
3937+
),
3938+
)
39243939
end
3940+
3941+
expect(locks_for_table(table_name, connection: alternate_connection)).to be_empty
3942+
end
3943+
3944+
it "allows re-entrancy when inner lock is a lower level" do
3945+
migration.safely_acquire_lock_for_table(table_name) do
3946+
migration.safely_acquire_lock_for_table(table_name, mode: :exclusive) do
3947+
locks_for_table = locks_for_table(table_name, connection: alternate_connection)
3948+
3949+
aggregate_failures do
3950+
expect(locks_for_table).to contain_exactly(
3951+
having_attributes(
3952+
table: "bogus_table",
3953+
lock_type: "AccessExclusiveLock",
3954+
granted: true,
3955+
pid: kind_of(Integer),
3956+
),
3957+
having_attributes(
3958+
table: "bogus_table",
3959+
lock_type: "ExclusiveLock",
3960+
granted: true,
3961+
pid: kind_of(Integer),
3962+
),
3963+
)
3964+
3965+
expect(locks_for_table.first.pid).to eq(locks_for_table.last.pid)
3966+
end
3967+
end
3968+
3969+
locks_for_table = locks_for_table(table_name, connection: alternate_connection)
3970+
3971+
aggregate_failures do
3972+
expect(locks_for_table).to contain_exactly(
3973+
having_attributes(
3974+
table: "bogus_table",
3975+
lock_type: "AccessExclusiveLock",
3976+
granted: true,
3977+
pid: kind_of(Integer),
3978+
),
3979+
having_attributes(
3980+
table: "bogus_table",
3981+
lock_type: "ExclusiveLock", # Postgres releases the inner lock once the outer lock is released
3982+
granted: true,
3983+
pid: kind_of(Integer),
3984+
),
3985+
)
3986+
3987+
expect(locks_for_table.first.pid).to eq(locks_for_table.last.pid)
3988+
end
3989+
end
3990+
39253991
expect(locks_for_table(table_name, connection: alternate_connection)).to be_empty
39263992
end
39273993

@@ -3939,6 +4005,9 @@ def up
39394005
"Lock escalation detected! Cannot change lock level from :share to :exclusive for \"public\".\"bogus_table\"."
39404006
)
39414007

4008+
# the exception above was caught and therefore the parent lock shouldn't be released yet
4009+
expect(locks_for_table(table_name, connection: alternate_connection)).to_not be_empty
4010+
39424011
migration.safely_acquire_lock_for_table(table_name, mode: :exclusive) {}
39434012
end
39444013
end.to raise_error(

0 commit comments

Comments
 (0)
Please sign in to comment.