くりにっき

フルスタックキュアエンジニアです

Jenkinsにスローテストのグラフを表示する

RSpecでは --profile オプションをつけることで

$ rspec --profile

Top 10 slowest examples (17.92 seconds, 65.4% of total time):
AndroidMarket use stub content behaves like android_market_base_examples #get_overall_top_selling_new_paid_apps
1.96 seconds ./spec/android_market_spec.rb:121
AndroidMarket use stub content behaves like android_market_base_examples #get_top_selling_paid_apps_in_category
1.94 seconds ./spec/android_market_spec.rb:92
 (略)

のようなスローテストのトップ10(ワースト10)を出すことができるのですが、これをJenkinsでグラフ化できたら便利かなぁと思ってスクリプトを書いてみました。

gist

使い方

1. JenkinsにPlot Plugin を入れる

2. Jenkinsでrspecを動かす時に標準出力をログファイルに出力し、それを前述の plot-rspec-slowest-examples.rb に読ませる。

通常だったら

rspec

ってやるところを

rspec --profile 5 > rspec-console.log
ruby plot-rspec-slowest-examples.rb rspec-console.log > plot-rspec-slowest-examples.csv

のようにします。profileの後の数字は出力する上位件数です。(デフォルトだと上位10件)

出力されたcsv
total,top 1,top 2,top 3,top 4,top 5,
8,1.67,1.59,1.59,1.58,1.58,

3. 上記で出力したcsvをplot pluginで読み込ませる

f:id:sue445:20130317015049p:plain

グラフ化した結果

f:id:sue445:20130315141739p:plain

テスト全体に対して1つだけ突出しているのがあればそこを見直すだけでスローテストを改善できると思います。*1

*1:既出かどうかは知らん

Jenkinsのビルド後にgh-pagesにpushする

以前書いた GithubのリポジトリでJavaDocを公開する - sue445's Blog というエントリでJavaDocをgh-pagesに公開する方法書いていましたが、それをJenkinsで自動化してみます。

0. 前提

上記のエントリを参考にmavenJavaDocが作られるようにしておいてください

1. Post build task pluginをインストールする

Jenkinsのビルド終了後に任意のスクリプトを実行するためのプラグイン

Post build task - hudson - Hudson Wiki

2. gh-pagesにpushするスクリプトをワークスペースに入れる

https://github.com/sue445/s3tiger/blob/master/script/deploy-gh-pages.sh

を参考に。REPO_URLの部分は適宜変えてください。

3. Jenkinsのジョブ設定に追加する

ビルド

f:id:sue445:20130211214825p:plain

test compile site

ビルド後の処理の追加 → Post build task

f:id:sue445:20130211214851p:plain

./script/deploy-gh-pages.sh "$WORKSPACE" "$BUILD_NUMBER" "$BUILD_ID"

4. ディレクトリ構成

だいたいこんな感じになります

workspace
  script/
    deploy-gh-pages.sh …ビルド後にsiteをtmp/repoにコピーしてgithubにpushする
  site/ …mavenで作られたJavaDocファイルなど
  tmp/
    repo/ …gh-pagesにpushするための作業ディレクトリ

うまくいけばtmp/repoがgithubにpushされるはず

おまけ

Jenkinsを動かしてるユーザ (自分の場合はtomcatユーザ) のメールアドレスを Gravatar に登録しておけばJenkinsの顔をgithubに表示させることもできます

f:id:sue445:20130211215608p:plain
https://github.com/sue445/s3tiger/commit/b70f851e8339723488d4731dd6e9410069643988

最後に

今回はmavenで作ったJavaDocをgh-pagesにpushしましたが、応用すれば他の静的ファイルでもアップロードできると思います。

JenkinsのXFDを作ってました

XFD自体は結構前に作ってたのですがブログのネタに困ったので今更紹介してみます

f:id:sue445:20130129224414j:plain:w320

使い方

ZIPでダウンロード
f:id:sue445:20130129234340p:plain

または

git clone git@github.com:sue445/jenkins_xfd.git

config.js.sample をconfig.js にリネームして設定を入れる

http://sue445.github.com/jenkins_xfd/ で使ってるのだとこんな感じ

var config = {
    job_urls : [
        "http://ci.sue445.net/jenkins/job/azusaar/",
        "http://ci.sue445.net/jenkins/job/azusaar_js/",
        "http://ci.sue445.net/jenkins/job/jubeatplusplus/",
        "http://ci.sue445.net/jenkins/job/kulib/",
        "http://ci.sue445.net/jenkins/job/s3tiger/",
    ],
    reload_seconds : 30
};

あとはファイルをブラウザで開けばXFD完成

特徴

  • ダウンロードして設定を書き換えるだけなのでシンプル
  • 静的ファイルしか使ってないため、githubのgh-pageで動かすこともできる
  • ビルド中は項目が点滅
  • JenkinsのREST APIしか使っていないので別途pluginは不要
    • ググってるとWebSocket pluginを使った事例が多かったのですが、CloudbeesのDEV@FREEだとWebSocket pluginが使えなかったため苦肉の策でREST APIだけで作りました
  • デザインはiPad用に最適化
    • 仕事だと「リポジトリにpush → Jenkinsに通知 → rspec実行 → 手元のiPadでビルド結果を確認」ということをやってます

f:id:sue445:20130129224414j:plain:w320

注意点

  • Jenkinsにログインしない状態で使いたい場合には「グローバルセキュリティの設定」で、匿名ユーザに対して「全体のRead」「ジョブのRead」の権限が必要 f:id:sue445:20130130000541p:plain
  • Cloudbeesだと一度ログインしていないとJenkinsのAPIにアクセスできない *1
  • .gitignore でconfig.js を登録してるため、gh-pagesにpushしたい場合は .gitignore 内の記述を削除してください
  • n番煎じです(´・ω・`)

*1:Jenkinsの認証とCloudbeesの認証は別物

個人でJenkinsを入れるために比較したこと

個人でJenkinsを入れてみたかったのでいろいろ調べてました

  • 料金体系は個人の小遣いで使える範囲(月数千円)でしか比較していません
  • 為替レートは $1 = 90円 で計算しています

CloudBees: The Java PaaS Company

Jenkinsのクラウドサービスで「DEV@cloud」というのがあります

料金体系

FREEの制限事項

  • 一度に実行できるビルドは1つだけ
  • ビルドは月300回月300分まで
  • Community plugins(プラグインマネージャーからのプラグインのインストール)が使えないため、使えるプラグインはデフォルトでインストールされているEssential pluginsのみに限られる

DEV@cloud自体の制限事項

  • Jenkinsの外側にcloudbeesの認証があるため、通常のやり方だとbuild hookが通らない
    • Githubに関してはGithub pluginを使えば問題なし
    • Bitbucketもできるみたいなんだけど、URLにパスワードを書かなきゃいけないのが・・・
      • http://developer.cloudbees.com/bin/view/DEV/Bitbucket
      • Bitbucketからの通知用にCloundbeesのアカウントをもう1つ作ったけどうまくいかず
      • ポーリングすればビルドできるけど、ポーリングした回数もビルドの回数に含まれるのであまり頻繁にはできない
      • 1分おきにポーリングしてるとすぐに制限オーバーします(経験者談)
    • CloudbeesがJenkinsとは別に提供してるCloudBees Forge(無料でGitとSVNのprivate repoository)があるので、bitbucketの人はそれを使うのがよさそう
      • ビルドトリガで設定できるのもよい f:id:sue445:20130123001158p:plain
      • 純粋なリポジトリ機能のみで、wikiとかissue管理はないです

制限はいろいろあるものの一通りセットアップされているためアカウント作成直後にすぐにJenkinsを使えるのは嬉しい

Amazon EC2

料金体系

  • http://aws.amazon.com/jp/ec2/#pricing
  • micro: 1時間あたり$0.027 = 月$19.44 = 月1749.6円
    • 最初1年間は無料で使える
  • small: 1時間あたり$0.092 = 月$66.24 = 月5961.6円

最初はmicroインスタンスでJenkinsを構築してたのですが、メモリ613MBしかないのが結構きついです

  • Javaのテストだとtomcatmavenで実質2つJavaが立ち上がることになるので、ピーキーなメモリ配分が求められるw
  • ビルド中に何度メモリ不足でビルドが突然死したことかorz
  • スペック表のCPUの欄に「最大2 EC2 コンピューティングユニット(ECU)(短期の定期的なバースト)」とあるけど、どうも1コア以下のスペックらしいのでビルドが走っているとJenkins自体がまともに動かない

さくらVPS

料金体系

  • 1G: 月980円
    • 仮想2コア
  • 2G: 月1480円
    • 仮想3コア
    • 自分の時は石狩リージョンだと期間限定で初期費用無料
  • 4G: 月3980円 + 初期費用5980円
    • 仮想4コア

自分が出した結論

  • Cloudbeesだとbitbucketとの連携がうまくいかなかったので断念 (単に自分のスキル不足なわけですが)
  • Amazon EC2はmicroインスタンスだとまともにJenkinsが使えないし、その次に安いsmallインスタンスだと月6000円に跳ね上がるため断念
  • さくらVPSだと値段の割にスペックが高め
    • 1Gと2Gで迷ったけど、メモリ1GBだと若干心配だったので2Gを選択
    • スペック高い方がビルドが早く終わるのが良いですね

まとめ

  • とりあえずさくっと使いたいならDEV@cloud のFREEを選択
  • そこで物足りなくなったらDEV@cloud BASEかさくらVPS(1Gか2G)を検討
  • 個人でJenkinsを使うためだけにAmazon EC2はきつい
  • 自宅サーバある人はそこに入れるのがいいと思う ( ´∀`)
                  • -

追記

Twitterでのやり取りを追記

microインスタンスを2つ利用&使わない時はインスタンス落とすという発想はなかった

デメリット

  • push前にEC2インスタンス起動→nginx or apache起動*1tomcat起動という手順が発生するので手間
    • jobのinstance起動はpluginでなんとかなるみたいだけどJenkins本体に関しては手動で上げないとダメな気がする
    • 面倒くさいと忘れる(にんげんだもの)
  • microインスタンスはスペックがしょぼいためテストが遅い
                  • -

2013/11/7追記

指摘をうけて修正

http://www.cloudbees.com/platform/pricing/devcloud.cb

「up to 300 per month」って月300回までじゃなくて月300分までって意味だったのかorz

*1:tomcatで直接アクセスを受けてる場合は不要

JenkinsでJavaScriptのテストをやってみる

調べてたらphantomjsを使うかnodeを使うかの2つが主流だったのですが、自分の場合元々phantomjsでの自動テストの仕組みがあったため前者でいくことにしました。

phantomjsでのJavaScriptのテストの自動化については過去のエントリを御覧ください

AZusaar! を全面リファクタリングしました - くりにっき

1. phantomjsをインストールする

Build Instructions を参考にコンパイルする。

build.shの冒頭で

----------------------------------------
               WARNING
----------------------------------------

Building PhantomJS from source takes a very long time, anywhere from 30 minutes
to several hours (depending on the machine configuration). It is recommended to
use the premade binary packages on supported operating systems.

For details, please go the the web site: http://phantomjs.org/download.html.

とあるようにコンパイルにすごく時間がかかります。

参考

  • さくらVPS 2G: 15〜20分くらい
  • EC2 micro: 一晩w

無事コンパイルができたらパスが通っているところにバイナリをコピーします

sudo cp bin/phantomjs /usr/local/bin/

バイナリで43MBとかどういうことですか (;´Д`)

$ ls -l /usr/local/bin/phantomjs
-rwxr-xr-x 1 root root 43212931  116 01:44 2013 /usr/local/bin/phantomjs

3. ジョブの設定

TAPの結果をファイルに出力して、それをTAP pluginに食わせてやればOK

自分の場合はこんな感じ
f:id:sue445:20130120000452p:plain

./test/phantomjs_test.sh の中身はこういう風になっています
https://github.com/sue445/azusaar_js/blob/master/test/phantomjs_test.sh

さくらVPSにnginx + Tomcat7の構成でJenkinsを入れてみる

さくらVPSにJenkinsを入れた時のメモ。
さくらVPSを使うかAmazon EC2を使うか迷ってたのですが、その辺の経緯はまた別の機会に書きます。

1. さくらVPSに登録する

http://vps.sakura.ad.jp/
お好みのプランを選択。僕は2Gを選びました

ログイン情報がメールで来るまで少しラグがあるため、その間にインスタンスを立ち上げます

さくらインターネットVPSコントロールパネル

f:id:sue445:20130115000657p:plain

2. ログインしてユーザを作る

メールがきたらログインできます

ssh root@【さくらVPSのホスト名】 

でログイン

Are you sure you want to continue connecting (yes/no)?

って聞かれるのでyesを入力。あとはメールに書いてあったパスワードを入れる

下記を参考にユーザ追加とsshの公開鍵登録までやる

「さくらのVPS」借りてみた(作業ユーザー作成,SSH設定) - rubellum's blog


rootのパスワードを変えるのも忘れずに

passwd


毎回ホスト名やパスワードを入れるのは大変なのでローカルPCの ~/.ssh/config に

Host my-vps
  HostName 【ホスト名】
  Port 22
  IdentityFile  ~/.ssh/id_rsa
  User          【yourname】

みたいに書いておくと、次からは

ssh my-vps

でログインできるので便利

3. Tomcat7をインストールする

yumでjenkinsを入れるのが一番手っ取り早いのですが、JENKINS_HOMEが /var/lib/jenkins/ から変えられない(?) のが気になったのでtomcatから入れることにしました。*1

バイナリから入れるのは面倒くさいのでパッケージ管理ツールを使います

tomcat7はデフォルトのリポジトリにはないので追加する

sudo yum -y install yum-plugin-priorities
sudo rpm -Uvh http://mirrors.dotsrc.org/jpackage/6.0/generic/free/RPMS/jpackage-release-6-3.jpp6.noarch.rpm

tomcat7をインストール

sudo yum install tomcat7-webapps

設定ファイルを編集する

sudo cp -a /usr/share/tomcat7/conf/tomcat7.conf{,.YYYYMMDD}
sudo vi /usr/share/tomcat7/conf/tomcat7.conf

メモリやJENKINS_HOMEの値はお好みで設定する

JAVA_OPTS="-Xminf0.1 -Xmaxf0.3 -Duser.timezone=Asia/Tokyo -Xms64m -Xmx256m"
LANG="ja_JP.UTF-8"
JENKINS_HOME="/data/jenkins"

忘れないようにJENKINS_HOMEを作る

sudo mkdir -p /data/jenkins
sudo chown tomcat /data/jenkins/
sudo chgrp tomcat /data/jenkins/

tomxatの設定をいじる

sudo cp -a /usr/share/tomcat7/conf/server.xml{,.YYYYMMDD}
sudo vi /usr/share/tomcat7/conf/server.xml

8080で検索して

    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8" />

のように、「URIEncoding="UTF-8"」 を付け加える。

tomcatの起動は

sudo /etc/init.d/tomcat7 start

起動確認

wget http://localhost:8080

ここでステータスコード200が返ってきてればOK

4. nginxのインストール

同じくyumを利用。apacheを使うかnginxを使うかは好みでいいと思います。
自分の場合仕事でnginxを使うことが多いのでnginxをフロントに立てています。*2

sudo yum install nginx
sudo mkdir /etc/nginx/sites-available
sudo mkdir /etc/nginx/sites-enabled

設定ファイルの編集

sudo cp -a /etc/nginx/nginx.conf{,.YYYYMMDD}
sudo vi /etc/nginx/nginx.conf

下記の場所に「include sites-enabled/*;」を追加する

http {
    (中略)

    include /etc/nginx/sites-enabled/*;
}

sites-enabledに設定ファイルを追加

sudo vi /etc/nginx/sites-available/tomcat
upstream tomcat {
  server 127.0.0.1:8080;
}

server {
  listen 80;
  server_name some.yourdomain.com;

  access_log /var/log/nginx/tomcat_access.log;
  error_log  /var/log/nginx/tomcat_error.log;

  root /var/www/tomcat;

  # for Jenkins plugin upload
  client_max_body_size 20M;

  location / {
    if (-f $request_filename) {
      access_log off;
      expires 1h;
      break;
    }

    if (!-f $request_filename) {
      proxy_pass http://tomcat;
      break;
    }
  }
}

document rootを作る

sudo mkdir -p /var/www/tomcat

sites-enabledにシンボリックリンクを作る

sudo ln -s /etc/nginx/sites-available/tomcat /etc/nginx/sites-enabled/tomcat


設定ファイルが正しいかどうかチェック

sudo /etc/init.d/nginx configtest

nginx起動

sudo /etc/init.d/nginx start

5. Jenkinsインストール

mkdir /tmp/
cd /tmp/
wget http://mirrors.jenkins-ci.org/war/latest/jenkins.war

最新版のwarを取得してwebappsに配置する

sudo -u tomcat cp /tmp/jenkins.war /usr/share/tomcat7/webapps/

ちゃんとデプロイされてるかどうかログを見る

tail -f /usr/share/tomcat7/logs/catalina.out

アップデートする前には念のためwarはどっかにbackupした方がいいです

6. Github/Bitbucket連携

Tomcattomcatユーザで実行されるため、tomcatユーザで秘密鍵と公開鍵を作る

基本的にはgithubに書いてあることをtomcatユーザで行えばいいです
https://help.github.com/articles/generating-ssh-keys

tomcatユーザのホームディレクトリを調べる

grep tomcat /etc/passwd
tomcat:x:91:91:Apache Tomcat:/usr/share/tomcat7:/bin/sh

上記だと /usr/share/tomcat7 がホームディレクトリ

sudo chown tomcat /usr/share/tomcat7
sudo chgrp tomcat /usr/share/tomcat7
sudo mkdir -m 700 /usr/share/tomcat7/.ssh
sudo chown tomcat /usr/share/tomcat7/.ssh
sudo chgrp tomcat /usr/share/tomcat7/.ssh
sudo -u tomcat ssh-keygen -t rsa -C "your_email@youremail.com"
sudo -u tomcat chmod 600 /usr/share/tomcat7/.ssh/id_rsa
sudo -u tomcat cat /usr/share/tomcat7/.ssh/id_rsa.pub

出てきた公開鍵をGithubやBitbucketに登録する

最初に手動1回接続してknown_hostsに登録しておかないとJenkinsでcloneできない。

sudo -u tomcat ssh -T git@github.com
sudo -u tomcat ssh -T git@bitbucket.org

これもtomcatユーザで実行するのがポイント


これでURLにアクセスすればJenkinsが使えるようになってると思います。

*1:ファイルサイズが大きくなりそうな時は /data/ に入れた方がいいってばっちゃが言ってた

*2:apacheも高互換性コンピューター言語「XML」を使っているのでいいと思います