はじめに
Apache Traffic Server ( GitHub - apache/trafficserver: Apache Traffic Server ) の tests/gold_tests 配下にある 各テストを参考に はじめて gold_tests を作成するのを試みた際に、悩んだ点・気づいた点などを、覚えているうちに書き留めておきます。
実行環境のつくりかた
今回、私は、gold_tests 実行環境については hnakamur さんの記事を参考に Dockerにて作成しました。
また、追加の手順として、自分のつくったテストだけ実行したいときには、gold_tests ディレクトリ配下を autest-site と 自分の作成したテストディレクトリのみ にして実行するのがお手軽だったので、そちらの方法でやってました。
【gold_tests配下の全件実行 のイメージ】
cd ~build/dev/trafficserver/tests
env-test/bin/autest -D gold_tests --ats-bin /usr/local/bin
【自分のgold_testsのみ実行 のイメージ】
mkdir ~build/tmp
mv ~build/dev/trafficserver/tests/gold_tests/* ~build/tmp/
mv ~build/tmp/autest-site ~build/dev/trafficserver/tests/gold_tests/
mv ~build/tmp/my-tests ~build/dev/trafficserver/tests/gold_tests/
cd ~build/dev/trafficserver/tests
env-test/bin/autest -D gold_tests --ats-bin /usr/local/bin
gold_tests での試行錯誤① Hierarchical Caching 構成にしたい
tests/gold_tests 配下を見回った限り Hierarchical Caching が無さそうでしたが、gold_tests 内で traffic server のプロセスを2つ作成して、各々の config を設定したところ 1コンテナ内に Child用プロセス と Parent用プロセス を動作させても問題なさそうでした。
私が試した方法では、なぜか DNS が timeout するタイミングがあるという問題があったので、コンテナ内の /etc/hosts にダミーの名前を追記しつつ、config に proxy.config.hostdb.host_file.path で呼び出すという方法で試していました (この方法だと動いたので...) 。
【gold_tests / master(9.0.0) で動かしたミニマムに記述の例】
## プロセスの作成
## ts = Child用 , ts2 = Parent用 として 2つ作成します。
ts = Test.MakeATSProcess("ts")
ts2 = Test.MakeATSProcess("ts2")
## Child の config
ts.Disk.plugin_config.AddLine('xdebug.so')
ts.Disk.remap_config.AddLine(
'map . http://origin.example.com'
)
ts.Disk.parent_config.AddLine(
'dest_domain=. parent="127.0.0.1:{port}"'.format(port=ts2.Variables.port)
)
ts.Disk.records_config.update({
'proxy.config.http.parent_proxy.self_detect' : 0,
'proxy.config.http.no_dns_just_forward_to_parent' : 1,
'proxy.config.http.request_via_str' : 'ApacheTrafficServerChild',
'proxy.config.http.response_via_str' : 'ApacheTrafficServerChild',
'proxy.config.log.logging_enabled' : 3,
'proxy.config.diags.debug.enabled': 1,
'proxy.config.diags.debug.tags': 'http|dns',
'proxy.config.diags.output.debug': 'L',
'proxy.config.hostdb.host_file.path' : '/etc/hosts',
})
## Parent の config
ts2.Disk.plugin_config.AddLine('xdebug.so')
ts2.Disk.remap_config.AddLine(
'map / http://127.0.0.1:{0}'.format(server.Variables.Port)
)
ts2.Disk.records_config.update({
'proxy.config.http.request_via_str' : 'ApacheTrafficServerParent',
'proxy.config.http.response_via_str' : 'ApacheTrafficServerParent',
'proxy.config.log.logging_enabled' : 3,
'proxy.config.diags.debug.enabled': 1,
'proxy.config.diags.debug.tags': 'http|dns',
'proxy.config.diags.output.debug': 'L',
'proxy.config.hostdb.host_file.path' : '/etc/hosts',
})
【DockerFileに追加】
USER root
RUN echo "127.0.0.1 origin.example.com" >> /etc/hosts
gold_tests での試行錯誤② 同一URLへのリクエストに対してのオリジンからのレスポンスを、違うものにしたい
例えば URI "/default" に対して 200 OK , 304 Not Modified の 2パターンを応答させるようにしたい、といったときのアプローチ方法です。
オリジンプロセスの作成 MakeOriginServer にて、lookup_key を指定しないときはデフォルトの lookup_key は PATH のみの挙動となっていました。
【lookup_key を指定しないとき】
server = Test.MakeOriginServer("server")
request_header1 = {"headers":
"GET /default HTTP/1.1\r\n" +
"Host: www.example.com\r\n" +
"\r\n",
"timestamp": "12345678",
"body" : "",
}
response_header6b = {"headers":
"HTTP/1.1 200 OK\r\n" +
"Content-Length: 4\r\n" +
"Connection: close\r\n" +
"Cache-Control: max-age=0\r\n" +
"ETag: \"5ca41161-1a\"\r\n" +
"\r\n",
"timestamp": "12345678",
"body": "test"
}
server.addResponse("sessionlog.json", request_header1, response_header1)
request_header2 = {"headers":
"GET /default HTTP/1.1\r\n" +
"Host: www.example.com\r\n" +
"\r\n",
"timestamp": "12345678",
"body" : "",
}
response_header2 = {"headers":
"HTTP/1.1 304 Not Modified\r\n" +
"Connection: close\r\n" +
"ETag: \"5ca41161-1a\"\r\n" +
"\r\n",
"timestamp": "12345678",
"body": None
}
server.addResponse("sessionlog.json", request_header2, response_header2)
⇒ この場合 "GET /default HTTP/1.1" でリクエストすると最後に定義した response_header2 が常にかえってくるという挙動になってしまいました...
などをみていて、HTTPヘッダを lookup_key に使えそうだったので、フック用のダミーのヘッダ X-Update を用意してみました。
【lookup_key をカスタマイズする】
server = Test.MakeOriginServer("server",lookup_key="{%X-Update}{PATH}")
request_header1 = {"headers":
"GET /default HTTP/1.1\r\n" +
"Host: www.example.com\r\n" +
"X-Update: no\r\n" +
"\r\n",
"timestamp": "12345678",
"body" : "",
}
response_header1 = {"headers":
"HTTP/1.1 200 OK\r\n" +
"Content-Length: 4\r\n" +
"Connection: close\r\n" +
"Cache-Control: max-age=0\r\n" +
"ETag: \"5ca41161-1a\"\r\n" +
"\r\n",
"timestamp": "12345678",
"body": "test"
}
server.addResponse("sessionlog.json", request_header1, response_header1)
request_header2 = {"headers":
"GET /default HTTP/1.1\r\n" +
"Host: www.example.com\r\n" +
"X-Update: yes\r\n" +
"\r\n",
"timestamp": "12345678",
"body" : "",
}
response_header2 = {"headers":
"HTTP/1.1 304 Not Modified\r\n" +
"Connection: close\r\n" +
"ETag: \"5ca41161-1a\"\r\n" +
"\r\n",
"timestamp": "12345678",
"body": None
}
server.addResponse("sessionlog.json", request_header2, response_header2)
⇒ この場合 "GET /default HTTP/1.1" + "X-Update: no" でリクエストするとresponse_header1 が, "GET /default HTTP/1.1" + "X-Update: yes" でリクエストするとresponse_header2かえってくるという挙動をさせることができました。
同一URLに対してオリジンからのレスポンスを変えたいときはこの手の仕込みが必要そうでした。