Traktor/myenv/Lib/site-packages/joblib/testing.py

100 lines
3.0 KiB
Python
Raw Normal View History

2024-05-23 01:57:24 +02:00
"""
Helper for testing.
"""
import sys
import warnings
import os.path
import re
import subprocess
import threading
import pytest
import _pytest
raises = pytest.raises
warns = pytest.warns
SkipTest = _pytest.runner.Skipped
skipif = pytest.mark.skipif
fixture = pytest.fixture
parametrize = pytest.mark.parametrize
timeout = pytest.mark.timeout
xfail = pytest.mark.xfail
param = pytest.param
def warnings_to_stdout():
""" Redirect all warnings to stdout.
"""
showwarning_orig = warnings.showwarning
def showwarning(msg, cat, fname, lno, file=None, line=0):
showwarning_orig(msg, cat, os.path.basename(fname), line, sys.stdout)
warnings.showwarning = showwarning
# warnings.simplefilter('always')
def check_subprocess_call(cmd, timeout=5, stdout_regex=None,
stderr_regex=None):
"""Runs a command in a subprocess with timeout in seconds.
A SIGTERM is sent after `timeout` and if it does not terminate, a
SIGKILL is sent after `2 * timeout`.
Also checks returncode is zero, stdout if stdout_regex is set, and
stderr if stderr_regex is set.
"""
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
def terminate_process(): # pragma: no cover
"""
Attempt to terminate a leftover process spawned during test execution:
ideally this should not be needed but can help avoid clogging the CI
workers in case of deadlocks.
"""
warnings.warn(f"Timeout running {cmd}")
proc.terminate()
def kill_process(): # pragma: no cover
"""
Kill a leftover process spawned during test execution: ideally this
should not be needed but can help avoid clogging the CI workers in
case of deadlocks.
"""
warnings.warn(f"Timeout running {cmd}")
proc.kill()
try:
if timeout is not None:
terminate_timer = threading.Timer(timeout, terminate_process)
terminate_timer.start()
kill_timer = threading.Timer(2 * timeout, kill_process)
kill_timer.start()
stdout, stderr = proc.communicate()
stdout, stderr = stdout.decode(), stderr.decode()
if proc.returncode != 0:
message = (
'Non-zero return code: {}.\nStdout:\n{}\n'
'Stderr:\n{}').format(
proc.returncode, stdout, stderr)
raise ValueError(message)
if (stdout_regex is not None and
not re.search(stdout_regex, stdout)):
raise ValueError(
"Unexpected stdout: {!r} does not match:\n{!r}".format(
stdout_regex, stdout))
if (stderr_regex is not None and
not re.search(stderr_regex, stderr)):
raise ValueError(
"Unexpected stderr: {!r} does not match:\n{!r}".format(
stderr_regex, stderr))
finally:
if timeout is not None:
terminate_timer.cancel()
kill_timer.cancel()