From 84ecd27e9131425b2eba1dce606279e478ade7dd Mon Sep 17 00:00:00 2001 From: Avia Avraham <145359432+AviaAv@users.noreply.github.com> Date: Wed, 15 Jan 2025 17:29:24 +0200 Subject: [PATCH 1/7] enable dds devices on run-unit-tests --- .../live/tools/test-enumerate-devices.py | 4 ++- unit-tests/py/rspy/devices.py | 36 +++++++++++++------ unit-tests/run-unit-tests.py | 4 +-- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/unit-tests/live/tools/test-enumerate-devices.py b/unit-tests/live/tools/test-enumerate-devices.py index 6636b3a77e..526bc954fa 100644 --- a/unit-tests/live/tools/test-enumerate-devices.py +++ b/unit-tests/live/tools/test-enumerate-devices.py @@ -14,9 +14,11 @@ rs_enumerate_devices = repo.find_built_exe( 'tools/enumerate-devices', 'rs-enumerate-devices' ) test.check(rs_enumerate_devices) if rs_enumerate_devices: + dev, ctx = test.find_first_device_or_exit() + camera_name = dev.get_info(rs.camera_info.name) import subprocess run_time_stopwatch = Stopwatch() - run_time_threshold = 2 + run_time_threshold = 2 if 'D555' not in camera_name else 5 p = subprocess.run( [rs_enumerate_devices], stdout=None, stderr=subprocess.STDOUT, diff --git a/unit-tests/py/rspy/devices.py b/unit-tests/py/rspy/devices.py index 7732a0b0c0..574aacb33a 100644 --- a/unit-tests/py/rspy/devices.py +++ b/unit-tests/py/rspy/devices.py @@ -35,7 +35,7 @@ def usage(): pyrs_dir = repo.find_pyrs_dir() sys.path.insert( 1, pyrs_dir ) -MAX_ENUMERATION_TIME = 10 # [sec] +MAX_ENUMERATION_TIME = 15 # [sec] # We need both pyrealsense2 and hub. We can work without hub, but # without pyrealsense2 no devices at all will be returned. @@ -43,7 +43,7 @@ def usage(): try: import pyrealsense2 as rs log.d( rs ) - hub = device_hub.create() + hub = device_hub.create() # if there's no hub, this will hold None sys.path = sys.path[:-1] # remove what we added except ModuleNotFoundError: log.w( 'No pyrealsense2 library is available! Running as if no cameras available...' ) @@ -73,8 +73,13 @@ def __init__( self, sn, dev ): self._physical_port = dev.supports( rs.camera_info.physical_port ) and dev.get_info( rs.camera_info.physical_port ) or None self._usb_location = None + self._is_dds = False try: - self._usb_location = _get_usb_location(self._physical_port) + if self._physical_port.startswith('realsense/'): + self._is_dds = True + # not trying to _get_usb_location as dds devices don't have it + else: + self._usb_location = _get_usb_location(self._physical_port) except Exception as e: log.e('Failed to get usb location:', e) self._port = None @@ -118,7 +123,11 @@ def handle( self ): @property def enabled( self ): - return self._removed is False + return self._removed is False and self._dev is not None + + @property + def is_dds(self): + return self._is_dds def wait_until_all_ports_disabled( timeout = 5 ): @@ -267,6 +276,7 @@ def _device_change_callback( info ): global _device_by_sn for device in _device_by_sn.values(): if device.enabled and info.was_removed( device.handle ): + device._dev = None log.d( 'device removed:', device.serial_number ) device._removed = True for handle in info.get_new_devices(): @@ -274,6 +284,7 @@ def _device_change_callback( info ): log.d( 'device added:', sn, handle ) if sn in _device_by_sn: device = _device_by_sn[sn] + device._dev = None # in case we get handle between the next 2 lines, it might still be the old one device._removed = False device._dev = handle # Because it has a new handle! else: @@ -529,8 +540,7 @@ def enable_only( serial_numbers, recycle = False, timeout = MAX_ENUMERATION_TIME else: # hub.enable_ports( ports, disable_other_ports = True ) - # - _wait_for( serial_numbers, timeout = timeout ) + # # elif recycle: # @@ -539,6 +549,9 @@ def enable_only( serial_numbers, recycle = False, timeout = MAX_ENUMERATION_TIME else: log.d( 'no hub; ports left as-is' ) + # doesn't matter what it did, enable_only should wait for the devices to be available again + _wait_for(serial_numbers, timeout=timeout) + def enable_all(): """ @@ -618,16 +631,19 @@ def hw_reset( serial_numbers, timeout = MAX_ENUMERATION_TIME ): :param timeout: Maximum # of seconds to wait for the devices to come back online :return: True if all devices have come back online before timeout """ + # for usb and dds devices, we can wait until they're removed + removable_devs_sns = {sn for sn in serial_numbers if + _device_by_sn[sn].port is not None or _device_by_sn[sn].is_dds} - usb_serial_numbers = { sn for sn in serial_numbers if _device_by_sn[sn].port is not None } - + _wait_for(serial_numbers, timeout=timeout) # make sure devices are added before doing hw reset for sn in serial_numbers: dev = get( sn ).handle dev.hardware_reset() # - if usb_serial_numbers: - _wait_until_removed( usb_serial_numbers ) + if removable_devs_sns: + _wait_until_removed( removable_devs_sns ) + # if relevant, we need to handle case where we have both removable and non-removable devices else: # normally we will get here with a mipi device, # we want to allow some time for the device to reinitialize as it was not disconnected diff --git a/unit-tests/run-unit-tests.py b/unit-tests/run-unit-tests.py index 914932022a..69a46b3204 100644 --- a/unit-tests/run-unit-tests.py +++ b/unit-tests/run-unit-tests.py @@ -594,8 +594,8 @@ def test_wrapper( test, configuration=None, repetition=1, serial_numbers=None ): try: log.d( 'configuration:', configuration_str( configuration, repetition, sns=serial_numbers ) ) log.debug_indent() - if not no_reset: - devices.enable_only( serial_numbers, recycle=True ) + should_reset = not no_reset + devices.enable_only( serial_numbers, recycle=should_reset ) except RuntimeError as e: log.w( log.red + test.name + log.reset + ': ' + str( e ) ) else: From cf09f1123f9010406e11615a32ec225a0820e713 Mon Sep 17 00:00:00 2001 From: Avia Avraham <145359432+AviaAv@users.noreply.github.com> Date: Sun, 19 Jan 2025 16:09:16 +0200 Subject: [PATCH 2/7] use connection_type --- .../live/tools/test-enumerate-devices.py | 4 ++-- unit-tests/py/rspy/devices.py | 19 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/unit-tests/live/tools/test-enumerate-devices.py b/unit-tests/live/tools/test-enumerate-devices.py index 526bc954fa..6c3b4d938d 100644 --- a/unit-tests/live/tools/test-enumerate-devices.py +++ b/unit-tests/live/tools/test-enumerate-devices.py @@ -15,10 +15,10 @@ test.check(rs_enumerate_devices) if rs_enumerate_devices: dev, ctx = test.find_first_device_or_exit() - camera_name = dev.get_info(rs.camera_info.name) + is_dds = dev.get_info(rs.camera_info.connection_type) and dev.get_info(rs.camera_info.connection_type) == "DDS" import subprocess run_time_stopwatch = Stopwatch() - run_time_threshold = 2 if 'D555' not in camera_name else 5 + run_time_threshold = 2 if is_dds else 5 # currently, DDS devices take longer time to complete rs_enumerate_devices p = subprocess.run( [rs_enumerate_devices], stdout=None, stderr=subprocess.STDOUT, diff --git a/unit-tests/py/rspy/devices.py b/unit-tests/py/rspy/devices.py index 574aacb33a..76b1e3478b 100644 --- a/unit-tests/py/rspy/devices.py +++ b/unit-tests/py/rspy/devices.py @@ -73,13 +73,12 @@ def __init__( self, sn, dev ): self._physical_port = dev.supports( rs.camera_info.physical_port ) and dev.get_info( rs.camera_info.physical_port ) or None self._usb_location = None - self._is_dds = False try: - if self._physical_port.startswith('realsense/'): - self._is_dds = True - # not trying to _get_usb_location as dds devices don't have it - else: - self._usb_location = _get_usb_location(self._physical_port) + if dev.supports(rs.camera_info.connection_type): + self._connection_type = dev.get_info(rs.camera_info.connection_type) + self._is_dds = self._connection_type == "DDS" + if self._connection_type == "USB": + self._usb_location = _get_usb_location(self._physical_port) except Exception as e: log.e('Failed to get usb location:', e) self._port = None @@ -540,7 +539,8 @@ def enable_only( serial_numbers, recycle = False, timeout = MAX_ENUMERATION_TIME else: # hub.enable_ports( ports, disable_other_ports = True ) - # + # + _wait_for( serial_numbers, timeout = timeout ) # elif recycle: # @@ -548,9 +548,8 @@ def enable_only( serial_numbers, recycle = False, timeout = MAX_ENUMERATION_TIME # else: log.d( 'no hub; ports left as-is' ) - - # doesn't matter what it did, enable_only should wait for the devices to be available again - _wait_for(serial_numbers, timeout=timeout) + # even without reset, enable_only should wait for the devices to be available again + _wait_for(serial_numbers, timeout=timeout) def enable_all(): From fb7feab7be48e13077936cb3f868d62b043167c4 Mon Sep 17 00:00:00 2001 From: Avia Avraham <145359432+AviaAv@users.noreply.github.com> Date: Sun, 19 Jan 2025 16:18:22 +0200 Subject: [PATCH 3/7] get_info -> supports --- unit-tests/live/tools/test-enumerate-devices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unit-tests/live/tools/test-enumerate-devices.py b/unit-tests/live/tools/test-enumerate-devices.py index 6c3b4d938d..73668139f0 100644 --- a/unit-tests/live/tools/test-enumerate-devices.py +++ b/unit-tests/live/tools/test-enumerate-devices.py @@ -15,7 +15,7 @@ test.check(rs_enumerate_devices) if rs_enumerate_devices: dev, ctx = test.find_first_device_or_exit() - is_dds = dev.get_info(rs.camera_info.connection_type) and dev.get_info(rs.camera_info.connection_type) == "DDS" + is_dds = dev.supports(rs.camera_info.connection_type) and dev.get_info(rs.camera_info.connection_type) == "DDS" import subprocess run_time_stopwatch = Stopwatch() run_time_threshold = 2 if is_dds else 5 # currently, DDS devices take longer time to complete rs_enumerate_devices From 1e1843350cab9ba7990fe2c520787211d2b18bed Mon Sep 17 00:00:00 2001 From: Avia Avraham <145359432+AviaAv@users.noreply.github.com> Date: Sun, 2 Feb 2025 10:41:08 +0200 Subject: [PATCH 4/7] rebase and small changes --- unit-tests/py/rspy/devices.py | 13 ++++++------- unit-tests/run-unit-tests.py | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/unit-tests/py/rspy/devices.py b/unit-tests/py/rspy/devices.py index 76b1e3478b..e8e30a1992 100644 --- a/unit-tests/py/rspy/devices.py +++ b/unit-tests/py/rspy/devices.py @@ -74,11 +74,10 @@ def __init__( self, sn, dev ): self._usb_location = None try: + self._usb_location = _get_usb_location(self._physical_port) if dev.supports(rs.camera_info.connection_type): self._connection_type = dev.get_info(rs.camera_info.connection_type) self._is_dds = self._connection_type == "DDS" - if self._connection_type == "USB": - self._usb_location = _get_usb_location(self._physical_port) except Exception as e: log.e('Failed to get usb location:', e) self._port = None @@ -122,7 +121,7 @@ def handle( self ): @property def enabled( self ): - return self._removed is False and self._dev is not None + return self._removed is False @property def is_dds(self): @@ -215,6 +214,7 @@ def query( monitor_changes=True, hub_reset=False, recycle_ports=True, disable_dd :param recycle_ports: True to recycle all ports before querying devices; False to leave as-is :param hub_reset: Whether we want to reset the hub - this might be a better way to recycle the ports in certain cases that leave the ports in a bad state + :param disable_dds: Whether we want to see dds devices or not """ global rs if not rs: @@ -275,17 +275,16 @@ def _device_change_callback( info ): global _device_by_sn for device in _device_by_sn.values(): if device.enabled and info.was_removed( device.handle ): + device._removed = True device._dev = None log.d( 'device removed:', device.serial_number ) - device._removed = True for handle in info.get_new_devices(): sn = handle.get_info( rs.camera_info.firmware_update_id ) log.d( 'device added:', sn, handle ) if sn in _device_by_sn: device = _device_by_sn[sn] - device._dev = None # in case we get handle between the next 2 lines, it might still be the old one - device._removed = False device._dev = handle # Because it has a new handle! + device._removed = False else: # shouldn't see new devices... log.d( 'new device detected!?' ) @@ -630,7 +629,7 @@ def hw_reset( serial_numbers, timeout = MAX_ENUMERATION_TIME ): :param timeout: Maximum # of seconds to wait for the devices to come back online :return: True if all devices have come back online before timeout """ - # for usb and dds devices, we can wait until they're removed + # we can wait for usb and dds devices to be removed, but not for mipi devices removable_devs_sns = {sn for sn in serial_numbers if _device_by_sn[sn].port is not None or _device_by_sn[sn].is_dds} diff --git a/unit-tests/run-unit-tests.py b/unit-tests/run-unit-tests.py index 69a46b3204..1b00cec4b4 100644 --- a/unit-tests/run-unit-tests.py +++ b/unit-tests/run-unit-tests.py @@ -480,8 +480,8 @@ def test_wrapper( test, configuration=None, repetition=1, serial_numbers=None ): if pyrs: sys.path.insert( 1, pyrs_path ) # Make sure we pick up the right pyrealsense2! from rspy import devices - - devices.query( hub_reset = hub_reset ) #resets the device + disable_dds = "dds" not in context + devices.query( hub_reset = hub_reset, disable_dds=disable_dds ) #resets the device devices.map_unknown_ports() # # Under a development environment (i.e., without a hub), we may only have one device connected From 8590f4fa7316c67dac131959f957da4533b677d6 Mon Sep 17 00:00:00 2001 From: Avia Avraham <145359432+AviaAv@users.noreply.github.com> Date: Sun, 2 Feb 2025 11:35:55 +0200 Subject: [PATCH 5/7] fix threshold time logic --- unit-tests/live/tools/test-enumerate-devices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unit-tests/live/tools/test-enumerate-devices.py b/unit-tests/live/tools/test-enumerate-devices.py index 73668139f0..caeabd5bbf 100644 --- a/unit-tests/live/tools/test-enumerate-devices.py +++ b/unit-tests/live/tools/test-enumerate-devices.py @@ -18,7 +18,7 @@ is_dds = dev.supports(rs.camera_info.connection_type) and dev.get_info(rs.camera_info.connection_type) == "DDS" import subprocess run_time_stopwatch = Stopwatch() - run_time_threshold = 2 if is_dds else 5 # currently, DDS devices take longer time to complete rs_enumerate_devices + run_time_threshold = 5 if is_dds else 2 # currently, DDS devices take longer time to complete rs_enumerate_devices p = subprocess.run( [rs_enumerate_devices], stdout=None, stderr=subprocess.STDOUT, From 1e4e06fb3bec0117c70f0bbaf63724399c3e1766 Mon Sep 17 00:00:00 2001 From: Avia Avraham <145359432+AviaAv@users.noreply.github.com> Date: Sun, 2 Feb 2025 12:07:22 +0200 Subject: [PATCH 6/7] define _is_dds w/o connection_type --- unit-tests/py/rspy/devices.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/unit-tests/py/rspy/devices.py b/unit-tests/py/rspy/devices.py index e8e30a1992..afdee63133 100644 --- a/unit-tests/py/rspy/devices.py +++ b/unit-tests/py/rspy/devices.py @@ -78,6 +78,9 @@ def __init__( self, sn, dev ): if dev.supports(rs.camera_info.connection_type): self._connection_type = dev.get_info(rs.camera_info.connection_type) self._is_dds = self._connection_type == "DDS" + else: + log.w("connection_type is not supported! Assuming not a dds device") + self._is_dds = False except Exception as e: log.e('Failed to get usb location:', e) self._port = None From 86d21764dbbb1cb8bf5425c62f1c09b6cea6d0db Mon Sep 17 00:00:00 2001 From: Avia Avraham <145359432+AviaAv@users.noreply.github.com> Date: Sun, 2 Feb 2025 14:11:26 +0200 Subject: [PATCH 7/7] move connection type before 'try-catch' block --- unit-tests/py/rspy/devices.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/unit-tests/py/rspy/devices.py b/unit-tests/py/rspy/devices.py index afdee63133..99f4943784 100644 --- a/unit-tests/py/rspy/devices.py +++ b/unit-tests/py/rspy/devices.py @@ -72,15 +72,16 @@ def __init__( self, sn, dev ): self._product_line = dev.get_info( rs.camera_info.product_line ) self._physical_port = dev.supports( rs.camera_info.physical_port ) and dev.get_info( rs.camera_info.physical_port ) or None + if dev.supports(rs.camera_info.connection_type): + self._connection_type = dev.get_info(rs.camera_info.connection_type) + self._is_dds = self._connection_type == "DDS" + else: + log.w("connection_type is not supported! Assuming not a dds device") + self._is_dds = False + self._usb_location = None try: self._usb_location = _get_usb_location(self._physical_port) - if dev.supports(rs.camera_info.connection_type): - self._connection_type = dev.get_info(rs.camera_info.connection_type) - self._is_dds = self._connection_type == "DDS" - else: - log.w("connection_type is not supported! Assuming not a dds device") - self._is_dds = False except Exception as e: log.e('Failed to get usb location:', e) self._port = None