varnishtestのHTTP/2対応 アップデート

これは、http2 Advent Calendar 2016の10日目の記事です。


今年の頭に書いた「varnishtestがHTTP2対応して超便利!」で紹介しましたvarnishtestのHTTP/2対応ですが、シンタックスの一部変更で当時のサンプルが使えなくなっていたのでアップデートについて軽く書きたいと思います。


当時は開発者様の個人リポジトリで開発が進められている状況でしたが、varnish5でmasterにマージされております。
また、varnish5で本体側もhttp2対応が進められているため、ようやくvarnish本体を経由するようなテストもかけるようになりました。ただし本体側のhttp2はまだまだバグがあるようで実際に使う場合は慎重になったほうが良いようです。


varnishtest自体については前回の記事を見ていただくか、いわなちゃんさんの記事がわかりやすいかと思います

サンプル

HTTP/2のサーバとクライアントでボディ付きの通信をする例になります。
https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishtest/tests/a02002.vtc

varnishtest "Simple request with body"

server s1 {
	stream 1 {
		rxreq
		txresp -body "bob"
	} -run
} -start

client c1 -connect ${s1_sock} {
	stream 1 {
		txreq
		rxresp
		expect resp.bodylen == 3
	} -run
} -run
  • 以前は「 h2client」のように明示的にh2対応のクライアントと書いていましたが、stream句を使うことで各エンドポイントはHTTP/2通信に切り替わるようになりましt(http1からのアップグレードの手順も記述できるようになっています)
  • HTTP/2で要求される疑似ヘッダ(scheme, method, authority)などが明示的に書く必要がなくなりました
その他新機能

コネクションレベル・ストリームレベルのウィンドウサイズのテストが記述できるようになりました
https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishtest/tests/a02023.vtc


ウィンドウサイズのテストにおいて、SETTINGSフレームで指定される初期ウィンドウサイズを考慮するようになりました
https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishtest/tests/a02010.vtc



ストリームの依存関係・ウェイトのテストが記述できるようになりました
https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishtest/tests/a02015.vtc



サーバプッシュのテストが記述できるようになりました
https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishtest/tests/a02017.vtc

varnishを間に挟む場合のテスト

varnish本体がh2(h2cのみ)に対応しているため、varnishtestもクライアント・(バックエンドとしての)サーバの間にvarnishを挟む形のテスト例も追加されています。


https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishtest/tests/t02000.vtc

server s1 {
	rxreq
	expect req.http.host == foo.bar
	txresp -bodylen 10
} -start

varnish v1 -vcl+backend {} -start

varnish v1 -cliok "param.set feature +http2"
varnish v1 -cliok "param.set debug +syncvsl"

client c1 {
	stream 1 {
		txprio -weight 10 -stream 0
	} -run
	stream 3 {
		txprio -weight 10 -stream 0
	} -run
	stream 5 {
		txprio -weight 10 -stream 2
	} -run
	stream 7 {
		txreq -hdr :authority foo.bar
		rxresp
		expect resp.status == 200
	} -start
	stream 0 {
		txping -data "_-__-_-_"
		rxping
		expect ping.ack == "true"
		expect ping.data == "_-__-_-_"
	} -run
	stream 7 -wait
} -run

この例では、バックエンドサーバはhttp/1を使用して、クライアント側からはh2で接続するテストになっています。
varnishのパラメータでhttp2を有効にする必要はありますが、ココらへんは記述方式的にはhttp2独自ではないので通常通り動くという感じになるかと思います。

おまけ

テスト例として、別のクライアント実装と通信する例もあります
https://github.com/varnishcache/varnish-cache/blob/master/bin/varnishtest/tests/a02022.vtc

feature cmd "nghttp --version | grep -q 'nghttp2/[1-9]'"

server s1 {
	rxreq
	upgrade

	stream 3 { rxprio } -run
	stream 5 { rxprio } -run
	stream 7 { rxprio } -run
	stream 9 { rxprio } -run
	stream 11 { rxprio } -run

	stream 1 {
		rxprio
		txresp
	} -start

} -start


shell { nghttp http://${s1_addr}:${s1_port} -nu }


varnishtestはvarnish以外でも使用できます。IP指定も出来ますし、今回はありませんが複数クライアントで同時にリクエストを送らせたりも出来ます。
工夫次第では色々な使い方ができるかと思います!!