From dfcded78b0e4153eccf398e3f5ce3183f4a98636 Mon Sep 17 00:00:00 2001 From: Nicholas Felt Date: Tue, 26 Mar 2024 11:07:51 -0700 Subject: [PATCH 1/2] Misc. workflow updates (#171) * ci: Update the workflow for updating python and pre-commit dependencies to check the github.actor value instead of the pull request user to prevent running the check more than once per pull request. --- .github/workflows/update-python-and-pre-commit-dependencies.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-python-and-pre-commit-dependencies.yml b/.github/workflows/update-python-and-pre-commit-dependencies.yml index af3d06786..a00a2b4d5 100644 --- a/.github/workflows/update-python-and-pre-commit-dependencies.yml +++ b/.github/workflows/update-python-and-pre-commit-dependencies.yml @@ -7,7 +7,7 @@ jobs: update-python-and-pre-commit-deps: name: Update python linters and pre-commit dependencies runs-on: ubuntu-latest - if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' && contains(github.head_ref, '/pip/') }} + if: ${{ github.actor == 'dependabot[bot]' && contains(github.head_ref, '/pip/') }} permissions: contents: write steps: From 2dd487688e372df0583533ec4d451bf7bc599681 Mon Sep 17 00:00:00 2001 From: Luke <111022789+ldantek@users.noreply.github.com> Date: Tue, 26 Mar 2024 14:17:26 -0700 Subject: [PATCH 2/2] Handle Visa IO Error on first connection (#172) * fix: exception handling for clearing Visa IO buffer on first connection * fix: unit testing device_manager.py warnings on connection --- src/tm_devices/device_manager.py | 32 +++++++++++++++++++----------- tests/test_device_manager.py | 34 +++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/tm_devices/device_manager.py b/src/tm_devices/device_manager.py index 0bfa212dc..56cca26c7 100644 --- a/src/tm_devices/device_manager.py +++ b/src/tm_devices/device_manager.py @@ -1072,20 +1072,30 @@ def __clear_visa_output_buffer_and_get_idn(visa_resource: MessageBasedResource) Raises: SystemError: Indicates that the buffer was unable to be cleared. """ - if 16 & visa_resource.read_stb(): - # 16 is the MAV bit (Message Available) from the Status Byte register - # MAV flag is only one bit and turns off after a single response is successfully read, - # even if there's more in the buffer + # use a try-except block to avoid any errors caused by Visa instruments that may not + # respond correctly to the read_stb or clear functions. + try: + if 16 & visa_resource.read_stb(): + # 16 is the MAV bit (Message Available) from the Status Byte register + # MAV flag is only one bit and turns off after a single response is + # successfully read, even if there is more in the buffer. + warnings.warn( + f"\nThe device `{visa_resource.resource_info.resource_name}` had data " + "sitting in the VISA Output Buffer on first connection. " + "\nDetected data in the buffer via the Status Byte register. " + "\nThe device_clear() will be called so VISA I/O buffers get flushed.", + stacklevel=1, + ) + # always flush the VISA I/O Buffers on the device to clean up any stale data. + # (note: the Events are kept in different buffers, so *ESR? is not impacted) + visa_resource.clear() + except visa.VisaIOError as e: warnings.warn( - f"\nThe device `{visa_resource.resource_info.resource_name}` had data " - "sitting in the VISA Output Buffer on first connection. " - "\nDetected data in the buffer via the Status Byte register. " - "\nThe device_clear() will be called so VISA I/O buffers get flushed.", + f"A VISA IO error occurred when attempting to read the status byte or clear the " + f"output buffer of the resource `{visa_resource.resource_info.resource_name}`.\n" + f"Error: {e}", stacklevel=1, ) - # always flush the VISA I/O Buffers on the device to clean up any stale data. - # (note: the Events are kept in different buffers, so *ESR? is not impacted) - visa_resource.clear() visa_resource.write("*IDN?") idn_response = "" error_msg = None diff --git a/tests/test_device_manager.py b/tests/test_device_manager.py index 4cc70936f..1d832e867 100644 --- a/tests/test_device_manager.py +++ b/tests/test_device_manager.py @@ -459,12 +459,44 @@ def test_failed_cleanup(self, device_manager: DeviceManager) -> None: device_manager.cleanup_all_devices() device_manager.remove_device(alias="bad-afg") + def test_warnings(self, device_manager: DeviceManager) -> None: + """Verify some of the warning printouts that the DeviceManager can log. + + Args: + device_manager: The DeviceManager object. + """ + # Remove all previous devices + device_manager.remove_all_devices() + # Test the warning logged with bad read_stb() call + with mock.patch( + "pyvisa.resources.messagebased.MessageBasedResource.read_stb", + mock.MagicMock(side_effect=visa.VisaIOError(pyvisa.constants.VI_ERROR_INV_SETUP)), + ), pytest.warns( + UserWarning, + match="A VISA IO error occurred when attempting to read the status byte or " + "clear the output buffer of the resource", + ): + device_manager.add_afg("afg3kc-hostname", alias="warning_bad_read_stb") + device_manager.remove_device(alias="warning_bad_read_stb") + + # Test the warning logged with message available (MAV) bit set + # patched the stb to return 16 (message available) + with mock.patch( + "pyvisa.resources.messagebased.MessageBasedResource.read_stb", + mock.MagicMock(return_value=16), + ), pytest.warns( + UserWarning, match="had data sitting in the VISA Output Buffer on first connection." + ): + device_manager.add_afg("afg3kc-hostname", alias="warning_mav") + device_manager.remove_device(alias="warning_mav") + def test_exceptions(self, device_manager: DeviceManager) -> None: """Verify some of the exceptions that the DeviceManager can raise. Args: device_manager: The DeviceManager object. """ + # Remove all previous devices device_manager.remove_all_devices() # Test getting a device type that was not the specified type @@ -502,7 +534,7 @@ def test_exceptions(self, device_manager: DeviceManager) -> None: mock.MagicMock(return_value=5), ), mock.patch( "pyvisa.resources.messagebased.MessageBasedResource.read", - mock.MagicMock(side_effect=visa.VisaIOError(pyvisa.constants.StatusCode.error_timeout)), + mock.MagicMock(side_effect=visa.VisaIOError(pyvisa.constants.VI_ERROR_TMO)), ): # patched the stb to return 16 (message available) with pytest.warns(UserWarning), pytest.raises(SystemError) as error: