I am using rails 6.1.4 (Ubuntu 20.04) and am running tests with rspec, factorybot, and capybara. I also got database_cleaner where I'm using :truncation to start each test block with a clean slate (yes, not the fastest way but the most rigorous way). When I run rspec spec
(applies to individual models too), I got one table where I randomly get a bunch of failing tests saying
Failure/Error: DatabaseCleaner.clean
ActiveRecord::Deadlocked:
PG::TRDeadlockDetected: ERROR: deadlock detected
DETAIL: Process 105987 waits for AccessExclusiveLock on relation 1876018 of database 1876015; blocked by process 105996.
Process 105996 waits for AccessShareLock on relation 1876043 of database 1876015; blocked by process 105987.
HINT: See server log for query details.
# ./spec/support/database_cleaner.rb:32:in `block (2 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# PG::TRDeadlockDetected:
# ERROR: deadlock detected
# DETAIL: Process 105987 waits for AccessExclusiveLock on relation 1876018 of database 1876015; blocked by process 105996.
# Process 105996 waits for AccessShareLock on relation 1876043 of database 1876015; blocked by process 105987.
# HINT: See server log for query details.
# ./spec/support/database_cleaner.rb:32:in `block (2 levels) in <top (required)>'
It is truly random where the tests start failing, i.e. I can run the same test commands consecutively and different tests will pass / fail.
in ./spec/support/database_cleaner.rb [I cut out the comments]
RSpec.configure do |config|
config.before(:suite) { DatabaseCleaner.clean_with(:truncation) }
config.before(:each) { DatabaseCleaner.strategy = :truncation }
config.before(:each, js: true) { DatabaseCleaner.strategy = :truncation }
config.before(:each) { DatabaseCleaner.start }
config.after(:each) do
[this is row 32:] DatabaseCleaner.clean
rescue NoMethodError => e # See: https://github.com/DatabaseCleaner/database_cleaner-sequel/issues/4
next puts("Warning: catch #{e.message}") if e.message == %(undefined method `rollback' for nil:NilClass (DB Cleaner gem))
raise e
end
end
Sometimes, after a while, all tests may work also. Does anyone have a sense for what's causing this issue? Thank you!
CodePudding user response:
Give some time to the database cleaner to do its job !
A dummy way of solving the issue is by using the sleep method like so:
sleep(1)
, at the begining of each "it" block. Should do the job ✅
What's hapenning is that database cleaner doesn't have the time to clean your PSQL DB thqt you are already trying to recreate the same instance you used in the previous test.