summaryrefslogtreecommitdiffstats
path: root/test/pyhttpd/env.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--test/pyhttpd/env.py143
1 files changed, 119 insertions, 24 deletions
diff --git a/test/pyhttpd/env.py b/test/pyhttpd/env.py
index af856ef..1d4e8b1 100644
--- a/test/pyhttpd/env.py
+++ b/test/pyhttpd/env.py
@@ -65,6 +65,8 @@ class HttpdTestSetup:
"proxy_http",
]
+ CURL_STDOUT_SEPARATOR = "===CURL_STDOUT_SEPARATOR==="
+
def __init__(self, env: 'HttpdTestEnv'):
self.env = env
self._source_dirs = [os.path.dirname(inspect.getfile(HttpdTestSetup))]
@@ -94,9 +96,8 @@ class HttpdTestSetup:
self.env.clear_curl_headerfiles()
def _make_dirs(self):
- if os.path.exists(self.env.gen_dir):
- shutil.rmtree(self.env.gen_dir)
- os.makedirs(self.env.gen_dir)
+ if not os.path.exists(self.env.gen_dir):
+ os.makedirs(self.env.gen_dir)
if not os.path.exists(self.env.server_logs_dir):
os.makedirs(self.env.server_logs_dir)
@@ -236,6 +237,8 @@ class HttpdTestEnv:
if HttpdTestEnv.LIBEXEC_DIR is None:
HttpdTestEnv.LIBEXEC_DIR = self._libexec_dir = self.get_apxs_var('LIBEXECDIR')
self._curl = self.config.get('global', 'curl_bin')
+ if 'CURL' in os.environ:
+ self._curl = os.environ['CURL']
self._nghttp = self.config.get('global', 'nghttp')
if self._nghttp is None:
self._nghttp = 'nghttp'
@@ -247,8 +250,10 @@ class HttpdTestEnv:
self._http_port2 = int(self.config.get('test', 'http_port2'))
self._https_port = int(self.config.get('test', 'https_port'))
self._proxy_port = int(self.config.get('test', 'proxy_port'))
+ self._ws_port = int(self.config.get('test', 'ws_port'))
self._http_tld = self.config.get('test', 'http_tld')
self._test_dir = self.config.get('test', 'test_dir')
+ self._clients_dir = os.path.join(os.path.dirname(self._test_dir), 'clients')
self._gen_dir = self.config.get('test', 'gen_dir')
self._server_dir = os.path.join(self._gen_dir, 'apache')
self._server_conf_dir = os.path.join(self._server_dir, "conf")
@@ -286,6 +291,7 @@ class HttpdTestEnv:
self._verify_certs = False
self._curl_headerfiles_n = 0
+ self._curl_version = None
self._h2load_version = None
self._current_test = None
@@ -319,6 +325,10 @@ class HttpdTestEnv:
self._log_interesting += f" {name}:{log_level}"
@property
+ def curl(self) -> str:
+ return self._curl
+
+ @property
def apxs(self) -> str:
return self._apxs
@@ -359,6 +369,10 @@ class HttpdTestEnv:
return self._proxy_port
@property
+ def ws_port(self) -> int:
+ return self._ws_port
+
+ @property
def http_tld(self) -> str:
return self._http_tld
@@ -383,6 +397,10 @@ class HttpdTestEnv:
return self._test_dir
@property
+ def clients_dir(self) -> str:
+ return self._clients_dir
+
+ @property
def server_dir(self) -> str:
return self._server_dir
@@ -471,6 +489,34 @@ class HttpdTestEnv:
return self._h2load_version >= self._versiontuple(minv)
return False
+ def curl_is_at_least(self, minv):
+ if self._curl_version is None:
+ p = subprocess.run([self._curl, '-V'], capture_output=True, text=True)
+ if p.returncode != 0:
+ return False
+ for l in p.stdout.splitlines():
+ m = re.match(r'curl ([0-9.]+)[- ].*', l)
+ if m:
+ self._curl_version = self._versiontuple(m.group(1))
+ break
+ if self._curl_version is not None:
+ return self._curl_version >= self._versiontuple(minv)
+ return False
+
+ def curl_is_less_than(self, version):
+ if self._curl_version is None:
+ p = subprocess.run([self._curl, '-V'], capture_output=True, text=True)
+ if p.returncode != 0:
+ return False
+ for l in p.stdout.splitlines():
+ m = re.match(r'curl ([0-9.]+)[- ].*', l)
+ if m:
+ self._curl_version = self._versiontuple(m.group(1))
+ break
+ if self._curl_version is not None:
+ return self._curl_version < self._versiontuple(version)
+ return False
+
def has_nghttp(self):
return self._nghttp != ""
@@ -497,14 +543,28 @@ class HttpdTestEnv:
if not os.path.exists(path):
return os.makedirs(path)
- def run(self, args, intext=None, debug_log=True):
+ def run(self, args, stdout_list=False, intext=None, inbytes=None, debug_log=True):
if debug_log:
log.debug(f"run: {args}")
start = datetime.now()
+ if intext is not None:
+ inbytes = intext.encode()
p = subprocess.run(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE,
- input=intext.encode() if intext else None)
+ input=inbytes)
+ stdout_as_list = None
+ if stdout_list:
+ try:
+ out = p.stdout.decode()
+ if HttpdTestSetup.CURL_STDOUT_SEPARATOR in out:
+ stdout_as_list = out.split(HttpdTestSetup.CURL_STDOUT_SEPARATOR)
+ if not stdout_as_list[len(stdout_as_list) - 1]:
+ stdout_as_list.pop()
+ p.stdout.replace(HttpdTestSetup.CURL_STDOUT_SEPARATOR.encode(), b'')
+ except:
+ pass
return ExecResult(args=args, exit_code=p.returncode,
stdout=p.stdout, stderr=p.stderr,
+ stdout_as_list=stdout_as_list,
duration=datetime.now() - start)
def mkurl(self, scheme, hostname, path='/'):
@@ -515,8 +575,13 @@ class HttpdTestEnv:
with open(self._test_conf, 'w') as fd:
fd.write('\n'.join(self._httpd_base_conf))
fd.write('\n')
+ fd.write(f"CoreDumpDirectory {self._server_dir}\n")
if self._verbosity >= 2:
- fd.write(f"LogLevel core:trace5 {self.mpm_module}:trace5\n")
+ fd.write(f"LogLevel core:trace5 {self.mpm_module}:trace5 http:trace5\n")
+ if self._verbosity >= 3:
+ fd.write(f"LogLevel dumpio:trace7\n")
+ fd.write(f"DumpIoOutput on\n")
+ fd.write(f"DumpIoInput on\n")
if self._log_interesting:
fd.write(self._log_interesting)
fd.write('\n\n')
@@ -637,17 +702,10 @@ class HttpdTestEnv:
os.remove(os.path.join(self.gen_dir, fname))
self._curl_headerfiles_n = 0
- def curl_complete_args(self, urls, timeout=None, options=None,
- insecure=False, force_resolve=True):
- if not isinstance(urls, list):
- urls = [urls]
- u = urlparse(urls[0])
- #assert u.hostname, f"hostname not in url: {urls[0]}"
- headerfile = f"{self.gen_dir}/curl.headers.{self._curl_headerfiles_n}"
- self._curl_headerfiles_n += 1
+ def curl_resolve_args(self, url, insecure=False, force_resolve=True, options=None):
+ u = urlparse(url)
args = [
- self._curl, "-s", "--path-as-is", "-D", headerfile,
]
if u.scheme == 'http':
pass
@@ -660,19 +718,33 @@ 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):
- assert u.port, f"port not in url: {urls[0]}"
+ assert u.port, f"port not in url: {url}"
args.extend(["--resolve", f"{u.hostname}:{u.port}:{self._httpd_addr}"])
+ return args
+
+ def curl_complete_args(self, urls, stdout_list=False,
+ timeout=None, options=None,
+ insecure=False, force_resolve=True):
+ headerfile = f"{self.gen_dir}/curl.headers.{self._curl_headerfiles_n}"
+ self._curl_headerfiles_n += 1
+
+ args = [
+ self._curl, "-s", "--path-as-is", "-D", headerfile,
+ ]
+ args.extend(self.curl_resolve_args(urls[0], insecure=insecure,
+ force_resolve=force_resolve,
+ options=options))
+ if stdout_list:
+ args.extend(['-w', '%{stdout}' + HttpdTestSetup.CURL_STDOUT_SEPARATOR])
+ if self._current_test is not None:
+ args.extend(["-H", f'AP-Test-Name: {self._current_test}'])
if timeout is not None and int(timeout) > 0:
args.extend(["--connect-timeout", str(int(timeout))])
if options:
args.extend(options)
- args += urls
return args, headerfile
def curl_parse_headerfile(self, headerfile: str, r: ExecResult = None) -> ExecResult:
@@ -730,16 +802,24 @@ class HttpdTestEnv:
return r
def curl_raw(self, urls, timeout=10, options=None, insecure=False,
- force_resolve=True):
+ force_resolve=True, no_stdout_list=False):
+ if not isinstance(urls, list):
+ urls = [urls]
+ stdout_list = False
+ if len(urls) > 1 and not no_stdout_list:
+ stdout_list = True
args, headerfile = self.curl_complete_args(
- urls=urls, timeout=timeout, options=options, insecure=insecure,
+ urls=urls, stdout_list=stdout_list,
+ timeout=timeout, options=options, insecure=insecure,
force_resolve=force_resolve)
- r = self.run(args)
+ args += urls
+ r = self.run(args, stdout_list=stdout_list)
if r.exit_code == 0:
self.curl_parse_headerfile(headerfile, r=r)
if r.json:
r.response["json"] = r.json
- os.remove(headerfile)
+ if os.path.isfile(headerfile):
+ os.remove(headerfile)
return r
def curl_get(self, url, insecure=False, options=None):
@@ -801,3 +881,18 @@ class HttpdTestEnv:
}
run.add_results({"h2load": stats})
return run
+
+ def make_data_file(self, indir: str, fname: str, fsize: int) -> str:
+ fpath = os.path.join(indir, fname)
+ s10 = "0123456789"
+ s = (101 * s10) + s10[0:3]
+ with open(fpath, 'w') as fd:
+ for i in range(int(fsize / 1024)):
+ fd.write(f"{i:09d}-{s}\n")
+ remain = int(fsize % 1024)
+ if remain != 0:
+ i = int(fsize / 1024) + 1
+ s = f"{i:09d}-{s}\n"
+ fd.write(s[0:remain])
+ return fpath
+