Slide 1

Slide 1 text

進行中の開発プロジェクトで 増えていくテストを自動で回し続けるために 行ったいくつかのこと 株式会社Aiming エンジニア 黒木 慎介

Slide 2

Slide 2 text

自己紹介 • 黒木 慎介 • Aimingのエンジニア(よくお昼寝している) • 主にRuby on Railsでお仕事 • Jenkins歴は3年くらい

Slide 3

Slide 3 text

今日話すこと • あるプロジェクトでのJenkins – 使い方 – 増えすぎたテスト件数≒実行時間との戦い – 増えすぎた実行頻度との戦い – 心構え • AimingでのJenkinsの使い方紹介

Slide 4

Slide 4 text

あるプロジェクト • PC向けブラウザゲーム • Ruby on Rails + CoffeeScript + Backbone.js + α • 2011-12年にかけての約8ヶ月で開発 • 最初2人→最後10人で開発

Slide 5

Slide 5 text

Jenkinsの使い方 • テストの実行 – Rspec(Ruby on Railsのテスト) • ci_reporterを使用 – Jasmine(JavaScriptのテスト)

Slide 6

Slide 6 text

ci_reporter • Rubyのgem • RSpecの実行結果をXML出力する • Jenkinsは、このXMLを読んで – テストの成功件数・失敗件数を表示できる – ジョブのページで、失敗したテストの情報を表示 できる

Slide 7

Slide 7 text

増えすぎたテスト件数≒実行時間との戦い

Slide 8

Slide 8 text

増えるテスト件数 ※再現イメージです

Slide 9

Slide 9 text

増えるテスト件数 ※再現イメージです

Slide 10

Slide 10 text

増えるテスト件数 ※再現イメージです

Slide 11

Slide 11 text

増えるテスト件数 ※再現イメージです

Slide 12

Slide 12 text

増えるテスト件数 ※再現イメージです

Slide 13

Slide 13 text

地獄 • テスト7000件越え • 実行時間1時間越え • 手元でのテスト全件実行が困難→自動テスト の重要性は増す

Slide 14

Slide 14 text

地獄 • テスト7000件越え • 実行時間1時間越え • 手元でのテスト全件実行が困難→自動テスト の重要性は増す – 引き下がるわけには行かない!!

Slide 15

Slide 15 text

対策 • 分割して並行に実行 – スレーブ(VM上)を2台から6台に増設 – テストをカテゴリ別に分割して実行

Slide 16

Slide 16 text

分割に便利なもの(1):ラベル付け テスト全件 60分

Slide 17

Slide 17 text

分割に便利なもの(1):ラベル付け カテゴリA 20分 カテゴリB カテゴリC D 20分 15分 5分

Slide 18

Slide 18 text

分割に便利なもの(1):ラベル付け カテゴリA 20分 カテゴリB カテゴリC D 20分 15分 5分

Slide 19

Slide 19 text

分割に便利なもの(1):ラベル付け ノードの設定画面で:

Slide 20

Slide 20 text

分割に便利なもの(1):ラベル付け ノードの設定画面で:

Slide 21

Slide 21 text

分割に便利なもの(1):ラベル付け ジョブの設定画面で:

Slide 22

Slide 22 text

分割に便利なもの(1):ラベル付け ジョブの設定画面で:

Slide 23

Slide 23 text

分割に便利なもの(1):ラベル付け

Slide 24

Slide 24 text

分割に便利なもの(2):Join Plugin • Aが成功したら、BとCを実行して、両方成功し たらDを実行する • 最後にメトリクス計測とか

Slide 25

Slide 25 text

分割に便利なもの(2):Join Plugin

Slide 26

Slide 26 text

分割に便利なもの(2):Join Plugin

Slide 27

Slide 27 text

分割に便利なもの(3):Build Pipeline Plugin

Slide 28

Slide 28 text

増えすぎた実行頻度との戦い

Slide 29

Slide 29 text

Gerrit • レビューシステム • ある変更がレビューを経てどう変化したかを 差分として見ることができる

Slide 30

Slide 30 text

Gerrit Trigger Plugin • Gerritのレビュー依頼が提出されたら、 Jenkinsのジョブを実行 • 提出された全ての変更が対象

Slide 31

Slide 31 text

Gerritレビューの流れ

Slide 32

Slide 32 text

Gerritレビューの流れ

Slide 33

Slide 33 text

Gerritレビューの流れ

Slide 34

Slide 34 text

Gerritレビューの流れ

Slide 35

Slide 35 text

Gerritレビューの流れ

Slide 36

Slide 36 text

Gerrit Trigger Plugin • Gerritのレビュー依頼が提出されたら、 Jenkinsのジョブを実行 • 提出された全ての変更が対象

Slide 37

Slide 37 text

そのとき、Gerrit Triggerは

Slide 38

Slide 38 text

そのとき、Gerrit Triggerは

Slide 39

Slide 39 text

そのとき、Gerrit Triggerは

Slide 40

Slide 40 text

そのとき、Gerrit Triggerは

Slide 41

Slide 41 text

そのとき、Gerrit Triggerは

Slide 42

Slide 42 text

地獄 • Jenkinsの実行が開発のペースに追いつかな い – 1回のレビュー提出で変更10個以上とか普通 – 増える開発人数 – 提出された差分のテストが終わらないうちに修正 再提出された差分のテストが積まれたり – 朝来てもビルドキューが空になってない

Slide 43

Slide 43 text

地獄 • Jenkinsの実行が開発のペースに追いつかな い – 1回のレビュー提出で変更10個以上とか普通 – 増える開発人数 – 提出された差分のテストが終わらないうちに修正 再提出された差分のテストが積まれたり – 朝来てもビルドキューが空になってない • Jenkinsの完了を待たずにマージ

Slide 44

Slide 44 text

地獄、しかし • 開発人員が増え、ペースが上がっていた • その分、テストが壊れる頻度もあがっていた

Slide 45

Slide 45 text

地獄、しかし • 開発人員が増え、ペースが上がっていた • その分、テストが壊れる頻度もあがっていた – 引き下がるわけには行かない!!

Slide 46

Slide 46 text

無駄なテスト実行を減らしたい • 既にマージされてる変更のテスト • 既に修正再提出されている変更の元のテスト • テストは成功終了でも失敗終了でもなく中断 させたい – テストしてないのに青や赤をつけたくないので

Slide 47

Slide 47 text

Jenkinsのジョブを中断 % exit 0 % exit 1 ? → → →

Slide 48

Slide 48 text

普段我々はどうやって Jenkinsのジョブを中断しているだろうか?

Slide 49

Slide 49 text

普段我々はどうやって Jenkinsのジョブを中断しているだろうか?

Slide 50

Slide 50 text

Webから止めればいいじゃない!! • JenkinsのWebから中断ボタンを押した時には、 所定のURLにgetしているだけだった • 同じurlをcurlで叩く • そのあとsleepすることで次の処理の開始を抑 止する % curl http://jenkins/job/my_project_a/$BUILD_NUMBER/stop && sleep 60

Slide 51

Slide 51 text

心構え

Slide 52

Slide 52 text

心構え(1) • Jenkinsがやってくれるのは自動化だけ – 自動化する処理は自前 – だからこそ頑張り次第でいろいろできる

Slide 53

Slide 53 text

心構え(2) • Pluginのドキュメントをちゃんと読む – Jenkins Wiki – 必要な情報はだいたい変数に入れてある – それでも挙動がよくわからんときはある、が…

Slide 54

Slide 54 text

心構え(3) • なんだったらコードも読む – だいたいGithubにある ここからレポジトリへ

Slide 55

Slide 55 text

今日話すこと • あるプロジェクトでのJenkins – 使い方 – 増えすぎたテスト件数≒実行時間との戦い – 増えすぎた実行頻度との戦い – 心構え • AimingでのJenkinsの使い方紹介

Slide 56

Slide 56 text

今日話すこと • あるプロジェクトでのJenkins – 使い方 – 増えすぎたテスト件数≒実行時間との戦い – 増えすぎた実行頻度との戦い – 心構え • AimingでのJenkinsの使い方紹介

Slide 57

Slide 57 text

AimingでのJenkinsの使い方 • ビルド – Android, iOS – ゲームサーバー(C++) • テスト実行 • デプロイ • サーバー再起動 • データチェック

Slide 58

Slide 58 text

結果の通知

Slide 59

Slide 59 text

データチェックをJenkinsで • 企画の人が作ったマスターデータ(Excelとcsv で、svnで管理)を、取り込んでデプロイ • データにミスがあるとデプロイが止まって困る • 取り込み部分だけをジョブ化 →ミスがあっても事前にわかる!

Slide 60

Slide 60 text

提供 ご清聴ありがとうございました!

Slide 61

Slide 61 text

時間が余った時用

Slide 62

Slide 62 text

分割に便利なもの(4):rakeのオプション • Ruby on Rails固有 • modelsだけで1時間かかるようになり、さらな る分割を行う方法として導入 • コマンドラインオプションで、実行するテストの ファイル名をパターン指定できる % rake spec SPEC='spec/models/**/[a-l]*_spec.rb‘

Slide 63

Slide 63 text

分割に便利なもの(4):rakeのオプション • コマンドラインオプションで、rspecに渡すオプ ションを指定できる • テスト項目にタグをつけておいて、tオプション でそれだけ流す/除外して流す % rake spec SPEC_OPTS=‘-t debt‘ % rake spec SPEC_OPTS=‘-t ~debt‘

Slide 64

Slide 64 text

既にマージされているか • Gerritのqueryコマンドを使う • status: mergedの結果の中に同じchange numberのものがあれば、マージされていると 判断できる % ssh -p 29418 -l s-kuroki gerrit_host ‘gerrit query project:my_project status:merged’ |grep "number: $GERRIT_CHANGE_NUMBER"

Slide 65

Slide 65 text

次のパッチセットが提出されているか • 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))