Closed epinault closed 1 year ago
I forgot to mention but the issue is that I need dynamic connection to sqlite DB . So I use the establish connection with a connection hash.. So I am not sure how to use Multiple ORM in this setup where I don t have control over the connection details and have database cleaner working proper. Is there a way to tell it to ignore for specific class and not run anything for database Cleaner?
So it is definitely an issue with DatabaseCleaner because code works fine when not in test mode. Also I added the following to force reset connection after each test. Seems to fix the issue but I am wondering is there is a clean way to do this when connection are not known or establish dynamically (not in database.yml)
ActiveRecord::Base.establish_connection(:test)
guess it is mostly working but not reliable still :( Looking at the code and see if I can find a way to improve it
So seems that to support a common before I had to do the following. Then all the test cases are now calling before and after common code (though in this example I duplicated for testing purpose)
class ActiveSupport::TestCase
include SharedHelpers
include ResqueUnit::Assertions
include ResqueUnit::SchedulerAssertions
before do
p :common_before_at
ActiveRecord::Base.establish_connection(:test)
DatabaseCleaner.start
end
after do
p :common_after_at
DatabaseCleaner.clean
end
end
# database cleaner
DatabaseCleaner.clean_with :truncation
DatabaseCleaner[:active_record].strategy = :transaction
class MiniTest::Spec
include FactoryGirl::Syntax::Methods
include ResqueUnit::Assertions
include ResqueUnit::SchedulerAssertions
before do
p :common_before_ms
ActiveRecord::Base.establish_connection(:test)
DatabaseCleaner.start
end
after do
p :common_after_ms
DatabaseCleaner.clean
end
include SharedHelpers
end
Ok so I am seeing where the error is thrown from but I am not sure why the connection is invalid I see only one connection configured. But somehow when switching from one to another type of connection, it seems to get confused/overriden. Still debugging but something nasty is happening at the connection level
home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/connection_adapters/sqlite3_adapter.rb:37:in rescue in sqlite3_connection' /home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/connection_adapters/sqlite3_adapter.rb:13:in
sqlite3_connection'
/home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:438:in new_connection' /home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:448:in
checkout_new_connection'
/home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:422:in acquire_connection' /home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:349:in
block in checkout'
/home/preseed/.rubies/ruby-2.1.5/lib/ruby/2.1.0/monitor.rb:211:in mon_synchronize' /home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:348:in
checkout'
/home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:263:in block in connection' /home/preseed/.rubies/ruby-2.1.5/lib/ruby/2.1.0/monitor.rb:211:in
mon_synchronize'
/home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:262:in connection' /home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/fixtures.rb:974:in
map'
/home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/fixtures.rb:974:in enlist_fixture_connections' /home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/fixtures.rb:944:in
setup_fixtures'
/home/preseed/.gem/ruby/2.1.5/gems/activerecord-4.2.4/lib/active_record/fixtures.rb:826:in before_setup' /home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest/spec.rb:312:in
before_setup'
/home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest/test.rb:106:in block (3 levels) in run' /home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest/test.rb:205:in
capture_exceptions'
/home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest/test.rb:105:in block (2 levels) in run' /home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest/test.rb:256:in
time_it'
/home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest/test.rb:104:in block in run' /home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:334:in
on_signal'
/home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest/test.rb:276:in with_info_handler' /home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest/test.rb:103:in
run'
/home/preseed/.gem/ruby/2.1.5/gems/minitest-reporters-1.1.0/lib/minitest/reporters.rb:47:in run_with_hooks' /home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:781:in
run_one_method'
/home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:308:in run_one_method' /home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:296:in
block (2 levels) in run'
/home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:295:in each' /home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:295:in
block in run'
/home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:334:in on_signal' /home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:321:in
with_info_handler'
/home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:294:in run' /home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:155:in
block in run'
/home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:155:in map' /home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:155:in
run'
/home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:129:in run' /home/preseed/.gem/ruby/2.1.5/gems/minitest-5.8.0/lib/minitest.rb:56:in
block in autorun'
I do not know if this is related, but it seems so.
Today, after using the same configuration for more than a year, PostgreSQL queries started to hang when in the debugger byebug. At the prompt, any ActiveRecord queries would just hang. Looking at the process list yielded this:
strike 1283 0.0 0.0 2650732 6080 ?? Ss 5:35PM 0:00.01 postgres: strike prompt_test ::1(49617) PARSE waiting
strike 1279 0.0 0.0 2652652 14624 ?? Ss 5:35PM 0:00.17 postgres: strike prompt_test ::1(49601) idle in transaction
According to some posts, this is an indication that the query has finished, but that the connection is open and idle. When this occurs, the app simply hangs waiting for the results to come back. I can kill those processes, but of course, the results are nuked in the process and ActiveRecord gets an exception.
This is my original config (which has worked for a super long time and broke today):
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.logger = Rails.logger
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.start
DatabaseCleaner.clean_with(:truncation)
FactoryGirl.lint
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
#
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
# RSpec.describe UsersController, :type => :controller do
# # ...
# end
#
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
config.infer_spec_type_from_file_location!
end
If I change the line...
DatabaseCleaner.strategy = :transaction
to
DatabaseCleaner.strategy = :truncation
... everything starts working again in the debugger. Oddly, this does not seem to affect the regular results of rspec, just the results of queries inside byebug.
This is definitely occurring on two machines now. Any ideas?
I am using this configuration now:
DatabaseCleaner.strategy = :truncation, { pre_count: true, cache_tables: true }
DatabaseCleaner.logger = Rails.logger
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.start
DatabaseCleaner.clean_with(:truncation)
FactoryGirl.lint
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
config.infer_spec_type_from_file_location!
config.use_transactional_fixtures = false
end
If I try to use the transaction strategy, I cannot do any database queries from within byebug. It just hangs up.
@epinault, http://edgeapi.rubyonrails.org/classes/ActiveSupport/Testing/SetupAndTeardown.html
Probably you can try to use setup
and teardown
instead of before
and after
@martinstreicher You don't need to explicitly call DatabaseCleaner.start
when you are using DatabaseCleaner.cleaning
- Could you try running your spec without DatabaseCleaner.start
?
@serg-kovalev will give it a try
I am migrating from Rails 4.0 to 4.2. Everything worked fine with Rails 4.0. The issue I am having is with rails 4.2 (something might have changed)
Anyway, I suspect database cleaner is the problem in my tests. When I run test independently, all works well. But when I run my full suite of test, I am getting
The issue from what I can tell is that I have a normal set of active record models that talks to a postgres db by default. But I also have a small separate set of sqlite to generate sqlite3 db using data stored in postgres and those model use as well active record. Those special model to use activerecord setup their own establish_connection with
But seems like DatabaseCleaner is not liking this. Iit seems to me that after it run the sqlite3 db test against those special models, the connection is remaining against that sqlite db (which is gone as the end of the tests concerning sqlite3 models). Then when other model get tested that uses Postgres, It still trying to access the sqlite 3 db
Any idea what I can do to fix this? I can try to make a repro model but would need more time