見出し画像

REALITYの自動負荷テスト〜iOS編〜

配信・視聴時に端末が熱くなる問題を解決すべく、端末の温度を定期的に自動計測する仕組みを考えました。
運用化まで至っておりませんが、UIテストフレームワークやプロファイラを駆使した自動化についてまとめたので、アプリの高熱問題に悩んでいる方々の参考になれば幸いです。

概要

連日REALITY運営が投稿している #終わりなき挑戦プロジェクト (以降: おわちょ)から、高熱問題で取り組んだことを書こうと思います。

REALITYの高熱問題

スマホ端末の高熱化により引き起こされる以下の問題を指します。

・性能が落ちる
 ・デバイスが一定以上の温度になるとCPU, GPUなどの処理速度が落ちる
 ・さらに温度が上昇すると温度警告メッセージによる使用不能になる
 ・(付随して)バッテリー関連の問題が出る
  ・充電のパフォーマンスが落ちることがある
  ・高温になるほどの負荷がかかっているため当然バッテリー消費も激しい

特にREALITYの場合、3Dアバター + フェイストラッキング + 配信という三重処理によりメイン機能が構成されていることに加え、ギフト, コラボ配信, ゲームなど配信がよりリッチになる機能が続々と追加されている状況です。

今回高熱チームが取り組んだ内容やその成果については、先日の成果発表会動画の中でもお話しているため(40:00〜)、合わせてご参照頂けると幸いです。

攻めと守り

この高熱問題に取り組むにあたり、私は攻めと守りの2つの取り組みが必要であると感じました。
攻めとは問題の調査・改善のことで、実際に高熱を引き起こす問題を解決するためのアクションです。
守りとはそれを今後も継続して問題解決に取り組めるための仕組み作りを指します。

私はこの守りの部分を担当し、アプリの特定画面におけるの端末の温度計測を定期的に行う仕組みについて取り組んでみました。

実行環境と運用ルール

仕組み作りに際し、必要なものは実行環境(端末・自動化プログラム)と運用ルールです。

実行環境のうち端末とは、テストに使う端末を自分たちで用意し管理するか、デバイスファームを利用するかという選択についてです。

手元にある端末を使うのは手っ取り早いのですが、OSアップデートや端末の不具合なども踏まえて管理するコストが発生します。一方でデバイスファームを使えば端末を自前で管理する必要がなく、例えばHeadSpinではOS操作(アップデートダイアログの操作など)をAPIで提供しているため、使い勝手も含めこちらが良さそうです。

が、おわちょの期間が2週間ということと、0からの仕組み作りということでデバイスファーム選定時間を削減し実証時間を担保すべく、今回は手元にある端末をオンプレミスサーバーで利用しているマシンに直接つなげる形での実現を試みました。

実行環境のうち自動化プログラムとは、実際に定期的にREALITYを検温するための処理, 環境構築についてです。一連の流れを図示するとこのような形になります。中の処理については後述します。

画像3

最後に運用ルールですが、今回のおわちょ期間中に詰め切ることができませんでした。

ジョブを実行する際に既存ジョブに支障が出ない時間帯を選定、端末の確保、測定する画面、運用フロー(問題があった際のタスク作成や優先度の定義)などを考慮する必要があります。今回は仕組み作りの中でiOSの動作検証に止まってしまったので、今後追って詰めていきたいと思っています。

実行プログラム

以下の3つの仕組みを並行で実行する仕組みを考えてみました。

1.  アプリをインストールし、指定の配信画面まで自動遷移する処理
2. 指定の配信画面上で一定時間ギフトを投下する処理
3. 一定時間の間端末の温度を測定する処理

1.は最新アプリをcloneしてUIテストを実行するプログラムです。
UIテストでは通常のアプリを起動する他にテストランナーアプリが起動し処理を実現しますが、実機でUIテストを実施するにあたりテストランナーアプリとの連携に苦労することがありました。

今回はREALITYでまだUIテストの本格導入がされていないこと、UIテストの用途が自動負荷テストしか無いことを受け、UIテスト用のプレーンなプロジェクトファイルを別に用意し、そこでUIテストを実施(REALITYのUI部品のID指定でREALITYを操作)するといった方法を取りました。

xcodebuild DTDKRemoteDeviceConnection: Unable to start com.apple.instruments.remoteserver.DVTSecureSocketProxy on device ${UDID}". 
Falling back to service without proxy.

(実機によるUIテストがうまくいかずこの期間一番睨めっこしたエラーログ)

2.は配信を特定し、一定時間ランダムでギフトを大量投下するというプログラムを用意しました。これにより配信画面上で描画処理に負荷をかけ端末温度を上昇させています。

スクリーンショット 2020-11-16 19.50.20


(画面が凄いことになってる)

3.はiOSの場合InstrumentsTime Profilerにより計測します。今回は自動処理で計測を行いたかったため、GUIではなくCLIにより測定を実施します。

xcrun xctrace record --template  'Time Profiler' --device ${udid} --time-limit ${time} --output 'thermal_result.trace' --launch -- ${appFile}

計測結果ファイル抽出〜Slackチャネルへ通知

計測完了後、計測結果として出力されるxctraceファイルより端末の温度情報を取得します。Xcode11まではInstrumentsのGUI上でしか計測結果を見ることは出来ませんでしたが、Xcode12よりxctraceコマンドを使いXML形式で計測結果を取得できるようになりました(Release notesの12491801)。

xcrun xctrace export --input 'thermal_result.trace' --xpath '/trace-toc/run[@number="1"]/data/table[@schema="device-thermal-state-intervals"]' --output thermal_result.xml'

このXMLファイルよりthermal-stateタグで取得できる端末温度状態と、start-timedurationタグで取得できるその温度の計測時間を取得します。

この値をスクリプトでSlackに通知する際のフォーマットに落とし込みます。iOSの場合、以下の様なフォーマットを考えてみました。

スクリーンショット 2020-11-15 21.40.40

このFairやNominalという単語はiOSのプロファイラにおける温度状態のことで、種類は以下の4種類です。

Nominal…正常。(プロファイラ上で)緑色で表現。
Failr…対応が必要なほどではないが熱くなり始めてる。緑色で表現。
Serious…温度が熱くなってきてアプリ自体に影響が出始める。橙色で表現。
Critical…今すぐ冷やす必要あり。赤色で表現

プロファイラ上で表現される色合いをSlackのattachmentのcolor指定で表現できるようにしています(上の画像だとFairなので緑)。

残課題

実運用に向けてまだ課題は幾つか残っています。

1. 運用ルールの策定(前述)
2. Android側の実行環境残り
3. iOS側の配信画面のハンドリング問題

Android側もチームメイトに協力してもらいながら進めていたのですが、途中でバトンタッチした経緯もありまだ完了には至っておりません。こちらも引き続き実現に向けて取り組んでいく予定です。

またiOS側も今回の期間内に全て完了したわけではなく、配信画面におけるUIテスト操作ができないという課題が残ってしまいました。

iOS/Androidともに配信画面はUnity上のUI部品を特定するのが難しいため、座標指定による特定位置の押下処理を行うワークアラウンドがあります。この方法によりAndroidは配信画面のUIテストが実現できているのですが、iOS側はこのワークアラウンドも適用が出来ず、課題解決にもう少し時間がかかりそうです。

最後に

この取り組みにあたり、今年のiOSDC 2020かりあどさんが発表されたセッションがとても参考になりました。配信アプリの高熱問題を例に取り上げられており、同じ問題で悩まれている方はこちらも参考になるかと思います。

おわちょ期間中に今回の取組を完成できなかったのが残念ですが、せっかく作った仕組みなのでAndroid含め運用まで持っていけるよう引き続き取り組んでいきたいと思います。
運用してから出てくる新たな課題や問題点なども、またnoteを通してOutputできたらと思います。

書いた人