2013-07-12 33 views
1

在我的Rails 3.2.13應用程序中,我使用了Zeus。在測試環境中,我使用PostgreSQL。當我運行黃瓜,然後RSpec的(或其他方式),9個10倍我得到的消息:用zeus測試黃瓜和RSpec:其他用戶正在訪問Postgres

PG::Error: ERROR: database "bp_test" is being accessed by other users 
DETAIL: There are 1 other session(s) using the database. 
: DROP DATABASE IF EXISTS "bp_test" 

Tasks: TOP => db:test:load => db:test:purge 
(See full trace by running task with --trace) 

它需要的想殺了數據庫連接得到這個整體非確定性馬戲團再次工作,如here所述。但是這並不總是有效,而且也是一個很大的麻煩。必須有更好的解決方案。有人知道嗎?

+0

它可以連接到: http://stackoverflow.com/questions/16665326/zeus-fails-when-testing-with-rspec/16694072#16694072 – pawurb

+0

是啊,我已經查那。我的項目中沒有任何「自動運行」。 –

+0

有效的事實表明postgres會話關閉正在完成,但是正在異步發生,並且運行下一次測試的zeus相關加速足以防止在正常情況下完成。但是,如果是這種情況,很難相信沒有更多關於它的文章。我不知道它是否相關,但你可能想看看http://platformonrails.wordpress.com/2013/04/06/smooth-rspec-experience-with-zeus/ –

回答

1

this answer的啓發,我們創建了以下database.rake文件。如果原始答案僅適用於PostgreSQL 9.1,那麼這一修改也適用於PostgreSQL 9.2。該機制並不是最漂亮的:當9.1命令失敗時,它只是執行9.2命令。但最重要的是:它的工作原理!

#{Rails.root}/lib/tasks/databases.rake 
# monkey patch ActiveRecord to avoid There are n other session(s) using the database. 
def drop_database(config) 
    case config['adapter'] 
    when /mysql/ 
    ActiveRecord::Base.establish_connection(config) 
    ActiveRecord::Base.connection.drop_database config['database'] 
    when /sqlite/ 
    require 'pathname' 
    path = Pathname.new(config['database']) 
    file = path.absolute? ? path.to_s : File.join(Rails.root, path) 

    FileUtils.rm(file) 
    when /postgresql/ 
    begin 
     ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public')) 
     ActiveRecord::Base.connection.select_all("select * from pg_stat_activity order by procpid;").each do |x| 
     if config['database'] == x['datname'] && x['current_query'] =~ /<IDLE>/ 
      ActiveRecord::Base.connection.execute("select pg_terminate_backend(#{x['procpid']})") 
     end 
     end 
     ActiveRecord::Base.connection.drop_database config['database'] 
    rescue # in PG 9.2 column procpid was renamed pid and the query status is checked not using 'current_query' but using 'state' 
     ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public')) 
     ActiveRecord::Base.connection.select_all("select * from pg_stat_activity order by pid;").each do |x| 
     if config['database'] == x['datname'] && x['state'] =~ /idle/ 
      ActiveRecord::Base.connection.execute("select pg_terminate_backend(#{x['pid']})") 
     end 
     end 
     ActiveRecord::Base.connection.drop_database config['database'] 
    end 
    end 
end 
0
namespace :db do 

    desc 'Clear the database' 
    task :clear_db => :environment do |t,args| 
    ActiveRecord::Base.establish_connection 
    ActiveRecord::Base.connection.tables.each do |table| 
     next if table == 'schema_migrations' 
     ActiveRecord::Base.connection.execute("TRUNCATE #{table}") 
    end 
    end 

    desc 'Delete all tables (but not the database)' 
    task :drop_schema => :environment do |t,args| 
    ActiveRecord::Base.establish_connection 
    ActiveRecord::Base.connection.execute("DROP SCHEMA public CASCADE") 
    ActiveRecord::Base.connection.execute("CREATE SCHEMA public") 
    ActiveRecord::Base.connection.execute("GRANT ALL ON SCHEMA public TO postgres") 
    ActiveRecord::Base.connection.execute("GRANT ALL ON SCHEMA public TO public") 
    ActiveRecord::Base.connection.execute("COMMENT ON SCHEMA public IS 'standard public schema'") 
    end 

    desc 'Recreate the database and seed' 
    task :redo_db => :environment do |t,args| 
    # Executes the dependencies, but only once 
    Rake::Task["db:drop_schema"].invoke 
    Rake::Task["db:migrate"].invoke 
    Rake::Task["db:migrate:status"].invoke 
    Rake::Task["db:structure:dump"].invoke 
    Rake::Task["db:seed"].invoke 
    end 

end