Kenichi Maehashi's Blog

脳内コアダンプ

RSS
Category: Apple
この記事は Jenkins CI Advent Calendar 2013 の 22 日目の記事です。

Mac 開発者の皆さん、自動テストはどうされていますか?
Mac アプリを作ったら OS X の各バージョン (Mavericks, Mountain Lion, Lion, ...) でテストを走らせたいところですが、テストのためだけに Mac を複数台用意するのは金銭面でも運用面でも大変ですね。
今回、VMware FusionJenkins を組み合わせた自動テスト環境を構築したのでご紹介します。

構築した環境


Jenkins のマルチノード機能を使用した構成になっています。
物理マシン上で Jenkins マスターと VMware Fusion を実行し、VMware の仮想マシン (VM) として Mavericks, Mountain Lion, Lion の 3 つを用意して Jenkins スレーブとして登録しています。執事の世界にもご主人様と奴隷の関係があるのですね :)

VMware Fusion を使うと OS X を VM の中で走らせることができるので、このように 1 台の Mac で複数 OS のテストを実行すればコストが節約できます。

課題と解決策

この段階で、次のような課題が出てきました。
  • メモリと CPU が足りない
    • 今回物理マシンとして使用したのは iMac Early 2009 で、メモリは 8 GB (上限)、CPU は Core 2 Duo です。実際の開発現場でも、潤沢にリソースを積んだ Mac をテスト専用に割り当てられることは少ないでしょう。OS X は少なくとも 2 GB のメモリを要求するため、複数の OS X VM を同時に立ち上げっぱなしにするのは非常にツライです。
  • テスト環境をクリーンに保てない
    • 前回のテスト結果によって後続のテスト結果が変わるような事態は避けたいものです。この問題にはテストコードの書き方と CI 環境の運用方法という二つの側面がありますが、そもそもテストを行うたびにフレッシュな OS 環境を利用できれば、厄介な問題にぶつかることもありません。
というわけで、これらの課題を解決するべく jenkins-vmware-integration というスクリプトを書きました。このスクリプトの機能は以下の通りです。
  • Jenkins のノード管理機能と VMware Fusion を統合
    • Jenkins がテストを実行するタイミングで各 VM を順に起動し、テストが終了したら VM をシャットダウンします。
  • テストが終了した段階で、各 VM の指定したスナップショットにロールバック
    • 毎回同じ構成でテストが実行されるので、テストの再現性が確保できます。
  • Jenkins スレーブを自動的に構築して起動
    • VM 側にあらかじめ Jenkins スレーブを用意する必要はありません。

使用方法

テスト用 VM の構築

まず、VMware Fusion で OS X の VM を作成します。「新しい仮想マシンを作成」画面で Mac App Store からダウンロードした OS X のインストーラを選択すれば簡単に作成できます。

次に、VM 内で以下の設定を行います。
  • 「ネットワーク」環境設定で固定 IP アドレスを設定。
  • 「共有」環境設定で SSH サーバを有効化し、公開鍵を ~/.ssh/authorized_keys に登録。
  • JRE をインストール (Jenkins スレーブを動作させるため)。
  • Xcode やテストに必要なツールなどをインストール。
ここまで完了したら、VM をシャットダウンしてスナップショットを撮っておきます。また、Jenkins を動作させるユーザに VM への書き込み権限を付与します (Tip: ホスト側の OS X を OS X Server にしておくと、Server アプリからアクセス権の伝搬機能が使えるので便利です)。

Jenkins ノードの設定

VM の準備ができたので、Jenkins にスレーブとして登録します。管理画面の「ノードの管理」を開き、次のようにダムスレーブを作成します。


jenkins-vmware スクリプトの引数は、それぞれ「VM に設定した IP アドレス」「VM のユーザ名」「VMX ファイルのパス」「テスト完了後にロールバックするスナップショットの名前 (空欄にした場合は自動ロールバックを行わない)」となっています。

Jenkins ジョブの設定

OS のバリエーションなど、同一のコードを複数の環境で実行するマトリクス型のテストを行う場合は、「マルチ構成プロジェクト」として Jenkins ジョブを作成しておくと便利です。
普段自動テストを設定するのと同じように Jenkins の設定を行うのに加えて、次のようにマトリックスの設定を行います。


これで、各ノード上で設定したテストが実行されるようになりました。「ビルド実行」を押して動作を確認してみてください。

まとめ

  • VMware Fusion と Jenkins を使うと、OS X のバージョンバリエーションテストが 1 台の Mac で実行できるので便利。
  • さらに jenkins-vmware-integration を組み合わせると、リソースを節約しながらクリーンな環境でテストを実行できる。

その他の Tips

  • 旧バージョンの OS X (Lion など) は、Mac App Store で新規購入することができません (一度購入したことのあるアカウントであれば再ダウンロードすることはできます)。Mac Developer Program に加入していても旧バージョンの OS X は入手できないようです。インストーラはバックアップしておくことをお勧めします。
  • VMware Fusion では OS X (EFI) のネットワーク起動もサポートしているので、VM のローカルハードディスクの代わりに OS X Server の NetBoot を使っても面白いです。場合によっては環境管理が楽になるかもしれません。

Comments

Leave Yours...
Name:
E-mail / URL (optional):
Comment:
Are You Robot?: