ophyd_async.epics.testing#
Package Contents#
Classes#
Device for use in a channel access test IOC. |
|
For testing strict enum values in test IOCs. |
|
For testing subset enum values in test IOCs. |
|
For testing superset enum values in test IOCs. |
|
Device for use in a pv access test IOC. |
|
Device for use in a generic PVI test IOC, independent of PandA/FastCS. |
|
Leaf sub-device for |
|
Real-IOC-backed structural PVI test device. |
|
Connects to the same served PVI tree as EpicsTestPviNestedDevice. |
|
An abstraction of a Table where each field is a column. |
Functions#
For generating random PV names in test devices. |
|
Start an EPICS IOC subprocess by running |
Data#
API#
- ophyd_async.epics.testing.CA_PVA_RECORDS#
None
- ophyd_async.epics.testing.IOC#
None
- ophyd_async.epics.testing.PVA_RECORDS#
None
- ophyd_async.epics.testing.PVI_NESTED_RECORDS#
None
- class ophyd_async.epics.testing.EpicsTestCaDevice(prefix: str, with_pvi: bool = False, name: str = '')[source]#
Bases:
ophyd_async.epics.core.EpicsDeviceDevice for use in a channel access test IOC.
- enum: Annotated[SignalRW[EpicsTestEnum], PvSuffix('enum')]#
None
- enum2: Annotated[SignalRW[EpicsTestEnum], PvSuffix('enum2')]#
None
- subset_enum: Annotated[SignalRW[EpicsTestSubsetEnum], PvSuffix('subset_enum')]#
None
- superset_enum: Annotated[SignalRW[EpicsTestSupersetEnum], PvSuffix('subset_enum')]#
None
- go: Annotated[TriggerableCommand, PvSuffix('go')]#
None
- class ophyd_async.epics.testing.EpicsTestEnum[source]#
Bases:
ophyd_async.core.StrictEnumFor testing strict enum values in test IOCs.
- A#
‘Aaa’
- B#
‘Bbb’
- C#
‘Ccc’
- class ophyd_async.epics.testing.EpicsTestSubsetEnum[source]#
Bases:
ophyd_async.core.SubsetEnumFor testing subset enum values in test IOCs.
The backing PV (mbbo with choices Aaa/Bbb/Ccc) has an extra choice (“Ccc”) beyond what this enum declares.
- A#
‘Aaa’
- B#
‘Bbb’
- class ophyd_async.epics.testing.EpicsTestSupersetEnum[source]#
Bases:
ophyd_async.core.SupersetEnumFor testing superset enum values in test IOCs.
Deliberately points at the same backing PV as
EpicsTestSubsetEnum(mbbo with choices Aaa/Bbb/Ccc): this enum declares a choice (“Ddd”) that does not exist in the backend, which is exactly what a superset enum allows.- A#
‘Aaa’
- B#
‘Bbb’
- C#
‘Ccc’
- D#
‘Ddd’
- class ophyd_async.epics.testing.EpicsTestPvaDevice(prefix: str, with_pvi: bool = False, name: str = '')[source]#
Bases:
ophyd_async.epics.testing._devices.EpicsTestCaDeviceDevice for use in a pv access test IOC.
- table: Annotated[SignalRW[EpicsTestTable], PvSuffix('table')]#
None
- class ophyd_async.epics.testing.EpicsTestPviDevice(prefix: str, with_pvi: bool = False, name: str = '')[source]#
Bases:
ophyd_async.epics.core.EpicsDeviceDevice for use in a generic PVI test IOC, independent of PandA/FastCS.
Construct with
with_pvi=True: signals here are plain type annotations with noPvSuffix(discovered and filled in from the IOC’s PVI structure byPviDeviceConnectorat connect time), exceptoverridden_float, which deliberately also carries aPvSuffixpointing at a different record — this checks that the PVI-supplied PV wins once connected.Most fields (
mbb_direct_bit_r,a_float,table,ntndarray,go) reuse the same attribute names, PVI entries and backing records asEpicsTestCaDevice/EpicsTestPvaDevice, rather than declaring new synthetic ones. Onlywo_float(no write-only field exists on those devices to reuse) andoverridden_float(inherently synthetic by design, see above) are bespoke to this device.- table: SignalRW[EpicsTestTable]#
None
- go: TriggerableCommand#
None
- class ophyd_async.epics.testing.EpicsTestPviLeafDevice(name: str = '', connector: DeviceConnector | None = None)[source]#
Bases:
ophyd_async.core.DeviceLeaf sub-device for
childanddevice_vectoron EpicsTestPviNestedDevice.- signal_x: TriggerableCommand#
None
- class ophyd_async.epics.testing.EpicsTestPviNestedDevice(prefix: str, with_pvi: bool = False, name: str = '')[source]#
Bases:
ophyd_async.epics.core.EpicsDeviceReal-IOC-backed structural PVI test device.
Exercises PviDeviceConnector’s handling of nested sub-devices, DeviceVector of devices, DeviceVector of signals, DeviceVector of commands, and an Optional signal absent from the served tree – the structural mechanics that tests/unit_tests/epics/pvi/test_pvi.py’s Block1-Block5 classes exercise only against a mocked PVI tree. Construct with
with_pvi=True.The served PVI tree also includes an
extra_devicesDeviceVector that is deliberately not annotated here, to prove that PviDeviceConnector fills in undeclared DeviceVectors of devices dynamically.Legacy list-based vector encoding (
PviTree._handle_legacy_entry) is deliberately not covered here: it’s exclusively produced by pandablocks-ioc’s own hand-rolled PVA server, not something a QSRV2/db-file-based IOC can construct declaratively, so it stays covered by the existing mock-only unit test instead.- signal_x: TriggerableCommand#
None
- child: EpicsTestPviLeafDevice#
None
- device_vector: DeviceVector[EpicsTestPviLeafDevice]#
None
- signal_vector: DeviceVector[SignalRW[float]]#
None
- command_vector: DeviceVector[TriggerableCommand]#
None
- class ophyd_async.epics.testing.EpicsTestPviNestedDeviceMissingChild(prefix: str, with_pvi: bool = False, name: str = '')[source]#
Bases:
ophyd_async.epics.core.EpicsDeviceConnects to the same served PVI tree as EpicsTestPviNestedDevice.
Declares an extra required (non-Optional) sub-device the server doesn’t actually provide – demonstrates that connecting raises a clear RuntimeError when a required field can’t be resolved via PVI (the mirror image of
optional_signalabove, which is allowed to be absent).- missing_child: EpicsTestPviLeafDevice#
None
- class ophyd_async.epics.testing.EpicsTestTable(**kwargs)[source]#
Bases:
ophyd_async.core.TableAn abstraction of a Table where each field is a column.
For example:
>>> from ophyd_async.core import Table, Array1D >>> import numpy as np >>> from collections.abc import Sequence >>> class MyTable(Table): ... a: Array1D[np.int8] ... b: Sequence[str] ... >>> t = MyTable(a=[1, 2], b=["x", "y"]) >>> len(t) # the length is the number of rows 2 >>> t2 = t + t # adding tables together concatenates them >>> t2.a array([1, 2, 1, 2], dtype=int8) >>> t2.b ['x', 'y', 'x', 'y'] >>> t2[1] # slice a row array([(2, b'y')], dtype=[('a', 'i1'), ('b', 'S40')])
- a_enum: Sequence[EpicsTestEnum]#
None
- ophyd_async.epics.testing.generate_random_pv_prefix() str[source]#
For generating random PV names in test devices.
- ophyd_async.epics.testing.start_ioc(script: Path, *args: str) ManagedSubprocess[source]#
Start an EPICS IOC subprocess by running
scriptwithargs.Mirrors
ophyd_async.tango.testing.start_tango_device_servers’s shape and subprocess handling: rather than building the IOC’s full argv inline, this always launches a real, independently-runnable file - the exact command a human would type by hand, so there’s no separate “does this even work standalone” code path to keep correct.- Parameters:
script – The script implementing the IOC topology to host, e.g.
ophyd_async.epics.demo.IOCorophyd_async.epics.testing.IOC.args – Positional args for that script’s
__main__, e.g.prefixorprefix, str(num_channels)- whatever it expects. Overriding which executable actually hosts the IOC (defaulting to the bundledepicscorelibs.ioc) is a command-line-only concern of that script itself - pass--softioc ...as one ofargsif you need that (see the script’s own--help); this function doesn’t thread it through.