diff --git a/tests/ioc_plugin.py b/tests/ioc_plugin.py index 91ab9f64..89b303ee 100644 --- a/tests/ioc_plugin.py +++ b/tests/ioc_plugin.py @@ -1,9 +1,8 @@ -# ioc_plugin.py import os import sys import time import threading -import importlib +import importlib import pkgutil import pytest import epics @@ -14,7 +13,6 @@ DEFAULT_PREFIX = "TEST:" MOTOR_IDS = [f"M{i}" for i in range(1, 16)] # M1..M15 STR_SUFFIXES = {"RTYP", "DESC", "EGU", "DIR"} # serve strings for these fields - # -------- Robust MorIOC loader (handles namespace packages) ------------------ def _load_morioc(): try: @@ -143,8 +141,9 @@ class _MorIOCProxy: _shared["hosted"].update(new.keys()) -def pytest_configure(config): - # Ensure prefix format and start shared IOC *before* test collection +@pytest.fixture(scope="function") +def start_ioc(): + """Start the IOC before each test, and clean up after.""" prefix = os.environ.get(PREFIX_ENV, DEFAULT_PREFIX) if not prefix.endswith(":"): prefix += ":" @@ -153,8 +152,34 @@ def pytest_configure(config): _start_shared_ioc(prefix) time.sleep(0.5) # small CA settle time + yield # This is where the actual test runs + # Cleanup after the test + _shared["stop"].set() + t = _shared.get("thread") + if t: + t.join(timeout=2.0) + mor = _shared.get("mor") + if mor: + try: + mor.__exit__(None, None, None) + except Exception: + pass + time.sleep(0.2) + +def pytest_configure(config): + """Configure pytest to start the IOC and make sure the MorIOC is patched.""" + prefix = os.environ.get(PREFIX_ENV, DEFAULT_PREFIX) + if not prefix.endswith(":"): + prefix += ":" + os.environ[PREFIX_ENV] = prefix + + _start_shared_ioc(prefix) + time.sleep(0.5) # small CA settle time + + def pytest_sessionfinish(session, exitstatus): + """Stop the IOC and cleanup after all tests.""" _shared["stop"].set() t = _shared.get("thread") if t: