プロジェクト

全般

プロフィール

Defect #515

ビルドの保存の設定時にエラー

Akiko Takano7年以上前に追加. 7年以上前に更新.

ステータス:
終了(Closed)
優先度:
通常(Normal)
担当者:
対象バージョン:
開始日:
2010/08/10
期日:
2010/10/03
進捗率:

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回でもビルド履歴を取得できれば、その後はエラーにならない。

既知の問題でしたら、大変申し訳ありません。
まずはご報告まで。

hudson-job-issue.png (1.92 KB) hudson-job-issue.png Hudson設定画面での指定 (このような感じで設定するとエラー) Akiko Takano, 2010/08/10 12:43
205

関係しているリビジョン

リビジョン 157:aa1d81739d96 (差分)
Toshiyuki Ando7年以上前に追加

refs #515
  • build rotator doesn't use limit in subquery. ( for mysql )
  • build rotator test can't detect "num to keep" 's bug

履歴

#1 Toshiyuki Ando7年以上前に更新

ご連絡ありがとうございます。
旅行中なので、帰ってからコードみてみます。

MySQL はLimit使えないんですね。うーむ。どうしたものか。

#2 Akiko Takano7年以上前に更新

お休みのところ、メッセージありがとうございます。
特に非常に困る、という状況ではありませんので、ご報告まで、ということで扱っていただければと思います。

また、本番で利用しているMySQLは5.0だったと思います。こちらは不具合があるかどうかはまだ確認していません。(少なくともLIMITに関するエラーは無かったような気がします)

#3 Toshiyuki Ando7年以上前に更新

サブクエリ内でINを使った場合は、LIMITが使えないみたい。
クエリは長くなるけど OR を使ったほうがよさそう。

#4 Toshiyuki Ando7年以上前に更新

  • 期日2010/10/03 にセット
  • ステータス新規(New) から 解決(Resolved) に変更
  • 担当者Toshiyuki Ando にセット
  • 対象バージョン1.0.7 にセット

#5 Toshiyuki Ando7年以上前に更新

他にも困ってる人 が出てきたので 何とか対応。

サブクエリに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")

もうちょっと賢いやり方ありそうな気がするんだけどなぁ…。

#6 Toshiyuki Ando7年以上前に更新

  • 対象バージョン1.0.7 から 1.0.6.1 に変更

#7 Toshiyuki Ando7年以上前に更新

  • ステータス解決(Resolved) から 終了(Closed) に変更
  • 進捗率0 から 100 に変更

他の形式にエクスポート: Atom PDF