diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/modules/http2/test_009_timing.py | 1 | ||||
-rw-r--r-- | test/modules/http2/test_800_websockets.py | 8 | ||||
-rwxr-xr-x | test/modules/md/dns01_v2.py | 62 | ||||
-rwxr-xr-x | test/modules/md/md_cert_util.py | 4 | ||||
-rwxr-xr-x | test/modules/md/md_env.py | 15 | ||||
-rw-r--r-- | test/modules/tls/test_08_vars.py | 2 | ||||
-rw-r--r-- | test/modules/tls/test_14_proxy_ssl.py | 2 | ||||
-rw-r--r-- | test/pyhttpd/curl.py | 2 | ||||
-rw-r--r-- | test/pyhttpd/nghttp.py | 2 | ||||
-rw-r--r-- | test/travis_Dockerfile_slapd.centos | 5 | ||||
-rw-r--r-- | test/travis_Dockerfile_slapd.centos7 | 5 | ||||
-rwxr-xr-x | test/travis_before_linux.sh | 37 |
12 files changed, 92 insertions, 53 deletions
diff --git a/test/modules/http2/test_009_timing.py b/test/modules/http2/test_009_timing.py index 2c62bb0..2784f9a 100644 --- a/test/modules/http2/test_009_timing.py +++ b/test/modules/http2/test_009_timing.py @@ -7,6 +7,7 @@ from .env import H2Conf, H2TestEnv @pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here") +@pytest.mark.skipif(not H2TestEnv().h2load_is_at_least('1.41.0'), reason="h2load misses --connect-to option") class TestTiming: LOGFILE = "" diff --git a/test/modules/http2/test_800_websockets.py b/test/modules/http2/test_800_websockets.py index 5b46da8..52af1a3 100644 --- a/test/modules/http2/test_800_websockets.py +++ b/test/modules/http2/test_800_websockets.py @@ -168,14 +168,14 @@ class TestWebSockets: def test_h2_800_03_not_found(self, env: H2TestEnv, ws_server): r, infos, frames = ws_run(env, path='/does-not-exist') assert r.exit_code == 0, f'{r}' - assert infos == ['[1] :status: 404', '[1] EOF'], f'{r}' + assert infos == ['[1] :status: 404', '[1] EOF'] or infos == ['[1] :status: 404', '[1] EOF', '[1] RST'], f'{r}' # CONNECT to a URL path that is a normal HTTP file resource # we do not want to receive the body of that def test_h2_800_04_non_ws_resource(self, env: H2TestEnv, ws_server): r, infos, frames = ws_run(env, path='/alive.json') assert r.exit_code == 0, f'{r}' - assert infos == ['[1] :status: 502', '[1] EOF'], f'{r}' + assert infos == ['[1] :status: 502', '[1] EOF'] or infos == ['[1] :status: 502', '[1] EOF', '[1] RST'], f'{r}' assert frames == b'' # CONNECT to a URL path that sends a delayed HTTP response body @@ -183,7 +183,7 @@ class TestWebSockets: def test_h2_800_05_non_ws_delay_resource(self, env: H2TestEnv, ws_server): r, infos, frames = ws_run(env, path='/h2test/error?body_delay=100ms') assert r.exit_code == 0, f'{r}' - assert infos == ['[1] :status: 502', '[1] EOF'], f'{r}' + assert infos == ['[1] :status: 502', '[1] EOF'] or infos == ['[1] :status: 502', '[1] EOF', '[1] RST'], f'{r}' assert frames == b'' # CONNECT missing the sec-webSocket-version header @@ -215,7 +215,7 @@ class TestWebSockets: r, infos, frames = ws_run(env, path='/ws/echo/', authority=f'test1.{env.http_tld}:{env.http_port}') assert r.exit_code == 0, f'{r}' - assert infos == ['[1] :status: 501', '[1] EOF'], f'{r}' + assert infos == ['[1] :status: 501', '[1] EOF'] or infos == ['[1] :status: 501', '[1] EOF', '[1] RST'], f'{r}' # CONNECT and exchange a PING def test_h2_800_10_ws_ping(self, env: H2TestEnv, ws_server): diff --git a/test/modules/md/dns01_v2.py b/test/modules/md/dns01_v2.py new file mode 100755 index 0000000..908b4f8 --- /dev/null +++ b/test/modules/md/dns01_v2.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +import subprocess +import sys + +curl = "curl" +challtestsrv = "localhost:8055" + + +def run(args): + sys.stderr.write(f"run: {' '.join(args)}\n") + p = subprocess.Popen(args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + output, errput = p.communicate(None) + rv = p.wait() + if rv != 0: + sys.stderr.write(errput.decode()) + sys.stdout.write(output.decode()) + return rv + + +def teardown(domain): + rv = run([curl, '-s', '-d', f'{{"host":"_acme-challenge.{domain}"}}', + f'{challtestsrv}/clear-txt']) + if rv == 0: + rv = run([curl, '-s', '-d', f'{{"host":"{domain}"}}', + f'{challtestsrv}/set-txt']) + return rv + + +def setup(domain, challenge): + teardown(domain) + rv = run([curl, '-s', '-d', f'{{"host":"{domain}", "addresses":["127.0.0.1"]}}', + f'{challtestsrv}/set-txt']) + if rv == 0: + rv = run([curl, '-s', '-d', f'{{"host":"_acme-challenge.{domain}.", "value":"{challenge}"}}', + f'{challtestsrv}/set-txt']) + return rv + + +def main(argv): + if len(argv) > 1: + if argv[1] == 'setup': + if len(argv) != 4: + sys.stderr.write("wrong number of arguments: dns01.py setup <domain> <challenge>\n") + sys.exit(2) + rv = setup(argv[2], argv[3]) + elif argv[1] == 'teardown': + if len(argv) != 4: + sys.stderr.write("wrong number of arguments: dns01.py teardown <domain> <challenge>\n") + sys.exit(1) + rv = teardown(argv[2]) + else: + sys.stderr.write(f"unknown option {argv[1]}\n") + rv = 2 + else: + sys.stderr.write("dns01.py wrong number of arguments\n") + rv = 2 + sys.exit(rv) + + +if __name__ == "__main__": + main(sys.argv) diff --git a/test/modules/md/md_cert_util.py b/test/modules/md/md_cert_util.py index 8cd99aa..abcd36b 100755 --- a/test/modules/md/md_cert_util.py +++ b/test/modules/md/md_cert_util.py @@ -166,10 +166,10 @@ class MDCertUtil(object): def get_san_list(self): text = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_TEXT, self.cert).decode("utf-8") - m = re.search(r"X509v3 Subject Alternative Name:\s*(.*)", text) + m = re.search(r"X509v3 Subject Alternative Name:(\s+critical)?\s*(.*)", text) sans_list = [] if m: - sans_list = m.group(1).split(",") + sans_list = m.group(2).split(",") def _strip_prefix(s): return s.split(":")[1] if s.strip().startswith("DNS:") else s.strip() diff --git a/test/modules/md/md_env.py b/test/modules/md/md_env.py index e8e36e5..1936519 100755 --- a/test/modules/md/md_env.py +++ b/test/modules/md/md_env.py @@ -73,7 +73,11 @@ class MDTestEnv(HttpdTestEnv): @classmethod def has_acme_eab(cls): - return cls.get_acme_server() == 'pebble' + return False + # Pebble, since v2.5.0 no longer supports HS256 for EAB, which + # is the only thing mod_md supports. Issue opened at pebble: + # https://github.com/letsencrypt/pebble/issues/455 + # return cls.get_acme_server() == 'pebble' @classmethod def is_pebble(cls) -> bool: @@ -356,13 +360,14 @@ class MDTestEnv(HttpdTestEnv): MDCertUtil.validate_privkey(self.store_domain_file(domain, 'privkey.pem')) cert = MDCertUtil(self.store_domain_file(domain, 'pubcert.pem')) cert.validate_cert_matches_priv_key(self.store_domain_file(domain, 'privkey.pem')) - # check SANs and CN - assert cert.get_cn() == domain + # No longer check CN, it may not be set or is not trusted anyway + # assert cert.get_cn() == domain, f'CN: expected "{domain}", got {cert.get_cn()}' + # check SANs # compare lists twice in opposite directions: SAN may not respect ordering san_list = list(cert.get_san_list()) assert len(san_list) == len(domains) - assert set(san_list).issubset(domains) - assert set(domains).issubset(san_list) + assert set(san_list).issubset(domains), f'{san_list} not subset of {domains}' + assert set(domains).issubset(san_list), f'{domains} not subset of {san_list}' # check valid dates interval not_before = cert.get_not_before() not_after = cert.get_not_after() diff --git a/test/modules/tls/test_08_vars.py b/test/modules/tls/test_08_vars.py index f1bd9b4..a8df99a 100644 --- a/test/modules/tls/test_08_vars.py +++ b/test/modules/tls/test_08_vars.py @@ -51,7 +51,7 @@ class TestVars: @pytest.mark.parametrize("name, pattern", [ ("SSL_VERSION_INTERFACE", r'mod_tls/\d+\.\d+\.\d+'), - ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+\.\d+'), + ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+(\.\d+)?'), ]) def test_tls_08_vars_match(self, env, name: str, pattern: str): r = env.tls_get(env.domain_b, f"/vars.py?name={name}") diff --git a/test/modules/tls/test_14_proxy_ssl.py b/test/modules/tls/test_14_proxy_ssl.py index 79b2fb4..cefcbf6 100644 --- a/test/modules/tls/test_14_proxy_ssl.py +++ b/test/modules/tls/test_14_proxy_ssl.py @@ -69,7 +69,7 @@ class TestProxySSL: @pytest.mark.parametrize("name, pattern", [ ("SSL_VERSION_INTERFACE", r'mod_tls/\d+\.\d+\.\d+'), - ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+\.\d+'), + ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+(\.\d+)?'), ]) def test_tls_14_proxy_ssl_vars_match(self, env, name: str, pattern: str): r = env.tls_get(env.domain_b, f"/proxy-ssl/vars.py?name={name}") diff --git a/test/pyhttpd/curl.py b/test/pyhttpd/curl.py index 5a215cd..3d7993f 100644 --- a/test/pyhttpd/curl.py +++ b/test/pyhttpd/curl.py @@ -112,7 +112,7 @@ class CurlPiper: recv_times = [] for line in "".join(recv_err).split('\n'): m = re.match(r'^\s*(\d+:\d+:\d+(\.\d+)?) <= Recv data, (\d+) bytes.*', line) - if m: + if m and int(m.group(3)) > 0: recv_times.append(datetime.time.fromisoformat(m.group(1))) # received as many chunks as we sent assert len(chunks) == len(recv_times), "received response not in {0} chunks, but {1}".format( diff --git a/test/pyhttpd/nghttp.py b/test/pyhttpd/nghttp.py index 43721f5..e857e95 100644 --- a/test/pyhttpd/nghttp.py +++ b/test/pyhttpd/nghttp.py @@ -224,7 +224,7 @@ class Nghttp: if 0 == r.exit_code: lines = re.findall(r'[^\n]*\n', r.stdout, re.MULTILINE) for lidx, l in enumerate(lines): - m = re.match(r'\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+/(.*)', l) + m = re.match(r'\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+/*(/.*)', l) if m: assets.append({ "path": m.group(7), diff --git a/test/travis_Dockerfile_slapd.centos b/test/travis_Dockerfile_slapd.centos new file mode 100644 index 0000000..713e5de --- /dev/null +++ b/test/travis_Dockerfile_slapd.centos @@ -0,0 +1,5 @@ +FROM quay.io/centos/centos:stream9 +RUN dnf install -y epel-release && \ + dnf install -y openldap openldap-clients openldap-servers openldap-devel && \ + dnf -y clean all --enablerepo='*' +CMD /usr/sbin/slapd -u ldap -d1 '-h ldap:// ldapi:///' diff --git a/test/travis_Dockerfile_slapd.centos7 b/test/travis_Dockerfile_slapd.centos7 deleted file mode 100644 index 85bcf0a..0000000 --- a/test/travis_Dockerfile_slapd.centos7 +++ /dev/null @@ -1,5 +0,0 @@ -FROM quay.io/centos/centos:7 -RUN yum install -y yum-utils && \ - yum install -y openldap openldap-clients openldap-servers openldap-devel && \ - yum -y clean all --enablerepo='*' -CMD /usr/sbin/slapd -u ldap -d1 '-h ldap:// ldapi:///' diff --git a/test/travis_before_linux.sh b/test/travis_before_linux.sh index 2722c6a..59aea2f 100755 --- a/test/travis_before_linux.sh +++ b/test/travis_before_linux.sh @@ -21,42 +21,13 @@ if grep ip6-localhost /etc/hosts; then cat /etc/hosts fi -# Use a rudimental retry workflow as workaround to svn export hanging for minutes. -# Travis automatically kills a build if one step takes more than 10 minutes without -# reporting any progress. -function run_svn_export() { - local url=$1 - local revision=$2 - local dest_dir=$3 - local max_tries=$4 - - # Disable -e to allow fail/retry - set +e - - for i in $(seq 1 $max_tries) - do - timeout 60 svn export -r ${revision} --force -q $url $dest_dir - if [ $? -eq 0 ]; then - break - else - if [ $i -eq $max_tries ]; then - exit 1 - else - sleep $((100 * i)) - fi - fi - done - - # Restore -e behavior after fail/retry - set -e -} - function install_apx() { local name=$1 local version=$2 local root=https://svn.apache.org/repos/asf/apr/${name} local prefix=${HOME}/root/${name}-${version} local build=${HOME}/build/${name}-${version} + local giturl=https://github.com/apache/${name}.git local config=$3 local buildconf=$4 @@ -76,7 +47,7 @@ function install_apx() { return 0 fi - svn export -q -r ${revision} ${url} ${build} + git clone -q --depth=1 --branch=$version ${giturl} ${build} pushd $build ./buildconf ${buildconf} ./configure --prefix=${prefix} ${config} @@ -113,13 +84,13 @@ if ! test -v SKIP_TESTING -o -v NO_TEST_FRAMEWORK; then unset pkgs # Make a shallow clone of httpd-tests git repo. - git clone --depth=1 https://github.com/apache/httpd-tests.git test/perl-framework + git clone -q --depth=1 https://github.com/apache/httpd-tests.git test/perl-framework fi # For LDAP testing, run slapd listening on port 8389 and populate the # directory as described in t/modules/ldap.t in the test framework: if test -v TEST_LDAP -a -x test/perl-framework/scripts/ldap-init.sh; then - docker build -t httpd_ldap -f test/travis_Dockerfile_slapd.centos7 test/ + docker build -t httpd_ldap -f test/travis_Dockerfile_slapd.centos test/ pushd test/perl-framework ./scripts/ldap-init.sh popd |