2013/6/18 第6回テックヒルズにて発表
進行中の開発プロジェクトで増えていくテストを自動で回し続けるために行ったいくつかのこと株式会社Aimingエンジニア黒木 慎介
View Slide
自己紹介• 黒木 慎介• Aimingのエンジニア(よくお昼寝している)• 主にRuby on Railsでお仕事• Jenkins歴は3年くらい
今日話すこと• あるプロジェクトでのJenkins– 使い方– 増えすぎたテスト件数≒実行時間との戦い– 増えすぎた実行頻度との戦い– 心構え• AimingでのJenkinsの使い方紹介
あるプロジェクト• PC向けブラウザゲーム• Ruby on Rails + CoffeeScript + Backbone.js + α• 2011-12年にかけての約8ヶ月で開発• 最初2人→最後10人で開発
Jenkinsの使い方• テストの実行– Rspec(Ruby on Railsのテスト)• ci_reporterを使用– Jasmine(JavaScriptのテスト)
ci_reporter• Rubyのgem• RSpecの実行結果をXML出力する• Jenkinsは、このXMLを読んで– テストの成功件数・失敗件数を表示できる– ジョブのページで、失敗したテストの情報を表示できる
増えすぎたテスト件数≒実行時間との戦い
増えるテスト件数※再現イメージです
地獄• テスト7000件越え• 実行時間1時間越え• 手元でのテスト全件実行が困難→自動テストの重要性は増す
地獄• テスト7000件越え• 実行時間1時間越え• 手元でのテスト全件実行が困難→自動テストの重要性は増す– 引き下がるわけには行かない!!
対策• 分割して並行に実行– スレーブ(VM上)を2台から6台に増設– テストをカテゴリ別に分割して実行
分割に便利なもの(1):ラベル付けテスト全件60分
分割に便利なもの(1):ラベル付けカテゴリA20分カテゴリB カテゴリC D20分 15分 5分
分割に便利なもの(1):ラベル付けノードの設定画面で:
分割に便利なもの(1):ラベル付けジョブの設定画面で:
分割に便利なもの(1):ラベル付け
分割に便利なもの(2):Join Plugin• Aが成功したら、BとCを実行して、両方成功したらDを実行する• 最後にメトリクス計測とか
分割に便利なもの(2):Join Plugin
分割に便利なもの(3):Build Pipeline Plugin
増えすぎた実行頻度との戦い
Gerrit• レビューシステム• ある変更がレビューを経てどう変化したかを差分として見ることができる
Gerrit Trigger Plugin• Gerritのレビュー依頼が提出されたら、Jenkinsのジョブを実行• 提出された全ての変更が対象
Gerritレビューの流れ
そのとき、Gerrit Triggerは
地獄• Jenkinsの実行が開発のペースに追いつかない– 1回のレビュー提出で変更10個以上とか普通– 増える開発人数– 提出された差分のテストが終わらないうちに修正再提出された差分のテストが積まれたり– 朝来てもビルドキューが空になってない
地獄• Jenkinsの実行が開発のペースに追いつかない– 1回のレビュー提出で変更10個以上とか普通– 増える開発人数– 提出された差分のテストが終わらないうちに修正再提出された差分のテストが積まれたり– 朝来てもビルドキューが空になってない• Jenkinsの完了を待たずにマージ
地獄、しかし• 開発人員が増え、ペースが上がっていた• その分、テストが壊れる頻度もあがっていた
地獄、しかし• 開発人員が増え、ペースが上がっていた• その分、テストが壊れる頻度もあがっていた– 引き下がるわけには行かない!!
無駄なテスト実行を減らしたい• 既にマージされてる変更のテスト• 既に修正再提出されている変更の元のテスト• テストは成功終了でも失敗終了でもなく中断させたい– テストしてないのに青や赤をつけたくないので
Jenkinsのジョブを中断% exit 0% exit 1?→→→
普段我々はどうやってJenkinsのジョブを中断しているだろうか?
Webから止めればいいじゃない!!• JenkinsのWebから中断ボタンを押した時には、所定のURLにgetしているだけだった• 同じurlをcurlで叩く• そのあとsleepすることで次の処理の開始を抑止する% curl http://jenkins/job/my_project_a/$BUILD_NUMBER/stop&& sleep 60
心構え
心構え(1)• Jenkinsがやってくれるのは自動化だけ– 自動化する処理は自前– だからこそ頑張り次第でいろいろできる
心構え(2)• Pluginのドキュメントをちゃんと読む– Jenkins Wiki– 必要な情報はだいたい変数に入れてある– それでも挙動がよくわからんときはある、が…
心構え(3)• なんだったらコードも読む– だいたいGithubにあるここからレポジトリへ
AimingでのJenkinsの使い方• ビルド– Android, iOS– ゲームサーバー(C++)• テスト実行• デプロイ• サーバー再起動• データチェック
結果の通知
データチェックをJenkinsで• 企画の人が作ったマスターデータ(Excelとcsvで、svnで管理)を、取り込んでデプロイ• データにミスがあるとデプロイが止まって困る• 取り込み部分だけをジョブ化→ミスがあっても事前にわかる!
提供ご清聴ありがとうございました!
時間が余った時用
分割に便利なもの(4):rakeのオプション• Ruby on Rails固有• modelsだけで1時間かかるようになり、さらなる分割を行う方法として導入• コマンドラインオプションで、実行するテストのファイル名をパターン指定できる% rake spec SPEC='spec/models/**/[a-l]*_spec.rb‘
分割に便利なもの(4):rakeのオプション• コマンドラインオプションで、rspecに渡すオプションを指定できる• テスト項目にタグをつけておいて、tオプションでそれだけ流す/除外して流す% rake spec SPEC_OPTS=‘-t debt‘% rake spec SPEC_OPTS=‘-t ~debt‘
既にマージされているか• Gerritのqueryコマンドを使う• status: mergedの結果の中に同じchangenumberのものがあれば、マージされていると判断できる% ssh -p 29418 -l s-kuroki gerrit_host‘gerrit query project:my_project status:merged’|grep "number: $GERRIT_CHANGE_NUMBER"
次のパッチセットが提出されているか• git ls-remoteで確認f4a80a6171d8287 refs/changes/96/2996/3→change number2996のPatch set 3% git ls-remote|grep $GERRIT_CHANGE_NUMBER/$((GERRIT_PATCHSET_NUMBER + 1))