東京日報 3/12

傍らに目覚ましがあってやってしまったかと思った。割と早めにセットしすぎてる気はする。やっぱり最終やばい時間のめざましとは別にしたほうがいいのかなぁ。

test-queueを動かそうと頑張ってた……んだけど結局悩んでたのはridgepoleをどうやってスマートに各DBに同期させるか、だった(結局は、ね)。

ridgepoleのサンプルがそれなりに便利なコマンドを作ってくれてるんだけど、そのラップ具合がよくわからなくて読解に苦労した。あげくうちもほとんど同じコマンド作ってることがわかって結局それに乗っかることにした(しかし、うちのはなぜか''で囲む必要があるんだよな。たぶん治すのがめんどくさくなってるだけの実装ミスだと思うので直そうかな、rake -T出ない(かったと思う)の不便だし、何より不自然だ)。環境変数絡めてdatabase.ymlの内容を切り替えるの苦労した。というかたぶん各々の動作のタイミング関係がよくわかってなかったのがダメなんだったと思う。

基本的に素のbundle execではなくてbin/rspec-queueを作ってそれをたたいてるんだけどここ参照、見ればわかるんだけどdbのmigrateにdb:resetとか使ってて、そのままやるとridgepole環境ではDBがsettingされない。なので、そのあたりをコメントアウトして、結局、

  def after_fork(num)
    ENV.update("TEST_ENV_NUMBER" => num > 1 ? num.to_s : "")
    ActiveRecord::Base.configurations["test"]["database"] << ENV["TEST_ENV_NUMBER"]
    ActiveRecord::Base.establish_connection(:test)
  end

というようにした。これを呼び出すrakeTaskの方は、

+namespace :rspec do
  desc "rspec-queue実行コマンド"
  task test_queue: :environment do
    ENV["RAILS_ENV"] = "test"
  #Drop,Create,Migrate
    (1..4).each do |i|
      num = i == 1 ? "" : i.to_s
      ENV.update("TEST_ENV_NUMBER" => i > 1 ? i.to_s : "")
      dry_result = `rake 'db:ridgepole:dry-run[test]'`
      if dry_result.include?("No change")
        STDERR.puts "database#{i} migrate skip"
        next
      end
      begin
        sh "mysql -u root -e 'drop database testDB#{num}'"
      rescue => e
        STDERR.puts "Error happened. Probably, database setting failed."
      end
      sh "mysql -u root -e 'create database testDB#{num} default character set=utf8'"
      sh "rake 'db:ridgepole:apply[test]'"
    end
    ENV.delete('TEST_ENV_NUMBER')
    sh "bin/rspec-queue #{ARGV.last}"
  end
end

というようにしている。sh使いまくるのなんだかカッコ悪いけど便利なんだよな。rake単純にruby出かけるshellscriptとしてべんりだ。とりあえずこれで動いている。まとまったらちゃんとした記事を書きます(特に、bin/rspec-queueActiveRecordの接続、設定周りで何を消して何を残すべきなのか意味も含めて理解したら)。とりあえずこれで動いた。

あと、並列実行した際に落ちるケースがあるときがあって(落ちない時もある)、テストが悪いのかなぁと思ったりした。ランダムで~というよりかはいくつか候補があって、そいつらが落ちることもあれば落ちないこともあるという感じ。一応orderは最初からrandom設定になってるんだけど何かDBが分かれることによる不都合が存在するようなコードがあるんだろうか。キャッシュ周りのケースが落ちるのはわからなくもないけど……そういえばオンメモリ系のあれこれ(redisとかmemchachedとか)がまだ中でどういう風に扱われるかわかってない(そもそもどういうことをしているのかもかなり理解していない)。ゆくゆくはそのあたりも勉強だなぁ。というか合宿で誰かに教えてもらえないかな。

とかを見るとmemachedボコボコに言われててウケる。というかredisは探したらソースコード中にいくつか単語が見つかったけどmemcachedは一つもなかったぞ。これ本当に使ってるのか……?

というか水島努へのリプライになってるやんけ。ピョエー

京都に下るバス取らないと。