run_iocsh

Package for running IOC and checking output.

Submodules

Attributes

Exceptions

IocshAlreadyRunningError

Exception raised when IOC is started a second time.

IocshExitedError

Exception raised when the IOC exits on its own before it is told to.

IocshFileNotFoundError

Exception raised when a file referenced in the startup script is not found.

IocshMissingSharedLibraryError

Exception raised when shared library is missing.

IocshModuleNotFoundError

Exception raised when the required module is not found.

IocshOutputError

Base exception for errors detected in IOC output.

IocshPatternMatchError

Exception raised when a fail_on pattern matches the IOC output.

IocshProcessError

Exception raised when the iocsh script exits with a non null return code.

IocshStartupError

Exception raised when IOC exits before the expected readiness pattern appears.

IocshStateError

Exception raised for programming errors (wrong state transitions).

IocshTimeoutError

Exception raised when an operation did not complete within its timeout.

RunIocshError

Base class for exceptions in this module.

Classes

IOC

Class to wrap IOC process.

Functions

detect_file_not_found(→ None)

Raise if the IOC shell reports a file it could not open.

detect_missing_shared_library(→ None)

Raise if the dynamic linker reports a library it could not open.

detect_module_not_found(→ None)

Raise if require reports that a module failed to load.

run_iocsh(→ IOC)

Start IOC, wait for pattern, settle, exit, then check the output.

wait_for(→ None)

Poll predicate until it returns True or timeout elapses.

Package Contents

exception run_iocsh.IocshAlreadyRunningError[source]

Bases: IocshStateError

Exception raised when IOC is started a second time.

exception run_iocsh.IocshExitedError[source]

Bases: RunIocshError

Exception raised when the IOC exits on its own before it is told to.

exception run_iocsh.IocshFileNotFoundError[source]

Bases: IocshOutputError, FileNotFoundError

Exception raised when a file referenced in the startup script is not found.

exception run_iocsh.IocshMissingSharedLibraryError[source]

Bases: IocshOutputError

Exception raised when shared library is missing.

exception run_iocsh.IocshModuleNotFoundError[source]

Bases: IocshOutputError

Exception raised when the required module is not found.

exception run_iocsh.IocshOutputError[source]

Bases: RunIocshError

Base exception for errors detected in IOC output.

exception run_iocsh.IocshPatternMatchError[source]

Bases: IocshOutputError

Exception raised when a fail_on pattern matches the IOC output.

exception run_iocsh.IocshProcessError[source]

Bases: IocshOutputError

Exception raised when the iocsh script exits with a non null return code.

exception run_iocsh.IocshStartupError[source]

Bases: RunIocshError

Exception raised when IOC exits before the expected readiness pattern appears.

exception run_iocsh.IocshStateError[source]

Bases: RunIocshError

Exception raised for programming errors (wrong state transitions).

exception run_iocsh.IocshTimeoutError[source]

Bases: RunIocshError, TimeoutError

Exception raised when an operation did not complete within its timeout.

Also a builtin TimeoutError, so except TimeoutError keeps working while except RunIocshError catches every error this library raises.

exception run_iocsh.RunIocshError[source]

Bases: Exception

Base class for exceptions in this module.

run_iocsh.DEFAULT_DETECTORS: tuple[Detector, Ellipsis][source]
run_iocsh.DEFAULT_FAIL_ON: tuple[str, Ellipsis][source]
class run_iocsh.IOC(*args: str, executable: str = DEFAULT_EXECUTABLE, exit_timeout: float | None = DEFAULT_EXIT_TIMEOUT, fail_on: collections.abc.Sequence[str] = DEFAULT_FAIL_ON, detectors: collections.abc.Sequence[Detector] = DEFAULT_DETECTORS, **kwargs: object)[source]

Class to wrap IOC process.

Not thread-safe: all public methods should be called from a single thread. Internal reader threads are managed by the class itself.

class State(*args, **kwds)

Bases: enum.Enum

Lifecycle state of the IOC subprocess.

CREATED
STARTED
EXITED
proc = None
args = ()
executable = 'iocsh'
exit_timeout = 10.0
state
__getattr__(name: str) object[source]
__setattr__(name: str, value: object) None[source]
__enter__() Self[source]
__exit__(exc_type: object, exc_value: object, exc_traceback: object) None[source]
property pid: int | None

Return the subprocess PID, or None if not yet started.

property stdout: str

Return accumulated stdout as a single newline-joined string.

property stderr: str

Return accumulated stderr as a single newline-joined string.

property output: str

Return stdout and stderr interleaved, in the order the lines arrived.

Prefer this over stdout + stderr for matching: concatenating the two glues the last stdout line onto the first stderr line, and orders every stderr line after every stdout line regardless of when it was emitted.

Ordering across the two pipes is approximate — it reflects the order the reader threads observed lines, which buffering can perturb. Order within a single stream is exact.

is_running() bool[source]

Return True if the subprocess is still running.

This only reflects subprocess state — it does NOT indicate that iocInit has completed, that records are available, or that CA/PVA is ready to serve clients. Use wait_for_output() for IOC readiness checks.

start() None[source]

Start the IOC subprocess.

Raises:

IocshAlreadyRunningError: If the IOC is already running. IocshStateError: If the IOC has already exited.

exit() None[source]

Send the exit command to the running IOC and wait for it to exit.

Raises:
IocshTimeoutError: If the IOC does not exit within exit_timeout.

It is killed first, so the process is always reaped.

kill() None[source]

Kill the IOC without asking it to exit gracefully.

For an IOC that will not exit on command – one that deadlocks during asInit and never reaches a shell that reads stdin – exit() can only time out. kill() stops it outright and, unlike exit(), does not raise. Captured output stays available, and check_output() can run afterwards: when kill() stopped a running process the return code is the kill signal and is not counted as a failure, so the fail_on and detector checks still apply. An IOC that had already exited on its own keeps its return code, which check_output() still checks.

classmethod ready(*args: str, pattern: str = DEFAULT_INIT_PATTERN, init_timeout: float | None = DEFAULT_INIT_TIMEOUT, executable: str = DEFAULT_EXECUTABLE, exit_timeout: float | None = DEFAULT_EXIT_TIMEOUT, fail_on: collections.abc.Sequence[str] = DEFAULT_FAIL_ON, detectors: collections.abc.Sequence[Detector] = DEFAULT_DETECTORS) collections.abc.Iterator[Self][source]

Start an IOC, block until it is ready, and yield it still running.

Constructs the IOC, starts it, waits until it is ready, and yields it still running for the caller to use over CA or PVA. Leaving the block exits the IOC and checks its output, the same contract as with IOC(...). Use it instead of run_iocsh() when a test needs the IOC to stay up. If the IOC never becomes ready, that is raised before the yield – as the recognised cause where a detector matches, else a startup error.

Args:

args: Arguments passed to the IOC executable. pattern: Regex to wait for before yielding, as in wait_for_output. init_timeout: Seconds to wait for pattern. None waits forever. executable: IOC executable to run. exit_timeout: Seconds to wait for the IOC to exit on block exit. fail_on: Regex patterns that make the exit-time check raise. detectors: Callables that recognise a failure in the output.

Yields:

The running IOC instance, ready for interaction.

wait_for_output(pattern: str = DEFAULT_INIT_PATTERN, timeout: float | None = DEFAULT_INIT_TIMEOUT, poll_interval: float = DEFAULT_POLL_INTERVAL) None[source]

Block until pattern appears in stdout or stderr.

Returns immediately if the pattern is already present in buffered output.

Args:

pattern: Regex pattern to search for in output. timeout: Maximum seconds to wait. None waits forever, as it does

throughout the standard library. 0 checks the buffered output once and never blocks.

poll_interval: Seconds to sleep between polls.

Raises:

IocshStateError: If called before the process has started. IocshStartupError: If the IOC exits before the pattern appears. IocshTimeoutError: If timeout expires while the IOC is still

running. For the readiness pattern the message names wait_for_init=False, since an IOC that never reaches iocInit cannot pass this wait.

check_output(*, fail_on: collections.abc.Sequence[str] | None = None, detectors: collections.abc.Sequence[Detector] | None = None) None[source]

Inspect accumulated output and raise on detected errors.

By default applies the fail_on patterns and detectors this instance was constructed with, plus the return-code check.

Args:
fail_on: Regex patterns to match against output. None (the

default) uses the instance’s fail_on. Any value replaces it entirely — pass (*DEFAULT_FAIL_ON, "MY:") to extend rather than replace, or () to disable pattern checks altogether.

detectors: Callables that inspect the output and raise if they

recognise a failure. None uses the instance’s detectors. Any value replaces them entirely; pass () to rely on fail_on and the return code alone.

Raises:

IocshStateError: If called before the process has exited. IocshPatternMatchError: If any pattern matches the output. IocshModuleNotFoundError: If a module failed to load. IocshFileNotFoundError: If a file could not be opened or does not exist. IocshMissingSharedLibraryError: If a required shared library is missing. IocshProcessError: If the process exited with a non-zero code.

run_iocsh.Detector[source]
run_iocsh.detect_file_not_found(output: str) None[source]

Raise if the IOC shell reports a file it could not open.

run_iocsh.detect_missing_shared_library(output: str) None[source]

Raise if the dynamic linker reports a library it could not open.

glibc and dyld report this differently: glibc prints “cannot open shared object file” for a .so, while dyld lists every path it tried for a .dylib. Both forms are matched.

run_iocsh.detect_module_not_found(output: str) None[source]

Raise if require reports that a module failed to load.

run_iocsh.run_iocsh(*args: str, settle: float = DEFAULT_SETTLE, exit_timeout: float | None = DEFAULT_EXIT_TIMEOUT, init_timeout: float | None = DEFAULT_INIT_TIMEOUT, pattern: str = DEFAULT_INIT_PATTERN, wait_for_init: bool = True, executable: str = DEFAULT_EXECUTABLE, fail_on: collections.abc.Sequence[str] = DEFAULT_FAIL_ON, detectors: collections.abc.Sequence[Detector] = DEFAULT_DETECTORS, **kwargs: object) IOC[source]

Start IOC, wait for pattern, settle, exit, then check the output.

Args:

args: Arguments passed to the IOC executable. settle: Seconds to keep the IOC running once it is ready, before

telling it to exit. Defaults to 0. Set it to catch an IOC that starts cleanly but then dies, or to give background work that leaves no trace in the output time to finish.

exit_timeout: Seconds to wait for the IOC to exit after being told to

exit. None waits forever.

init_timeout: Seconds to wait for pattern to appear. None waits

forever.

pattern: Regex to wait for before considering the IOC ready. Ignored

when wait_for_init is False.

wait_for_init: Whether to wait for the IOC to become ready at all. Pass

False for an IOC that never reaches iocInit – one started with require’s --no-init, or one whose startup deadlocks during asInit – where the wait could only ever time out.

executable: IOC executable to run. fail_on: Regex patterns that make check_output raise. detectors: Callables that recognise a failure in the output. kwargs: Taken only to reject renamed arguments by the name that

replaced them. Anything else raises the usual TypeError.

Returns:

The exited IOC instance. Access .output, .stdout and .stderr for inspection after the call returns.

run_iocsh.wait_for(predicate: collections.abc.Callable[[], bool], timeout: float | None = DEFAULT_POLL_TIMEOUT, poll_interval: float = DEFAULT_POLL_INTERVAL) None[source]

Poll predicate until it returns True or timeout elapses.

Exceptions from predicate are caught and treated as a false result (polling continues until timeout).

Args:

predicate: Callable invoked repeatedly; success when it returns True. timeout: Maximum seconds to wait. None waits forever, as it does

throughout the standard library. 0 evaluates predicate once and never blocks.

poll_interval: Seconds to sleep between polls.

Raises:
IocshTimeoutError: If the predicate never returns True within

timeout. Also catchable as the builtin TimeoutError.