blob: bf2a88c57bc61f1c96cc34d4d7cd20a9377f035c [file]
'''
'''
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Test.Summary = '''
Basic cache_range_requests plugin test
'''
# Test description:
# Preload the cache with the entire asset to be range requested.
# Reload remap rule with cache_range_requests plugin
# Request content through the cache_range_requests plugin
Test.SkipUnless(
Condition.PluginExists('cache_range_requests.so'),
Condition.PluginExists('header_rewrite.so'),
Condition.PluginExists('xdebug.so'),
)
Test.ContinueOnFail = False
Test.testName = "cache_range_requests"
# Define and configure ATS
ts = Test.MakeATSProcess("ts")
# Define and configure origin server
server = Test.MakeOriginServer("server", lookup_key="{%uuid}")
# default root
req_chk = {
"headers": "GET / HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "uuid: none\r\n" + "\r\n",
"timestamp": "1469733493.993",
"body": ""
}
res_chk = {"headers": "HTTP/1.1 200 OK\r\n" + "Connection: close\r\n" + "\r\n", "timestamp": "1469733493.993", "body": ""}
server.addResponse("sessionlog.json", req_chk, res_chk)
body = "lets go surfin now"
req_full = {
"headers": "GET /path HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Accept: */*\r\n" + "uuid: full\r\n" + "\r\n",
"timestamp": "1469733493.993",
"body": ""
}
res_full = {
"headers": "HTTP/1.1 200 OK\r\n" + "Cache-Control: max-age=500\r\n" + "Connection: close\r\n" + 'Etag: "path"\r\n' + "\r\n",
"timestamp": "1469733493.993",
"body": body
}
server.addResponse("sessionlog.json", req_full, res_full)
block_bytes = 7
bodylen = len(body)
inner_str = "7-15"
req_inner = {
"headers":
"GET /path HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Accept: */*\r\n" + "Range: bytes={}\r\n".format(inner_str) +
"uuid: inner\r\n" + "\r\n",
"timestamp": "1469733493.993",
"body": ""
}
res_inner = {
"headers":
"HTTP/1.1 206 Partial Content\r\n" + "Accept-Ranges: bytes\r\n" + "Cache-Control: max-age=500\r\n" +
"Content-Range: bytes {0}/{1}\r\n".format(inner_str, bodylen) + "Connection: close\r\n" + 'Etag: "path"\r\n' + "\r\n",
"timestamp": "1469733493.993",
"body": body[7:15]
}
server.addResponse("sessionlog.json", req_inner, res_inner)
frange_str = "0-"
req_frange = {
"headers":
"GET /path HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Accept: */*\r\n" + "Range: bytes={}\r\n".format(frange_str) +
"uuid: frange\r\n" + "\r\n",
"timestamp": "1469733493.993",
"body": ""
}
res_frange = {
"headers":
"HTTP/1.1 206 Partial Content\r\n" + "Accept-Ranges: bytes\r\n" + "Cache-Control: max-age=500\r\n" +
"Content-Range: bytes 0-{0}/{0}\r\n".format(bodylen) + "Connection: close\r\n" + 'Etag: "path"\r\n' + "\r\n",
"timestamp": "1469733493.993",
"body": body
}
server.addResponse("sessionlog.json", req_frange, res_frange)
last_str = "-5"
req_last = {
"headers":
"GET /path HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Accept: */*\r\n" + "Range: bytes={}\r\n".format(last_str) +
"uuid: last\r\n" + "\r\n",
"timestamp": "1469733493.993",
"body": ""
}
res_last = {
"headers":
"HTTP/1.1 206 Partial Content\r\n" + "Accept-Ranges: bytes\r\n" + "Cache-Control: max-age=200\r\n" +
"Content-Range: bytes {0}-{1}/{1}\r\n".format(bodylen - 5, bodylen) + "Connection: close\r\n" + 'Etag: "path"\r\n' + "\r\n",
"timestamp": "1469733493.993",
"body": body[-5:]
}
server.addResponse("sessionlog.json", req_last, res_last)
pselect_str = "1-10"
req_pselect = {
"headers":
"GET /path HTTP/1.1\r\n" + "Host: parentselect\r\n" + "Accept: */*\r\n" + "Range: bytes={}\r\n".format(pselect_str) +
"uuid: pselect\r\n" + "\r\n",
"timestamp": "1469733493.993",
"body": ""
}
res_pselect = {
"headers":
"HTTP/1.1 206 Partial Content\r\n" + "Accept-Ranges: bytes\r\n" + "Cache-Control: max-age=200\r\n" +
"Content-Range: bytes {}/19\r\n".format(pselect_str) + "Connection: close\r\n" + 'Etag: "path"\r\n' + "\r\n",
"timestamp": "1469733493.993",
"body": body[1:10]
}
server.addResponse("sessionlog.json", req_pselect, res_pselect)
req_psd = {
"headers":
"GET /path HTTP/1.1\r\n" + "Host: psd\r\n" + "Accept: */*\r\n" + "Range: bytes={}\r\n".format(pselect_str) +
"uuid: pselect\r\n" + "\r\n",
"timestamp": "1469733493.993",
"body": ""
}
server.addResponse("sessionlog.json", req_psd, res_pselect)
# cache range requests plugin remap
ts.Setup.CopyAs('reason.conf', Test.RunDirectory)
ts.Disk.remap_config.AddLines(
[
'map http://www.example.com http://127.0.0.1:{}'.format(server.Variables.Port) +
' @plugin=header_rewrite.so @pparam={}/reason.conf @plugin=cache_range_requests.so'.format(Test.RunDirectory),
# parent select cache key option
'map http://parentselect http://127.0.0.1:{}'.format(server.Variables.Port) +
' @plugin=cache_range_requests.so @pparam=--ps-cachekey',
# deprecated
'map http://psd http://127.0.0.1:{}'.format(server.Variables.Port) +
' @plugin=cache_range_requests.so @pparam=ps_mode:cache_key_url',
])
# cache debug
ts.Disk.plugin_config.AddLine('xdebug.so --enable=x-cache,x-parentselection-key')
# minimal configuration
ts.Disk.records_config.update(
{
'proxy.config.diags.debug.enabled': 1,
'proxy.config.diags.debug.tags': 'cache_range_requests|http',
})
curl_and_args = '-s -D /dev/stdout -o /dev/stderr -x localhost:{} -H "x-debug: x-cache"'.format(ts.Variables.port)
# 0 Test - Fetch whole asset into cache
tr = Test.AddTestRun("full asset cache miss bypass")
ps = tr.Processes.Default
ps.StartBefore(server, ready=When.PortOpen(server.Variables.Port))
ps.StartBefore(Test.Processes.ts)
tr.MakeCurlCommand(curl_and_args + ' http://www.example.com/path -H "uuid: full"', ts=ts)
ps.ReturnCode = 0
ps.Streams.stderr = "gold/full.stderr.gold"
tr.StillRunningAfter = ts
# test inner range
# 1 Test - Fetch range into cache
tr = Test.AddTestRun("inner range cache miss")
ps = tr.Processes.Default
tr.MakeCurlCommand(curl_and_args + ' http://www.example.com/path -r {} -H "uuid: inner"'.format(inner_str), ts=ts)
ps.ReturnCode = 0
ps.Streams.stderr = "gold/inner.stderr.gold"
ps.Streams.stdout.Content = Testers.ContainsExpression("X-Cache: miss", "expected cache miss")
ps.Streams.stdout.Content += Testers.ContainsExpression("Content-Range: bytes 7-15/18", "expected content-range header")
ps.Streams.stdout.Content += Testers.ContainsExpression("206 Foo Bar", "Expected 206 Foo Bar status")
tr.StillRunningAfter = ts
# 2 Test - Fetch from cache
tr = Test.AddTestRun("inner range cache hit")
ps = tr.Processes.Default
tr.MakeCurlCommand(curl_and_args + ' http://www.example.com/path -r {}'.format(inner_str), ts=ts)
ps.ReturnCode = 0
ps.Streams.stderr = "gold/inner.stderr.gold"
ps.Streams.stdout.Content = Testers.ContainsExpression("X-Cache: hit", "expected cache hit")
ps.Streams.stdout.Content += Testers.ContainsExpression("Content-Range: bytes 7-15/18", "expected content-range header")
ps.Streams.stdout.Content += Testers.ContainsExpression("206 Foo Bar", "Expected 206 Foo Bar status")
tr.StillRunningAfter = ts
# full range
# 3 Test - 0- request
tr = Test.AddTestRun("0- request miss")
ps = tr.Processes.Default
tr.MakeCurlCommand(curl_and_args + ' http://www.example.com/path -r {} -H "uuid: frange"'.format(frange_str), ts=ts)
ps.ReturnCode = 0
ps.Streams.stderr = "gold/full.stderr.gold"
ps.Streams.stdout.Content = Testers.ContainsExpression("X-Cache: miss", "expected cache miss")
ps.Streams.stdout.Content += Testers.ContainsExpression("Content-Range: bytes 0-18/18", "expected content-range header")
ps.Streams.stdout.Content += Testers.ContainsExpression("206 Foo Bar", "Expected 206 Foo Bar status")
tr.StillRunningAfter = ts
# 4 Test - 0- request
tr = Test.AddTestRun("0- request hit")
ps = tr.Processes.Default
tr.MakeCurlCommand(curl_and_args + ' http://www.example.com/path -r {}'.format(frange_str), ts=ts)
ps.ReturnCode = 0
ps.Streams.stderr = "gold/full.stderr.gold"
ps.Streams.stdout.Content = Testers.ContainsExpression("X-Cache: hit", "expected cache hit")
ps.Streams.stdout.Content += Testers.ContainsExpression("Content-Range: bytes 0-18/18", "expected Content-Range header")
ps.Streams.stdout.Content += Testers.ContainsExpression("206 Foo Bar", "Expected 206 Foo Bar header")
tr.StillRunningAfter = ts
# end range
# 5 Test - -5 request miss
tr = Test.AddTestRun("-5 request miss")
ps = tr.Processes.Default
tr.MakeCurlCommand(curl_and_args + ' http://www.example.com/path -r {} -H "uuid: last"'.format(last_str), ts=ts)
ps.ReturnCode = 0
ps.Streams.stderr = "gold/last.stderr.gold"
ps.Streams.stdout.Content = Testers.ContainsExpression("X-Cache: miss", "expected cache miss")
ps.Streams.stdout.Content += Testers.ContainsExpression("Content-Range: bytes 13-18/18", "expected content-range header")
ps.Streams.stdout.Content += Testers.ContainsExpression("206 Foo Bar", "Expected 206 Foo Bar status")
tr.StillRunningAfter = ts
# 6 Test - -5 request hit
tr = Test.AddTestRun("-5 request hit")
ps = tr.Processes.Default
tr.MakeCurlCommand(curl_and_args + ' http://www.example.com/path -r {}'.format(last_str), ts=ts)
ps.ReturnCode = 0
ps.Streams.stderr = "gold/last.stderr.gold"
ps.Streams.stdout.Content = Testers.ContainsExpression("X-Cache: hit", "expected cache hit")
ps.Streams.stdout.Content += Testers.ContainsExpression("Content-Range: bytes 13-18/18", "expected content-range header")
ps.Streams.stdout.Content += Testers.ContainsExpression("206 Foo Bar", "Expected 206 Bar Bar status")
tr.StillRunningAfter = ts
# Ensure 404's aren't getting cached
# 7 Test - 404
tr = Test.AddTestRun("404 request 1st")
ps = tr.Processes.Default
tr.MakeCurlCommand(curl_and_args + ' http://www.example.com/404 -r 0-', ts=ts)
ps.Streams.stdout = "gold/404.stdout.gold"
ps.Streams.stdout.Content = Testers.ContainsExpression("X-Cache: miss", "expected cache miss")
tr.StillRunningAfter = ts
# 8 Test - 404
tr = Test.AddTestRun("404 request 2nd")
ps = tr.Processes.Default
tr.MakeCurlCommand(curl_and_args + ' http://www.example.com/404 -r 0-', ts=ts)
ps.Streams.stdout.Content = Testers.ContainsExpression("X-Cache: miss", "expected cache miss")
ps.Streams.stdout.Content += Testers.ContainsExpression("404 Not Found", "expected 404 response")
tr.StillRunningAfter = ts
# 9 Test - origin returns 200 response to range request
tr = Test.AddTestRun("origin returns 200")
ps = tr.Processes.Default
tr.MakeCurlCommand(curl_and_args + ' http://www.example.com/path -r {} -H "uuid: full"', ts=ts)
ps.ReturnCode = 3 # <--- note the return code
ps.Streams.stdout.Content = Testers.ContainsExpression("X-Cache: miss", "expected cache miss")
ps.Streams.stdout.Content += Testers.ContainsExpression("200 OK", "expected full 200 response")
ps.Streams.stdout.Content += Testers.ExcludesExpression("Content-Range:", "didn't expect Content-Range header")
tr.StillRunningAfter = ts
curl_and_args = '-s -D /dev/stdout -o /dev/stderr -x localhost:{} -H "x-debug: x-parentselection-key"'.format(ts.Variables.port)
# 10 Test - cache_key_url request
tr = Test.AddTestRun("cache_key_url request")
ps = tr.Processes.Default
tr.MakeCurlCommand(curl_and_args + ' http://parentselect/path -r {} -H "uuid: pselect"'.format(pselect_str), ts=ts)
ps.ReturnCode = 0
ps.Streams.stdout.Content = Testers.ContainsExpression(
"X-ParentSelection-Key: .*-bytes=",
"expected bytes in parent selection key",
)
tr.StillRunningAfter = ts
tr.StillRunningAfter = server
# 11 Test - non cache_key_url request ... no X-ParentSelection-Key
tr = Test.AddTestRun("non cache_key_url request")
ps = tr.Processes.Default
tr.MakeCurlCommand(curl_and_args + ' http://www.example.com/path -r {} -H "uuid: inner"'.format(inner_str), ts=ts)
ps.ReturnCode = 0
ps.Streams.stdout.Content = Testers.ExcludesExpression("X-ParentSelection-Key", "parent select key shouldn't show up")
tr.StillRunningAfter = ts
tr.StillRunningAfter = server
# 12 Test - cache_key_url request -- deprecated
tr = Test.AddTestRun("cache_key_url request - deprecated")
ps = tr.Processes.Default
tr.MakeCurlCommand(curl_and_args + ' http://psd/path -r {} -H "uuid: pselect"'.format(pselect_str), ts=ts)
ps.ReturnCode = 0
ps.Streams.stdout.Content = Testers.ContainsExpression(
"X-ParentSelection-Key: .*-bytes=",
"expected bytes in parent selection key",
)
tr.StillRunningAfter = ts
tr.StillRunningAfter = server