pytest: adapt for runs with openssl-1.1.1

Fix use of nghttpx fixture to be present even when h3 is not
available in curl. Fix TLS protocol versions expectations for
older openssl versions.

Closes #17538
This commit is contained in:
Stefan Eissing 2025-06-05 10:37:24 +02:00 committed by Daniel Stenberg
parent 5d9f425302
commit d9bebede59
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 70 additions and 22 deletions

View File

@ -36,6 +36,8 @@ sys.path.append(os.path.join(os.path.dirname(__file__), '.'))
from testenv import Env, Nghttpx, Httpd, NghttpxQuic, NghttpxFwd
log = logging.getLogger(__name__)
def pytest_report_header(config):
# Env inits its base properties only once, we can report them here
@ -109,7 +111,9 @@ def httpd(env) -> Generator[Httpd, None, None]:
@pytest.fixture(scope='session')
def nghttpx(env, httpd) -> Generator[Union[Nghttpx,bool], None, None]:
nghttpx = NghttpxQuic(env=env)
if nghttpx.exists() and env.have_h3():
if nghttpx.exists():
if not nghttpx.supports_h3() and env.have_h3_curl():
log.warning('nghttpx does not support QUIC, but curl does')
nghttpx.clear_logs()
assert nghttpx.initial_start()
yield nghttpx

View File

@ -635,8 +635,7 @@ class TestDownload:
if m:
earlydata[int(m.group(1))] = int(m.group(2))
continue
m = re.match(r'\[1-1] \* SSL reusing session.*', line)
if m:
if re.match(r'\[1-1] \* SSL reusing session.*', line):
reused_session = True
assert reused_session, 'session was not reused for 2nd transfer'
assert earlydata[0] == 0, f'{earlydata}'

View File

@ -318,6 +318,9 @@ class TestSSLUse:
supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3']
elif env.curl_uses_lib('aws-lc'):
supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3']
elif env.curl_uses_lib('openssl') and \
env.curl_lib_version_before('openssl', '3.0.0'):
supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3']
else: # most SSL backends dropped support for TLSv1.0, TLSv1.1
supported = [None, None, 'TLSv1.2', 'TLSv1.3']
# test

View File

@ -66,6 +66,33 @@ DEF_CONFIG = init_config_from(CONFIG_PATH)
CURL = os.path.join(TOP_PATH, 'src', 'curl')
class NghttpxUtil:
CMD = None
VERSION_FULL = None
@classmethod
def version(cls, cmd):
if cmd is None:
return None
if cls.VERSION_FULL is None or cmd != cls.CMD:
p = subprocess.run(args=[cmd, '--version'],
capture_output=True, text=True)
if p.returncode != 0:
raise RuntimeError(f'{cmd} --version failed with exit code: {p.returncode}')
cls.CMD = cmd
for line in p.stdout.splitlines(keepends=False):
if line.startswith('nghttpx '):
cls.VERSION_FULL = line
if cls.VERSION_FULL is None:
raise RuntimeError(f'{cmd}: unable to determine version')
return cls.VERSION_FULL
@staticmethod
def version_with_h3(version):
return re.match(r'.* ngtcp2/\d+\.\d+\.\d+.*', version) is not None
class EnvConfig:
def __init__(self, pytestconfig: Optional[pytest.Config] = None,
@ -169,15 +196,13 @@ class EnvConfig:
self._nghttpx_version = None
self.nghttpx_with_h3 = False
if self.nghttpx is not None:
p = subprocess.run(args=[self.nghttpx, '-v'],
capture_output=True, text=True)
if p.returncode != 0:
try:
self._nghttpx_version = NghttpxUtil.version(self.nghttpx)
self.nghttpx_with_h3 = NghttpxUtil.version_with_h3(self._nghttpx_version)
except RuntimeError:
# not a working nghttpx
log.exception('checking nghttpx version')
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
@ -386,6 +411,16 @@ class Env:
Env.CONFIG.versiontuple(lversion)
return False
@staticmethod
def curl_lib_version_before(libname: str, lib_version) -> bool:
lversion = Env.curl_lib_version(libname)
if lversion != 'unknown':
if m := re.match(r'(\d+\.\d+\.\d+).*', lversion):
lversion = m.group(1)
return Env.CONFIG.versiontuple(lib_version) > \
Env.CONFIG.versiontuple(lversion)
return False
@staticmethod
def curl_os() -> str:
return Env.CONFIG.curl_props['os']

View File

@ -33,7 +33,7 @@ import time
from typing import Optional, Dict
from datetime import datetime, timedelta
from .env import Env
from .env import Env, NghttpxUtil
from .curl import CurlClient
from .ports import alloc_ports_and_do
@ -58,10 +58,10 @@ class Nghttpx:
self._process: Optional[subprocess.Popen] = None
self._cred_name = self._def_cred_name = cred_name
self._loaded_cred_name = ''
self._rmf(self._pid_file)
self._rmf(self._error_log)
self._mkpath(self._run_dir)
self._write_config()
self._version = NghttpxUtil.version(self._cmd)
def supports_h3(self):
return NghttpxUtil.version_with_h3(self._version)
def set_cred_name(self, name: str):
self._cred_name = name
@ -98,7 +98,10 @@ class Nghttpx:
return True
def initial_start(self):
pass
self._rmf(self._pid_file)
self._rmf(self._error_log)
self._mkpath(self._run_dir)
self._write_config()
def start(self, wait_live=True):
pass
@ -215,6 +218,7 @@ class NghttpxQuic(Nghttpx):
self._https_port = env.https_port
def initial_start(self):
super().initial_start()
def startup(ports: Dict[str, int]) -> bool:
self._port = ports['nghttpx_https']
@ -235,11 +239,13 @@ class NghttpxQuic(Nghttpx):
creds = self.env.get_credentials(self._cred_name)
assert creds # convince pytype this isn't None
self._loaded_cred_name = self._cred_name
args = [
self._cmd,
f'--frontend=*,{self._port};tls',
f'--frontend=*,{self.env.h3_port};quic',
'--frontend-quic-early-data',
args = [self._cmd, f'--frontend=*,{self._port};tls']
if self.supports_h3():
args.extend([
f'--frontend=*,{self.env.h3_port};quic',
'--frontend-quic-early-data',
])
args.extend([
f'--backend=127.0.0.1,{self.env.https_port};{self._domain};sni={self._domain};proto=h2;tls',
f'--backend=127.0.0.1,{self.env.http_port}',
'--log-level=ERROR',
@ -254,7 +260,7 @@ class NghttpxQuic(Nghttpx):
'--frontend-http3-connection-window-size=10M',
'--frontend-http3-max-connection-window-size=100M',
# f'--frontend-quic-debug-log',
]
])
ngerr = open(self._stderr, 'a')
self._process = subprocess.Popen(args=args, stderr=ngerr)
if self._process.returncode is not None:
@ -270,6 +276,7 @@ class NghttpxFwd(Nghttpx):
cred_name=env.proxy_domain)
def initial_start(self):
super().initial_start()
def startup(ports: Dict[str, int]) -> bool:
self._port = ports['h2proxys']