From 9182eb1b54bce100280c59ebdbdb86fb4dd448bc Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Fri, 30 Jun 2023 10:10:54 +0200 Subject: [PATCH] Sync test cases and their version checks with mod_h2 --- test/modules/http2/test_003_get.py | 6 +- test/modules/http2/test_008_ranges.py | 146 ------------------ test/modules/http2/test_009_timing.py | 76 --------- test/modules/http2/test_401_early_hints.py | 8 +- test/modules/http2/test_500_proxy.py | 6 - test/modules/http2/test_600_h2proxy.py | 8 +- .../modules/http2/test_601_h2proxy_twisted.py | 12 +- 7 files changed, 19 insertions(+), 243 deletions(-) diff --git a/test/modules/http2/test_003_get.py b/test/modules/http2/test_003_get.py index cc7e5117955..57c3775bfd0 100644 --- a/test/modules/http2/test_003_get.py +++ b/test/modules/http2/test_003_get.py @@ -251,7 +251,8 @@ def test_h2_003_70(self, env): # produce an error during response body def test_h2_003_71(self, env, repeat): - pytest.skip("needs fix in core protocol handling") + if env.httpd_is_at_least('2.5.0'): + pytest.skip("needs fix in core protocol handling") url = env.mkurl("https", "cgi", "/h2test/error?body_error=timeout") r = env.curl_get(url) assert r.exit_code != 0, f"{r}" @@ -261,7 +262,8 @@ def test_h2_003_71(self, env, repeat): # produce an error, fail to generate an error bucket def test_h2_003_72(self, env, repeat): - pytest.skip("needs fix in core protocol handling") + if env.httpd_is_at_least('2.5.0'): + pytest.skip("needs fix in core protocol handling") url = env.mkurl("https", "cgi", "/h2test/error?body_error=timeout&error_bucket=0") r = env.curl_get(url) assert r.exit_code != 0, f"{r}" diff --git a/test/modules/http2/test_008_ranges.py b/test/modules/http2/test_008_ranges.py index ce86399a5d4..8bf8a3f161b 100644 --- a/test/modules/http2/test_008_ranges.py +++ b/test/modules/http2/test_008_ranges.py @@ -116,152 +116,6 @@ def test_h2_008_03(self, env, repeat): ]) assert r.exit_code != 0, f'{r}' found = False - for line in open(TestRanges.LOGFILE).readlines(): - e = json.loads(line) - if e['request'] == f'GET {path}?03broken HTTP/2.0': - assert e['bytes_rx_I'] > 0 - assert e['bytes_resp_B'] == 100*1024*1024 - assert e['bytes_tx_O'] > 1024 - assert e['bytes_tx_O'] < 5*1024*1024 # curl buffers, but not that much - found = True - break - assert found, f'request not found in {self.LOGFILE}' - - # upload and GET again using curl, compare to original content - def curl_upload_and_verify(self, env, fname, options=None): - url = env.mkurl("https", "cgi", "/upload.py") - fpath = os.path.join(env.gen_dir, fname) - r = env.curl_upload(url, fpath, options=options) - assert r.exit_code == 0, f"{r}" - assert 200 <= r.response["status"] < 300 - - r2 = env.curl_get(r.response["header"]["location"]) - assert r2.exit_code == 0 - assert r2.response["status"] == 200 - with open(os.path.join(TestRanges.SRCDIR, fpath), mode='rb') as file: - src = file.read() - assert src == r2.response["body"] - -import inspect -import json -import os -import pytest - -from .env import H2Conf, H2TestEnv - - -@pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here") -class TestRanges: - - LOGFILE = "" - - @pytest.fixture(autouse=True, scope='class') - def _class_scope(self, env): - TestRanges.LOGFILE = os.path.join(env.server_logs_dir, "test_008") - TestRanges.SRCDIR = os.path.dirname(inspect.getfile(TestRanges)) - if os.path.isfile(TestRanges.LOGFILE): - os.remove(TestRanges.LOGFILE) - destdir = os.path.join(env.gen_dir, 'apache/htdocs/test1') - env.make_data_file(indir=destdir, fname="data-100m", fsize=100*1024*1024) - conf = H2Conf(env=env) - conf.add([ - "CustomLog logs/test_008 combined" - ]) - conf.add_vhost_cgi() - conf.add_vhost_test1() - conf.install() - assert env.apache_restart() == 0 - - def test_h2_008_01(self, env): - # issue: #203 - resource = "data-1k" - full_length = 1000 - chunk = 200 - self.curl_upload_and_verify(env, resource, ["-v", "--http2"]) - assert env.apache_restart() == 0 - url = env.mkurl("https", "cgi", f"/files/{resource}?01full") - r = env.curl_get(url, 5, options=["--http2"]) - assert r.response["status"] == 200 - url = env.mkurl("https", "cgi", f"/files/{resource}?01range") - r = env.curl_get(url, 5, options=["--http1.1", "-H", "Range: bytes=0-{0}".format(chunk-1)]) - assert 206 == r.response["status"] - assert chunk == len(r.response["body"].decode('utf-8')) - r = env.curl_get(url, 5, options=["--http2", "-H", "Range: bytes=0-{0}".format(chunk-1)]) - assert 206 == r.response["status"] - assert chunk == len(r.response["body"].decode('utf-8')) - # Restart for logs to be flushed out - assert env.apache_restart() == 0 - # now check what response lengths have actually been reported - detected = {} - for line in open(TestRanges.LOGFILE).readlines(): - e = json.loads(line) - if e['request'] == f'GET /files/{resource}?01full HTTP/2.0': - assert e['bytes_rx_I'] > 0 - assert e['bytes_resp_B'] == full_length - assert e['bytes_tx_O'] > full_length - detected['h2full'] = 1 - elif e['request'] == f'GET /files/{resource}?01range HTTP/2.0': - assert e['bytes_rx_I'] > 0 - assert e['bytes_resp_B'] == chunk - assert e['bytes_tx_O'] > chunk - assert e['bytes_tx_O'] < chunk + 256 # response + frame stuff - detected['h2range'] = 1 - elif e['request'] == f'GET /files/{resource}?01range HTTP/1.1': - assert e['bytes_rx_I'] > 0 # input bytes received - assert e['bytes_resp_B'] == chunk # response bytes sent (payload) - assert e['bytes_tx_O'] > chunk # output bytes sent - detected['h1range'] = 1 - assert 'h1range' in detected, f'HTTP/1.1 range request not found in {TestRanges.LOGFILE}' - assert 'h2range' in detected, f'HTTP/2 range request not found in {TestRanges.LOGFILE}' - assert 'h2full' in detected, f'HTTP/2 full request not found in {TestRanges.LOGFILE}' - - def test_h2_008_02(self, env, repeat): - path = '/002.jpg' - res_len = 90364 - url = env.mkurl("https", "test1", f'{path}?02full') - r = env.curl_get(url, 5) - assert r.response["status"] == 200 - assert "HTTP/2" == r.response["protocol"] - h = r.response["header"] - assert "accept-ranges" in h - assert "bytes" == h["accept-ranges"] - assert "content-length" in h - clen = h["content-length"] - assert int(clen) == res_len - # get the first 1024 bytes of the resource, 206 status, but content-length as original - url = env.mkurl("https", "test1", f'{path}?02range') - r = env.curl_get(url, 5, options=["-H", "range: bytes=0-1023"]) - assert 206 == r.response["status"] - assert "HTTP/2" == r.response["protocol"] - assert 1024 == len(r.response["body"]) - assert "content-length" in h - assert clen == h["content-length"] - # Restart for logs to be flushed out - assert env.apache_restart() == 0 - # now check what response lengths have actually been reported - found = False - for line in open(TestRanges.LOGFILE).readlines(): - e = json.loads(line) - if e['request'] == f'GET {path}?02range HTTP/2.0': - assert e['bytes_rx_I'] > 0 - assert e['bytes_resp_B'] == 1024 - assert e['bytes_tx_O'] > 1024 - assert e['bytes_tx_O'] < 1024 + 256 # response and frame stuff - found = True - break - assert found, f'request not found in {self.LOGFILE}' - - # send a paced curl download that aborts in the middle of the transfer - def test_h2_008_03(self, env, repeat): - if not env.httpd_is_at_least('2.5.0'): - pytest.skip(f'needs r1909769 from trunk') - path = '/data-100m' - url = env.mkurl("https", "test1", f'{path}?03broken') - r = env.curl_get(url, 5, options=[ - '--limit-rate', '2k', '-m', '2' - ]) - assert r.exit_code != 0, f'{r}' - found = False for line in open(TestRanges.LOGFILE).readlines(): e = json.loads(line) if e['request'] == f'GET {path}?03broken HTTP/2.0': diff --git a/test/modules/http2/test_009_timing.py b/test/modules/http2/test_009_timing.py index d73327c2b3e..2c62bb0738b 100644 --- a/test/modules/http2/test_009_timing.py +++ b/test/modules/http2/test_009_timing.py @@ -72,79 +72,3 @@ def test_h2_009_02(self, env): assert e['time_taken'] < 500 * 1000, f'time for 1st request not reported correctly' found = True assert found, f'request not found in {TestTiming.LOGFILE}' -import inspect -import json -import os -import pytest - -from .env import H2Conf, H2TestEnv - - -@pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here") -class TestTiming: - - LOGFILE = "" - - @pytest.fixture(autouse=True, scope='class') - def _class_scope(self, env): - TestTiming.LOGFILE = os.path.join(env.server_logs_dir, "test_009") - if os.path.isfile(TestTiming.LOGFILE): - os.remove(TestTiming.LOGFILE) - conf = H2Conf(env=env) - conf.add([ - "CustomLog logs/test_009 combined" - ]) - conf.add_vhost_cgi() - conf.add_vhost_test1() - conf.install() - assert env.apache_restart() == 0 - - # check that we get a positive time_taken reported on a simple GET - def test_h2_009_01(self, env): - path = '/002.jpg' - url = env.mkurl("https", "test1", f'{path}?01') - args = [ - env.h2load, "-n", "1", "-c", "1", "-m", "1", - f"--connect-to=localhost:{env.https_port}", - f"--base-uri={url}", url - ] - r = env.run(args) - # Restart for logs to be flushed out - assert env.apache_restart() == 0 - found = False - for line in open(TestTiming.LOGFILE).readlines(): - e = json.loads(line) - if e['request'] == f'GET {path}?01 HTTP/2.0': - assert e['time_taken'] > 0 - found = True - assert found, f'request not found in {TestTiming.LOGFILE}' - - # test issue #253, where time_taken in a keepalive situation is not - # reported until the next request arrives - def test_h2_009_02(self, env): - if not env.httpd_is_at_least('2.5.0'): - pytest.skip(f'needs r1909769 from trunk') - baseurl = env.mkurl("https", "test1", '/') - tscript = os.path.join(env.gen_dir, 'h2load-timing-009_02') - with open(tscript, 'w') as fd: - fd.write('\n'.join([ - f'0.0\t/002.jpg?02a', # 1st request right away - f'1000.0\t/002.jpg?02b', # 2nd a second later - ])) - args = [ - env.h2load, - f'--timing-script-file={tscript}', - f"--connect-to=localhost:{env.https_port}", - f"--base-uri={baseurl}" - ] - r = env.run(args) - # Restart for logs to be flushed out - assert env.apache_restart() == 0 - found = False - for line in open(TestTiming.LOGFILE).readlines(): - e = json.loads(line) - if e['request'] == f'GET /002.jpg?02a HTTP/2.0': - assert e['time_taken'] > 0 - assert e['time_taken'] < 500 * 1000, f'time for 1st request not reported correctly' - found = True - assert found, f'request not found in {TestTiming.LOGFILE}' diff --git a/test/modules/http2/test_401_early_hints.py b/test/modules/http2/test_401_early_hints.py index 0991d94e983..57043052c2c 100644 --- a/test/modules/http2/test_401_early_hints.py +++ b/test/modules/http2/test_401_early_hints.py @@ -9,8 +9,8 @@ class TestEarlyHints: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - if not env.httpd_is_at_least('2.5.0'): - pytest.skip(f'needs r1909769 from trunk') + if not env.httpd_is_at_least('2.4.58'): + pytest.skip(f'needs httpd 2.4.58') H2Conf(env).start_vhost(domains=[f"hints.{env.http_tld}"], port=env.https_port, doc_root="htdocs/test1" ).add(""" @@ -69,8 +69,8 @@ def test_h2_401_33(self, env, repeat): # H2EarlyHints enabled, no PUSH, check that it works for H2EarlyHint def test_h2_401_34(self, env, repeat): - if not env.httpd_is_at_least('2.5.0'): - pytest.skip(f'needs r1909769 from trunk') + if not env.httpd_is_at_least('2.4.58'): + pytest.skip(f'needs httpd 2.4.58') url = env.mkurl("https", "hints", "/006-early-no-push.html") r = env.nghttp().get(url) assert r.response["status"] == 200 diff --git a/test/modules/http2/test_500_proxy.py b/test/modules/http2/test_500_proxy.py index deb123d86b3..88a8ece3f6e 100644 --- a/test/modules/http2/test_500_proxy.py +++ b/test/modules/http2/test_500_proxy.py @@ -61,12 +61,6 @@ def test_h2_500_11(self, env): ]) self.curl_upload_and_verify(env, "data-1k", ["--http2", "-H", "Content-Length:"]) - def test_h2_500_11(self, env): - self.curl_upload_and_verify(env, "data-1k", [ - "--http1.1", "-H", "Content-Length:", "-H", "Transfer-Encoding: chunked" - ]) - self.curl_upload_and_verify(env, "data-1k", ["--http2", "-H", "Content-Length:"]) - # POST some data using nghttp and see it echo'ed properly back def nghttp_post_and_verify(self, env, fname, options=None): url = env.mkurl("https", "cgi", "/proxy/echo.py") diff --git a/test/modules/http2/test_600_h2proxy.py b/test/modules/http2/test_600_h2proxy.py index d6f14527301..4f071cc4376 100644 --- a/test/modules/http2/test_600_h2proxy.py +++ b/test/modules/http2/test_600_h2proxy.py @@ -153,7 +153,8 @@ def test_h2_600_30(self, env): # produce an error during response body def test_h2_600_31(self, env, repeat): - pytest.skip("needs fix in core protocol handling") + if env.httpd_is_at_least('2.5.0'): + pytest.skip("needs fix in core protocol handling") conf = H2Conf(env) conf.add_vhost_cgi(h2proxy_self=True) conf.install() @@ -163,11 +164,12 @@ def test_h2_600_31(self, env, repeat): # depending on when the error is detect in proxying, if may RST the # stream (exit_code != 0) or give a 503 response. if r.exit_code == 0: - assert r.response['status'] == 503 + assert r.response['status'] == 502 # produce an error, fail to generate an error bucket def test_h2_600_32(self, env, repeat): - pytest.skip("needs fix in core protocol handling") + if env.httpd_is_at_least('2.5.0'): + pytest.skip("needs fix in core protocol handling") conf = H2Conf(env) conf.add_vhost_cgi(h2proxy_self=True) conf.install() diff --git a/test/modules/http2/test_601_h2proxy_twisted.py b/test/modules/http2/test_601_h2proxy_twisted.py index 276558eeed5..45b46d649c5 100644 --- a/test/modules/http2/test_601_h2proxy_twisted.py +++ b/test/modules/http2/test_601_h2proxy_twisted.py @@ -45,8 +45,8 @@ def test_h2_601_02_echo_delayed(self, env, name): "data-1k", "data-10k", "data-100k", "data-1m", ]) def test_h2_601_03_echo_fail_early(self, env, name): - if not env.httpd_is_at_least('2.5.0'): - pytest.skip(f'needs r1910157 from trunk') + if not env.httpd_is_at_least('2.4.58'): + pytest.skip(f'needs httpd 2.4.58') fpath = os.path.join(env.gen_dir, name) url = env.mkurl("https", "cgi", "/h2proxy/h2test/echo?fail_after=512") r = env.curl_upload(url, fpath, options=[]) @@ -57,8 +57,8 @@ def test_h2_601_03_echo_fail_early(self, env, name): "data-1k", "data-10k", "data-100k", "data-1m", ]) def test_h2_601_04_echo_fail_late(self, env, name): - if not env.httpd_is_at_least('2.5.0'): - pytest.skip(f'needs r1910157 from trunk') + if not env.httpd_is_at_least('2.4.58'): + pytest.skip(f'needs httpd 2.4.58') fpath = os.path.join(env.gen_dir, name) url = env.mkurl("https", "cgi", f"/h2proxy/h2test/echo?fail_after={os.path.getsize(fpath)}") r = env.curl_upload(url, fpath, options=[]) @@ -66,8 +66,8 @@ def test_h2_601_04_echo_fail_late(self, env, name): assert r.exit_code == 92 or r.response["status"] == 502 def test_h2_601_05_echo_fail_many(self, env): - if not env.httpd_is_at_least('2.5.0'): - pytest.skip(f'needs r1910157 from trunk') + if not env.httpd_is_at_least('2.4.58'): + pytest.skip(f'needs httpd 2.4.58') if not env.curl_is_at_least('8.0.0'): pytest.skip(f'need at least curl v8.0.0 for this') count = 200