blob: 181f3595d99ac19d7d7d37828f65e36f80ca3fef [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 = '''
Test compress plugin
'''
# This test case is very bare-bones. It only covers a few scenarios that have caused problems.
# Skip if plugins not present.
#
Test.SkipUnless(
Condition.PluginExists('compress.so'), Condition.PluginExists('conf_remap.so'), Condition.HasATSFeature('TS_HAS_BROTLI'),
Condition.HasATSFeature('TS_HAS_ZSTD'))
server = Test.MakeOriginServer("server", options={'--load': f'{Test.TestDirectory}/compress_observer.py'})
# Need a fairly big body, otherwise the plugin will refuse to compress
line = "lets go surfin now everybodys learnin how"
body = f'{line}\n' * 24 + line
orig_path = f'{Test.RunDirectory}/orig.txt'
open(orig_path, 'w').write(body)
# expected response from the origin server
response_header = {
"headers":
"HTTP/1.1 200 OK\r\nConnection: close\r\n" + 'Etag: "359670651"\r\n' + "Cache-Control: public, max-age=31536000\r\n" +
"Accept-Ranges: bytes\r\n" + "Content-Type: text/javascript\r\n" + "\r\n",
"timestamp": "1469733493.993",
"body": body
}
for i in range(6):
# add request/response to the server dictionary
request_header = {"headers": f"GET /obj{i} HTTP/1.1\r\nHost: just.any.thing\r\n\r\n", "timestamp": "1469733493.993", "body": ""}
server.addResponse("sessionfile.log", request_header, response_header)
# post for the origin server
post_request_header = {
"headers":
"POST /obj3 HTTP/1.1\r\nHost: just.any.thing\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 11\r\n\r\n",
"timestamp": "1469733493.993",
"body": "knock knock"
}
server.addResponse("sessionfile.log", post_request_header, response_header)
def curl(ts, idx, encodingList, out_path):
return (
f"-o {out_path} --verbose --proxy http://127.0.0.1:{ts.Variables.port}"
f" --header 'X-Ats-Compress-Test: {idx}/{encodingList}'"
f" --header 'Accept-Encoding: {encodingList}' 'http://ae-{idx}/obj{idx}'"
" 2>> compress_long.log ; printf '\n===\n' >> compress_long.log")
def curl_post(ts, idx, encodingList, out_path):
return (
f"-o {out_path} --verbose -d 'knock knock' --proxy http://127.0.0.1:{ts.Variables.port}"
f" --header 'X-Ats-Compress-Test: {idx}/{encodingList}'"
f" --header 'Accept-Encoding: {encodingList}' 'http://ae-{idx}/obj{idx}'"
" 2>> compress_long.log ; printf '\n===\n' >> compress_long.log")
waitForServer = True
waitForTs = True
ts = Test.MakeATSProcess("ts", enable_cache=False)
ts.Disk.records_config.update(
{
'proxy.config.diags.debug.enabled': 1,
'proxy.config.diags.debug.tags': 'compress',
'proxy.config.http.normalize_ae': 0,
})
ts.Setup.Copy("compress.config")
ts.Setup.Copy("compress2.config")
ts.Setup.Copy("compress3.config")
ts.Disk.remap_config.AddLine(
f'map http://ae-0/ http://127.0.0.1:{server.Variables.Port}/' +
f' @plugin=compress.so @pparam={Test.RunDirectory}/compress.config')
ts.Disk.remap_config.AddLine(
f'map http://ae-1/ http://127.0.0.1:{server.Variables.Port}/' +
' @plugin=conf_remap.so @pparam=proxy.config.http.normalize_ae=1' +
f' @plugin=compress.so @pparam={Test.RunDirectory}/compress.config')
ts.Disk.remap_config.AddLine(
f'map http://ae-2/ http://127.0.0.1:{server.Variables.Port}/' +
' @plugin=conf_remap.so @pparam=proxy.config.http.normalize_ae=2' +
f' @plugin=compress.so @pparam={Test.RunDirectory}/compress2.config')
ts.Disk.remap_config.AddLine(
f'map http://ae-3/ http://127.0.0.1:{server.Variables.Port}/' +
' @plugin=conf_remap.so @pparam=proxy.config.http.normalize_ae=3' +
f' @plugin=compress.so @pparam={Test.RunDirectory}/compress2.config')
ts.Disk.remap_config.AddLine(
f'map http://ae-4/ http://127.0.0.1:{server.Variables.Port}/' +
' @plugin=conf_remap.so @pparam=proxy.config.http.normalize_ae=4' +
f' @plugin=compress.so @pparam={Test.RunDirectory}/compress3.config')
ts.Disk.remap_config.AddLine(
f'map http://ae-5/ http://127.0.0.1:{server.Variables.Port}/' +
' @plugin=conf_remap.so @pparam=proxy.config.http.normalize_ae=5' +
f' @plugin=compress.so @pparam={Test.RunDirectory}/compress3.config')
out_path_counter = 0
def get_out_path():
global out_path_counter
out_path = f'{Test.RunDirectory}/curl_out_{out_path_counter}'
out_path_counter += 1
return out_path
deflate_path = f'{Test.RunDirectory}/deflate.txt'
def get_verify_command(out_path, decrompressor):
return f"{decrompressor} {out_path} > {deflate_path} && diff {deflate_path} {orig_path}"
for i in range(6):
tr = Test.AddTestRun(f'gzip, deflate, sdch, br, zstd: {i}')
if (waitForTs):
tr.Processes.Default.StartBefore(ts)
waitForTs = False
if (waitForServer):
tr.Processes.Default.StartBefore(server, ready=When.PortOpen(server.Variables.Port))
waitForServer = False
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, i, 'gzip, deflate, sdch, br, zstd', out_path), ts=ts)
tr = Test.AddTestRun(f'verify gzip, deflate, sdch, br, zstd: {i}')
tr.ReturnCode = 0
if i == 0:
tr.Processes.Default.Command = get_verify_command(out_path, "brotli -d -c")
elif i == 1:
tr.Processes.Default.Command = get_verify_command(out_path, "gunzip -k -c")
elif i == 2:
tr.Processes.Default.Command = get_verify_command(out_path, "brotli -d -c")
elif i == 3:
tr.Processes.Default.Command = get_verify_command(out_path, "brotli -d -c")
elif i == 4:
tr.Processes.Default.Command = get_verify_command(out_path, "zstd -d -c")
elif i == 5:
tr.Processes.Default.Command = get_verify_command(out_path, "zstd -d -c")
tr = Test.AddTestRun(f'gzip: {i}')
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, i, "gzip", out_path), ts=ts)
tr = Test.AddTestRun(f'verify gzip: {i}')
tr.ReturnCode = 0
tr.Processes.Default.Command = get_verify_command(out_path, "gunzip -k -c")
tr = Test.AddTestRun(f'br: {i}')
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, i, "br", out_path), ts=ts)
tr = Test.AddTestRun(f'verify br: {i}')
tr.ReturnCode = 0
if i == 1:
tr.Processes.Default.Command = f"diff {out_path} {orig_path}"
else:
tr.Processes.Default.Command = get_verify_command(out_path, "brotli -d -c")
tr = Test.AddTestRun(f'deflate: {i}')
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, i, "deflate", out_path), ts=ts)
tr = Test.AddTestRun(f'verify deflate: {i}')
tr.ReturnCode = 0
tr.Processes.Default.Command = f"diff {out_path} {orig_path}"
tr = Test.AddTestRun(f'zstd: {i}')
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, i, "zstd", out_path))
tr = Test.AddTestRun(f'verify zstd: {i}')
tr.ReturnCode = 0
if i == 4 or i == 5:
tr.Processes.Default.Command = get_verify_command(out_path, "zstd -d -c")
else:
tr.Processes.Default.Command = get_verify_command(out_path, "cat")
# Test Accept-Encoding normalization.
tr = Test.AddTestRun()
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, 0, "gzip;q=0.666", out_path), ts=ts)
tr = Test.AddTestRun(f'verify gzip;q=0.666')
tr.ReturnCode = 0
tr.Processes.Default.Command = get_verify_command(out_path, "gunzip -k -c")
tr = Test.AddTestRun()
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, 0, "gzip;q=0.666x", out_path), ts=ts)
tr = Test.AddTestRun(f'verify gzip;q=0.666x')
tr.ReturnCode = 0
tr.Processes.Default.Command = get_verify_command(out_path, "gunzip -k -c")
tr = Test.AddTestRun()
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, 0, "gzip;q=#0.666", out_path), ts=ts)
tr = Test.AddTestRun(f'verify gzip;q=#0.666')
tr.ReturnCode = 0
tr.Processes.Default.Command = get_verify_command(out_path, "gunzip -k -c")
tr = Test.AddTestRun()
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, 0, "gzip; Q = 0.666", out_path), ts=ts)
tr = Test.AddTestRun(f'verify gzip; Q = 0.666')
tr.ReturnCode = 0
tr.Processes.Default.Command = get_verify_command(out_path, "gunzip -k -c")
tr = Test.AddTestRun()
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, 0, "gzip;q=0.0", out_path), ts=ts)
tr = Test.AddTestRun(f'verify gzip;q=0.0')
tr.ReturnCode = 0
tr.Processes.Default.Command = f"diff {out_path} {orig_path}"
tr = Test.AddTestRun()
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, 0, "gzip;q=-0.1", out_path), ts=ts)
tr = Test.AddTestRun(f'verify gzip;q=-0.1')
tr.ReturnCode = 0
tr.Processes.Default.Command = get_verify_command(out_path, "gunzip -k -c")
tr = Test.AddTestRun()
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, 0, "aaa, gzip;q=0.666, bbb", out_path), ts=ts)
tr = Test.AddTestRun(f'verify aaa, gzip;q=0.666, bbb')
tr.ReturnCode = 0
tr.Processes.Default.Command = get_verify_command(out_path, "gunzip -k -c")
tr = Test.AddTestRun()
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, 0, " br ; q=0.666, bbb", out_path), ts=ts)
tr = Test.AddTestRun(f'verify br ; q=0.666, bbb')
tr.ReturnCode = 0
tr.Processes.Default.Command = get_verify_command(out_path, "brotli -d -c")
tr = Test.AddTestRun()
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, 0, "aaa, gzip;q=0.666 , ", out_path), ts=ts)
tr = Test.AddTestRun(f'verify aaa, gzip;q=0.666 , ')
tr.ReturnCode = 0
tr.Processes.Default.Command = get_verify_command(out_path, "gunzip -k -c")
# post
tr = Test.AddTestRun()
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl_post(ts, 3, "gzip", out_path), ts=ts)
tr = Test.AddTestRun(f'verify gzip post')
tr.ReturnCode = 0
tr.Processes.Default.Command = get_verify_command(out_path, "gunzip -k -c")
# Test Vary header: compressible content without Accept-Encoding should get Vary: Accept-Encoding
tr = Test.AddTestRun('vary header test: no accept-encoding')
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(
f"-o {out_path} --verbose --proxy http://127.0.0.1:{ts.Variables.port}"
f" --header 'X-Ats-Compress-Test: vary-no-accept-encoding'"
f" 'http://ae-0/obj0'"
" 2>> compress_vary.log",
ts=ts)
# Test Vary header: compressible content with unsupported Accept-Encoding should get Vary: Accept-Encoding
tr = Test.AddTestRun('vary header test: unsupported accept-encoding')
tr.Processes.Default.ReturnCode = 0
out_path = get_out_path()
tr.MakeCurlCommand(curl(ts, 0, "compress, identity", out_path).replace("compress_long.log", "compress_vary.log"), ts=ts)
# Verify Vary header is present in both cases
tr = Test.AddTestRun('verify vary headers')
tr.Processes.Default.ReturnCode = 0
tr.Processes.Default.Command = (
r"tr -d '\r' < compress_vary.log | grep -i 'vary:.*accept-encoding' | sort > compress_vary_short.log")
f = tr.Disk.File("compress_vary_short.log")
f.Content = "compress_vary.gold"
# compress_long.log contains all the output from the curl commands. The tr removes the carriage returns for easier
# readability. Curl seems to have a bug, where it will neglect to output an end of line before outputting an HTTP
# message header line. The sed command is a work-around for this problem. greplog.sh uses the grep command to
# select HTTP request/response line that should be consistent every time the test runs.
#
tr = Test.AddTestRun()
tr.Processes.Default.ReturnCode = 0
tr.Processes.Default.Command = (
r"tr -d '\r' < compress_long.log | sed 's/\(..*\)\([<>]\)/\1\n\2/' | {0}/greplog.sh > compress_short.log".format(
Test.TestDirectory))
f = tr.Disk.File("compress_short.log")
f.Content = "compress.gold"
tr = Test.AddTestRun()
tr.Processes.Default.Command = "echo"
f = tr.Disk.File("compress_userver.log")
f.Content = "compress_userver.gold"