Skip to content

Commit 5658972

Browse files
committed
Update on_update to be blocking by default
Improve pva test
1 parent a2a7808 commit 5658972

File tree

3 files changed

+65
-66
lines changed

3 files changed

+65
-66
lines changed

src/fastcs/transports/epics/ca/ioc.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,11 @@ def _make_record(
193193
)
194194
attribute_record_metadata = record_metadata_from_attribute(attribute)
195195

196-
update = {"always_update": True, "on_update": on_update} if on_update else {}
196+
update = (
197+
{"on_update": on_update, "always_update": True, "blocking": True}
198+
if on_update
199+
else {}
200+
)
197201

198202
record = builder_callable(
199203
pv, **update, **datatype_record_metadata, **attribute_record_metadata

tests/transports/epics/ca/test_softioc.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ def test_make_output_record(
187187

188188
kwargs.update(record_metadata_from_datatype(attribute.datatype, out_record=True))
189189
kwargs.update(record_metadata_from_attribute(attribute))
190-
kwargs.update({"always_update": True, "on_update": update})
190+
kwargs.update({"always_update": True, "on_update": update, "blocking": True})
191191

192192
getattr(builder, record_type).assert_called_once_with(
193193
pv,
@@ -265,6 +265,7 @@ def test_ioc(mocker: MockerFixture, epics_controller_api: ControllerAPI):
265265
builder.aOut.assert_any_call(
266266
f"{DEVICE}:ReadWriteFloat",
267267
always_update=True,
268+
blocking=True,
268269
on_update=mocker.ANY,
269270
**record_metadata_from_attribute(
270271
epics_controller_api.attributes["read_write_float"]
@@ -286,6 +287,7 @@ def test_ioc(mocker: MockerFixture, epics_controller_api: ControllerAPI):
286287
builder.longOut.assert_called_with(
287288
f"{DEVICE}:ReadWriteInt",
288289
always_update=True,
290+
blocking=True,
289291
on_update=mocker.ANY,
290292
**record_metadata_from_attribute(
291293
epics_controller_api.attributes["read_write_int"]
@@ -304,6 +306,7 @@ def test_ioc(mocker: MockerFixture, epics_controller_api: ControllerAPI):
304306
builder.mbbOut.assert_called_once_with(
305307
f"{DEVICE}:Enum",
306308
always_update=True,
309+
blocking=True,
307310
on_update=mocker.ANY,
308311
**record_metadata_from_attribute(epics_controller_api.attributes["enum"]),
309312
**record_metadata_from_datatype(
@@ -313,6 +316,7 @@ def test_ioc(mocker: MockerFixture, epics_controller_api: ControllerAPI):
313316
builder.boolOut.assert_called_once_with(
314317
f"{DEVICE}:WriteBool",
315318
always_update=True,
319+
blocking=True,
316320
on_update=mocker.ANY,
317321
**record_metadata_from_attribute(epics_controller_api.attributes["write_bool"]),
318322
**record_metadata_from_datatype(
@@ -460,6 +464,7 @@ def test_long_pv_names_discarded(mocker: MockerFixture):
460464
builder.longOut.assert_called_once_with(
461465
f"{DEVICE}:{short_pv_name}",
462466
always_update=True,
467+
blocking=True,
463468
on_update=mocker.ANY,
464469
**record_metadata_from_datatype(
465470
long_name_controller_api.attributes["attr_rw_short_name"].datatype,
@@ -500,6 +505,7 @@ def test_long_pv_names_discarded(mocker: MockerFixture):
500505
builder.longOut.assert_called_once_with(
501506
f"{DEVICE}:{long_rw_pv_name}",
502507
always_update=True,
508+
blocking=True,
503509
on_update=mocker.ANY,
504510
)
505511
with pytest.raises(AssertionError):

tests/transports/epics/pva/test_p4p.py

Lines changed: 53 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,8 @@ class SomeController(Controller):
394394
}
395395

396396

397-
def test_more_exotic_datatypes():
397+
@pytest.mark.asyncio
398+
async def test_more_exotic_datatypes():
398399
table_columns: list[tuple[str, DTypeLike]] = [
399400
("A", "i"),
400401
("B", "i"),
@@ -439,7 +440,6 @@ class SomeController(Controller):
439440
client_put_enum_value = "C"
440441

441442
async def _wait_and_set_attrs():
442-
await asyncio.sleep(0.1)
443443
# This demonstrates an update from hardware,
444444
# resulting in only a change in the read back.
445445
await asyncio.gather(
@@ -449,7 +449,6 @@ async def _wait_and_set_attrs():
449449
)
450450

451451
async def _wait_and_put_pvs():
452-
await asyncio.sleep(0.3)
453452
ctxt = Context("pva")
454453
# This demonstrates a client put,
455454
# resulting in a change in the demand and read back.
@@ -471,72 +470,62 @@ async def _wait_and_put_pvs():
471470
enum_values.append,
472471
)
473472

474-
serve = asyncio.ensure_future(fastcs.serve(interactive=False))
475-
wait_and_set_attrs = asyncio.ensure_future(_wait_and_set_attrs())
476-
wait_and_put_pvs = asyncio.ensure_future(_wait_and_put_pvs())
477-
try:
478-
asyncio.get_event_loop().run_until_complete(
479-
asyncio.wait_for(
480-
asyncio.gather(serve, wait_and_set_attrs, wait_and_put_pvs),
481-
timeout=0.6,
482-
)
483-
)
484-
except TimeoutError:
485-
...
486-
finally:
487-
waveform_monitor.close()
488-
table_monitor.close()
489-
enum_monitor.close()
490-
serve.cancel()
491-
wait_and_set_attrs.cancel()
492-
wait_and_put_pvs.cancel()
473+
serve = asyncio.create_task(fastcs.serve(interactive=False))
474+
await asyncio.sleep(0.1) # Wait for task to start
493475

494-
expected_waveform_gets = [
495-
initial_waveform_value,
496-
server_set_waveform_value,
497-
client_put_waveform_value,
498-
]
476+
await _wait_and_set_attrs()
477+
await _wait_and_put_pvs()
478+
await asyncio.sleep(0.1) # Wait for monitors to return
499479

500-
for expected_waveform, actual_waveform in zip(
501-
expected_waveform_gets, waveform_values, strict=True
502-
):
503-
np.testing.assert_array_equal(
504-
expected_waveform, actual_waveform.todict()["value"].reshape(10, 10)
505-
)
480+
waveform_monitor.close()
481+
table_monitor.close()
482+
enum_monitor.close()
483+
serve.cancel()
506484

507-
expected_table_gets = [
508-
NTTable(columns=table_columns).wrap(initial_table_value),
509-
NTTable(columns=table_columns).wrap(server_set_table_value),
510-
client_put_table_value,
511-
]
512-
for expected_table, actual_table in zip(
513-
expected_table_gets, table_values, strict=True
514-
):
515-
expected_table = expected_table.todict()["value"]
516-
actual_table = actual_table.todict()["value"]
517-
for expected_column, actual_column in zip(
518-
expected_table.values(), actual_table.values(), strict=True
519-
):
520-
if isinstance(expected_column, np.ndarray):
521-
np.testing.assert_array_equal(expected_column, actual_column)
522-
else:
523-
assert expected_column == actual_column and actual_column is None
524-
525-
expected_enum_gets = [
526-
initial_enum_value,
527-
server_set_enum_value,
528-
AnEnum.C,
529-
]
485+
expected_waveform_gets = [
486+
initial_waveform_value,
487+
server_set_waveform_value,
488+
client_put_waveform_value,
489+
]
490+
491+
for expected_waveform, actual_waveform in zip(
492+
expected_waveform_gets, waveform_values, strict=True
493+
):
494+
np.testing.assert_array_equal(
495+
expected_waveform, actual_waveform.todict()["value"].reshape(10, 10)
496+
)
530497

531-
for expected_enum, actual_enum in zip(
532-
expected_enum_gets, enum_values, strict=True
498+
expected_table_gets = [
499+
NTTable(columns=table_columns).wrap(initial_table_value),
500+
NTTable(columns=table_columns).wrap(server_set_table_value),
501+
client_put_table_value,
502+
]
503+
for expected_table, actual_table in zip(
504+
expected_table_gets, table_values, strict=True
505+
):
506+
expected_table = expected_table.todict()["value"]
507+
actual_table = actual_table.todict()["value"]
508+
for expected_column, actual_column in zip(
509+
expected_table.values(), actual_table.values(), strict=True
533510
):
534-
assert (
535-
expected_enum
536-
== controller.some_enum.datatype.members[ # type: ignore
537-
actual_enum.todict()["value"]["index"]
538-
]
539-
)
511+
if isinstance(expected_column, np.ndarray):
512+
np.testing.assert_array_equal(expected_column, actual_column)
513+
else:
514+
assert expected_column == actual_column and actual_column is None
515+
516+
expected_enum_gets = [
517+
initial_enum_value,
518+
server_set_enum_value,
519+
AnEnum.C,
520+
]
521+
522+
for expected_enum, actual_enum in zip(expected_enum_gets, enum_values, strict=True):
523+
assert (
524+
expected_enum
525+
== controller.some_enum.datatype.members[ # type: ignore
526+
actual_enum.todict()["value"]["index"]
527+
]
528+
)
540529

541530

542531
@pytest.mark.timeout(4)

0 commit comments

Comments
 (0)