diff options
author | Stefan Eissing <icing@apache.org> | 2022-09-21 13:03:44 +0200 |
---|---|---|
committer | Stefan Eissing <icing@apache.org> | 2022-09-21 13:03:44 +0200 |
commit | cbb10f366c95401b717e26791d31f1d084dee195 (patch) | |
tree | 029cf85d2385294f8e87b6ee07c03e8f385382b5 /test/pyhttpd | |
parent | *) mod_proxy_http2: use only the ':authority' header to forward 'Host' (diff) | |
download | apache2-cbb10f366c95401b717e26791d31f1d084dee195.tar.xz apache2-cbb10f366c95401b717e26791d31f1d084dee195.zip |
*) tests: load the top-level mod_aptest in all test suites.
- aptest logs the test name from the header 'AP-Test-Name' with
the request line. LogLevel aptest:info is switched on.
- pytest sets 'AP-Test-Name' for all curl/nghttp invocation
against the server.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1904188 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test/pyhttpd')
-rw-r--r-- | test/pyhttpd/env.py | 52 | ||||
-rw-r--r-- | test/pyhttpd/mod_aptest/mod_aptest.c | 66 | ||||
-rw-r--r-- | test/pyhttpd/nghttp.py | 10 |
3 files changed, 115 insertions, 13 deletions
diff --git a/test/pyhttpd/env.py b/test/pyhttpd/env.py index 45f6d2f066..991ead9e11 100644 --- a/test/pyhttpd/env.py +++ b/test/pyhttpd/env.py @@ -90,6 +90,7 @@ class HttpdTestSetup: self.add_modules([self.env.ssl_module]) self._make_modules_conf() self._make_htdocs() + self._add_aptest() self.env.clear_curl_headerfiles() def _make_dirs(self): @@ -179,6 +180,21 @@ class HttpdTestSetup: st = os.stat(py_file) os.chmod(py_file, st.st_mode | stat.S_IEXEC) + def _add_aptest(self): + local_dir = os.path.dirname(inspect.getfile(HttpdTestSetup)) + p = subprocess.run([self.env.apxs, '-c', 'mod_aptest.c'], + capture_output=True, + cwd=os.path.join(local_dir, 'mod_aptest')) + rv = p.returncode + if rv != 0: + log.error(f"compiling mod_aptest failed: {p.stderr}") + raise Exception(f"compiling mod_aptest failed: {p.stderr}") + + modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf') + with open(modules_conf, 'a') as fd: + # load our test module which is not installed + fd.write(f"LoadModule aptest_module \"{local_dir}/mod_aptest/.libs/mod_aptest.so\"\n") + class HttpdTestEnv: @@ -255,7 +271,7 @@ class HttpdTestEnv: self._verbosity = pytestconfig.option.verbose if pytestconfig is not None else 0 self._test_conf = os.path.join(self._server_conf_dir, "test.conf") self._httpd_base_conf = [] - self._httpd_log_modules = [] + self._httpd_log_modules = ['aptest'] self._log_interesting = None self._setup = None @@ -269,6 +285,8 @@ class HttpdTestEnv: self._verify_certs = False self._curl_headerfiles_n = 0 + self._h2load_version = None + self._current_test = None def add_httpd_conf(self, lines: List[str]): self._httpd_base_conf.extend(lines) @@ -403,6 +421,13 @@ class HttpdTestEnv: return self._ca @property + def current_test_name(self) -> str: + return self._current_test + + def set_current_test_name(self, val) -> None: + self._current_test = val + + @property def apachectl_stderr(self): return self._apachectl_stderr @@ -416,6 +441,7 @@ class HttpdTestEnv: return [] def _versiontuple(self, v): + v = re.sub(r'(\d+\.\d+(\.\d+)?)(-\S+)?', r'\1', v) return tuple(map(int, v.split('.'))) def httpd_is_at_least(self, minv): @@ -428,14 +454,16 @@ class HttpdTestEnv: def h2load_is_at_least(self, minv): if not self.has_h2load(): return False - p = subprocess.run([self._h2load, '--version'], capture_output=True, text=True) - if p.returncode != 0: - return False - s = p.stdout.strip() - m = re.match(r'h2load nghttp2/(\S+)', s) - if m: - hv = self._versiontuple(m.group(1)) - return hv >= self._versiontuple(minv) + if self._h2load_version is None: + p = subprocess.run([self._h2load, '--version'], capture_output=True, text=True) + if p.returncode != 0: + return False + s = p.stdout.strip() + m = re.match(r'h2load nghttp2/(\S+)', s) + if m: + self._h2load_version = self._versiontuple(m.group(1)) + if self._h2load_version is not None: + return self._h2load_version >= self._versiontuple(minv) return False def has_nghttp(self): @@ -627,6 +655,9 @@ class HttpdTestEnv: if ca_pem: args.extend(["--cacert", ca_pem]) + if self._current_test is not None: + args.extend(["-H", f'AP-Test-Name: {self._current_test}']) + if force_resolve and u.hostname and u.hostname != 'localhost' \ and u.hostname != self._httpd_addr \ and not re.match(r'^(\d+|\[|:).*', u.hostname): @@ -739,7 +770,8 @@ class HttpdTestEnv: return -1 def nghttp(self): - return Nghttp(self._nghttp, connect_addr=self._httpd_addr, tmp_dir=self.gen_dir) + return Nghttp(self._nghttp, connect_addr=self._httpd_addr, + tmp_dir=self.gen_dir, test_name=self._current_test) def h2load_status(self, run: ExecResult): stats = {} diff --git a/test/pyhttpd/mod_aptest/mod_aptest.c b/test/pyhttpd/mod_aptest/mod_aptest.c new file mode 100644 index 0000000000..d1a8e0533d --- /dev/null +++ b/test/pyhttpd/mod_aptest/mod_aptest.c @@ -0,0 +1,66 @@ +/* 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. + */ + +#include <apr_optional.h> +#include <apr_optional_hooks.h> +#include <apr_strings.h> +#include <apr_cstr.h> +#include <apr_want.h> + +#include <httpd.h> +#include <http_protocol.h> +#include <http_request.h> +#include <http_log.h> + +static void aptest_hooks(apr_pool_t *pool); + +AP_DECLARE_MODULE(aptest) = { + STANDARD20_MODULE_STUFF, + NULL, /* func to create per dir config */ + NULL, /* func to merge per dir config */ + NULL, /* func to create per server config */ + NULL, /* func to merge per server config */ + NULL, /* command handlers */ + aptest_hooks, +#if defined(AP_MODULE_FLAG_NONE) + AP_MODULE_FLAG_ALWAYS_MERGE +#endif +}; + + +static int aptest_post_read_request(request_rec *r) +{ + const char *test_name = apr_table_get(r->headers_in, "AP-Test-Name"); + if (test_name) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "test[%s]: %s", + test_name, r->the_request); + } + return DECLINED; +} + +/* Install this module into the apache2 infrastructure. + */ +static void aptest_hooks(apr_pool_t *pool) +{ + ap_log_perror(APLOG_MARK, APLOG_TRACE1, 0, pool, + "installing hooks and handlers"); + + /* test case monitoring */ + ap_hook_post_read_request(aptest_post_read_request, NULL, + NULL, APR_HOOK_MIDDLE); + +} + diff --git a/test/pyhttpd/nghttp.py b/test/pyhttpd/nghttp.py index 84b8f20c6f..6dea97b55c 100644 --- a/test/pyhttpd/nghttp.py +++ b/test/pyhttpd/nghttp.py @@ -15,10 +15,12 @@ def _get_path(x): class Nghttp: - def __init__(self, path, connect_addr=None, tmp_dir="/tmp"): + def __init__(self, path, connect_addr=None, tmp_dir="/tmp", + test_name: str = None): self.NGHTTP = path self.CONNECT_ADDR = connect_addr self.TMP_DIR = tmp_dir + self._test_name = test_name @staticmethod def get_stream(streams, sid): @@ -104,7 +106,7 @@ class Nghttp: body += m.group(1) s = self.get_stream(streams, m.group(2)) if s: - print("stream %d: recv %d header" % (s["id"], len(s["header"]))) + print("stream %d: recv %d header" % (s["id"], len(s["header"]))) response = s["response"] hkey = "header" if "header" in response: @@ -194,9 +196,11 @@ class Nghttp: output["response"] = streams[main_stream]["response"] output["paddings"] = streams[main_stream]["paddings"] return output - + def _raw(self, url, timeout, options): args = ["-v"] + if self._test_name is not None: + args.append(f'--header=AP-Test-Name: {self._test_name}') if options: args.extend(options) r = self._baserun(url, timeout, args) |