Defect #515
完了ビルドの保存の設定時にエラー
100%
説明
いつもお世話になっております。
とても便利に利用させていただいております。
気になる症状が出たので、報告させていただきます。
Hudson上では1件しかビルドの記録が無いジョブについて、Redmine_Hudsonプラグイン側の設定で、下記の操作を行ったところ、500 Internal Server Error が発生しました。
2 点ほど、別のエラーが出ています。
1点目:¶
--------------------------------------------------------------------------------
1. プロジェクト -> Hudsonの設定でジョブを1つ選択。
選んだジョブは、数件ビルド記録があります。(Redmine側のHudsonのテーブルにはまだ記録無しで0件)
2.Hudsonの設定画面で、対象のジョブのビルド履歴を削除するにチェックを入れます。
また、保存日数と保存数を適当に指定します。
3. 設定を保存し、Hudsonのタブでindexを呼び出します。
--------------------------------------------------------------------------------
このとき、下記のエラーが発生しました。
NoMethodError (undefined method `number' for nil:NilClass): vendor/plugins/redmine_hudson/app/models/hudson_build_rotator.rb:37:in `can_store?' vendor/plugins/redmine_hudson/app/models/hudson_job.rb:214:in `fetch_detail' /usr/local/lib/ruby/1.8/rexml/element.rb:891:in `each' /usr/local/lib/ruby/1.8/rexml/xpath.rb:53:in `each' /usr/local/lib/ruby/1.8/rexml/element.rb:891:in `each' vendor/plugins/redmine_hudson/app/models/hudson_job.rb:211:in `fetch_detail' vendor/plugins/redmine_hudson/app/models/hudson_job.rb:141:in `fetch_builds' vendor/plugins/redmine_hudson/app/models/hudson.rb:103:in `fetch_buildresults' .....
def HudsonBuildRotator.can_store?(job, number) の return number.to_i >= oldest.number.to_i でエラーが出ています。
oldest がNULLだったためかな...と思っています。
2点目:¶
上記の現象を、手元の環境で検証しようとしました。
手元の環境はMySQL 5.1 を使っています。
同じ条件を設定したところ、下記のエラーが先に出ました。
ActiveRecord::StatementInvalid in HudsonController#index Mysql::Error: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery': SELECT * FROM `hudson_builds` WHERE (hudson_builds.hudson_job_id = 7 and hudson_builds.id not in (select hudson_builds.id from hudson_builds where hudson_builds.hudson_job_id = 7 AND (hudson_builds.finished_at <= '2010-08-07 23:59:59' OR hudson_builds.id not in (select hudson_builds.id from hudson_builds where hudson_builds.hudson_job_id = 7 order by hudson_builds.number desc limit 3)))) ORDER BY hudson_builds.number LIMIT 1
Hudsonプラグインのコードそのものよりは、DBやRORの環境に依存するのかもしれませんが、エラーのためやはりindex画面が表示されませんでした。
Hudsonの設定画面は、Hudsonタブをクリックし、サイドバーからアクセスする仕様のため、最初に上記のエラーを報告してきたユーザは、Hudsonの設定画面に戻れず、どうやって設定を戻したら良いか困ってしまっておりました。
/hudson_settings/edit/project-name で設定画面に戻れることを確認し、ジョブの設定で、履歴の削除のチェックを外すと、index の画面が正常に表示されるようになっています。
その後は、ジョブの削除の設定を有効にしても問題なくなりました。
長くなってしまい、恐縮ですが、かいつまむとこのような感じです。
1. Hudsonのビルド履歴を一度もFetchしていないジョブに対して、履歴の削除設定を有効にし、保存日数と保持数を指定して保存 -> index画面に移動するとInternal Server Errorになる。
2. もしくは、MySQLのエラーが発生する。
3. 設定を戻し、1回でもビルド履歴を取得できれば、その後はエラーにならない。
既知の問題でしたら、大変申し訳ありません。
まずはご報告まで。
ファイル
Toshiyuki Ando さんが13年以上前に更新
ご連絡ありがとうございます。
旅行中なので、帰ってからコードみてみます。
MySQL はLimit使えないんですね。うーむ。どうしたものか。
Akiko Takano さんが13年以上前に更新
お休みのところ、メッセージありがとうございます。
特に非常に困る、という状況ではありませんので、ご報告まで、ということで扱っていただければと思います。
また、本番で利用しているMySQLは5.0だったと思います。こちらは不具合があるかどうかはまだ確認していません。(少なくともLIMITに関するエラーは無かったような気がします)
Toshiyuki Ando さんが13年以上前に更新
- 期日 を 2010/10/03 にセット
- ステータス を 新規(New) から 解決(Resolved) に変更
- 担当者 を Toshiyuki Ando にセット
- 対象バージョン を 1.0.7 にセット
Toshiyuki Ando さんが13年以上前に更新
他にも困ってる人 が出てきたので 何とか対応。
サブクエリにLIMITが使えないので、
1) 削除するビルドの中で最大の番号を取得する
2) その番号以下のビルドを全部消す
という方法に切り替えたんだけど、 1 が微妙に面倒だった。
HudsonBuild.find(:last, :conditions => "hudson_job_id = job_id", :order => "number ASC", limit => "削除する件数")
でいけると思ったんだけど、何故か ActiveRecord のクエリは order を number DESC で発行する。
どーも、:last の場合は、並び順を逆にして最初の1件目を取り出そうとするらしい。
- 100件のデータを降順に並べて10件目までを取り出し、最後のデータを取り出す。
- 100件のデータを昇順に並べて10件目までを取り出し、最初のデータを取り出す。
だと、結果違うんだけど…。
仕方ないので、並び順を変更されないように、 all で取得することに。
さすがに、1件しか必要ないのに、全レコードをインスタンスかするのは無駄すぎるので、offset で 最後の1件だけ取り出すように指定してみた。
HudsonBuild.find(:all, :conditions => "hudson_job_id = job_id", :order => "number ASC", limit => "削除する件数", :offset => "削除する件数 - 1")
もうちょっと賢いやり方ありそうな気がするんだけどなぁ…。