Repository navigation
Conversation
|
Question for reviewers. In the case where we pass just a For example, if I want to use a specific mock for Motor, but maybe default everything else I can use the {Device: True, Motor: VelocityRespectingMotorMock}should passing just # extract `Motor` from VelocityRespectingMotorMock(DeviceMock[Motor])
{Motor: VelocityRespectingMotorMock}with non-supported devices connecting for real? For now I've made it work like the former. If the latter behavior is desired one can always fall back to the |
coretl
left a comment
There was a problem hiding this comment.
I've put #1446 up which fixes this in a more general way, please could you take a look at that? If it covers your use case I'd suggest we close this one in favour of it.
Question for reviewers. In the case where we pass just a type[DeviceMock], we can use what it's generic on to figure out whether a device can or cannot be mocked with it. In the event that there is a device that doesn't support it, should we fall back to a default mock, or connect for real?
I suggest we fall back to the default mock. In #1446 mock can either be a bool (like at the moment) or mapping of type[Device] to type[DeviceMock], so your example becomes:
with init_devices(mock={Motor: VeloAndAcclRespectingMotorMock}):
...For each device, the first key where isinstance(device, key) gives the DeviceMock to instantiate and pass to connect(mock=. Any device with no match gets its default mock and the same mapping/bool is also propogated to child connects so you can reach children of the top level devices too.
You can't mix mock and real connects though in init_devices, is that a requirement?
It would be nice if we could. I'd basically like to have a way to quickly decide on a subset of devices to mock when working at a beamline (for example, I want to mock all shutters, and all but one motor) |
@jwlodek I like the idea of mixing real and mocked Devices in the same mapping, but there's 2 ways we can do it. In both, mapping values are A: any mix. with init_devices(mock={Motor: True}):
thing = ThingWithMotors("BL:THING:") # thing real, its Motors mocked
with init_devices(mock={ThingWithMotors: True, Motor: False}):
thing = ThingWithMotors("BL:THING:") # thing mocked, its Motors real
await thing.connect(mock={Motor: True}) # also works on one DeviceB: when you reach a real connect, everything under is real. Only with init_devices(mock={Motor: False}):
thing = ThingWithMotors("BL:THING:") # thing mocked, its Motors realSo A can also mock inside a real tree, at the cost of a third type for Which do you need for your use case? |
|
I think we'd prefer A - I want to be able to make child motors use Mock but not other children for example. Would it be possible to have this behavior, but specifically exclude signals? I.e. mock device with direct child signals makes the signals mocked? I don't really see a case where I'd want a real device and mocked signals, or a mocked device with real signals. |
|
Ok, I think A with excluded Signals is sensible. I propose:
So: # real, except motors (and everything under them) are mocked
with init_devices(mock={Motor: True}):
...
# mocked, except motors, which are real all the way down, signals included
with init_devices(mock={Device: True, Motor: False}):
...
# real, except motors, which use a specific mock
with init_devices(mock={Motor: VelocityRespectingMotorMock}):
...
# the whole detector mocked, plugins included
with init_devices(mock={AreaDetector: True}):
...So to answer your earlier question, Does that work for you? |
|
Yes, the above would be great. |
|
Ok, I'll make these changes in #1446 |
Updates
init_devicesto allow for more granular selection of device mocks, as discussed in #1344.Now, one can pass in a
type[DeviceMock], or adict[type[Device], bool | type[DeviceMock]]instead of just a bool.