Rspec tests freeze as soon as DatabaseCleaner begins to work
toomanyjoes opened this issue · 1 comments
I'm in the middle of a painful upgrade from Rails 5.2.7 to 6.1 (as well as Ruby 2.7.6 to 3.1.4) and DatabaseCleaner is the bulk of my headache. At this point the specs are just freezing as soon as the cleaner begins its work. My setup is rather complicated but based on everything I've pieced together I believe my syntax is correct for what I'm trying to accomplish.
I have a two database setup: Postgres and a legacy mysql database that both need to be cleaned. Here is what I currently have in my rails helper including required files which there isn't much documentation on. I have a hunch maybe I have too many or two few requires.
Relevant Gems
capybara (~> 3.39)
capybara-screenshot
database_cleaner-active_record
geckodriver-helper
selenium-webdriver (~> 4.11)
database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: localhost
test:
<<: *default
database: test_db
test_legacy:
url: <%= ENV['LEGACY_DB_TEST_URL'] %>
adapter: mysql2
connect_timeout:
rails_helper.rb
require 'spec_helper'
require 'rspec/rails'
require 'devise'
require 'support/devise_login_helper'
require 'support/factory_bot'
require 'paper_trail/frameworks/rspec'
require 'selenium/webdriver'
require 'capybara/rails'
require 'database_cleaner/active_record'
require 'support/select2_helper'
require 'support/feature_spec_helpers/wait_for_ajax'
require 'support/feature_spec_helpers/sessions'
require 'capybara-screenshot/rspec'
config.use_transactional_fixtures = false
config.before(:suite) do
if config.use_transactional_fixtures?
raise(<<-MSG)
Delete line `config.use_transactional_fixtures = true` from rails_helper.rb
(or set it to false) to prevent uncommitted transactions being used in
JavaScript-dependent specs.
During testing, the app-under-test that the browser driver connects to
uses a different database connection to the database connection used by
the spec. The app's database connection would not be able to access
uncommitted transaction data setup over the spec's database connection.
MSG
end
DatabaseCleaner[:active_record, db: :test_legacy].clean_with(:truncation)
DatabaseCleaner[:active_record, db: ApplicationRecord].clean_with(:truncation, { except: %w[submission_statuses submission_definitions] })
DatabaseCleaner.strategy = :transaction
end
config.after(:all) do
DatabaseCleaner[:active_record, db: :test_legacy].clean_with(:truncation)
DatabaseCleaner[:active_record, db: ApplicationRecord].clean_with(:truncation, { except: %w[submission_statuses submission_definitions] })
end
config.before(:each) do |example|
if example.metadata[:js]
DatabaseCleaner.strategy = :truncation
elsif example.metadata[:type] == :feature
# :rack_test driver's Rack app under test shares database connection
# with the specs, so continue to use transaction strategy for speed.
driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test
unless driver_shares_db_connection_with_specs
# Driver is probably for an external browser with an app
# under test that does *not* share a database connection with the
# specs, so use truncation strategy.
DatabaseCleaner.strategy = :truncation
end
end
end
config.before(:each) do
DatabaseCleaner[:active_record, db: :test_legacy].start
DatabaseCleaner[:active_record, db: ApplicationRecord].start
end
config.append_after(:each) do
DatabaseCleaner[:active_record, db: :test_legacy].clean
DatabaseCleaner[:active_record, db: ApplicationRecord].clean
end
for the line:
DatabaseCleaner[:active_record, db: ApplicationRecord].clean_with(:truncation, { except: %w[submission_statuses submission_definitions] })
I've tried several different things including:
DatabaseCleaner[:active_record, db: :test].clean_with(:truncation, { except: %w[submission_statuses submission_definitions] })
and
DatabaseCleaner[:active_record].clean_with(:truncation, { except: %w[submission_statuses submission_definitions] })
and
DatabaseCleaner.clean_with(:truncation, { except: %w[submission_statuses submission_definitions] })
All with no success. It's frustrating because there is zero to go off of here. The test suite just stops running with no errors:
The test.log file looks like this:
(0.2ms) SELECT @@FOREIGN_KEY_CHECKS
(0.1ms) SET FOREIGN_KEY_CHECKS = 0
(0.6ms) select table_name from information_schema.views where table_schema = 'legacy_test'
and it only chokes on the legacy because it's cleaning comes first in the code, if I switch the order it chokes on the Postgres DB instead.
I've removed DB cleaner altogether and turned back on use_transactional_fixtures just as a test and my tests run fine until I run a test that uses the legacy database. The transactional fixtures apparently only works for the one main postgres db.
I found some old questions about this very same thing that had been closed so I wanted to post my question here to see if others are experiencing the same issue.
Looking forward to your help! Thanks!
Well after several hours of trying things I just threw up my hands and rebooted my machine and the problem seems to have gone away