Genymotion On Demandを使うようになってAndroidのCIがさらに1分短縮した話

こんにちは。技術部モバイル基盤グループの門田(@_litmon_)です。

モバイル基盤グループでは、エンジニアの方々が快適に開発できる環境を整えるため、日々アプリのビルド時間やCIの実行時間などを短くする方法を模索しています。

今回は、Genymotion On Demandを使ってみた結果、CI上でのAndroidアプリのinstrumentation testの実行時間が1分短くなった話をしようと思います。

前回のあらすじ

今回の記事は、OpenSTFでAndroidのCIを2倍早くする の続編のような記事で、AndroidのCI環境を整えている話です。 まだ読んでいない方はぜひ上の記事から読むことをオススメします。

前回は、Jenkins上でAndroidのエミュレータを起動して使用する方法から、OpenSTFというリモートで実機端末を操作することが出来るオープンソースツールを使用する方法に切り替えた結果、エミュレータの起動時間などが削られ実行時間が約9分近く削ることが出来ました。

しかし、OpenSTFをしばらく運用していくといくつかの問題点が見つかりました。

OpenSTFをCIで使う際の問題点

OpenSTFはエミュレータの起動を待つこと無くテストを行うことが出来るため、とても優秀なツールだったのですが、実際に運用を進めていくと以下のような問題点が見つかりました。

  1. OpenSTFサーバー自体が不安定になることが時々あり、サーバーのプロセスが終了してしまうことが度々あった
  2. 実機の状態が不安定で、時々接続に失敗することがあったりしてメンテナンスコストが高い
  3. CI専用の端末を用意する必要があり、slaveごとに端末が必要になるのでスケールしづらい

1.のOpenSTFサーバーが不安定な点に関しては、正しくメンテナンスを行うことで回避することが出来たかもしれませんが、しばらくはプロセスが終了しており失敗している場合は手作業で立ち上げ直すという運用を取っていました。だいたい、2週間に一度は調子が悪くなり、そのたびに再起動を行っている、という状況でした。

また、2.に関しては、実機の状態が不安定で"なぜか"OpenSTFに認識されないときがあり、そのたびに検証端末が置かれた棚を開きにいっており、毎回原因を追求することまではせず運用でカバーしていました。そのため、端末を管理するコストが大きくなっていました。

現状の問題点

ということで、現状の問題点を整理すると、

  • 自社でOpenSTFサーバーを立てると相応のメンテナンスコストがかかる
  • 物理端末に依存することで、端末の管理コストがかかりスケールしづらい

という2点が挙げられます。

これらの問題点を解決するため、様々なサービスを検討した結果、Genymotion On Demandにたどり着きました。

Genymotionとは

Genymotionは、Genymobile Inc.が出している非公式のAndroidエミュレータです。 Android Studioに標準で搭載されている公式のエミュレータよりも多機能なエミュレータで、x86仮想化を使った公式エミュレータが利用できなかった頃はお世話になったAndroidエンジニアのみなさんも多いのではないでしょうか?

Genymotion On Demandとは

Genymotion On Demandは、そんなGenymotionをAmazon EC2(EC2)インスタンス上で起動し、扱うことが出来るものです。 EC2インスタンス上に起動したエミュレータとADB接続でき、ADBコマンドから端末を操作することが出来るすぐれものです。

Genymotion On Demandを導入することで、物理端末の制約から逃れ、快適なCI環境を手に入れることが出来ると考え、クックパッドでは5月頃から導入を始めています。

Genymotion On Demandの使い方

ここで、簡単にGenymotion On Demandの使い方を紹介します。

といっても、手順は公式のチュートリアルにとてもよくまとまっているので、そのとおり進めるだけで簡単に使うことが出来ます。

Genymotion on Demand – Tutorial –

おおまかな流れとしては、以下のような形になります。とても簡単ですね。

  • AWS ConsoleからGenymotion On Demandのインスタンスを購入する
  • sshでエミュレータに接続し、ADBを有効に設定する
    • この設定はインスタンスごとに一度行えばよく、再起動時には不要
  • sshでport:5555に対して接続することで、エミュレータをADBで認識できるようにする

Genymotion On Demandで使用できるAndroid OSバージョンは、現在5.1, 6.0, 7.0の3種類になります。クックパッドでは、導入時の最新である6.0を使用しています(5月時点では5.1, 6.0の2バージョンだった)。

また、Genymotion On Demandでは、EC2のインスタンスタイプも指定できますが、t2.smallではテスト実行時間が若干遅くなるものの、それぞれ大きな差はありませんでした。 クックパッドでは現在m4.largeを使用しています。

CI上でのGenymotion On Demandの利用

現在、クックパッドではJenkinsのSlaveとしてEC2インスタンスを用いています。(参照: OpenSTFでAndroidのCIを2倍早くする)

そして、Slave 用のインスタンスの起動時に localhost:5555 を Genymotion On Demand のインスタンスへと転送する簡易プロキシを起動しています。 こうすることで、Slaveを立ち上げた時点ですでにGenymotionのエミュレータがADBに認識された状態になるため、Job側でなにも設定することなくエミュレータを使うことが出来ます。

そのため、既存のJobの設定を編集する際も、OpenSTFのプラグインの設定を無効にするだけで簡単に移行が完了します。

f:id:litmon:20170822115529p:plain

導入しただけでinstrumentation testの実行時間が1分短く!

導入してしばらく様子を見ていたのですが、明らかにJobの実行時間が短くなっているのを体感しました。 以下の画像は、縦軸が時間で横軸が実行したジョブの番号を示しています。そして、 #1899 以降がGenymotion On Demandを導入した後になっています(※ときどき失敗しているのは、不安定なテストがあるせいです。気にしないでください)。

f:id:litmon:20170822115903p:plain

このグラフから分かる通り、7分近くあったジョブの実行時間が6分弱に収まっていることが分かります。約1分弱の短縮に成功しました!🎉

詳しく状況を見てみると、以下のようになっていました。

  • 端末との接続を確立するまでで 20秒 短縮
  • ./gradlew :cookpad:connectedAndroidTestStagingDebug が 45秒 短縮
  • ./gradlew :cookpad:uninstallAll が 10秒 短縮

なんと、instrumentation testの実行時間が45秒も短くなっているではありませんか! それだけではなく、端末との接続時間や、アプリのアンインストール時間が短縮されていることが分かります。

仮説ですが、OpenSTFは自社のローカルネットワーク上で起動しており、Genymotion On DemandはJenkins Slaveと同じEC2インスタンスのため、ネットワークの接続(apkの転送時間など)に影響があったのではないかと考えています。

安定感がスゴイ!

そんなGenymotion On Demandですが、やはり気になるのは安定性です。 現在、導入して3ヶ月ほど経ちました。弊社のJenkins Slaveは2台あり、内1台はフルタイムで活動しています。そして、Genymotion On DemandのインスタンスはSlaveの起動時に同時に起動し接続しているため、内1台は常に活動したままです。

にも関わらず、5月31日に起動して以来今までGenymotionのエミュレータの調子がおかしくなったことはありません。すごい安定性ですね! これだけ安定して使えるのであれば、ということで、6月の半ば辺りから徐々に既存のJobで使われているOpenSTFをGenymotion On Demandに置き換えていって、今ではほとんどのJobがGenymotion On Demandを使うようになっています。

Genymotion On Demandの制限・注意点

ここまで、Genymotion On Demandの良いところをたくさん挙げてきましたが、いくつか制限もあります。

  • Google Play Serviceが利用できない
  • instrumentation testでタイムゾーンに依存するテストがある場合、失敗する可能性がある
    • 一度これでハマってテストが落ち続けていたので、注意する…
    • エミュレータのタイムゾーンを変更することは可能です

現在、クックパッドの日本のアプリでは上記2つともそこまで大きな問題ではないのですが、プロジェクトによっては導入する際の障害になりうるので、参考になればと思います。

まとめ

OpenSTFを使った実機でのinstrumentation testをGenymotion On Demandを使ったGenymotionエミュレータでのテストに置き換えた結果、CIの実行時間が1分近く短縮されました。また、安定性やスケーラビリティなど、実機で管理していた際の問題点も解消することが出来ました。

クックパッドでは、アプリの開発ももちろんのこと、こういったアプリのビルドやCI周りに対しても様々な取り組みを積極的に行っています。 アプリの基盤の仕組みを整えたり、新たに作り出していける、いきたいAndroidエンジニアのみなさんを募集しています。 もし興味があったらぜひぜひ遊びに来てください。お待ちしています!

クックパッド株式会社 採用情報

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/