mirror of
https://github.com/curl/curl.git
synced 2026-08-05 16:26:15 +03:00
tests: use dynamic ports numbers in pytest suite
- necessary ports are bound at start of test suite and then given to server fixtures for use. - this make parallel use of pytest (in separate directories), practically safe for use as OS tend to not reuse such port numbers for a while Closes #10692
This commit is contained in:
parent
257416023d
commit
b0564c1d54
6 changed files with 118 additions and 39 deletions
|
|
@ -27,11 +27,15 @@
|
|||
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__)
|
||||
|
||||
|
|
@ -95,11 +99,14 @@ class EnvConfig:
|
|||
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']
|
||||
|
|
@ -126,6 +133,7 @@ class EnvConfig:
|
|||
]
|
||||
|
||||
self.nghttpx = self.config['nghttpx']['nghttpx']
|
||||
self._nghttpx_version = None
|
||||
self.nghttpx_with_h3 = False
|
||||
if len(self.nghttpx) == 0:
|
||||
self.nghttpx = 'nghttpx'
|
||||
|
|
@ -136,10 +144,12 @@ class EnvConfig:
|
|||
# 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:
|
||||
|
|
@ -149,10 +159,9 @@ class EnvConfig:
|
|||
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):
|
||||
|
|
@ -189,6 +198,14 @@ class EnvConfig:
|
|||
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:
|
||||
|
||||
|
|
@ -242,6 +259,14 @@ 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)
|
||||
|
|
@ -303,36 +328,36 @@ class Env:
|
|||
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:
|
||||
|
|
|
|||
49
tests/http/testenv/ports.py
Normal file
49
tests/http/testenv/ports.py
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#!/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
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue