Added homing test and switched to NICOS-like caproto backend implementaiton

This commit is contained in:
Stefan Mathis
2025-07-28 16:43:53 +02:00
parent f1eb2b27bb
commit ed03816888
22 changed files with 646 additions and 162 deletions

90
runtests Executable file
View File

@@ -0,0 +1,90 @@
#!/usr/bin/env python3
# This script is a wrapper around pytest which performs the following tasks:
# 1) If the IOC in ioc/startioc.py is not running, start it
# 2) Run tests in parallel by starting a separate pytest process
# for each separate motor given in FOLDER. This allows to run tests on different
# motors in parallel, cutting down execution time and testing parallelism.
# The script accepts any arguments and forwards them to the pytest call.
# If a folder is given as an argument, all tests which are not within this
# folder are ignored:
# - `pytestpar` will run all tests parallelized per motor
# - `pytestpar tests/sinqMotor/turboPmac` will run all Turbo PMAC tests parallelized per motor
# - `pytestpar tests/sinqMotor/turboPmac/ax1` will only run the tests for motor `ax1`.
# These tests are run sequentially.
import sys
import subprocess
import os
from pathlib import Path
import time
from tests.conftest import check_ioc_running
from setup.classes import IocNotRunning
# Define the test folders you want to run in parallel
FOLDERS = ["tests/sinqMotor/turboPmac/ax1", "tests/sinqMotor/turboPmac/ax5"]
# Time we excpect the IOC needs to start up
TIMEOUT_IOC_STARTUP = 10
# Separate path-like arguments from other pytest args
path_args = []
extra_args = []
for arg in sys.argv[1:]:
if '/' in arg or os.path.exists(arg):
path_args.append(arg)
else:
extra_args.append(arg)
# Filter folders to run based on path_args
enabled_folders = []
if not path_args:
enabled_folders = FOLDERS
else:
for folder in FOLDERS:
if any(Path(arg).resolve().as_posix().startswith(Path(folder).resolve().as_posix()) for arg in path_args):
enabled_folders.append(folder)
# Check if the IOC is running and try to start it, if it isn't
try:
check_ioc_running()
except IocNotRunning:
print('Starting IOC ...')
# Start the IOC as a separate process, wait a bit and try again
path = Path(__file__).resolve().parent / 'ioc' / 'startioc'
p = subprocess.Popen([path],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
now = time.time()
while now + TIMEOUT_IOC_STARTUP > time.time():
time.sleep(0.5)
try:
check_ioc_running()
except IocNotRunning:
pass
check_ioc_running()
print(f'Started IOC successfully (process ID {p.pid})! It will automatically terminate after all tests are done.')
# Run each enabled folder's relevant tests in parallel
processes = []
for folder in enabled_folders:
folder_path_args = (
[arg for arg in path_args if Path(arg).resolve().as_posix().startswith(Path(folder).resolve().as_posix())]
if path_args else [folder]
)
command = ["pytest"] + folder_path_args + extra_args
print(f"Running: {' '.join(command)}")
proc = subprocess.Popen(command)
processes.append(proc)
# Wait for all processes and collect exit codes
exit_code = 0
for proc in processes:
code = proc.wait()
if code != 0:
exit_code = code
sys.exit(exit_code)