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 を使っても面白いです。場合によっては環境管理が楽になるかもしれません。
Category: Computer
仕事で使っている Windows 7 のノート PC (富士通)、右 Ctrl と矢印キーの同時押しで PgUp/PgDn/Home/End にしたい (Mac の日本語キーボードだと、この位置には Fn が付いている)。

ということで、初めての AutoHotKey でサクッと remap してみた。あんまり情報が無くてつらい。
>^Up::Send,{PgUp}
>^Down::Send,{PgDn}
>^Left::Send,{Home}
>^Right::Send,{End}
Category: Jubatus
11/22 に Jubatus 0.5.0 がリリースされました。
以前ご紹介した Jubatus を CUI から叩くシェル環境 jubash も、これに合わせて Jubatus 0.5.0 対応を行ったものをリリースしています。
なお、過去の Jubatus に対応する Jubash は、各ブランチから入手することができます。

ちなみに、明にフォーカスされていませんが、Jubatus 0.5.0 の Python クライアントは Python 2.6 でも動作するようになりました。これによって、Python 2.6.6 が標準の RHEL 6 系 OS で利用する際の障壁が一つ少なくなっています。
Jubash では、これまで Python 2.7 以降のみに含まれているライブラリである argparse をコマンドラインオプションの解析に使用していましたが、Jubatus に合わせて Python 2.6 で動作するよう、argparse から optparse へのダウングレードを行っています。手順としては optparse からのアップグレードの逆を辿ったのですが、Usage の表示機能が大幅に制限されるなど、なかなか苦痛を伴う作業でした...。
Category: Apple

例の HHKB 祭りに乗っかりました & 調子に乗って英字配列の無刻印モデルを買ってみました。
KeyRemap4MacBook を使用して以下キーを remap したらすごく快適になったのでメモ。
  • 左右のコマンドキーを「英数/かな」としても使う
  • Fn+Delete (Clear) を Forward Delete として使用する (以下の XML ファイル)

Pull-Request してもいいよとドキュメントに書いてあったので送ってみた。 (追記: マージされました)

“左右のコマンドキーを「英数/かな」としても使う” は超強烈で、個人的にはこの機能があるならもう日本語キーボードに拘る理由は全くないな、という感じ。
Category: Apple
Xcode が Mac App Store から配布になって、いつの間にか AU Lab がどこかに消えてしまったので困った。
現在は Mastered for iTunes のページから入手できる模様。

コード署名されていないので、右クリックで「開く」を選択する必要あり。