Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DatabaseCleaner.clean sometimes fails with undefined method "database_type" #4

Open
joshuaswilcox opened this issue Aug 18, 2016 · 15 comments

Comments

@joshuaswilcox
Copy link

For some reason DatabaseCleaner.clean fails occasionally with this error:

  Failure/Error: DatabaseCleaner.clean
  NoMethodError:
    undefined method `database_type' for :default:Symbol
  # /Users/jwilcox/.rvm/gems/ruby-2.3.1/gems/database_cleaner-1.5.3/lib/database_cleaner/sequel/truncation.rb:58:in `txid'
  # /Users/jwilcox/.rvm/gems/ruby-2.3.1/gems/database_cleaner-1.5.3/lib/database_cleaner/sequel/truncation.rb:54:in `dirty?'
  # /Users/jwilcox/.rvm/gems/ruby-2.3.1/gems/database_cleaner-1.5.3/lib/database_cleaner/sequel/truncation.rb:15:in `clean'
  # /Users/jwilcox/.rvm/gems/ruby-2.3.1/gems/database_cleaner-1.5.3/lib/database_cleaner/base.rb:92:in `clean'
  # /Users/jwilcox/.rvm/gems/ruby-2.3.1/gems/database_cleaner-1.5.3/lib/database_cleaner/configuration.rb:79:in `block in clean'
  # /Users/jwilcox/.rvm/gems/ruby-2.3.1/gems/database_cleaner-1.5.3/lib/database_cleaner/configuration.rb:79:in `each'
  # /Users/jwilcox/.rvm/gems/ruby-2.3.1/gems/database_cleaner-1.5.3/lib/database_cleaner/configuration.rb:79:in `clean'
  # ./spec/spec_helper.rb:48:in `block (2 levels) in <top (required)>'

I am using the Sequel gem and have rspec configured with

  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
  end

  config.after(:each) do |example|
    DatabaseCleaner.clean
  end

The tests that fail are not even using and database operations, they are just unit tests

@joshuaswilcox
Copy link
Author

joshuaswilcox commented Aug 18, 2016

here is a pry from within where i fails

    57:       def txid
 => 58: binding.pry
    59:         case db.database_type
    60:         when :postgres
    61:           db.fetch('SELECT txid_snapshot_xmax(txid_current_snapshot()) AS txid').first[:txid]
    62:         end
    63:       end

[1] pry(#<DatabaseCleaner::Sequel::Truncation>)> db
=> :default

I am unsure what "default" is in this instance

and here is what DatabaseCleaner.connections.inspect outputs

[#<DatabaseCleaner::Base:0x007ff56d6ba908 @orm=:sequel, @strategy=#<DatabaseCleaner::Sequel::Transaction:0x007ff56d6ba6b0 @db=:default>, @db=:default>]

@SkyWriter
Copy link

Stumbled upon the same issue. And you gave me a hint:

The tests that fail are not even using and database operations, they are just unit tests

Turns out that it happens when you don't establish a database connection. Once you issue a Sequel.connect call, it all works fine.

@dreammaker
Copy link

dreammaker commented Jun 28, 2017

I'm having this problem too. It's repeatable for specific run orders with a --seed. The specific error that I got for anyone searching is:

NoMethodError: undefined method `rollback' for nil:NilClass
    activerecord (5.1.1) lib/active_record/connection_adapters/abstract/transaction.rb:185:in `block in rollback_transaction'
    ~/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
    activerecord (5.1.1) lib/active_record/connection_adapters/abstract/transaction.rb:183:in `rollback_transaction'
    activerecord (5.1.1) lib/active_record/connection_adapters/abstract/database_statements.rb:233:in `rollback_transaction'
    database_cleaner (1.6.1) lib/database_cleaner/active_record/transaction.rb:34:in `block in clean'
    database_cleaner (1.6.1) lib/database_cleaner/active_record/transaction.rb:30:in `each'
    database_cleaner (1.6.1) lib/database_cleaner/active_record/transaction.rb:30:in `clean'
    database_cleaner (1.6.1) lib/database_cleaner/base.rb:92:in `clean'
    database_cleaner (1.6.1) lib/database_cleaner/configuration.rb:79:in `block in clean'
    database_cleaner (1.6.1) lib/database_cleaner/configuration.rb:79:in `each'
    database_cleaner (1.6.1) lib/database_cleaner/configuration.rb:79:in `clean'
    test/test_helper.rb:52:in `block in <class:Spec>'

I'm using database_cleaner v1.6.1, which is currently the latest release.

What's the best way to fix this? It seems like creating a connection unnecessarily is not ideal.

@redtachyons
Copy link

I am getting this error randomly in rails 5.1

@yb66
Copy link

yb66 commented May 16, 2018

My quick and dirty solution was to use an ENV var:

unless ENV["NO_DB"]
   # Cleaning the database
   config.before(:suite) do
     DatabaseCleaner.orm = "sequel"

     DatabaseCleaner.strategy = :transaction
     DatabaseCleaner.clean_with :truncation
     #Sequel::Migration.descendants.each{|m| m.apply(DB, :up)}
   end

   config.before(:each, :db => true) do
     # open transaction
     DatabaseCleaner.start
   end

   config.after(:each, :db => true) do
     DatabaseCleaner.clean
   end
 end

And then in the specs that don't need the database:

ENV["NO_DB"] = "true"
require 'spec_helper'

Regards,
iain

@benoror
Copy link

benoror commented Nov 18, 2019

Seeing the same issue in Codeship with version 1.7.0. Clearing the build cache temporarily fixes the issue. Any new insight/workaround?

@botandrose
Copy link
Contributor

@benoror Can you reduce it down to a repo you can share that reproduces the problem? I'd be happy to get to the bottom of it.

@benoror
Copy link

benoror commented Nov 18, 2019

Hey @botandrose thanks for the reply. I will try to have something soon that can replicate the issue, but I noted if happens randomly. For now, not sure if this could help, but here's our only place where we run DatabaseCleaner (for some reason is in the same initializer as factory_bot_rails' 🙈 ):

# https://github.com/thoughtbot/factory_bot_rails
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods

  config.before(:suite) do
    begin
      DatabaseCleaner[:active_record].strategy = :transaction
      DatabaseCleaner.clean_with(:truncation)
      DatabaseCleaner.start
      FactoryBot.lint
    ensure
      DatabaseCleaner.clean
    end
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end

@benoror
Copy link

benoror commented Dec 19, 2019

In our case it seems that there was a race condition between starting transactions with DatabaseCleaner.start and closing it with DatabaseCleaner.clean in two different (async?) RSpec config hooks: before(:suite) and .before(:each), as wometimes would attempt to rollback a transaction which was already rollbacked.

I based on existing examples from DatabaseCleaner & FactoryBot, and split them to make them play well together, by surrounding the FactoryBot.lint synchronously by DatabaseCleaner transaction opening and closing:

*The :around and cleaning syntax blocks didn't seem to work, might be an issue with our RSpec version


spec/support/database_cleaner.rb

RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end

spec/support/factory_bot.rb

RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods

  config.before(:suite) do
    DatabaseCleaner.start
    FactoryBot.lint
    DatabaseCleaner.clean
  end
end

@benoror
Copy link

benoror commented Dec 19, 2019

NVM, failed again inside the CI (Codeship), trying this workaround instead: darren987469/membership-system#19 (comment)

@botandrose botandrose transferred this issue from DatabaseCleaner/database_cleaner Feb 18, 2020
@khiav223577
Copy link

I got this error randomly, too. And it only occurs in one specific test case.

My setting:
spec/support/database_cleaner.rb

RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end

The only test case that is possible to get this error:
image

@botandrose
Copy link
Contributor

@khiav223577 I see that you're using database_cleaner v1.7.0. Can you try with latest v1.8 release (and/or database_cleaner-sequel gem) and tell me if the issue still is occurring?

@botandrose
Copy link
Contributor

@khiav223577 Looking at your backtrace more closely, you appear to be using the ActiveRecord adapter, not the Sequel adapter, so this is not the bug for you! :)

Can you open an issue on https://github.com/DatabaseCleaner/database_cleaner-active_record instead?

@botandrose
Copy link
Contributor

@benoror Can you see if #11 fixes your issue?

@khiav223577
Copy link

@khiav223577 Looking at your backtrace more closely, you appear to be using the ActiveRecord adapter, not the Sequel adapter, so this is not the bug for you! :)

Can you open an issue on https://github.com/DatabaseCleaner/database_cleaner-active_record instead?

Thanks for your quick reply. I'll try the latest version of database_cleaner and submit another issue if the issue still exists.

khiav223577 pushed a commit to khiav223577/rails_app_template that referenced this issue Dec 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants