tests: address mutable class vars and naive datetime in Python code

Mark Python mutable class variables with ClassVar, to denote that the
danger this can cause has been considered.  Since any change made to
these in any object affects all other objects, this can cause locality
errors. However, as used in the test suite, they are are never modified
and so they are annotated as being intended.

Always set a timezone in datetime objects, as mixing naive and
timezone-aware object can cause errors.

These fix ruff rules DTZ005, RUF012.
This commit is contained in:
Dan Fandrich 2026-07-25 13:23:21 -07:00
parent b151a0bb90
commit e13362c20a
13 changed files with 81 additions and 78 deletions

View file

@ -26,6 +26,8 @@ import json
import logging import logging
import os import os
import re import re
from dataclasses import dataclass
from typing import ClassVar, Dict, List
import pytest import pytest
from testenv import CurlClient, Env, LocalClient from testenv import CurlClient, Env, LocalClient
@ -33,15 +35,16 @@ from testenv import CurlClient, Env, LocalClient
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@dataclass(frozen=True)
class TLSDefs: class TLSDefs:
TLS_VERSIONS = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3'] TLS_VERSIONS: ClassVar[List[str]] = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3']
TLS_VERSION_IDS = { TLS_VERSION_IDS: ClassVar[Dict[str, int]] = {
'TLSv1': 0x301, 'TLSv1': 0x301,
'TLSv1.1': 0x302, 'TLSv1.1': 0x302,
'TLSv1.2': 0x303, 'TLSv1.2': 0x303,
'TLSv1.3': 0x304 'TLSv1.3': 0x304
} }
CURL_ARG_MIN_VERSION_ID = { CURL_ARG_MIN_VERSION_ID: ClassVar[Dict[str, int]] = {
'none': 0x0, 'none': 0x0,
'tlsv1': 0x301, 'tlsv1': 0x301,
'tlsv1.0': 0x301, 'tlsv1.0': 0x301,
@ -49,7 +52,7 @@ class TLSDefs:
'tlsv1.2': 0x303, 'tlsv1.2': 0x303,
'tlsv1.3': 0x304, 'tlsv1.3': 0x304,
} }
CURL_ARG_MAX_VERSION_ID = { CURL_ARG_MAX_VERSION_ID: ClassVar[Dict[str, int]] = {
'none': 0x0, 'none': 0x0,
'1.0': 0x301, '1.0': 0x301,
'1.1': 0x302, '1.1': 0x302,

View file

@ -32,7 +32,7 @@ import socket
import subprocess import subprocess
import threading import threading
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from typing import Dict from typing import Dict
import pytest import pytest
@ -59,8 +59,8 @@ class WsServer:
def check_alive(self, env, port, timeout=Env.SERVER_TIMEOUT): def check_alive(self, env, port, timeout=Env.SERVER_TIMEOUT):
curl = CurlClient(env=env) curl = CurlClient(env=env)
url = f'http://localhost:{port}/' url = f'http://localhost:{port}/'
end = datetime.now() + timedelta(seconds=timeout) end = datetime.now(timezone.utc) + timedelta(seconds=timeout)
while datetime.now() < end: while datetime.now(timezone.utc) < end:
r = curl.http_download(urls=[url]) r = curl.http_download(urls=[url])
if r.exit_code == 0: if r.exit_code == 0:
return True return True

View file

@ -27,9 +27,9 @@ import os
import socket import socket
import subprocess import subprocess
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from json import JSONEncoder from json import JSONEncoder
from typing import Dict from typing import ClassVar, Dict
from .curl import CurlClient from .curl import CurlClient
from .env import Env from .env import Env
@ -40,7 +40,7 @@ log = logging.getLogger(__name__)
class Caddy: class Caddy:
PORT_SPECS = { PORT_SPECS: ClassVar[Dict[str, int]] = {
'caddy': socket.SOCK_STREAM, 'caddy': socket.SOCK_STREAM,
'caddys': socket.SOCK_STREAM, 'caddys': socket.SOCK_STREAM,
} }
@ -137,8 +137,8 @@ class Caddy:
def wait_dead(self, timeout: timedelta): def wait_dead(self, timeout: timedelta):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir) curl = CurlClient(env=self.env, run_dir=self._tmp_dir)
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
check_url = f'https://{self.env.domain1}:{self.port}/' check_url = f'https://{self.env.domain1}:{self.port}/'
r = curl.http_get(url=check_url) r = curl.http_get(url=check_url)
if r.exit_code != 0: if r.exit_code != 0:
@ -150,8 +150,8 @@ class Caddy:
def wait_live(self, timeout: timedelta): def wait_live(self, timeout: timedelta):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir) curl = CurlClient(env=self.env, run_dir=self._tmp_dir)
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
check_url = f'https://{self.env.domain1}:{self.port}/' check_url = f'https://{self.env.domain1}:{self.port}/'
r = curl.http_get(url=check_url) r = curl.http_get(url=check_url)
if r.exit_code == 0: if r.exit_code == 0:

View file

@ -350,7 +350,7 @@ class CertStore:
(cert.not_valid_before_utc > now)): (cert.not_valid_before_utc > now)):
return None return None
except AttributeError: # older python except AttributeError: # older python
now = datetime.now() now = datetime.now(timezone.utc)
if check_valid and \ if check_valid and \
((cert.not_valid_after < now) or ((cert.not_valid_after < now) or
(cert.not_valid_before > now)): (cert.not_valid_before > now)):
@ -422,10 +422,10 @@ class TestCA:
pubkey = pkey.public_key() pubkey = pkey.public_key()
issuer_subject = issuer_subject if issuer_subject is not None else subject issuer_subject = issuer_subject if issuer_subject is not None else subject
valid_from = datetime.now() valid_from = datetime.now(timezone.utc)
if valid_until_delta is not None: if valid_until_delta is not None:
valid_from += valid_from_delta valid_from += valid_from_delta
valid_until = datetime.now() valid_until = datetime.now(timezone.utc)
if valid_until_delta is not None: if valid_until_delta is not None:
valid_until += valid_until_delta valid_until += valid_until_delta

View file

@ -26,7 +26,7 @@ import logging
import os import os
import shutil import shutil
import subprocess import subprocess
from datetime import datetime from datetime import datetime, timezone
from typing import Dict, Optional from typing import Dict, Optional
from . import ExecResult from . import ExecResult
@ -81,7 +81,7 @@ class LocalClient:
def run(self, args): def run(self, args):
self._rmf(self._stdoutfile) self._rmf(self._stdoutfile)
self._rmf(self._stderrfile) self._rmf(self._stderrfile)
start = datetime.now() start = datetime.now(timezone.utc)
exception = None exception = None
myargs = [self.path, self.name] myargs = [self.path, self.name]
myargs.extend(args) myargs.extend(args)
@ -107,7 +107,7 @@ class LocalClient:
cerrput = ferr.readlines() cerrput = ferr.readlines()
return ExecResult(args=myargs, exit_code=exitcode, exception=exception, return ExecResult(args=myargs, exit_code=exitcode, exception=exception,
stdout=coutput, stderr=cerrput, stdout=coutput, stderr=cerrput,
duration=datetime.now() - start) duration=datetime.now(timezone.utc) - start)
def dump_logs(self): def dump_logs(self):
lines = [] lines = []

View file

@ -35,7 +35,7 @@ from datetime import datetime, timedelta, timezone
from functools import cmp_to_key from functools import cmp_to_key
from statistics import fmean, mean from statistics import fmean, mean
from threading import Thread from threading import Thread
from typing import Any, Dict, List, Optional, Tuple, Union from typing import Any, ClassVar, Dict, List, Optional, Tuple, Union
from urllib.parse import urlparse from urllib.parse import urlparse
import psutil import psutil
@ -47,7 +47,7 @@ log = logging.getLogger(__name__)
class RunProfile: class RunProfile:
STAT_KEYS = ['cpu', 'rss', 'vsz'] STAT_KEYS: ClassVar[List[str]] = ['cpu', 'rss', 'vsz']
@classmethod @classmethod
def AverageStats(cls, profiles: List['RunProfile']): def AverageStats(cls, profiles: List['RunProfile']):
@ -76,7 +76,7 @@ class RunProfile:
return self._stats return self._stats
def sample(self): def sample(self):
elapsed = datetime.now() - self._started_at elapsed = datetime.now(timezone.utc) - self._started_at
try: try:
if self._psu is None: if self._psu is None:
self._psu = psutil.Process(pid=self._pid) self._psu = psutil.Process(pid=self._pid)
@ -92,7 +92,7 @@ class RunProfile:
pass pass
def finish(self): def finish(self):
self._duration = datetime.now() - self._started_at self._duration = datetime.now(timezone.utc) - self._started_at
if len(self._samples) > 0: if len(self._samples) > 0:
weights = [s['time'].total_seconds() for s in self._samples] weights = [s['time'].total_seconds() for s in self._samples]
self._stats = {} self._stats = {}
@ -605,7 +605,7 @@ class ExecResult:
class CurlClient: class CurlClient:
ALPN_ARG = { ALPN_ARG: ClassVar[Dict[str, str]] = {
'http/0.9': '--http0.9', 'http/0.9': '--http0.9',
'http/1.0': '--http1.0', 'http/1.0': '--http1.0',
'http/1.1': '--http1.1', 'http/1.1': '--http1.1',
@ -1028,7 +1028,7 @@ class CurlClient:
if with_tcpdump: if with_tcpdump:
tcpdump = RunTcpDump(self.env, self._run_dir) tcpdump = RunTcpDump(self.env, self._run_dir)
tcpdump.start() tcpdump.start()
started_at = datetime.now() started_at = datetime.now(timezone.utc)
try: try:
with open(self._stdoutfile, 'w') as cout, open(self._stderrfile, 'w') as cerr: with open(self._stdoutfile, 'w') as cout, open(self._stderrfile, 'w') as cerr:
if with_profile: if with_profile:
@ -1051,7 +1051,7 @@ class CurlClient:
p.wait(timeout=ptimeout) p.wait(timeout=ptimeout)
break break
except subprocess.TimeoutExpired as e: except subprocess.TimeoutExpired as e:
if end_at and datetime.now() >= end_at: if end_at and datetime.now(timezone.utc) >= end_at:
p.kill() p.kill()
raise subprocess.TimeoutExpired(cmd=args, timeout=self._timeout) from e raise subprocess.TimeoutExpired(cmd=args, timeout=self._timeout) from e
profile.sample() profile.sample()
@ -1067,13 +1067,13 @@ class CurlClient:
env=self._run_env, check=False) env=self._run_env, check=False)
exitcode = p.returncode exitcode = p.returncode
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
now = datetime.now() now = datetime.now(timezone.utc)
duration = now - started_at duration = now - started_at
log.warning(f'Timeout at {now} after {duration.total_seconds()}s ' log.warning(f'Timeout at {now} after {duration.total_seconds()}s '
f'(configured {self._timeout}s): {args}') f'(configured {self._timeout}s): {args}')
exitcode = -1 exitcode = -1
exception = 'TimeoutExpired' exception = 'TimeoutExpired'
ended_at = datetime.now() ended_at = datetime.now(timezone.utc)
if tcpdump: if tcpdump:
tcpdump.finish() tcpdump.finish()
if perf: if perf:

View file

@ -27,7 +27,7 @@ import os
import socket import socket
import subprocess import subprocess
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from typing import Dict from typing import Dict
from . import CurlClient from . import CurlClient
@ -137,8 +137,8 @@ class Dante:
timeout=timeout.total_seconds(), socks_args=[ timeout=timeout.total_seconds(), socks_args=[
'--socks5', f'127.0.0.1:{self._port}' '--socks5', f'127.0.0.1:{self._port}'
]) ])
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
r = curl.http_get(url=f'http://{self.env.domain1}:{self.env.http_port}/') r = curl.http_get(url=f'http://{self.env.domain1}:{self.env.http_port}/')
if r.exit_code == 0: if r.exit_code == 0:
return True return True

View file

@ -27,7 +27,7 @@ import os
import socket import socket
import subprocess import subprocess
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from typing import Dict, List, Optional from typing import Dict, List, Optional
from .env import Env from .env import Env
@ -133,8 +133,8 @@ class Dnsd:
return self.wait_live(timeout=timedelta(seconds=Env.SERVER_TIMEOUT)) return self.wait_live(timeout=timedelta(seconds=Env.SERVER_TIMEOUT))
def wait_live(self, timeout: timedelta): def wait_live(self, timeout: timedelta):
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
if os.path.exists(self._log_file): if os.path.exists(self._log_file):
return True return True
time.sleep(.1) time.sleep(.1)

View file

@ -28,8 +28,8 @@ import signal
import socket import socket
import subprocess import subprocess
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from typing import Dict, Optional from typing import ClassVar, Dict, Optional
from .curl import CurlClient from .curl import CurlClient
from .env import Env from .env import Env
@ -181,12 +181,12 @@ class H2o:
running = self._process running = self._process
self._process = None self._process = None
os.kill(running.pid, signal.SIGQUIT) os.kill(running.pid, signal.SIGQUIT)
end_wait = datetime.now() + timedelta(seconds=5) end_wait = datetime.now(timezone.utc) + timedelta(seconds=5)
exited = False exited = False
if not self.start(wait_live=False): if not self.start(wait_live=False):
self._process = running self._process = running
return False return False
while datetime.now() < end_wait: while datetime.now(timezone.utc) < end_wait:
try: try:
self._log("debug", f"waiting for h2o({running.pid}) to exit.") self._log("debug", f"waiting for h2o({running.pid}) to exit.")
running.wait(1) running.wait(1)
@ -199,7 +199,7 @@ class H2o:
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
self._log("warning", f"h2o({running.pid}), not shut down yet.") self._log("warning", f"h2o({running.pid}), not shut down yet.")
os.kill(running.pid, signal.SIGQUIT) os.kill(running.pid, signal.SIGQUIT)
if not exited and datetime.now() >= end_wait: if not exited and datetime.now(timezone.utc) >= end_wait:
self._log("error", f"h2o({running.pid}), terminate forcefully.") self._log("error", f"h2o({running.pid}), terminate forcefully.")
os.kill(running.pid, signal.SIGKILL) os.kill(running.pid, signal.SIGKILL)
running.terminate() running.terminate()
@ -215,10 +215,10 @@ class H2o:
log_prefix: str = "h2o", log_prefix: str = "h2o",
): ):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir) curl = CurlClient(env=self.env, run_dir=self._tmp_dir)
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
if url is None: if url is None:
url = f"https://{self._domain}:{self._port}/" url = f"https://{self._domain}:{self._port}/"
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
if live: if live:
r = curl.http_get( r = curl.http_get(
url=url, extra_args=["--trace", "curl.trace", "--trace-time"] url=url, extra_args=["--trace", "curl.trace", "--trace-time"]
@ -245,7 +245,7 @@ class H2o:
class H2oServer(H2o): class H2oServer(H2o):
"""h2o HTTP/3 server for testing.""" """h2o HTTP/3 server for testing."""
PORT_SPECS = { PORT_SPECS: ClassVar[Dict[str, int]] = {
"h2o_https": socket.SOCK_STREAM, "h2o_https": socket.SOCK_STREAM,
} }
@ -422,10 +422,10 @@ error-log: {self._error_log}
log_prefix: str = "h2o", log_prefix: str = "h2o",
): ):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir) curl = CurlClient(env=self.env, run_dir=self._tmp_dir)
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
if url is None: if url is None:
url = f"https://{self.env.proxy_domain}:{self._port}/" url = f"https://{self.env.proxy_domain}:{self._port}/"
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
if live: if live:
r = curl.http_get( r = curl.http_get(
url=url, extra_args=["--trace", "curl.trace", "--trace-time"] url=url, extra_args=["--trace", "curl.trace", "--trace-time"]

View file

@ -31,9 +31,9 @@ import socket
import subprocess import subprocess
import textwrap import textwrap
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from json import JSONEncoder from json import JSONEncoder
from typing import Dict, List, Optional, Union from typing import ClassVar, Dict, List, Optional, Union
from .curl import CurlClient, ExecResult from .curl import CurlClient, ExecResult
from .env import Env, EnvError from .env import Env, EnvError
@ -44,7 +44,7 @@ log = logging.getLogger(__name__)
class Httpd: class Httpd:
MODULES = [ MODULES: ClassVar[List[str]] = [
'log_config', 'logio', 'unixd', 'version', 'watchdog', 'log_config', 'logio', 'unixd', 'version', 'watchdog',
'authn_core', 'authn_file', 'authn_core', 'authn_file',
'authz_user', 'authz_core', 'authz_host', 'authz_user', 'authz_core', 'authz_host',
@ -55,14 +55,14 @@ class Httpd:
'brotli', 'brotli',
'mpm_event', 'mpm_event',
] ]
COMMON_MODULES_DIRS = [ COMMON_MODULES_DIRS: ClassVar[List[str]] = [
'/usr/lib/apache2/modules', # debian '/usr/lib/apache2/modules', # debian
'/usr/libexec/apache2/', # macos '/usr/libexec/apache2/', # macos
] ]
MOD_CURLTEST = None MOD_CURLTEST = None
PORT_SPECS = { PORT_SPECS: ClassVar[Dict[str, int]] = {
'http': socket.SOCK_STREAM, 'http': socket.SOCK_STREAM,
'https': socket.SOCK_STREAM, 'https': socket.SOCK_STREAM,
'https-tcp-only': socket.SOCK_STREAM, 'https-tcp-only': socket.SOCK_STREAM,
@ -141,11 +141,11 @@ class Httpd:
p = subprocess.run(args, capture_output=True, cwd=self.env.gen_dir, p = subprocess.run(args, capture_output=True, cwd=self.env.gen_dir,
input=intext.encode() if intext else None, input=intext.encode() if intext else None,
env=env, check=True) env=env, check=True)
start = datetime.now() start = datetime.now(timezone.utc)
return ExecResult(args=args, exit_code=p.returncode, return ExecResult(args=args, exit_code=p.returncode,
stdout=p.stdout.decode().splitlines(), stdout=p.stdout.decode().splitlines(),
stderr=p.stderr.decode().splitlines(), stderr=p.stderr.decode().splitlines(),
duration=datetime.now() - start) duration=datetime.now(timezone.utc) - start)
def _cmd_httpd(self, cmd: str): def _cmd_httpd(self, cmd: str):
args = [self.env.httpd, args = [self.env.httpd,
@ -221,8 +221,8 @@ class Httpd:
def wait_dead(self, timeout: timedelta): def wait_dead(self, timeout: timedelta):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir) curl = CurlClient(env=self.env, run_dir=self._tmp_dir)
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
r = curl.http_get(url=f'http://{self.env.domain1}:{self.ports["http"]}/') r = curl.http_get(url=f'http://{self.env.domain1}:{self.ports["http"]}/')
if r.exit_code != 0: if r.exit_code != 0:
self._maybe_running = False self._maybe_running = False
@ -234,8 +234,8 @@ class Httpd:
def wait_live(self, timeout: timedelta): def wait_live(self, timeout: timedelta):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir, curl = CurlClient(env=self.env, run_dir=self._tmp_dir,
timeout=timeout.total_seconds()) timeout=timeout.total_seconds())
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
r = curl.http_get(url=f'http://{self.env.domain1}:{self.ports["http"]}/') r = curl.http_get(url=f'http://{self.env.domain1}:{self.ports["http"]}/')
if r.exit_code == 0: if r.exit_code == 0:
self._maybe_running = True self._maybe_running = True

View file

@ -29,8 +29,8 @@ import socket
import subprocess import subprocess
import textwrap import textwrap
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from typing import Dict, Optional from typing import ClassVar, Dict, Optional
from .curl import CurlClient from .curl import CurlClient
from .env import Env, NghttpxUtil from .env import Env, NghttpxUtil
@ -135,11 +135,11 @@ class Nghttpx:
running = self._process running = self._process
self._process = None self._process = None
os.kill(running.pid, signal.SIGQUIT) os.kill(running.pid, signal.SIGQUIT)
end_wait = datetime.now() + timedelta(seconds=5) end_wait = datetime.now(timezone.utc) + timedelta(seconds=5)
if not self.start(wait_live=False): if not self.start(wait_live=False):
self._process = running self._process = running
return False return False
while datetime.now() < end_wait: while datetime.now(timezone.utc) < end_wait:
try: try:
log.debug(f'waiting for nghttpx({running.pid}) to exit.') log.debug(f'waiting for nghttpx({running.pid}) to exit.')
running.wait(1) running.wait(1)
@ -149,7 +149,7 @@ class Nghttpx:
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
log.warning(f'nghttpx({running.pid}), not shut down yet.') log.warning(f'nghttpx({running.pid}), not shut down yet.')
os.kill(running.pid, signal.SIGQUIT) os.kill(running.pid, signal.SIGQUIT)
if running and datetime.now() >= end_wait: if running and datetime.now(timezone.utc) >= end_wait:
log.error(f'nghttpx({running.pid}), terminate forcefully.') log.error(f'nghttpx({running.pid}), terminate forcefully.')
os.kill(running.pid, signal.SIGKILL) os.kill(running.pid, signal.SIGKILL)
running.terminate() running.terminate()
@ -159,8 +159,8 @@ class Nghttpx:
def wait_dead(self, timeout: timedelta): def wait_dead(self, timeout: timedelta):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir) curl = CurlClient(env=self.env, run_dir=self._tmp_dir)
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
xargs = [ xargs = [
'--trace', 'curl.trace', '--trace-time', '--trace', 'curl.trace', '--trace-time',
'--connect-timeout', '1' '--connect-timeout', '1'
@ -178,8 +178,8 @@ class Nghttpx:
def wait_live(self, timeout: timedelta): def wait_live(self, timeout: timedelta):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir) curl = CurlClient(env=self.env, run_dir=self._tmp_dir)
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
xargs = [ xargs = [
'--trace', 'curl.trace', '--trace-time', '--trace', 'curl.trace', '--trace-time',
'--connect-timeout', '1' '--connect-timeout', '1'
@ -212,7 +212,7 @@ class Nghttpx:
class NghttpxQuic(Nghttpx): class NghttpxQuic(Nghttpx):
PORT_SPECS = { PORT_SPECS: ClassVar[Dict[str, int]] = {
'nghttpx_https': socket.SOCK_STREAM, 'nghttpx_https': socket.SOCK_STREAM,
} }
@ -327,8 +327,8 @@ class NghttpxFwd(Nghttpx):
def wait_dead(self, timeout: timedelta): def wait_dead(self, timeout: timedelta):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir) curl = CurlClient(env=self.env, run_dir=self._tmp_dir)
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
check_url = f'https://{self.env.proxy_domain}:{self._port}/' check_url = f'https://{self.env.proxy_domain}:{self._port}/'
r = curl.http_get(url=check_url) r = curl.http_get(url=check_url)
if r.exit_code != 0: if r.exit_code != 0:
@ -340,8 +340,8 @@ class NghttpxFwd(Nghttpx):
def wait_live(self, timeout: timedelta): def wait_live(self, timeout: timedelta):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir) curl = CurlClient(env=self.env, run_dir=self._tmp_dir)
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
check_url = f'https://{self.env.proxy_domain}:{self._port}/' check_url = f'https://{self.env.proxy_domain}:{self._port}/'
r = curl.http_get(url=check_url, extra_args=[ r = curl.http_get(url=check_url, extra_args=[
'--trace', 'curl.trace', '--trace-time' '--trace', 'curl.trace', '--trace-time'

View file

@ -28,7 +28,7 @@ import socket
import stat import stat
import subprocess import subprocess
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from typing import Dict from typing import Dict
from . import CurlClient from . import CurlClient
@ -242,8 +242,8 @@ class Sshd:
def wait_live(self, timeout: timedelta): def wait_live(self, timeout: timedelta):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir, curl = CurlClient(env=self.env, run_dir=self._tmp_dir,
timeout=timeout.total_seconds()) timeout=timeout.total_seconds())
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
r = curl.http_get(url=f'scp://{self.env.domain1}:{self._port}/{self.home_dir}/data', r = curl.http_get(url=f'scp://{self.env.domain1}:{self._port}/{self.home_dir}/data',
extra_args=[ extra_args=[
'--insecure', '--insecure',

View file

@ -28,7 +28,7 @@ import re
import socket import socket
import subprocess import subprocess
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from typing import Dict, List, Tuple from typing import Dict, List, Tuple
from .curl import CurlClient, ExecResult from .curl import CurlClient, ExecResult
@ -152,8 +152,8 @@ class VsFTPD:
def wait_dead(self, timeout: timedelta): def wait_dead(self, timeout: timedelta):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir) curl = CurlClient(env=self.env, run_dir=self._tmp_dir)
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
check_url = f'{self._scheme}://{self.domain}:{self.port}/' check_url = f'{self._scheme}://{self.domain}:{self.port}/'
r = curl.ftp_get(urls=[check_url], extra_args=['-v']) r = curl.ftp_get(urls=[check_url], extra_args=['-v'])
if r.exit_code != 0: if r.exit_code != 0:
@ -165,8 +165,8 @@ class VsFTPD:
def wait_live(self, timeout: timedelta): def wait_live(self, timeout: timedelta):
curl = CurlClient(env=self.env, run_dir=self._tmp_dir) curl = CurlClient(env=self.env, run_dir=self._tmp_dir)
try_until = datetime.now() + timeout try_until = datetime.now(timezone.utc) + timeout
while datetime.now() < try_until: while datetime.now(timezone.utc) < try_until:
check_url = f'{self._scheme}://{self.domain}:{self.port}/' check_url = f'{self._scheme}://{self.domain}:{self.port}/'
r = curl.ftp_get(urls=[check_url], extra_args=[ r = curl.ftp_get(urls=[check_url], extra_args=[
'--trace', 'curl-start.trace', '--trace-time' '--trace', 'curl-start.trace', '--trace-time'