2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
リンクをコピー
記事をブックマーク
石澤基氏:今日は、GoとOCI Artifactsを使ってインターネットプロトコルのテストケースを共有可能にするという話をしていきたいと思います。
私はカンムという会社でソフトウェアエンジニアをしています、石澤基と申します。カンムでは主にサービスのバックエンドやインフラ領域を担当していて、Goは個人的に書いているのも含めて、5年ぐらい前から書いたり読んだりしています。
私が所属するカンムでは、VISAのプリペイドカードをアプリですぐに発行して使える、「バンドルカード」というサービスを展開しています。バンドルカードのバックエンドはGoで書かれていて、Goを使ってプリペイドカードの仕組みを改善していきたい、もっとよくしていきたいと考えているエンジニアを広く募集しているので、興味があればぜひお声がけください。
それでは本題に入っていきたいと思います。突然ですが、みなさんは何かしらのプロトコルで通信するサーバーをゼロから実装したことがあるでしょうか。私は以前、HTTP/2の仕様に興味をもって、HTTP/2のサーバーをゼロから実装していた時期があります。その時に感じた問題が今日のお話しするテーマの始まりです。
HTTP/2をゼロから実装するのはなかなか大変な作業でしたが、特に、自分が書いたサーバーが仕様どおりに動作しているかを確認するためのテストを用意するのがとても難しいと感じていました。なぜなら、仕様そのものをよく理解していることが必要で、理解をしていないときちんとしたテストも書けないからです。
当時、複数のHTTP/2サーバー実装がすでに存在していたのですが、これらの実装を見て、多くの実装者はみな似たようなテストを自分たちの実装のために書いていることがわかりました。しかしながら、プログラミング言語の違いや構造の違いといった実装方法自体の違いからテストそのものを共有して使うのは難しそうだなと思いました。
そこで、もうちょっとうまくテストを共有する仕組みができないかと考えたのが、この「h2spec」という仕組みです。
h2specは、HTTP/2サーバーが仕様に準拠しているかを簡単にテストできるツールです。Goを使って、コマンドラインツールとして実装しています。スライドに表示しているように、HTTP/2サーバーのポートを指定してコマンドを実行すると、そのサーバーが仕様に準拠した挙動をしているのかをテストしてくれます。
おかげさまでこのツールは、HTTP/2サーバーの実装者たちの間で広く受け入れられました。MicrosoftのIIS(Internet Information Services)や、オープンソースでいうとApache Traffic Serverといったサーバー実装のテストにも使われていると聞いています。
では、仕様への準拠を確認するh2specのようなテストツールが、どのような動きをするのかを簡単に説明したいと思います。
まず、テストツールは、サーバーに対して仕様で定められているデータを何かしら送信します。するとサーバーは、それに対して何かしらの応答をします。テストツール側は、その応答の内容を確認して、それが仕様の通りの挙動かどうかをテストします。これが基本的な動きです。
h2specでは、HTTP/2のフレームと呼ばれるデータ形式でデータを送信して、それに応じたサーバーの動きをテストしています。ただ、このような仕組みも完璧ではありません。例えば応答を返さないプロトコルや、サーバーが複雑な内部状態をもっていてそこから挙動を行う場合に、内部状態に直接アクセスしないと結果が判断できないテストを書くのは難しいという弱点もあるので、注意が必要です。
h2specをなぜGoで開発したのかを簡単に説明します。まず、Goを使えば複数のOSで動作するコマンドラインツールが簡単に実装できることが挙げられます。これにより、Linux環境や、CIなどの環境でも簡単にテストの実行ができるようになりました。また、ビルドをすればシングルバイナリーが生成されるので、インストールを容易にできたのも大きなポイントです。
ほかにも、使いやすいインターフェイスをもった公式のHTTP/2パッケージが、仕様策定の途中から提供されていて、h2specを実装するにはちょうどよかったというのも大きな1つの理由です。
h2specは多くのサーバー実装者に使ってもらえたのですが、それでも課題はたくさんありました。1つは、テストケースがGoで実装されているため、テストケースの追加や修正をするのにGo実装のための知識が必要になってしまうという点です。
また、自分の実装に合わせてテストを少し修正して、実行してみたいなというケースがまれにあるのですが、そういった場合、Goのビルド環境を作って、そのうえで再ビルドが必要になってしまうのも課題の1つでした。
ほかにも、さまざまなHTTP/2サーバーがもつ細かい実装の差異のすべてに対応するのが難しかったです。例えば「あるHTTP/2サーバーは、ヘッダーフィールドのサイズが4KBまでしか受け付けられないから、特定のテストが通らない」というようなフィードバックをもらうケースもありました。こういった実装固有の要件にテストツール側を合わせていくのも、なかなか大変です。
また、「HTTP/2以外にも、こういったツールは非常に便利だからTLS1.3やQUICみたいな、他のプロトコルのテストもできるとうれしいんだけど、どう?」みたいなフィードバックをもらうこともありました。
こういった課題を踏まえて、よりテストの追加や変更が容易であり、かつ、他のプロトコルにも対応可能なツールがあるといいのではないかと考えるようになりました。
そこで、これらの課題を解決するために開発しているのが「protospec」というツールです。protospecもGoで実装していて、より汎用的なプロトコルの仕様準拠テストツールを目指しています。
h2specの、テストケースの追加や変更がしにくいという課題は、テストケースをYAML形式のファイルとして書けるようにすることで対応しています。また、作成したテストケースを他のユーザーにより簡単に共有するために、OCI Artifactsという仕組みにも対応しています。
ここからはこれらの仕組みについて、簡単に紹介をしていきたいと思います。なお、protospecのコードはスライドに記載のURLにアップロードしていますので、興味がある方はアクセスしてみてください。
これがprotospecでテストを実行した時の結果です。基本的なかたちは、先ほどのh2specと非常に似て、ほぼ変わりません。
今日は、個々のテストケースの記述方法をより具体的に説明していきたいと思います。
例えばHTTP/2の仕様では、通信を開始する際にこのような定義がされています。簡単に要約すると、「クライアントは最初にconnection prefaceを送信しなければならない」というものです。connection prefaceは「HTTP/2の通信を開始するよ」ということを示す文字列です。今回はHTTP/2サーバーにconnection prefaceを送信して、実際にハンドシェイクが完了するかを確認するテストケースを書いていこうと思います。
まずテストケースを定義したYAMLファイルを用意します。ファイル全体の内容はこのようなかたちです。先頭に名前などのメタデータがあり、testsというフィールドに複数のテストケースが書けるようになっています。
個々のテストケースは、タイトルやその説明をもちます。いわゆるメタデータのようなものを書けるところですね。個々のテストケースはstepsというフィールドをもち、ここにテストで実際にどういった処理を行うかを書いていきます。
今回は、connection prefaceを送信して、ハンドシェイクが完了するかをテストしたいので、仕様に従って、まずはconnection prefaceをサーバーに送信するという動作を書きます。これは仕様で定義された固定の文字列を送信するというかたちです。
次にHTTP/2のSETTINGSフレームと呼ばれるデータを送信します。これもハンドシェイクに必要なデータです。このレスポンスをサーバーに送信すると、あとはサーバー側の応答が来るのを待つことになります。
なので、次はackという、応答フラグ付きのSETTINGSフレームをHTTP/2サーバーから受信するのを待つための定義を書きます。もし一定期間内に、サーバーから応答フラグ付きのSETTINGSフレームによる応答がなかった場合は、テストが失敗するというかたちです。
定義したテストをprotospecを使って実行すると、このようになります。この例ではテストに成功した、つまり応答フラグ付きのSETTINGSフレームがサーバーから正しく送られてきたことを確認した、ということです。
(次回へつづく)
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05