Jenkins 導入と MATLAB の自動テスト (教員のための Mac Tips:9)

背景

校務支援システムの業者とのやりとりの中で、テスト状況を共有したいとの依頼があり、Jenkins を導入することになりました。もともと開発自体は私一人でやっていたので、autotest によるファイル更新時の自動テストで済ませていたのですが、Jenkins でコミット時の全体テストを行うようにしました(テストをかなりサボっていますが、それでも一度テストが動き出すと10分くらいは帰ってきません)。とりいそぎ開発者ではない管理課の職員でもブラウザ上でテスト状況が確認できるようになりました。

Jenkins の存在は知ってはいたものの、今まで使っていたわけではなかったので、図書館で本を借りて急ぎ学習しました。せっかく学習したわけですから、知識を無駄にするのも勿体ないということで、早速自分の手元のマシンにもインストールして使ってみました。今回は使用例も含めてその報告をしたいと思います。

インストール

今回は homebrew でインストールしました。homebrew については一度記事にしようとは思っていますが、今回は Jenkins のお話なので、導入については割愛します。homebrew が使える環境であれば、以下のコマンドで Jenkins がインストールされます。

brew install jenkins

homebrew でインストールすると、自分のホームフォルダ下に .jenkins というフォルダが作成されて、そこが作業場所になります。Jenkis サーバは常に立ち上げておきたいので、インストール後に表示されるコマンドを使って launchctl で load しておきます。

launchctl load ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist

今回インストールしたマシンは、自分の Macbook Pro です。基本的に研究に関する開発や趣味の開発に対するものなので、出先でも作業できるようにするためです。研究室用には研究室の OS X Server にインストールする予定です。こちらはいずれ卒研及び授業用に使う予定です。

基本的な設定

インストールしてサーバを起動したら、ブラウザでサーバにアクセスするだけです。今回はサーバとクライアントが同一なので、localhost:8080 にアクセスすればよいことになります。Jenkins 自体は国際化されているので、ちゃんと日本語で表示されます。なお、自分の用途で設定したのは以下の項目くらいです。

  • Git プラグインのインストール
  • 認証の設定
  • サインアップして hkob ユーザを作成

新規ジョブの作成

最近テストをサボりがちな Matlab の画像処理ライブラリを Jenkins でテストするようにしてみました。ジョブ名は MATLAB_Image_Library にしました。プロジェクト名がそのまま workspace の名前になるので、日本語やスペースの入った名前は避けた方がよいです(一度ミスりました)。先ほど Git プラグインをインストールしたので、リポジトリに Git が設定できるはずです。親リポジトリの場所を設定するだけで、Jenkins がビルド時にリポジトリからソースを取得してくれます。

私の場合、myMatlab というフォルダを自分用のライブラリ置き場にしており、自分で作成したグレースケール画像用クラス(@MD)、カラー画像用クラス(@CD)、及びそれらのテストクラス(@MDtest, @CDtest)が入っています。myMatlab フォルダを git で管理しているので、これら全体をテストすることになります。ただし、現在 @CD はまだ開発途中であるため、今回はすでに運用実績のある @MD の方を説明します。

Jenkins での MATLAB テストですが、コマンドライン駆動をして matlab に組み込まれた unittest を実行するだけの簡単な仕組みですみます。Jenkins のビルド設定では「シェルスクリプトを実行」として、以下のスクリプトをテキストフィールドに記述すれば完成です。

#!/bin/sh

PWD=`pwd`
/Applications/MATLAB_R2014a.app/bin/matlab -nojvm -nodisplay -nosplash -r "cd $PWD; result = run(MDTest); exit(sum([result.Failed]))"

Mac 版の MATLAB はアプリケーションバンドルになっているので、コマンドラインから実行するには、バンドル内の実行ファイルを直接指定します。余計な表示等がされないように、noXXX 系のオプションを付けています。この辺りの詳しいことはオフィシャルのページをご覧ください。なお、unittest の結果は TestResult オブジェクトの塊として帰ってきます。一つでもテストに失敗すると sum が 0 以外となるので、exit 関数を通じて Jenkins にエラーの有無を伝えられます。なお、R2013B からはメッセージが日本語化されているのですが、悲しいことにマイクロソフト漢字コードとなっています。そのため、このコマンドを通常のターミナルで実行すると文字化けしてしまいました。ただし、Jenkins のコンソールはブラウザなので、気にせず日本語がちゃんと表示されるようです。

ここまで設定したら、「ビルドの実行」を押してみます。コンソールにはテストの結果が表示されていると思います。テストを追加してみてリポジトリを更新し、再度「ビルドを実行」をすると異なる結果が表示されると思います。

Git のフックによる自動ビルドの設定

Jenkins はビルドのタイミングをユーザが指定するだけでなく、自動的にビルドを実行することもできます。この時、Jenkins 側からリポジトリを定期的にアクセスするポーリングと、リポジトリから Jenkins に対して通知を渡すプッシュのどちらでも設定できます。今回は、後者のプッシュ通知を設定してみました。また Git については、親リポジトリにおいて push を受け取った時に実行される post-receive hook を使用することにしました。これは、Jenkins が親リポジトリを監視しているためです。今後の授業展開の時を考えるとき、サーバ側で処理が完結した方が楽だという理由もあります。

基本的な作業は「ビルドを実行」リンクを外部からアクセスするだけとなります。ただし、今回は認証を設定しているので、幾つかの手順が必要となります。

  • wget をインストールします。
brew install wget
  • ユーザの設定で API トークンを取得します。開発者を表示して、設定画面の「API トークンを表示...」で表示される32桁の16進数をメモしておきます。
  • ジョブのビルド・トリガの設定で、リモートからのビルドを有効にして、ビルド用の「認証トークン」文字列を設定します。
  • リポジトリの hooks ディレクトリに以下の内容の post-receive ファイルを保存します。
#!/bin/sh

echo "Hook post-receive start"

/usr/local/bin/wget --auth-no-challenge --http-user=hkob --http-password=開発者のAPIトークン http://localhost:8080/job/MATLAB_Image_Libarary/build?token=認証トークン -O /dev/null || echo "wget failed"

echo "Hook post-receive end"
  • post-receive に実行属性を付与します。
chmod +x post-receive

設定は以上です。Matlab のフォルダで git commit 及び git push すれば、自動的に Jenkins で自動テストが行われています。

まとめ

自動テストの設定があまりに楽だったのに驚きました。まだ完成していないソフトウェア設計Iの授業における cpu 作成のジョブ、これから佳境に入る情報処理IIの授業における複素数ライブラリのジョブを導入すると確認が楽そうだなと思いました。

written by iHatenaSync