summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorStefan Eissing <icing@apache.org>2022-09-21 11:03:44 +0000
committerStefan Eissing <icing@apache.org>2022-09-21 11:03:44 +0000
commitcbb10f366c95401b717e26791d31f1d084dee195 (patch)
tree029cf85d2385294f8e87b6ee07c03e8f385382b5 /test
parent4ef081eddf3b243bb7f7fbdbf4750b451c052840 (diff)
downloadhttpd-cbb10f366c95401b717e26791d31f1d084dee195.tar.gz
*) 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')
-rw-r--r--test/conftest.py7
-rw-r--r--test/modules/http2/test_200_header_invalid.py8
-rw-r--r--test/modules/http2/test_700_load_get.py2
-rw-r--r--test/modules/http2/test_710_load_post_static.py3
-rw-r--r--test/modules/http2/test_711_load_post_cgi.py3
-rw-r--r--test/pyhttpd/env.py52
-rw-r--r--test/pyhttpd/mod_aptest/mod_aptest.c66
-rw-r--r--test/pyhttpd/nghttp.py10
8 files changed, 135 insertions, 16 deletions
diff --git a/test/conftest.py b/test/conftest.py
index 3472e969f2..2ae35f34ed 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -1,6 +1,8 @@
import sys
import os
+import pytest
+
sys.path.append(os.path.join(os.path.dirname(__file__), '.'))
from pyhttpd.env import HttpdTestEnv
@@ -21,4 +23,9 @@ def pytest_generate_tests(metafunc):
metafunc.fixturenames.append('tmp_ct')
metafunc.parametrize('repeat', range(count))
+@pytest.fixture(autouse=True, scope="function")
+def _function_scope(env, request):
+ env.set_current_test_name(request.node.name)
+ yield
+ env.set_current_test_name(None)
diff --git a/test/modules/http2/test_200_header_invalid.py b/test/modules/http2/test_200_header_invalid.py
index 5f8c976808..44ad69bc6b 100644
--- a/test/modules/http2/test_200_header_invalid.py
+++ b/test/modules/http2/test_200_header_invalid.py
@@ -88,7 +88,8 @@ class TestInvalidHeaders:
def test_h2_200_12(self, env):
url = env.mkurl("https", "cgi", "/")
opt = []
- for i in range(98): # curl sends 2 headers itself (user-agent and accept)
+ # curl sends 3 headers itself (user-agent, accept, and our AP-Test-Name)
+ for i in range(97):
opt += ["-H", "x: 1"]
r = env.curl_get(url, options=opt)
assert r.response["status"] == 200
@@ -100,8 +101,9 @@ class TestInvalidHeaders:
def test_h2_200_13(self, env):
url = env.mkurl("https", "cgi", "/")
opt = []
- for i in range(98): # curl sends 2 headers itself (user-agent and accept)
- opt += ["-H", "x{0}: 1".format(i)]
+ # curl sends 3 headers itself (user-agent, accept, and our AP-Test-Name)
+ for i in range(97):
+ opt += ["-H", f"x{i}: 1"]
r = env.curl_get(url, options=opt)
assert r.response["status"] == 200
r = env.curl_get(url, options=(opt + ["-H", "y: 2"]))
diff --git a/test/modules/http2/test_700_load_get.py b/test/modules/http2/test_700_load_get.py
index d1121a6065..9ee8898dfd 100644
--- a/test/modules/http2/test_700_load_get.py
+++ b/test/modules/http2/test_700_load_get.py
@@ -30,6 +30,7 @@ class TestLoadGet:
1000, 80000
])
def test_h2_700_10(self, env, start):
+ assert env.is_live()
text = "X"
chunk = 32
for n in range(0, 5):
@@ -47,6 +48,7 @@ class TestLoadGet:
1, 2, 16, 32
])
def test_h2_700_11(self, env, conns):
+ assert env.is_live()
text = "X"
start = 1200
chunk = 64
diff --git a/test/modules/http2/test_710_load_post_static.py b/test/modules/http2/test_710_load_post_static.py
index fd1b5abe80..ad8ae96aef 100644
--- a/test/modules/http2/test_710_load_post_static.py
+++ b/test/modules/http2/test_710_load_post_static.py
@@ -26,6 +26,7 @@ class TestLoadPostStatic:
# test POST on static file, slurped in by server
def test_h2_710_00(self, env, repeat):
+ assert env.is_live()
url = env.mkurl("https", "test1", "/index.html")
n = 10
m = 1
@@ -38,6 +39,7 @@ class TestLoadPostStatic:
self.check_h2load_ok(env, r, n)
def test_h2_710_01(self, env, repeat):
+ assert env.is_live()
url = env.mkurl("https", "test1", "/index.html")
n = 1000
m = 100
@@ -50,6 +52,7 @@ class TestLoadPostStatic:
self.check_h2load_ok(env, r, n)
def test_h2_710_02(self, env, repeat):
+ assert env.is_live()
url = env.mkurl("https", "test1", "/index.html")
n = 100
m = 50
diff --git a/test/modules/http2/test_711_load_post_cgi.py b/test/modules/http2/test_711_load_post_cgi.py
index 94c16002a7..82529d1764 100644
--- a/test/modules/http2/test_711_load_post_cgi.py
+++ b/test/modules/http2/test_711_load_post_cgi.py
@@ -26,6 +26,7 @@ class TestLoadCgi:
# test POST on cgi, where input is read
def test_h2_711_10(self, env, repeat):
+ assert env.is_live()
url = env.mkurl("https", "test1", "/echo.py")
n = 100
m = 5
@@ -41,6 +42,7 @@ class TestLoadCgi:
# test POST on cgi via http/1.1 proxy, where input is read
def test_h2_711_11(self, env, repeat):
+ assert env.is_live()
url = env.mkurl("https", "test1", "/proxy/echo.py")
n = 100
m = 5
@@ -56,6 +58,7 @@ class TestLoadCgi:
# test POST on cgi via h2proxy, where input is read
def test_h2_711_12(self, env, repeat):
+ assert env.is_live()
url = env.mkurl("https", "test1", "/h2proxy/echo.py")
n = 100
m = 5
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)