Move shell and perl util functions to isctest.run
Previously, these functions have been provided as fixtures. This was
limiting re-use, because it wasn't possible to call these outside of
tests / other fixtures without passing these utility functions around.
Move them into isctest.run package instead.
(cherry picked from commit b6d645410c)
This commit is contained in:
committed by
Michal Nowak
parent
f76cacae35
commit
184160ac36
@@ -9,7 +9,6 @@
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
from functools import partial
|
||||
import filecmp
|
||||
import os
|
||||
from pathlib import Path
|
||||
@@ -18,7 +17,7 @@ import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
from typing import Any, List, Optional
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -490,46 +489,6 @@ def templates(system_test_dir: Path):
|
||||
return isctest.template.TemplateEngine(system_test_dir)
|
||||
|
||||
|
||||
def _run_script(
|
||||
system_test_dir: Path,
|
||||
interpreter: str,
|
||||
script: str,
|
||||
args: Optional[List[str]] = None,
|
||||
):
|
||||
"""Helper function for the shell / perl script invocations (through fixtures below)."""
|
||||
if args is None:
|
||||
args = []
|
||||
path = Path(script)
|
||||
if not path.is_absolute():
|
||||
# make sure relative paths are always relative to system_dir
|
||||
path = system_test_dir.parent / path
|
||||
script = str(path)
|
||||
cwd = os.getcwd()
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(f"script {script} not found in {cwd}")
|
||||
isctest.log.debug("running script: %s %s %s", interpreter, script, " ".join(args))
|
||||
isctest.log.debug(" workdir: %s", cwd)
|
||||
returncode = 1
|
||||
|
||||
cmd = [interpreter, script] + args
|
||||
with subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
bufsize=1,
|
||||
universal_newlines=True,
|
||||
errors="backslashreplace",
|
||||
) as proc:
|
||||
if proc.stdout:
|
||||
for line in proc.stdout:
|
||||
isctest.log.info(" %s", line.rstrip("\n"))
|
||||
proc.communicate()
|
||||
returncode = proc.returncode
|
||||
if returncode:
|
||||
raise subprocess.CalledProcessError(returncode, cmd)
|
||||
isctest.log.debug(" exited with %d", returncode)
|
||||
|
||||
|
||||
def _get_node_path(node) -> Path:
|
||||
if isinstance(node.parent, pytest.Session):
|
||||
if _pytest_major_ver >= 8:
|
||||
@@ -540,23 +499,11 @@ def _get_node_path(node) -> Path:
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def shell(system_test_dir):
|
||||
"""Function to call a shell script with arguments."""
|
||||
return partial(_run_script, system_test_dir, os.environ["SHELL"])
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def perl(system_test_dir):
|
||||
"""Function to call a perl script with arguments."""
|
||||
return partial(_run_script, system_test_dir, os.environ["PERL"])
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def run_tests_sh(system_test_dir, shell):
|
||||
def run_tests_sh(system_test_dir):
|
||||
"""Utility function to execute tests.sh as a python test."""
|
||||
|
||||
def run_tests():
|
||||
shell(f"{system_test_dir}/tests.sh")
|
||||
isctest.run.shell(f"{system_test_dir}/tests.sh")
|
||||
|
||||
return run_tests
|
||||
|
||||
@@ -566,8 +513,6 @@ def system_test(
|
||||
request,
|
||||
system_test_dir,
|
||||
templates,
|
||||
shell,
|
||||
perl,
|
||||
):
|
||||
"""
|
||||
Driver of the test setup/teardown process. Used automatically for every test module.
|
||||
@@ -593,14 +538,16 @@ def system_test(
|
||||
|
||||
def check_net_interfaces():
|
||||
try:
|
||||
perl("testsock.pl", ["-p", os.environ["PORT"]])
|
||||
isctest.run.perl(
|
||||
f"{os.environ['srcdir']}/testsock.pl", ["-p", os.environ["PORT"]]
|
||||
)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
isctest.log.error("testsock.pl: exited with code %d", exc.returncode)
|
||||
pytest.skip("Network interface aliases not set up.")
|
||||
|
||||
def check_prerequisites():
|
||||
try:
|
||||
shell(f"{system_test_dir}/prereq.sh")
|
||||
isctest.run.shell(f"{system_test_dir}/prereq.sh")
|
||||
except FileNotFoundError:
|
||||
pass # prereq.sh is optional
|
||||
except subprocess.CalledProcessError:
|
||||
@@ -609,7 +556,7 @@ def system_test(
|
||||
def setup_test():
|
||||
templates.render_auto()
|
||||
try:
|
||||
shell(f"{system_test_dir}/setup.sh")
|
||||
isctest.run.shell(f"{system_test_dir}/setup.sh")
|
||||
except FileNotFoundError:
|
||||
pass # setup.sh is optional
|
||||
except subprocess.CalledProcessError as exc:
|
||||
@@ -618,14 +565,17 @@ def system_test(
|
||||
|
||||
def start_servers():
|
||||
try:
|
||||
perl("start.pl", ["--port", os.environ["PORT"], system_test_dir.name])
|
||||
isctest.run.perl(
|
||||
f"{os.environ['srcdir']}/start.pl",
|
||||
["--port", os.environ["PORT"], system_test_dir.name],
|
||||
)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
isctest.log.error("Failed to start servers")
|
||||
pytest.fail(f"start.pl exited with {exc.returncode}")
|
||||
|
||||
def stop_servers():
|
||||
try:
|
||||
perl("stop.pl", [system_test_dir.name])
|
||||
isctest.run.perl(f"{os.environ['srcdir']}/stop.pl", [system_test_dir.name])
|
||||
except subprocess.CalledProcessError as exc:
|
||||
isctest.log.error("Failed to stop servers")
|
||||
get_core_dumps()
|
||||
@@ -633,7 +583,9 @@ def system_test(
|
||||
|
||||
def get_core_dumps():
|
||||
try:
|
||||
shell("get_core_dumps.sh", [system_test_dir.name])
|
||||
isctest.run.shell(
|
||||
f"{os.environ['srcdir']}/get_core_dumps.sh", [system_test_dir.name]
|
||||
)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
isctest.log.error("Found core dumps or sanitizer reports")
|
||||
pytest.fail(f"get_core_dumps.sh exited with {exc.returncode}")
|
||||
|
||||
@@ -10,9 +10,10 @@
|
||||
# information regarding copyright ownership.
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import time
|
||||
from typing import Optional
|
||||
from typing import List, Optional
|
||||
|
||||
import isctest.log
|
||||
from isctest.compat import dns_rcode
|
||||
@@ -65,6 +66,51 @@ def cmd(
|
||||
return exc
|
||||
|
||||
|
||||
def _run_script(
|
||||
interpreter: str,
|
||||
script: str,
|
||||
args: Optional[List[str]] = None,
|
||||
):
|
||||
if args is None:
|
||||
args = []
|
||||
path = Path(script)
|
||||
script = str(path)
|
||||
cwd = os.getcwd()
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(f"script {script} not found in {cwd}")
|
||||
isctest.log.debug("running script: %s %s %s", interpreter, script, " ".join(args))
|
||||
isctest.log.debug(" workdir: %s", cwd)
|
||||
returncode = 1
|
||||
|
||||
command = [interpreter, script] + args
|
||||
with subprocess.Popen(
|
||||
command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
bufsize=1,
|
||||
universal_newlines=True,
|
||||
errors="backslashreplace",
|
||||
) as proc:
|
||||
if proc.stdout:
|
||||
for line in proc.stdout:
|
||||
isctest.log.info(" %s", line.rstrip("\n"))
|
||||
proc.communicate()
|
||||
returncode = proc.returncode
|
||||
if returncode:
|
||||
raise subprocess.CalledProcessError(returncode, command)
|
||||
isctest.log.debug(" exited with %d", returncode)
|
||||
|
||||
|
||||
def shell(script: str, args: Optional[List[str]] = None) -> None:
|
||||
"""Run a given script with system's shell interpreter."""
|
||||
_run_script(os.environ["SHELL"], script, args)
|
||||
|
||||
|
||||
def perl(script: str, args: Optional[List[str]] = None) -> None:
|
||||
"""Run a given script with system's perl interpreter."""
|
||||
_run_script(os.environ["PERL"], script, args)
|
||||
|
||||
|
||||
def retry_with_timeout(func, timeout, delay=1, msg=None):
|
||||
start_time = time.time()
|
||||
while time.time() < start_time + timeout:
|
||||
|
||||
Reference in New Issue
Block a user