2024.10.10
将来は卵1パックの価格が2倍に? 多くの日本人が知らない世界の新潮流、「動物福祉」とは
リンクをコピー
記事をブックマーク
石澤基氏:今日は、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.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略