#
###########################################################################
#
-import logging
-import os
-import sys
-from typing import Optional
+import sys, os
-import pytest
+sys.path.append(os.path.join(os.path.dirname(__file__), 'http'))
+import pytest
+from testenv import Env
def pytest_report_header(config, startdir):
- return f"curl tests"
+ # Env inits its base properties only once, we can report them here
+ env = Env()
+ report = [
+ f'Testing curl {env.curl_version()}',
+ f' httpd: {env.httpd_version()}, http:{env.http_port} https:{env.https_port}',
+ f' httpd-proxy: {env.httpd_version()}, http:{env.proxy_port} https:{env.proxys_port}'
+ ]
+ if env.have_h3_server():
+ report.extend([
+ f' nghttpx: {env.nghttpx_version()}, h3:{env.https_port}'
+ ])
+ if env.has_caddy():
+ report.extend([
+ f' Caddy: {env.caddy_version()}, http:{env.caddy_http_port} https:{env.caddy_https_port}'
+ ])
+ return '\n'.join(report)
def pytest_addoption(parser):
import logging
import os
import re
+import socket
import subprocess
+import sys
from configparser import ConfigParser, ExtendedInterpolation
from typing import Optional
from .certs import CertificateSpec, TestCA, Credentials
+from .ports import alloc_ports
+
log = logging.getLogger(__name__)
self.nghttpx_with_h3 = re.match(r'.* nghttp3/.*', p.stdout.strip())
log.debug(f'nghttpx -v: {p.stdout}')
- self.http_port = self.config['test']['http_port']
- self.https_port = self.config['test']['https_port']
- self.proxy_port = self.config['test']['proxy_port']
- self.proxys_port = self.config['test']['proxys_port']
- self.h3_port = self.config['test']['h3_port']
+ self.ports = alloc_ports(port_specs={
+ 'http': socket.SOCK_STREAM,
+ 'https': socket.SOCK_STREAM,
+ 'proxy': socket.SOCK_STREAM,
+ 'proxys': socket.SOCK_STREAM,
+ 'caddy': socket.SOCK_STREAM,
+ 'caddys': socket.SOCK_STREAM,
+ })
self.httpd = self.config['httpd']['httpd']
self.apachectl = self.config['httpd']['apachectl']
self.apxs = self.config['httpd']['apxs']
]
self.nghttpx = self.config['nghttpx']['nghttpx']
+ self._nghttpx_version = None
self.nghttpx_with_h3 = False
if len(self.nghttpx) == 0:
self.nghttpx = 'nghttpx'
# not a working nghttpx
self.nghttpx = None
else:
+ self._nghttpx_version = re.sub(r'^nghttpx\s*', '', p.stdout.strip())
self.nghttpx_with_h3 = re.match(r'.* nghttp3/.*', p.stdout.strip()) is not None
log.debug(f'nghttpx -v: {p.stdout}')
self.caddy = self.config['caddy']['caddy']
+ self._caddy_version = None
if len(self.caddy.strip()) == 0:
self.caddy = None
if self.caddy is not None:
if p.returncode != 0:
# not a working caddy
self.caddy = None
+ self._caddy_version = re.sub(r' .*', '', p.stdout.strip())
except:
self.caddy = None
- self.caddy_http_port = self.config['caddy']['http_port']
- self.caddy_https_port = self.config['caddy']['https_port']
@property
def httpd_version(self):
return f"apxs ({self.apxs}) not found"
return None
+ @property
+ def nghttpx_version(self):
+ return self._nghttpx_version
+
+ @property
+ def caddy_version(self):
+ return self._caddy_version
+
class Env:
def httpd_version() -> str:
return Env.CONFIG.httpd_version
+ @staticmethod
+ def nghttpx_version() -> str:
+ return Env.CONFIG.nghttpx_version
+
+ @staticmethod
+ def caddy_version() -> str:
+ return Env.CONFIG.caddy_version
+
@staticmethod
def httpd_is_at_least(minv) -> bool:
return Env.CONFIG.httpd_is_at_least(minv)
return self.CONFIG.proxy_domain
@property
- def http_port(self) -> str:
- return self.CONFIG.http_port
+ def http_port(self) -> int:
+ return self.CONFIG.ports['http']
@property
- def https_port(self) -> str:
- return self.CONFIG.https_port
+ def https_port(self) -> int:
+ return self.CONFIG.ports['https']
@property
- def h3_port(self) -> str:
- return self.CONFIG.h3_port
+ def h3_port(self) -> int:
+ return self.https_port
@property
def proxy_port(self) -> str:
- return self.CONFIG.proxy_port
+ return self.CONFIG.ports['proxy']
@property
def proxys_port(self) -> str:
- return self.CONFIG.proxys_port
+ return self.CONFIG.ports['proxys']
@property
def caddy(self) -> str:
return self.CONFIG.caddy
@property
- def caddy_https_port(self) -> str:
- return self.CONFIG.caddy_https_port
+ def caddy_https_port(self) -> int:
+ return self.CONFIG.ports['caddys']
@property
- def caddy_http_port(self) -> str:
- return self.CONFIG.caddy_http_port
+ def caddy_http_port(self) -> int:
+ return self.CONFIG.ports['caddy']
@property
def curl(self) -> str:
--- /dev/null
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2008 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+#
+import logging
+import socket
+from typing import Dict
+
+log = logging.getLogger(__name__)
+
+
+def alloc_ports(port_specs: Dict[str, int]) -> Dict[str, int]:
+ ports = {}
+ socks = []
+ for name, ptype in port_specs.items():
+ try:
+ s = socket.socket(type=ptype)
+ s.bind(('', 0))
+ ports[name] = s.getsockname()[1]
+ socks.append(s)
+ except Exception as e:
+ raise e
+ for s in socks:
+ s.close()
+ return ports
+
+