From 289897eecae1a3abe00e91b8f79e443e6bc4fea7 Mon Sep 17 00:00:00 2001 From: AlexWells Date: Tue, 30 May 2023 10:20:48 +0100 Subject: [PATCH] Improve string representation of RecordWrapper The returned string is the full DeviceName:RecordName. Previously the string representation would be lost when builder.LoadDatabase() is called, as the __builder instance is removed and so __str__ returns None. The __device is not removed at any point, and so can always be safely used to fetch the full name. --- CHANGELOG.rst | 4 +++ softioc/pythonSoftIoc.py | 3 +-- tests/test_records.py | 58 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 34d0bc3c..7afd2070 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,10 @@ Versioning `_. Unreleased_ ----------- +Changed: + +- `Improve string representation of RecordWrapper instances <../../pull/130>` + 4.3.0_ - 2023-04-04 ------------------- diff --git a/softioc/pythonSoftIoc.py b/softioc/pythonSoftIoc.py index 0aa36e05..048b7bf8 100644 --- a/softioc/pythonSoftIoc.py +++ b/softioc/pythonSoftIoc.py @@ -80,8 +80,7 @@ def __call__(self, *specifiers): return self.__builder(*specifiers) def __str__(self): - return str(self.__builder) - + return self.__device._name class PythonDevice(object): diff --git a/tests/test_records.py b/tests/test_records.py index 8e347307..64d23cb6 100644 --- a/tests/test_records.py +++ b/tests/test_records.py @@ -289,6 +289,64 @@ def test_clear_records_too_late(): pytest.fail("Process did not terminate") +def str_ioc_test_func(device_name, conn): + builder.SetDeviceName(device_name) + + record_name = "MyAI" + + full_name = device_name + ":" + record_name + + ai = builder.aIn(record_name) + + + log("CHILD: Created ai record: ", ai.__str__()) + + assert ( + ai.__str__() == full_name + ), f"Record name {ai.__str__()} before LoadDatabase did not match " \ + f"expected string {full_name}" + + builder.LoadDatabase() + + assert ( + ai.__str__() == full_name + ), f"Record name {ai.__str__()} after LoadDatabase did not match " \ + f"expected string {full_name}" + + dispatcher = asyncio_dispatcher.AsyncioDispatcher() + softioc.iocInit(dispatcher) + + assert ( + ai.__str__() == full_name + ), f"Record name {ai.__str__()} after iocInit did not match expected " \ + f"string {full_name}" + + conn.send("R") # "Ready" + log("CHILD: Sent R over Connection to Parent") + + + +def test_record_wrapper_str(): + """Test that the __str__ method on the RecordWrapper behaves as expected, + both before and after loading the record database""" + + ctx = get_multiprocessing_context() + parent_conn, child_conn = ctx.Pipe() + + device_name = create_random_prefix() + + ioc_process = ctx.Process( + target=str_ioc_test_func, + args=(device_name, child_conn), + ) + + ioc_process.start() + + + # Wait for message that IOC has started + # If we never receive R it probably means an assert failed + select_and_recv(parent_conn, "R") + def validate_fixture_names(params): """Provide nice names for the out_records fixture in TestValidate class"""