varnishtestがHTTP2対応して超便利!

既に記法が変わっています。サンプルコードはそのままでは使用できません。リポジトリ内のテストコードを参考にしてください (2016/04/04)


20161210 「varnishtestのHTTP/2対応 アップデート」にて、更新項目について書きました


Varnish-CacheのvarnishtestがHTTP2に対応した(まだWIP状態であり、正式ではない。)

varnishtestと言う名前だが、Varnishのテスト以外にも十分使えると思う。


イメージしやすいように先に簡単なサンプルを載せる。

サンプル

テストコードはvtcと呼ばれるコードで記述する。

h2client c1 -connect localhost:8080 {
        stream 1 {
                txreq -req GET -url / -hdr :scheme http -hdr :authority localhost
                rxresp
                expect resp.http.:status == 200
        } -run

        stream 3 {
                txreq -req GET -url /404 -hdr :authority localhost
                rxrst
                expect rst.err == 1
        } -run

        stream 0 {
                txprio -stream 0 -weight 1
                rxgoaway
                expect goaway.err == 1
                expect goaway.laststream == 3
        } -run
} -run


このコードでは、クライアントがlocalhost:8080のサーバに対して以下のテストを実行する

  • stream1でGETを送信し、受信したレスポンスはstatusコードが200である
  • stream3で:schemeヘッダのないGETを送信し、受信したRST_STREAMフレームのエラーコードは1である
  • stream0でPRIORITYフレームを送信し、受信したGOAWAYフレームのエラーコードは1、laststreamは3である


このようにクライアントの振る舞いを自由に記述し、テストすることが出来る。
記述方法は一見分かりづらいかもしれないがすぐに慣れる(最下部記述の参考資料を御覧ください)

実行する

実際に実行してみる

vagrant@vagrant:~/Varnish-Cache/bin/varnishtest$ ./varnishtest ./h2c.vct
#     top  TEST ./h2c.vct passed (0.163)


サーバ側

vagrant@vagrant:~/nghttp2/src$ ./nghttpd --no-tls 8080 -v |grep frame
...(略)
[id=1] [  8.405] recv HEADERS frame <length=80, flags=0x05, stream_id=1>
[id=1] [  8.406] send HEADERS frame <length=94, flags=0x04, stream_id=1>
[id=1] [  8.406] send DATA frame <length=2, flags=0x01, stream_id=1>
[  8.452] [INVALID; error=Violation in HTTP messaging rule] recv HEADERS frame <length=47, flags=0x05, stream_id=3>
[id=1] [  8.452] send RST_STREAM frame <length=4, flags=0x00, stream_id=3>
[id=1] [  8.496] recv PRIORITY frame <length=5, flags=0x00, stream_id=1>
[  8.496] [INVALID; error=Protocol error] recv PRIORITY frame <length=5, flags=0x00, stream_id=0>
[id=1] [  8.496] send GOAWAY frame <length=32, flags=0x00, stream_id=0>

サーバ側のログを見ることで、実際にHTTP/2の通信が指定通り行なわれていることが確認できた。



もちろん、上記のテストを 「expect rst.err == 2」のように変更すると、FAILEDになる。

**   c1    0.1 === expect rst.err == 2
---- c1    0.1 (s3) EXPECT rst.err (1) == "2" failed

#     top  TEST ./h2c.vct FAILED (60.062) signal=9 exit=0


複雑な例では、HPACKでヘッダを指定したり、テーブルの状態をテストすることも出来るようだ

 stream 1 {
         txreq \
                 -litIdxHdr inc 8 plain "302" \
                 -litIdxHdr inc 24 plain "private" \
                 -litIdxHdr inc 33 plain "Mon, 21 Oct 2013 20:13:21 GMT" \
                 -litIdxHdr inc 46 plain "https://www.example.com"
         expect outtable[1].key == "location"
         expect outtable[1].value == "https://www.example.com"


WIP/h2testブランチより、その他のテストケース例も確認できる。
h2serverとしてサーバの振る舞いも記述できるようだし、色々便利ぽい。



参考資料

まだWIPなものなので程々に

varnishtest自体のすばらしい参考資料


試すにあたってアドバイスを頂いた方に感謝してます。