![見出し画像](https://assets.st-note.com/production/uploads/images/44949963/rectangle_large_type_2_1af8995d3d3172698a7d15aa5c27ea39.jpeg?width=1200)
COCOAが実機テストできる設計を考える
おっす。バレンタインが近いのにチョコレートのココアじゃなくてアプリのココアですかぁ?ってマウント取られることを封じるために、カカオの実のサムネイル画像を拝借してきました。
ちなみにカカオの実の中にカカオ豆が入っていて、ココアは何ぞやかというとそれをパウダーにしたものだそうです。もうちょっと言うと無添加の状態がカカオパウダーで、飲料用に甘いものを足したのがココアパウダーだそうです。あまり詳しく聞くと、貴重なカカオニブやパウダーの実物を出して説明が始まってしまうのでとっとと本題に参りましょう。
発端はこのニュースです。新型コロナウイルスの感染者と濃厚接触した可能性を通知する接触確認アプリ「COCOA(ココア)」が、不具合で通知しないというニュースが話題になりました。
Twitterで散々報告されてた問題なので「ちょwそれいつの話よw」と数か月も前にブームが終わったんですけどみたいな目線で見ていたら、思いの外大きな話題になりました。
大臣が記者会見して謝罪する問題に。そこまでくると「バグだから大げさすぎん?w」って気持ちになります。そもそも普通は大概のアプリにバグが潜んでます。まあ、これは致命的な問題かもしれないけど、4か月放置はひどいけど、世の中的にあることです。
すると、こんな話が。
COCOAは途中まで私たち補佐官も入っていたので、決して運用保守を軽視したつもりはなかったのですが、EN API自体のプライバシー哲学に沿おうとすると既存のデバッグ用ツールがほぼ使えなくなってしまったのと、EN APIの更新がスマホOSの更に何倍も頻繁かつトリッキーだったのは、正直誤算でしたね https://t.co/Hb1Z4NsHBZ
— Masanori Kusunoki / 楠 正憲 (@masanork) February 6, 2021
読み進めるとこんな原因があったそうです。
・EA APIに対応することでいっぱいだった
・CI/CDに追いつけなかった
・Azureの有識者がいなかった
・運用フェーズでは検証環境がなく、実機テストができなかった
・テスト体制や、バックエンドエンジニアがいなかった
まず、スマホアプリは一般的に更新を迫られる頻度が高いため結構な手間とお金がかかります。EA APIは私も知らないですが、通常よりもかなり大変な道のりだったと思います。
CI/CDはアプリ品質が安定してから徐々に実現していくのがいいと思います。また、品質を自動テストのみに依存するのは危険なので、これがあっても実機のテストはできるようにすべきです。
Azureの有識者は少ないです。MSが絡んでたのでAzureを選んだのかもしれませんが、現場に手練れがいないのはどこでも共通の悩みです。
実機テストができなかったことはクリティカルな問題です。作ったものは必ずバグが潜みますので、実機で確認しなければバグを発見する機会を見失います。こういうのは本当に動かしてみないとわかりません。アプリ自身に問題がなくてもOSの相性や端末固有の問題などでいくらでも問題が出ます。開発者のPCで動くことと実機で動くことは別の話です。
なので、これが本当なら非常にまずい事態になります。これをどうしたらいいのかって考えることがこの記事の趣旨です。(導入の話が長い)
適当なことしか書かないので品質には期待しないでください。
情報収集する
強制労働し・・じゃなくて厚生労働省のサイトで情報収集しましょう。
https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/cocoa_00138.html
サイト内にこんな画像を見つけました。近接の情報は端末内のみで暗号化して保持するんですね。サーバに情報を送らないってのは思い切った設計です。通信量を減らせますしインフラコストも圧縮できます。反面、あとからログを追跡したり分析したりすることができなくなります。
COCOAは個人情報を一切持たない設計なので、悪い人にクラッキングしても困らない設計になってます。であるのに脆弱性診断まで受けてます。リッチですね。設計思想がかなりセキュアです。というわけでセキュリティ的なリスクは非常に低いアプリと明言していいと思います。
位置情報を追いかけないのもこの手のアプリとしては斬新です。行動を追跡したくなるのが心理ってものですが、GPSだと濃厚接触かどうかの距離を識別することが難しいです。Wi-Fiでもかなり難しい。ということで、Bluetoothだけで濃厚接触を判断することにしたのでしょう。
これは、バッテリーを長持ちさせてアプリの品質を保つ効果もあると思います。中国やインドなどの海外勢が実装しているにもかかわらずそれを諦めたのは、良い判断だと思います。「技術的にできそうだけど実はかなり困難」なことがこの世界にはたくさんあります。とはいえ、位置情報があれば分析の参考にできることは間違いありません。
実際に通知を受け取っても「〇日の〇時に濃厚接触してました」と言われたところで、利用者が思い出せるかどうかなど別の問題がありますが、ここでは深追いしないことにしましょう。
構成を想像する
先ほどのツイートのツリーに「接触確認アプリはAzure Functionsを使ったシステム」とありました。
AzureのPaaSを使った基盤ですね。これはAWSのlambdaというFaaSに相当する機能です。サーバに情報を持たせないことからも、完全にサーバレスの設計なのでしょう。PaaSはAzureの強みですし、クラウドをクラウドっぽい使い方できることがエンジニア的にわくわくする設定でもあります。
このへんで構成図を書こうと思ったけど非常にめんどいしたいして需要がないと思うので、さぼって文字だけでいきます。私用PCにパワポないし。
開発環境がない
開発環境で実機を使ってテストができないという困った課題をどうすればいいでしょうか。そんなもん絶対作れやオラオラ!って言おうにも運用フェーズで構築メンバーがいない状態でそれをできるのか、しかもバックエンド得意な人がいないのに、となるとこれを諦めるのも選択肢です。
私が今ここの現場にいても、予算と時間がないなら開発環境を作るのを現実的に諦めると思います。
しかし、基本的には本番用と開発用に両方の環境を作るべきです。
PaaSを使ってるということはステートレスなので、比較的環境構築は容易なはずです。しかも普段は停止しておけばコストは最小限です。インフラコストは月額数万とかでいけるはず。仕事じゃないから明細は書かないけど、 Azure Application Gateway みたいにどうしてもお金かかるところだけはしょうがないけど、App ServiceはFreeプランまで落とすという方法もあるし。
ちなみに私がいたところは開発用と本番用は別アプリを作ってました。iOSの審査もまず開発用を出して審査を通して、公開せずクローズドのまま実機テストをする。問題がなければ本番用を審査通して公開する、みたいなことをしてました。
実機テストのためにアプリを作っていたのです。これはこれで多少は管理が煩雑になりますが、品質の担保のためには有効でした。
しかし、開発環境がない、作れないのではあれば別の手を使うしかありません。
ブルーグリーンデプロイを活用する
ブルーグリーンデプロイは他のクラウドでもできるし一般的な用語なので、知らない人はググってください。
なんて不親切なことを言ったらダメですよね。僕がそんな不親切なブログ見つけたら「ググってわかるなら俺だってクラウドエンジニア名乗れるわ!」って真っ赤な顔で叫んで、地団駄を踏んで悔しがります。
要は、本番環境をコピーして分身させる技なんです。たとえば開発者がGitHubでpushしてマージしてデプロイして、そのままAzureに自動連携されてリリースされたとするじゃないですか。
「それは分身だ!」
って言われるやつです。
MSの一次情報を使って説明していきます。面白いので期待してください。
https://docs.microsoft.com/ja-jp/azure/app-service/deploy-staging-slots
Azureでは分身のことを「スロット」と言います。
App Service プランがスタンダード以上だとスロットを使えます。僕はお金が1円だって惜しいので、MSの記事から画像を拝借して説明します。MSも外人が書いたものを翻訳してるだけなので画像も英語ですが我慢してください。(Freeで使える機能なら自前で画像用意するんですが)
以下、ほぼそのまま流用して説明します。
1.Azure portal で、 [App Services] を探して選択し、アプリを選択します。
2.左側のウィンドウで、 [デプロイ スロット] > [スロットの追加](英語のキャプチャと合ってないですが雰囲気で理解オネシャス) と選択します。(このあたりの翻訳はしょっちゅう変わります。私が以前やったときは「新しいスロット」でした)
3.[スロットの追加] ダイアログ ボックスで、スロット名を指定し、別のデプロイ スロットからアプリ構成を複製するかどうかを選択します。 [追加] を選択して続行します。
ここまででスロット作成終了です。手順2のところにスロットが追加されます。次にスワップの手順の説明をします。
本体と分身(新しいスロット)は全く同じものを用意することができます。そして、その片方にだけリリースをします。インフラ側で本体と分身のどちらを表にするか操作をします。表になった方が本番稼働して働いてます。
開発者はそういうことを意識せずに更新作業をします。仮にGitHubでmasterブランチにマージしたらAzureの環境に自動更新される作りをしてれば、表になってるスロットに適用されます。本番リリースが完了です。
もう片方のスロットは裏に隠れたままです。こいつはどういう役割かというと、本番リリースで問題があったときに切り戻す際に役立ちます。瞬時にスロットの表と裏が入れ替わり、ダウンタイムなしで切り戻しができます。この入れ替えをスワップと言います。
これがブルーグリーンデプロイです。環境を瞬時に入れ替えられるというメリットがあります。アプリ側はあまりインフラを意識せずに、かなり楽に環境を作れてしまいます。あまりに簡単すぎるので、終わった後に廃棄するスロットを間違えてしまいそうになるくらいです。(簡単すぎてどちらが今表なのか見失う)
さらにこの機能はDevOps パイプラインとかに混ぜて使ったり、自動化に組み込んだり、今みたいにGUI操作で使ったり、なかなか痒い所に手が届く機能なのです。
スロットがあればCOCOAはどうなるか
COCOAの運用では開発環境がなく実機でのテストができてないとのことでした。しかし、インフラの知識が全くなくてもスロットを作成することはできます。ただしこれは本番環境のコピーで、ロールバックが簡単にできるに過ぎません。
ですが、本番環境にリリースしてから実機でテストをして、問題があれば速やかに切り戻す対応ができます。幸いCOCOAは複雑な機能を持つアプリではないので、テスト対象の実機にだけ通知を飛ばすツールとか最低限の用意だけで時間をあまりかけずにテスト可能と思われます。
ただし、新しいスロットの機能でテスト環境の解決ができるのは、Web側だけです。
クラウドインフラとスマホアプリの対策が必要
ツイートではAzureとか開発環境がとか言ってたので思いっきりそっちに引きずられて考えてましたが、クラウドインフラに問題がある場合とスマホアプリに問題がある場合は別で考えなければなりません。もし、androidのスマホアプリに不具合が潜んでいる場合は、クラウド基盤の切り戻しをしても解消しません。
これは当事者が切り分けるしかないので、設計の理解がある人間がテストをすべきです。ですが、androidアプリは切り戻しは簡単です。
まとめ
本番環境でテストをするという我ながら非常に微妙な提案だなーと思いますが、環境がなくて用意できるエンジニアもいなくて、テストを今までしていないというなら、とりあえずの応急処置として本番環境でまずテストをして、問題があればすぐに切り戻す準備をするべきです。
バグが出るのは仕方ないので、それを検知して修正する体制を用意すべきなのですが、こういう無償のサービスだと苦しいだろうなとは思います。品質を維持できるだけの予算がなければスマホアプリのサービスは打ち切るしかありません。ユーザーは無料のサービスを利用することに慣れてますが、サービスを公開し続けることはお金がかかります。OSやいろんなものがバージョンあがりますし、バックエンドのインフラの維持費もかかります。
そして薄い内容をたらたら書いてたらいつの間にか5000文字超えてました。本記事はクレームを受け付けませんので、もっといい提案があればぜひ自分で記事を書いてください。修正は受け付けますので記載誤りや誤字などあればご指摘をお願いします。