gma / tconsole

Testing console for Rails. Helps out with test performance and also makes it easier to run specific tests
177 stars 18 forks source link

All database-related test fails #46

Closed krzyzak closed 12 years ago

krzyzak commented 12 years ago

Hi, Tconsole now works (ie. I can run tests), however all tests, which depends on database fails, I've got folowing error:

  ActiveRecord::StatementInvalid: ArgumentError: prepare called on a closed database: PRAGMA table_info("topics")

I'm running with latest (1.1.1) tconsole, rails 3.2.1, ruby 1.9.3 and sqlite.

batasrki commented 12 years ago

Do you have a connection pool open or are manipulating one anywhere? If possible, can you post your database structure, even if anonymized?

Basically, a bit more information and a more detailed error log would help out a lot.

We'll try to get this issue solved as soon as possible.

krzyzak commented 12 years ago

Hi. Do you have a connection pool open or are manipulating one anywhere? No, I've even stopped rails dev server (should be irrelevant, but to be absolutely sure) If possible, can you post your database structure, even if anonymized? You mean schema.rb, or something like this? I'm affraid that I can't right now

Here's sample stacktrace:

195) Error:
test_saves_with_valid_attributes(TopicTest):
ActiveRecord::StatementInvalid: ArgumentError: prepare called on a closed database: PRAGMA table_info("topics")
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/sqlite3-1.3.5/lib/sqlite3/database.rb:91:in `initialize'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/sqlite3-1.3.5/lib/sqlite3/database.rb:91:in `new'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/sqlite3-1.3.5/lib/sqlite3/database.rb:91:in `prepare'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/connection_adapters/sqlite_adapter.rb:251:in `block in exec_query'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:280:in `block in log'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.1/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:275:in `log'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/connection_adapters/sqlite_adapter.rb:247:in `exec_query'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/connection_adapters/sqlite_adapter.rb:469:in `table_structure'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/connection_adapters/sqlite_adapter.rb:351:in `columns'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/connection_adapters/schema_cache.rb:12:in `block in initialize'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/model_schema.rb:228:in `yield'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/model_schema.rb:228:in `default'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/model_schema.rb:228:in `columns'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/model_schema.rb:243:in `column_defaults'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/base.rb:479:in `initialize'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/factory_girl-2.6.0/lib/factory_girl/factory.rb:152:in `new'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/factory_girl-2.6.0/lib/factory_girl/factory.rb:152:in `block in instance_builder'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/factory_girl-2.6.0/lib/factory_girl/attribute_assigner.rb:32:in `instance_exec'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/factory_girl-2.6.0/lib/factory_girl/attribute_assigner.rb:32:in `build_class_instance'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/factory_girl-2.6.0/lib/factory_girl/attribute_assigner.rb:11:in `object'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/factory_girl-2.6.0/lib/factory_girl/strategy/build.rb:9:in `result'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/factory_girl-2.6.0/lib/factory_girl/factory.rb:48:in `run'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/factory_girl-2.6.0/lib/factory_girl/syntax/methods.rb:150:in `run_factory_girl_strategy'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/factory_girl-2.6.0/lib/factory_girl/syntax/methods.rb:40:in `build'
    /Users/krzyzak/my_project/test/unit/topic_test.rb:5:in `block in <class:TopicTest>'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.1/lib/active_support/callbacks.rb:429:in `_run__3735208369444094797__setup__369323223382060363__callbacks'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.1/lib/active_support/callbacks.rb:405:in `__run_callback'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.1/lib/active_support/callbacks.rb:385:in `_run_setup_callbacks'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.1/lib/active_support/callbacks.rb:81:in `run_callbacks'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/activesupport-3.2.1/lib/active_support/testing/setup_and_teardown.rb:34:in `run'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/tconsole-1.1.1/lib/tconsole/minitest_handler.rb:175:in `block in _run_suite'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/tconsole-1.1.1/lib/tconsole/minitest_handler.rb:142:in `map'
    /Users/krzyzak/.rvm/gems/ruby-1.9.3-p125/gems/tconsole-1.1.1/lib/tconsole/minitest_handler.rb:142:in `_run_suite'
batasrki commented 12 years ago

Have you verified that all tests pass without using tconsole? In other words, does this happen only in tconsole?

batasrki commented 12 years ago

Also, would it be possible for you to paste in the source of the TopicTest file and maybe the Topic file?

krzyzak commented 12 years ago

Have you verified that all tests pass without using tconsole? In other words, does this happen only in tconsole? Sure thing, unfortunately, it's definately something related with tconsole.

Here's TopicTest:


require 'test_helper'

class TopicTest < ActiveSupport::TestCase
  setup do
    @topic = FactoryGirl.build(:topic)
  end

  test "saves with valid attributes" do
    assert @topic.valid?
  end

  test "is invalid without a teacher" do
    @topic.teacher = nil

    assert @topic.invalid?
    assert_not_empty @topic.errors[:teacher]
  end

  test "is invalid without a name" do
    @topic.name = nil

    assert @topic.invalid?
    assert_not_empty @topic.errors[:name]
  end
end

Basically: nothing special, same as Topic:

class Topic < ActiveRecord::Base
  belongs_to :teacher

  validates :teacher, :presence => true
  validates :lesson, :presence => true
  validates :name, :presence => true
end
batasrki commented 12 years ago

OK, I'll take a look at it later tonight, try to reproduce your issue and keep you posted.

nalanj commented 12 years ago

Hi @krzyzak - thanks for reporting this. It's a really strange issue, but I'm wondering if the problem is that your sqlite3 connection is being used across forked processes (we use fork to set up and clean up the testing environment on each run). Try putting the content in this gist in a file named .tconsole in the root of your project and see if that helps out:

https://gist.github.com/1955584

I basically just added some extra disconnect code to try and keep that sqlite connection from being shared over the fork. It's a long shot, but maybe it'll work. If not, we'll keep troubleshooting. Thanks!

krzyzak commented 12 years ago

Hi, I found cause of problem. Actually, @commondream's message was very big hint ;) I'm using shared connection snippet, required by capybara (see Transactions and database setup section). When I turn it off, all tests work like a charm. Is it tconsole's bug, that it's not working with that snippet, or it's irrelevant with tconsole?(It would be worth noticing in readme, because it's preety popular piece of code ;) )

itstommymorgan commented 12 years ago

krzyzak:

The "shared connection snippet" isn't really required by capybara, it's just one of the options... and, honestly, not a terribly great one - I'd suggest using the database_cleaner gem instead, as it works just fine. In fact, this is the recommended method for capybara when using MiniTest/Test::Unit (see the "Using Capybara with Test::Unit" section in the capybara readme).

nalanj commented 12 years ago

@krzyzak: My recommendation would be to use database_cleaner rather than using that snippet, but that said, in my testing, if you remove the last line from the snippet it resolves the issue:

class ActiveRecord::Base
  mattr_accessor :shared_connection
  @@shared_connection = nil

  def self.connection
    @@shared_connection || retrieve_connection
  end
end
krzyzak commented 12 years ago

The "shared connection snippet" isn't really required by capybara, it's just one of the options... and, honestly, not a terribly great one - I'd suggest using the database_cleaner gem instead, as it works just fine.

I know that it's only one of the options, but in my previous experience it was working, and it was quite faster than database_cleaner. I'm switching now to database_cleaner, nonetheless I believe that it would be worth noticing in readme ;)

itstommymorgan commented 12 years ago

It may be faster but it makes some flawed assumptions about how the database connection should be established, which is why the fix @commondream suggested works.

But I'd agree, maybe some kind of note in the README under a "common problems" section, just to prevent the issue from coming up as a bug report again?