はじめに
「ネットワークプログラミング...マルチプレイ...」
その甘美な響きに魅了され、手を出したエンジニアの方も多いのではないでしょうか。
私もその一人で、気がつけば何でもかんでもマルチ対応させたがるやっかいなエンジニアへと変貌していました。
昨今では昔に比べ、ゲームエンジンの発展やPhotonをはじめとする各種サービスの登場などにより、実装自体への敷居は下がっていますが、様々なエラーケースが存在する点についてはまだまだ整備されておらず「なんかとりあえず動くけど、少し変な事をするとすぐに落ちる」状況は多量に発生し、日々我々のMPへ強烈なダメージを与えてくることは必然の理であり、私自身も幾度となく涙を涙で拭う体験をしてきました。皆そうだよね?
本題
マルチプレイ実装時の品質を少しでも高めるために「サーバーでロジック上起こり得るエラーケースを出来るだけ早期に発見する」を目標として、BOTクライアントによるモンキーテストでの解決をはかった際、どのような対応をしたのか、結果と合わせて話せればと思います。
要件と対応
要件としてはざっくり下記を定義しました。
- ネットワークを介して動作する
- 並列で複数動作する
- 操作にランダム性を持たせる
上記を踏まえ、具体的には下記を満たすBOTクライアントを作成し、コード変更時、あるいは定期的に実行するようにしました。
※CI/CDへ組み込むか、常時稼働させておくと安定的にチェックが出来ると思います。
- ネットワークを介して動作させる
- 実際にネットワークを介して処理することで、実行環境の制約を減らす
- 接続・切断時の問題や、ロードバランサーのタイムアウトについてもある程度視野に入れる
- 手軽に実行できる
-
go run bot.go -count {実行数} -host {接続先アドレス}
のような形で実行 - ただでさえ複雑な箇所になりがちなので、テストだけでも
楽をしたい効率的に実施したい
-
- 並列で複数BOT稼働できる
- モンキーテストなので、単純にテストの回転数を上げたい
- 大抵の問題は、複数ユーザーが同時にプレイする際に発生する
- 決まりきった行動ではなく、ある程度ランダムに行動させる
- サーバーロジックを良い意味で破壊したい
実際に導入してみた結果
思っていた以上にサーバーエラーが発覚
これはとても良いことなのですが、思っていた以上にサーバーエラーが排他制御を含む様々な箇所で発生しました。
また、正規のクライアントでは出来ない挙動をさせることも可能なので、例えば不正なパケット操作に対しても一定の効果を出せたかと思います。
負荷テスト(シナリオ)への流用が可能
副産物として、負荷テストへそのまま流用できた事も、大きなメリットの一つでした。
状態を伴うマルチプレイの負荷テストを行う際の一つの答えになったのではないかと思います。
通常のテストでは発覚しにくい問題を早期に発見
例えば排他制御をしている箇所に起こり得る問題は、大抵の場合ほぼ同時に呼び出されることで発覚するのですが、これらの多くを実装段階で発見・修正することができました。
「そんな奇跡的なタイミングでサービスロジックと切断処理が走るんなんて聞いてないよ!(げきおこ)」
と叫ぶ回数が圧倒的に減少しました。
導入時のデメリット
保守コストが発生する
サーバー/クライアント間のインターフェースへ変更が発生した場合、BOTも修正する必要があります。ただし、クライアントの実装に入る前にある程度検証ができる事から、むしろメリットへ転ずるとも考えられます。
サービスごとに実装が必要
サービスの根幹部分に関係するため、どうしてもドメイン領域に依存します。
つまり、サービス毎に開発する必要があります。
結果と今後の課題
導入後、ロジック上の不具合があまり出なかった事から、目標に対して一定の成果は上げられたのではないかと思います。実際に排他制御が甘い箇所の多くをBOTでのテスト段階で発見することができました。
しかし、実機上で起こり得る問題の発見に対してはあまり意味をなしていないため、その点について今後どの様に対策を行なっていくかは、一つの大きな課題かと感じます。
- EOF未検知切断
- Wifiハンドオーバー
- 瞬断
- etc ...
(終わりなき戦い...!)
最後に
今回BOTによるテストについて書かせていただきました。
MMORPGでは嫌われるBOTですが、テストという面においては非常に優秀かと思います。
今回書かせていただいた手法はあくまで一例ですが、マルチプレイへ対するテスト手法の一つとして参考になれば幸いです。