Closed stan-dot closed 1 week ago
@coretl I narrowed down where the knowledge gap is https://github.com/bluesky/ophyd-async/actions/runs/9397709655/job/25881480270?pr=368
the error string does not appear to be present anywhere but in the test. not sure where is it coming from .
async def test_signal_can_be_given_backend_on_connect():
sim_signal = SignalR()
backend = MockSignalBackend(int)
assert sim_signal._backend is None
await sim_signal.connect(mock=False, backend=backend)
assert await sim_signal.get_value() == 0
what is the goal of this test? right now it clashes with the caching implementation. we can either stop supporting this use case and drop the test (easy) or somehow change it OR the implementation of the feature (hard)
that test was added 6 months ago by Rose
that test was added 6 months ago by Rose
Looks like it was added quite recently to support supplying backend on connect:
We have to keep the test.
I suggest we always force a reconnect if backend is supplied, as this will only be used if the Signal is part of a Device, in which case the caching will happen there.
@evalott100 do you agree?
support supplying backend on connect:
I think I am missing some context. what does this do, when it is used and why do we support it?
support supplying backend on connect:
I think I am missing some context. what does this do, when it is used and why do we support it?
This is used when we know that a Signal
will exist, like in https://github.com/bluesky/ophyd-async/blob/cbbb2950ed4c4b0bf4ca4c03729562b842b44b03/src/ophyd_async/panda/_common_blocks.py#L31-L37 but we don't know what PV it will connect to until connect()
. What we will do is create the given SignalRW
with backend=None
, then on Device.connect()
we actually create the backend and pass it to Signal.connect()
.
huh, I'd never have guessed that
should we have a flag for a case like that? it looks quite unusual. I'm thinking a flag next to 'force_reconnect' and 'mock'. then we can do logic flow around that.
should we have a flag for a case like that? it looks quite unusual. I'm thinking a flag next to 'force_reconnect' and 'mock'. then we can do logic flow around that.
The flag is a supplied backend
. If backend is not None
we should force a reconnect, otherwise do the existing behaviour
this is the error I get, but it looks like expected:
File "/workspaces/ophyd-async/tests/core/test_signal.py", line 80, in test_signal_connect_fails_if_different_backend_but_same_by_value
assert str(exc.value) == "Backend at connection different from initialised one."
AssertionError: assert 'Cannot make a MockSignalBackend for a MockSignalBackends' == 'Backend at connection different from initialised one.'
- Backend at connection different from initialised one.
+ Cannot make a MockSignalBackend for a MockSignalBackends
these two are too similar, I'd delete the second one or change the expected message. because the value is different.
what is the goal of this test? right now it clashes with the caching implementation. we can either stop supporting this use case and drop the test (easy) or somehow change it OR the implementation of the feature (hard)
It tests that you can choose to pass the signal backend in at runtime - why would this be hard to support with your changes?
these two are too similar, I'd delete the second one or change the expected message. because the value is different.
I don't mind putting them in the same test but it's still nicer to check that equality by value and by ref
@evalott100 now the latest version has both tests, just the expected string is different for the second test
@evalott100 now the latest version has both tests, just the expected string is different for the second test
That makes sense, you got rid of the validation on the backends in the new connect
logic
ok, trying to make this right now
and now we're back to the test string error:
and now we're back to the test string error
This is because you're trying to mock a MockSignalBackend
...
This is why we only mock if initial_backend
isn't a MockSignalBackend
(in which case it's already mocked).
https://github.com/bluesky/ophyd-async/pull/368#discussion_r1638133666
This is because you're trying to mock a MockSignalBackend...
I know that it is what happens in the test. I am not sure what is the expected behavior, as I do not fully understand the use case (https://github.com/bluesky/ophyd-async/pull/368#issuecomment-2161054867)
I know that the test or code should be changed
I know that it is what happens in the test. I am not sure what is the expected behavior, as I do not fully understand the use case (#368 (comment))
In those tests -
This should be what is failing
But in your change you're not checking to see if the backend passed in on connect is the same as the one passed into __init__
.
is it all right now @coretl @evalott100 ?
For some reason github won't let me respond to your single comments.
https://github.com/bluesky/ophyd-async/pull/368#discussion_r1639598291
ok I still find this bizarre. What if there is no backend passed on init? then it's None.
We now allow for no backend passed in on init, then one will need to be provided on connect:
signal = SignalRW()
signal.connect(backend=any_backend_will_do) # passes
# or
signal.connect(backend=any_backend_will_do, mock=True) # passes
We don't allow for replacement of a signal passed in on init:
backend = PvaSignalBackend(int)
signal = SignalRW(backend)
signal.connect(backend=backend) # passes since the backend is the same
signal.connect(backend=PvaSignalBackend(int) # fails since the backend isn't the same by ref
# fails as to be accurate to production
signal.connect(backend=PvaSignalBackend(int), mock=True)
https://github.com/bluesky/ophyd-async/pull/368#discussion_r1639616142
I thought that the mode is redundant.
I believe the comment
# If mock is false it will be handled like a normal signal, otherwise it will
# initalize a new backend from the one in the line above
was from before we added the second condition to
with which, we don't replace the original MockSignalBackend
.
I believe the test is still useful to show you can use a MockSignalBackend
for a backend and have mock=True
, whether you need it or not.
I could be convinced that we shouldn't allow the mock
keyword if the backend is MockSignalBackend
- since I've seen PRs assuming that mock=True
is needed when the backend has been manually set as MockSignalBackend
mock_signal = SignalRW(MockSignalBackend(int))
non_mock_signal = SignalRW(PvaSignalBackend(int))
non_mock_signal.connect(mock=True) # passes
mock_signal.connect() # passes
mock_signal_connect(mock=True)
# raises ValueError("`mock=True` unnecessary, backend is already `MockSignalBackend`")
I think this is probably not required though? - We don't need to police behaviour in tests that much.
I suggest we always force a reconnect if backend is supplied, as this will only be used if the Signal is part of a Device, in which case the caching will happen there.
Missed this comment, but I agree
https://github.com/bluesky/ophyd-async/pull/368#discussion_r1646161096
what is the type of the
self._previous_connect_was_mock
boolean or an object?
Optional[boolean]
- it should obviously be None
if the signal hasn't been connected yet.
You're running backend.connect
as a task whether backend
is a MockSignalBackend
or not.
@evalott100 that was passing finally, but I added some more tests and there have issues patching the debug method. I think I have a better grasp of what is going on here, now I'd just like to make those 2 tests pass
re: testing the signal. how should I instantiate the object? with
epics_signal_rw
or the constructor?@coretl