Zeus and db:test:prepare

Posted: June 22, 2013. Tags: Rails, Zeus, RSpec, PostgreSQL

On some Rails projects that use PostgreSQL as their database, you may find running Zeus will stop you doing rake db:test:prepare. Here's now to make them play nice together.

If you see the following when you run rake db:test:prepare, you may be experiencing this problem:

rake aborted!
PG::ObjectInUse: ERROR:  database "sampierson_test" is being accessed by other users
DETAIL:  There is 1 other session using the database.
: DROP DATABASE IF EXISTS "sampierson_test"

The reason for this is that unlike MySQL, Postgres will not let you do major surgery on your database (e.g. drop/create) while other sessions are using that database, and someone is holding a connection to the database open.

If you have anything in your spec_helper.rb that accesses the database during parsing of that file, that will create the offending database connection. The usual suspects for this are Fixture Builder, and in some versions of Rails, the pending migrations check:

require Rails.root.join *%w[spec support fixture_builder]

ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)

The solution to this problem is to not run these lines until Zeus forks off a process to actually run the tests. In RSpec this is accomplished by placing the lines in a before(:suite):

RSpec.configure do |config|
  config.before(:suite) do
    require Rails.root.join *%w[spec support fixture_builder]
    ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
  end
end

Now you can migrate at your leisure.