Skip to content
This repository was archived by the owner on Aug 13, 2025. It is now read-only.

Commit ca77d0d

Browse files
committed
Execute the system test workflow in pytest runner
This is basically the pytest re-implementation of the run.sh script. The fixture is applied to every module and ensures complete test setup/teardown, such as starting/stopping servers, detecting coredumps etc. Note that the fixture system_test_dir is not defined yet. It is omitted now for review readability and it's added in follow-up commits.
1 parent 8e98c8d commit ca77d0d

File tree

1 file changed

+96
-1
lines changed

1 file changed

+96
-1
lines changed

bin/tests/system/conftest.py

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def control_port():
5757
import re
5858
import subprocess
5959
import time
60-
from typing import List, Optional
60+
from typing import Any, Dict, List, Optional
6161

6262
# Silence warnings caused by passing a pytest fixture to another fixture.
6363
# pylint: disable=redefined-outer-name
@@ -271,3 +271,98 @@ def shell(env, system_test_dir, logger):
271271
def perl(env, system_test_dir, logger):
272272
"""Function to call a perl script with arguments."""
273273
return partial(_run_script, env, logger, system_test_dir, env["PERL"])
274+
275+
@pytest.fixture(scope="module", autouse=True)
276+
def system_test( # pylint: disable=too-many-arguments,too-many-statements
277+
request,
278+
env: Dict[str, str],
279+
logger,
280+
system_test_dir,
281+
shell,
282+
perl,
283+
):
284+
"""
285+
Driver of the test setup/teardown process. Used automatically for every test module.
286+
287+
This is the most important one-fixture-to-rule-them-all. Note the
288+
autouse=True which causes this fixture to be loaded by every test
289+
module without the need to explicitly specify it.
290+
291+
When this fixture is used, it utilizes other fixtures, such as
292+
system_test_dir, which handles the creation of the temporary test
293+
directory.
294+
295+
Afterwards, it checks the test environment and takes care of starting
296+
the servers. When everything is ready, that's when the actual tests are
297+
executed. Once that is done, this fixture stops the servers and checks
298+
for any artifacts indicating an issue (e.g. coredumps).
299+
300+
Finally, when this fixture reaches an end (or encounters an exception,
301+
which may be caused by fail/skip invocations), any fixtures which is
302+
used by this one are finalized - e.g. system_test_dir performs final
303+
checks and cleans up the temporary test directory.
304+
"""
305+
306+
def check_net_interfaces():
307+
try:
308+
perl("testsock.pl", ["-p", env["PORT"]])
309+
except subprocess.CalledProcessError as exc:
310+
logger.error("testsock.pl: exited with code %d", exc.returncode)
311+
pytest.skip("Network interface aliases not set up.")
312+
313+
def check_prerequisites():
314+
try:
315+
shell(f"{system_test_dir}/prereq.sh")
316+
except FileNotFoundError:
317+
pass # prereq.sh is optional
318+
except subprocess.CalledProcessError:
319+
pytest.skip("Prerequisites missing.")
320+
321+
def setup_test():
322+
try:
323+
shell(f"{system_test_dir}/setup.sh")
324+
except FileNotFoundError:
325+
pass # setup.sh is optional
326+
except subprocess.CalledProcessError as exc:
327+
logger.error("Failed to run test setup")
328+
pytest.fail(f"setup.sh exited with {exc.returncode}")
329+
330+
def start_servers():
331+
try:
332+
perl("start.pl", ["--port", env["PORT"], system_test_dir.name])
333+
except subprocess.CalledProcessError as exc:
334+
logger.error("Failed to start servers")
335+
pytest.fail(f"start.pl exited with {exc.returncode}")
336+
337+
def stop_servers():
338+
try:
339+
perl("stop.pl", [system_test_dir.name])
340+
except subprocess.CalledProcessError as exc:
341+
logger.error("Failed to stop servers")
342+
pytest.fail(f"stop.pl exited with {exc.returncode}")
343+
344+
def get_core_dumps():
345+
try:
346+
shell("get_core_dumps.sh", [system_test_dir.name])
347+
except subprocess.CalledProcessError as exc:
348+
logger.error("Found core dumps")
349+
pytest.fail(f"get_core_dumps.sh exited with {exc.returncode}")
350+
351+
os.environ.update(env) # Ensure pytests have the same env vars as shell tests.
352+
logger.info(f"test started: {request.node.name}")
353+
port = int(env["PORT"])
354+
logger.info("using port range: <%d, %d>", port, port + PORTS_PER_TEST - 1)
355+
356+
# Perform checks which may skip this test.
357+
check_net_interfaces()
358+
check_prerequisites()
359+
360+
setup_test()
361+
try:
362+
start_servers()
363+
logger.debug("executing test(s)")
364+
yield
365+
finally:
366+
logger.debug("test(s) finished")
367+
stop_servers()
368+
get_core_dumps()

0 commit comments

Comments
 (0)