From d96da7164d08bcbd9dd08b86b5292856de84dd39 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 20 Jun 2024 16:14:52 +0200 Subject: [PATCH] [Python] Convert async API functions to python asyncio (#33989) * [Python] Use context manager for Commissioning Use a context manager to handle the commissioning process in the device controller. This will ensure that the commissioning resources are properly cleaned up after completion and removes boiler plate code. Also clear fabricCheckNodeId and mark it internal use by adding the underline prefix. Also call pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete directly on the Python Thread, as this is an atomic operation. This is will also be more asyncio friendly as it is guaranteed to not block. * [Python] Use context manager for all callbacks Use context managers for all APIs which wait for callbacks. This allows to cleanly wrap the future and add additional handling e.g. locks for asyncio in the future. * [Python] Convert commissioning APIs to async functions Make all commissioning APIs async functions. This avoids the need to use run_in_executor() to call them from asyncio code in a non- blocking way. * [Python] Convert UnpairDevice/OpenCommissioningWindow to asyncio * [Python] Convert EstablishPASESession to asyncio * [Python] Convert IssueNOCChain to asyncio * [Python] Add locking to prevent concurrent access with asyncio Make sure that different asyncio tasks do not run the same function concurrently. This is done by adding an asyncio lock to functions which use callbacks. * [Python] Raise an exception if the future did not complete * [Python] Convert tests in src/controller/python/ to asyncio * [Python] Convert tests in src/python_testing/ to asyncio * Adjust yamltest_with_chip_repl_tester to use asyncio * [Python] Add documentation to the new context managers * [Python] Use asyncio.run() to run async tests --- .../yamltest_with_chip_repl_tester.py | 8 +- src/controller/python/chip/ChipDeviceCtrl.py | 308 +++++++++--------- .../python/chip/commissioning/pase.py | 6 +- .../chip/utils/CommissioningBuildingBlocks.py | 4 +- src/controller/python/chip/yaml/runner.py | 2 +- .../matter_yamltest_repl_adapter/runner.py | 2 +- .../python/test/test_scripts/base.py | 48 +-- .../commissioning_failure_test.py | 32 +- .../test/test_scripts/commissioning_test.py | 20 +- .../test_scripts/commissioning_window_test.py | 6 +- .../example_python_commissioning_flow.py | 4 +- .../test/test_scripts/failsafe_tests.py | 12 +- .../test/test_scripts/mobile-device-test.py | 26 +- .../python_commissioning_flow_test.py | 2 +- .../test_scripts/split_commissioning_test.py | 30 +- ...cription_resumption_capacity_test_ctrl1.py | 12 +- ...cription_resumption_capacity_test_ctrl2.py | 13 +- .../subscription_resumption_test.py | 12 +- .../subscription_resumption_timeout_test.py | 12 +- src/python_testing/TC_ACE_1_5.py | 4 +- src/python_testing/TC_CGEN_2_4.py | 12 +- src/python_testing/TC_DA_1_5.py | 4 +- src/python_testing/TC_IDM_1_2.py | 10 +- src/python_testing/TC_OPCREDS_3_1.py | 32 +- src/python_testing/TC_TIMESYNC_2_13.py | 4 +- .../TestCommissioningTimeSync.py | 4 +- .../basic_composition_support.py | 6 +- src/python_testing/matter_testing_support.py | 18 +- 28 files changed, 331 insertions(+), 322 deletions(-) diff --git a/scripts/tests/chiptest/yamltest_with_chip_repl_tester.py b/scripts/tests/chiptest/yamltest_with_chip_repl_tester.py index 484e21370e5252..1b301c572874d0 100644 --- a/scripts/tests/chiptest/yamltest_with_chip_repl_tester.py +++ b/scripts/tests/chiptest/yamltest_with_chip_repl_tester.py @@ -101,7 +101,7 @@ async def execute_test(yaml, runner): '--pics-file', default=None, help='Optional PICS file') -def main(setup_code, yaml_path, node_id, pics_file): +async def main(setup_code, yaml_path, node_id, pics_file): # Setting up python environment for running YAML CI tests using python parser. with tempfile.NamedTemporaryFile() as chip_stack_storage: chip.native.Init() @@ -122,7 +122,7 @@ def main(setup_code, yaml_path, node_id, pics_file): # Creating and commissioning to a single controller to match what is currently done when # running. dev_ctrl = ca_list[0].adminList[0].NewController() - dev_ctrl.CommissionWithCode(setup_code, node_id) + await dev_ctrl.CommissionWithCode(setup_code, node_id) def _StackShutDown(): # Tearing down chip stack. If not done in the correct order test will fail. @@ -143,7 +143,7 @@ def _StackShutDown(): runner = ReplTestRunner( clusters_definitions, certificate_authority_manager, dev_ctrl) - asyncio.run(execute_test(yaml, runner)) + await execute_test(yaml, runner) except Exception: print(traceback.format_exc()) @@ -153,4 +153,4 @@ def _StackShutDown(): if __name__ == '__main__': - main() + asyncio.run(main()) diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index 890e7618882e49..9fa0f5089b8485 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -226,6 +226,52 @@ def wrapper(*args, **kwargs): return wrapper +class CallbackContext: + """A context manager for handling callbacks that are expected to be called exactly once. + + The context manager makes sure that no concurrent operations which use the same callback + handlers are executed. + """ + + def __init__(self, lock: asyncio.Lock) -> None: + self._lock = lock + self._future = None + + async def __aenter__(self): + await self._lock.acquire() + self._future = concurrent.futures.Future() + return self + + @property + def future(self) -> typing.Optional[concurrent.futures.Future]: + return self._future + + async def __aexit__(self, exc_type, exc_value, traceback): + if not self._future.done(): + raise RuntimeError("CallbackContext future not completed") + self._future = None + self._lock.release() + + +class CommissioningContext(CallbackContext): + """A context manager for handling commissioning callbacks that are expected to be called exactly once. + + This context also resets commissioning related device controller state. + """ + + def __init__(self, devCtrl: ChipDeviceController, lock: asyncio.Lock) -> None: + super().__init__(lock) + self._devCtrl = devCtrl + + async def __aenter__(self): + await super().__aenter__() + self._devCtrl._fabricCheckNodeId = -1 + return self + + async def __aexit__(self, exc_type, exc_value, traceback): + await super().__aexit__(exc_type, exc_value, traceback) + + class CommissionableNode(discovery.CommissionableNode): def SetDeviceController(self, devCtrl: 'ChipDeviceController'): self._devCtrl = devCtrl @@ -342,15 +388,16 @@ def __init__(self, name: str = ''): self.pairingDelegate = pairingDelegate self.devCtrl = devCtrl self.name = name - self.fabricCheckNodeId = -1 + self._fabricCheckNodeId = -1 self._isActive = False self._Cluster = ChipClusters(builtins.chipStack) self._Cluster.InitLib(self._dmLib) - self._commissioning_complete_future: typing.Optional[concurrent.futures.Future] = None - self._open_window_complete_future: typing.Optional[concurrent.futures.Future] = None - self._unpair_device_complete_future: typing.Optional[concurrent.futures.Future] = None - self._pase_establishment_complete_future: typing.Optional[concurrent.futures.Future] = None + self._commissioning_lock: asyncio.Lock = asyncio.Lock() + self._commissioning_context: CommissioningContext = CommissioningContext(self, self._commissioning_lock) + self._open_window_context: CallbackContext = CallbackContext(asyncio.Lock()) + self._unpair_device_context: CallbackContext = CallbackContext(asyncio.Lock()) + self._pase_establishment_context: CallbackContext = CallbackContext(self._commissioning_lock) def _set_dev_ctrl(self, devCtrl, pairingDelegate): def HandleCommissioningComplete(nodeId: int, err: PyChipError): @@ -364,17 +411,17 @@ def HandleCommissioningComplete(nodeId: int, err: PyChipError): if self._dmLib.pychip_TestCommissionerUsed(): err = self._dmLib.pychip_GetCompletionError() - if self._commissioning_complete_future is None: + if self._commissioning_context.future is None: logging.exception("HandleCommissioningComplete called unexpectedly") return if err.is_success: - self._commissioning_complete_future.set_result(nodeId) + self._commissioning_context.future.set_result(nodeId) else: - self._commissioning_complete_future.set_exception(err.to_exception()) + self._commissioning_context.future.set_exception(err.to_exception()) def HandleFabricCheck(nodeId): - self.fabricCheckNodeId = nodeId + self._fabricCheckNodeId = nodeId def HandleOpenWindowComplete(nodeid: int, setupPinCode: int, setupManualCode: str, setupQRCode: str, err: PyChipError) -> None: @@ -385,14 +432,14 @@ def HandleOpenWindowComplete(nodeid: int, setupPinCode: int, setupManualCode: st else: logging.warning("Failed to open commissioning window: {}".format(err)) - if self._open_window_complete_future is None: + if self._open_window_context.future is None: logging.exception("HandleOpenWindowComplete called unexpectedly") return if err.is_success: - self._open_window_complete_future.set_result(commissioningParameters) + self._open_window_context.future.set_result(commissioningParameters) else: - self._open_window_complete_future.set_exception(err.to_exception()) + self._open_window_context.future.set_exception(err.to_exception()) def HandleUnpairDeviceComplete(nodeid: int, err: PyChipError): if err.is_success: @@ -400,14 +447,14 @@ def HandleUnpairDeviceComplete(nodeid: int, err: PyChipError): else: logging.warning("Failed to unpair device: {}".format(err)) - if self._unpair_device_complete_future is None: + if self._unpair_device_context.future is None: logging.exception("HandleUnpairDeviceComplete called unexpectedly") return if err.is_success: - self._unpair_device_complete_future.set_result(None) + self._unpair_device_context.future.set_result(None) else: - self._unpair_device_complete_future.set_exception(err.to_exception()) + self._unpair_device_context.future.set_exception(err.to_exception()) def HandlePASEEstablishmentComplete(err: PyChipError): if not err.is_success: @@ -415,21 +462,21 @@ def HandlePASEEstablishmentComplete(err: PyChipError): else: logging.info("Established secure session with Device") - if self._commissioning_complete_future is not None: + if self._commissioning_context.future is not None: # During Commissioning, HandlePASEEstablishmentComplete will also be called. # Only complete the future if PASE session establishment failed. if not err.is_success: - self._commissioning_complete_future.set_exception(err.to_exception()) + self._commissioning_context.future.set_exception(err.to_exception()) return - if self._pase_establishment_complete_future is None: + if self._pase_establishment_context.future is None: logging.exception("HandlePASEEstablishmentComplete called unexpectedly") return if err.is_success: - self._pase_establishment_complete_future.set_result(None) + self._pase_establishment_context.future.set_result(None) else: - self._pase_establishment_complete_future.set_exception(err.to_exception()) + self._pase_establishment_context.future.set_exception(err.to_exception()) self.pairingDelegate = pairingDelegate self.devCtrl = devCtrl @@ -465,10 +512,8 @@ def _finish_init(self): ChipDeviceController.activeList.add(self) - def _enablePairingCompeleteCallback(self, value: bool): - self._ChipStack.Call( - lambda: self._dmLib.pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete(self.pairingDelegate, value) - ).raise_on_error() + def _enablePairingCompleteCallback(self, value: bool): + self._dmLib.pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete(self.pairingDelegate, value) @property def fabricAdmin(self) -> FabricAdmin.FabricAdmin: @@ -547,7 +592,7 @@ def IsConnected(self): self.devCtrl) ) - def ConnectBLE(self, discriminator: int, setupPinCode: int, nodeid: int, isShortDiscriminator: bool = False) -> int: + async def ConnectBLE(self, discriminator: int, setupPinCode: int, nodeid: int, isShortDiscriminator: bool = False) -> int: """Connect to a BLE device using the given discriminator and setup pin code. Returns: @@ -555,31 +600,26 @@ def ConnectBLE(self, discriminator: int, setupPinCode: int, nodeid: int, isShort """ self.CheckIsActive() - self._commissioning_complete_future = concurrent.futures.Future() - - try: - self._enablePairingCompeleteCallback(True) - self._ChipStack.Call( + async with self._commissioning_context as ctx: + self._enablePairingCompleteCallback(True) + res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectBLE( self.devCtrl, discriminator, isShortDiscriminator, setupPinCode, nodeid) - ).raise_on_error() + ) + res.raise_on_error() - return self._commissioning_complete_future.result() - finally: - self._commissioning_complete_future = None + return await asyncio.futures.wrap_future(ctx.future) - def UnpairDevice(self, nodeid: int) -> None: + async def UnpairDevice(self, nodeid: int) -> None: self.CheckIsActive() - self._unpair_device_complete_future = concurrent.futures.Future() - try: - self._ChipStack.Call( + async with self._unpair_device_context as ctx: + res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_UnpairDevice( self.devCtrl, nodeid, self.cbHandleDeviceUnpairCompleteFunct) - ).raise_on_error() - self._unpair_device_complete_future.result() - finally: - self._unpair_device_complete_future = None + ) + res.raise_on_error() + return await asyncio.futures.wrap_future(ctx.future) def CloseBLEConnection(self): self.CheckIsActive() @@ -610,50 +650,32 @@ def CloseSession(self, nodeid): self.devCtrl, nodeid) ).raise_on_error() - def EstablishPASESessionBLE(self, setupPinCode: int, discriminator: int, nodeid: int) -> None: + async def _establishPASESession(self, callFunct): self.CheckIsActive() - self._pase_establishment_complete_future = concurrent.futures.Future() - try: - self._enablePairingCompeleteCallback(True) - self._ChipStack.Call( - lambda: self._dmLib.pychip_DeviceController_EstablishPASESessionBLE( - self.devCtrl, setupPinCode, discriminator, nodeid) - ).raise_on_error() - - self._pase_establishment_complete_future.result() - finally: - self._pase_establishment_complete_future = None - - def EstablishPASESessionIP(self, ipaddr: str, setupPinCode: int, nodeid: int, port: int = 0) -> None: - self.CheckIsActive() + async with self._pase_establishment_context as ctx: + self._enablePairingCompleteCallback(True) + res = await self._ChipStack.CallAsync(callFunct) + res.raise_on_error() + await asyncio.futures.wrap_future(ctx.future) - self._pase_establishment_complete_future = concurrent.futures.Future() - try: - self._enablePairingCompeleteCallback(True) - self._ChipStack.Call( - lambda: self._dmLib.pychip_DeviceController_EstablishPASESessionIP( - self.devCtrl, ipaddr.encode("utf-8"), setupPinCode, nodeid, port) - ).raise_on_error() - - self._pase_establishment_complete_future.result() - finally: - self._pase_establishment_complete_future = None - - def EstablishPASESession(self, setUpCode: str, nodeid: int) -> None: - self.CheckIsActive() + async def EstablishPASESessionBLE(self, setupPinCode: int, discriminator: int, nodeid: int) -> None: + await self._establishPASESession( + lambda: self._dmLib.pychip_DeviceController_EstablishPASESessionBLE( + self.devCtrl, setupPinCode, discriminator, nodeid) + ) - self._pase_establishment_complete_future = concurrent.futures.Future() - try: - self._enablePairingCompeleteCallback(True) - self._ChipStack.Call( - lambda: self._dmLib.pychip_DeviceController_EstablishPASESession( - self.devCtrl, setUpCode.encode("utf-8"), nodeid) - ).raise_on_error() + async def EstablishPASESessionIP(self, ipaddr: str, setupPinCode: int, nodeid: int, port: int = 0) -> None: + await self._establishPASESession( + lambda: self._dmLib.pychip_DeviceController_EstablishPASESessionIP( + self.devCtrl, ipaddr.encode("utf-8"), setupPinCode, nodeid, port) + ) - self._pase_establishment_complete_future.result() - finally: - self._pase_establishment_complete_future = None + async def EstablishPASESession(self, setUpCode: str, nodeid: int) -> None: + await self._establishPASESession( + lambda: self._dmLib.pychip_DeviceController_EstablishPASESession( + self.devCtrl, setUpCode.encode("utf-8"), nodeid) + ) def GetTestCommissionerUsed(self): return self._ChipStack.Call( @@ -778,8 +800,8 @@ class CommissioningWindowPasscode(enum.IntEnum): kOriginalSetupCode = 0, kTokenWithRandomPin = 1, - def OpenCommissioningWindow(self, nodeid: int, timeout: int, iteration: int, - discriminator: int, option: CommissioningWindowPasscode) -> CommissioningParameters: + async def OpenCommissioningWindow(self, nodeid: int, timeout: int, iteration: int, + discriminator: int, option: CommissioningWindowPasscode) -> CommissioningParameters: ''' Opens a commissioning window on the device with the given nodeid. nodeid: Node id of the device timeout: Command timeout @@ -794,16 +816,15 @@ def OpenCommissioningWindow(self, nodeid: int, timeout: int, iteration: int, Returns CommissioningParameters ''' self.CheckIsActive() - self._open_window_complete_future = concurrent.futures.Future() - try: - self._ChipStack.Call( + + async with self._open_window_context as ctx: + res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_OpenCommissioningWindow( self.devCtrl, self.pairingDelegate, nodeid, timeout, iteration, discriminator, option) - ).raise_on_error() + ) + res.raise_on_error() - return self._open_window_complete_future.result() - finally: - self._open_window_complete_future = None + return await asyncio.futures.wrap_future(ctx.future) def GetCompressedFabricId(self): self.CheckIsActive() @@ -861,18 +882,18 @@ def GetClusterHandler(self): return self._Cluster - def FindOrEstablishPASESession(self, setupCode: str, nodeid: int, timeoutMs: int = None) -> typing.Optional[DeviceProxyWrapper]: + async def FindOrEstablishPASESession(self, setupCode: str, nodeid: int, timeoutMs: int = None) -> typing.Optional[DeviceProxyWrapper]: ''' Returns CommissioneeDeviceProxy if we can find or establish a PASE connection to the specified device''' self.CheckIsActive() returnDevice = c_void_p(None) - res = self._ChipStack.Call(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( + res = await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) if res.is_success: return DeviceProxyWrapper(returnDevice, DeviceProxyWrapper.DeviceProxyType.COMMISSIONEE, self._dmLib) - self.EstablishPASESession(setupCode, nodeid) + await self.EstablishPASESession(setupCode, nodeid) - res = self._ChipStack.Call(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( + res = await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) if res.is_success: return DeviceProxyWrapper(returnDevice, DeviceProxyWrapper.DeviceProxyType.COMMISSIONEE, self._dmLib) @@ -1831,7 +1852,7 @@ def __init__(self, opCredsContext: ctypes.c_void_p, fabricId: int, nodeId: int, f"caIndex({fabricAdmin.caIndex:x})/fabricId(0x{fabricId:016X})/nodeId(0x{nodeId:016X})" ) - self._issue_node_chain_complete: typing.Optional[concurrent.futures.Future] = None + self._issue_node_chain_context: CallbackContext = CallbackContext(asyncio.Lock()) self._dmLib.pychip_DeviceController_SetIssueNOCChainCallbackPythonCallback(_IssueNOCChainCallbackPythonCallback) pairingDelegate = c_void_p(None) @@ -1869,7 +1890,7 @@ def caIndex(self) -> int: def fabricAdmin(self) -> FabricAdmin: return self._fabricAdmin - def Commission(self, nodeid) -> int: + async def Commission(self, nodeid) -> int: ''' Start the auto-commissioning process on a node after establishing a PASE connection. This function is intended to be used in conjunction with `EstablishPASESessionBLE` or @@ -1885,29 +1906,27 @@ def Commission(self, nodeid) -> int: ''' self.CheckIsActive() - self._commissioning_complete_future = concurrent.futures.Future() - - try: - self._ChipStack.Call( + async with self._commissioning_context as ctx: + self._enablePairingCompleteCallback(False) + res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_Commission( self.devCtrl, nodeid) - ).raise_on_error() + ) + res.raise_on_error() - return self._commissioning_complete_future.result() - finally: - self._commissioning_complete_future = None + return await asyncio.futures.wrap_future(ctx.future) - def CommissionThread(self, discriminator, setupPinCode, nodeId, threadOperationalDataset: bytes, isShortDiscriminator: bool = False) -> int: + async def CommissionThread(self, discriminator, setupPinCode, nodeId, threadOperationalDataset: bytes, isShortDiscriminator: bool = False) -> int: ''' Commissions a Thread device over BLE ''' self.SetThreadOperationalDataset(threadOperationalDataset) - return self.ConnectBLE(discriminator, setupPinCode, nodeId, isShortDiscriminator) + return await self.ConnectBLE(discriminator, setupPinCode, nodeId, isShortDiscriminator) - def CommissionWiFi(self, discriminator, setupPinCode, nodeId, ssid: str, credentials: str, isShortDiscriminator: bool = False) -> int: + async def CommissionWiFi(self, discriminator, setupPinCode, nodeId, ssid: str, credentials: str, isShortDiscriminator: bool = False) -> int: ''' Commissions a Wi-Fi device over BLE. ''' self.SetWiFiCredentials(ssid, credentials) - return self.ConnectBLE(discriminator, setupPinCode, nodeId, isShortDiscriminator) + return await self.ConnectBLE(discriminator, setupPinCode, nodeId, isShortDiscriminator) def SetWiFiCredentials(self, ssid: str, credentials: str): ''' Set the Wi-Fi credentials to set during commissioning.''' @@ -2003,10 +2022,11 @@ def DisableICDRegistration(self): def GetFabricCheckResult(self) -> int: ''' Returns the fabric check result if SetCheckMatchingFabric was used.''' - return self.fabricCheckNodeId + return self._fabricCheckNodeId - def CommissionOnNetwork(self, nodeId: int, setupPinCode: int, - filterType: DiscoveryFilterType = DiscoveryFilterType.NONE, filter: typing.Any = None, discoveryTimeoutMsec: int = 30000) -> int: + async def CommissionOnNetwork(self, nodeId: int, setupPinCode: int, + filterType: DiscoveryFilterType = DiscoveryFilterType.NONE, filter: typing.Any = None, + discoveryTimeoutMsec: int = 30000) -> int: ''' Does the routine for OnNetworkCommissioning, with a filter for mDNS discovery. Supported filters are: @@ -2034,19 +2054,17 @@ def CommissionOnNetwork(self, nodeId: int, setupPinCode: int, if isinstance(filter, int): filter = str(filter) - self._commissioning_complete_future = concurrent.futures.Future() - try: - self._enablePairingCompeleteCallback(True) - self._ChipStack.Call( + async with self._commissioning_context as ctx: + self._enablePairingCompleteCallback(True) + res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_OnNetworkCommission( self.devCtrl, self.pairingDelegate, nodeId, setupPinCode, int(filterType), str(filter).encode("utf-8") if filter is not None else None, discoveryTimeoutMsec) - ).raise_on_error() + ) + res.raise_on_error() - return self._commissioning_complete_future.result() - finally: - self._commissioning_complete_future = None + return await asyncio.futures.wrap_future(ctx.future) - def CommissionWithCode(self, setupPayload: str, nodeid: int, discoveryType: DiscoveryType = DiscoveryType.DISCOVERY_ALL) -> int: + async def CommissionWithCode(self, setupPayload: str, nodeid: int, discoveryType: DiscoveryType = DiscoveryType.DISCOVERY_ALL) -> int: ''' Commission with the given nodeid from the setupPayload. setupPayload may be a QR or manual code. @@ -2057,20 +2075,17 @@ def CommissionWithCode(self, setupPayload: str, nodeid: int, discoveryType: Disc ''' self.CheckIsActive() - self._commissioning_complete_future = concurrent.futures.Future() - - try: - self._enablePairingCompeleteCallback(True) - self._ChipStack.Call( + async with self._commissioning_context as ctx: + self._enablePairingCompleteCallback(True) + res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectWithCode( self.devCtrl, setupPayload.encode("utf-8"), nodeid, discoveryType.value) - ).raise_on_error() + ) + res.raise_on_error() - return self._commissioning_complete_future.result() - finally: - self._commissioning_complete_future = None + return await asyncio.futures.wrap_future(ctx.future) - def CommissionIP(self, ipaddr: str, setupPinCode: int, nodeid: int) -> int: + async def CommissionIP(self, ipaddr: str, setupPinCode: int, nodeid: int) -> int: """ DEPRECATED, DO NOT USE! Use `CommissionOnNetwork` or `CommissionWithCode` Raises a ChipStackError on failure. @@ -2080,40 +2095,35 @@ def CommissionIP(self, ipaddr: str, setupPinCode: int, nodeid: int) -> int: """ self.CheckIsActive() - self._commissioning_complete_future = concurrent.futures.Future() - - try: - self._enablePairingCompeleteCallback(True) - self._ChipStack.Call( + async with self._commissioning_context as ctx: + self._enablePairingCompleteCallback(True) + res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectIP( self.devCtrl, ipaddr.encode("utf-8"), setupPinCode, nodeid) - ).raise_on_error() + ) + res.raise_on_error() - return self._commissioning_complete_future.result() - finally: - self._commissioning_complete_future = None + return await asyncio.futures.wrap_future(ctx.future) def NOCChainCallback(self, nocChain): - if self._issue_node_chain_complete is None: + if self._issue_node_chain_context.future is None: logging.exception("NOCChainCallback while not expecting a callback") return - self._issue_node_chain_complete.set_result(nocChain) + self._issue_node_chain_context.future.set_result(nocChain) return - def IssueNOCChain(self, csr: Clusters.OperationalCredentials.Commands.CSRResponse, nodeId: int): + async def IssueNOCChain(self, csr: Clusters.OperationalCredentials.Commands.CSRResponse, nodeId: int): """Issue an NOC chain using the associated OperationalCredentialsDelegate. The NOC chain will be provided in TLV cert format.""" self.CheckIsActive() - self._issue_node_chain_complete = concurrent.futures.Future() - try: - self._ChipStack.Call( + async with self._issue_node_chain_context as ctx: + res = await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_IssueNOCChain( self.devCtrl, py_object(self), csr.NOCSRElements, len(csr.NOCSRElements), nodeId) - ).raise_on_error() - return self._issue_node_chain_complete.result() - finally: - self._issue_node_chain_complete = None + ) + res.raise_on_error() + return await asyncio.futures.wrap_future(ctx.future) class BareChipDeviceController(ChipDeviceControllerBase): diff --git a/src/controller/python/chip/commissioning/pase.py b/src/controller/python/chip/commissioning/pase.py index 9b7e8c5077242f..c0cfca5ee8b93f 100644 --- a/src/controller/python/chip/commissioning/pase.py +++ b/src/controller/python/chip/commissioning/pase.py @@ -44,9 +44,9 @@ def __exit__(self, type, value, traceback): self.devCtrl.CloseBLEConnection(self.is_ble) -def establish_session(devCtrl: ChipDeviceCtrl.ChipDeviceControllerBase, parameter: commissioning.PaseParameters) -> ContextManager: +async def establish_session(devCtrl: ChipDeviceCtrl.ChipDeviceControllerBase, parameter: commissioning.PaseParameters) -> ContextManager: if isinstance(parameter, commissioning.PaseOverBLEParameters): - devCtrl.EstablishPASESessionBLE(parameter.setup_pin, parameter.discriminator, parameter.temporary_nodeid) + await devCtrl.EstablishPASESessionBLE(parameter.setup_pin, parameter.discriminator, parameter.temporary_nodeid) elif isinstance(parameter, commissioning.PaseOverIPParameters): device = devCtrl.DiscoverCommissionableNodes(filterType=discovery.FilterType.LONG_DISCRIMINATOR, filter=parameter.long_discriminator, stopOnFirst=True) @@ -63,7 +63,7 @@ def establish_session(devCtrl: ChipDeviceCtrl.ChipDeviceControllerBase, paramete break if selected_address is None: raise ValueError("The node for commissioning does not contains routable ip addresses information") - devCtrl.EstablishPASESessionIP(selected_address, parameter.setup_pin, parameter.temporary_nodeid) + await devCtrl.EstablishPASESessionIP(selected_address, parameter.setup_pin, parameter.temporary_nodeid) else: raise TypeError("Expect PaseOverBLEParameters or PaseOverIPParameters for establishing PASE session") return ContextManager( diff --git a/src/controller/python/chip/utils/CommissioningBuildingBlocks.py b/src/controller/python/chip/utils/CommissioningBuildingBlocks.py index 4c3826fd6914ee..b6dac307dfd997 100644 --- a/src/controller/python/chip/utils/CommissioningBuildingBlocks.py +++ b/src/controller/python/chip/utils/CommissioningBuildingBlocks.py @@ -167,7 +167,7 @@ async def AddNOCForNewFabricFromExisting(commissionerDevCtrl, newFabricDevCtrl, csrForAddNOC = await commissionerDevCtrl.SendCommand(existingNodeId, 0, opCreds.Commands.CSRRequest(CSRNonce=os.urandom(32))) - chainForAddNOC = newFabricDevCtrl.IssueNOCChain(csrForAddNOC, newNodeId) + chainForAddNOC = await newFabricDevCtrl.IssueNOCChain(csrForAddNOC, newNodeId) if (chainForAddNOC.rcacBytes is None or chainForAddNOC.icacBytes is None or chainForAddNOC.nocBytes is None or chainForAddNOC.ipkBytes is None): @@ -225,7 +225,7 @@ async def UpdateNOC(devCtrl, existingNodeId, newNodeId): return False csrForUpdateNOC = await devCtrl.SendCommand( existingNodeId, 0, opCreds.Commands.CSRRequest(CSRNonce=os.urandom(32), isForUpdateNOC=True)) - chainForUpdateNOC = devCtrl.IssueNOCChain(csrForUpdateNOC, newNodeId) + chainForUpdateNOC = await devCtrl.IssueNOCChain(csrForUpdateNOC, newNodeId) if (chainForUpdateNOC.rcacBytes is None or chainForUpdateNOC.icacBytes is None or chainForUpdateNOC.nocBytes is None or chainForUpdateNOC.ipkBytes is None): diff --git a/src/controller/python/chip/yaml/runner.py b/src/controller/python/chip/yaml/runner.py index 312940f34bffd5..f0b681fb2b4cbe 100644 --- a/src/controller/python/chip/yaml/runner.py +++ b/src/controller/python/chip/yaml/runner.py @@ -665,7 +665,7 @@ async def run_action(self, dev_ctrl: ChipDeviceController) -> _ActionResult: return _ActionResult(status=_ActionStatus.SUCCESS, response=_GetCommissionerNodeIdResult(dev_ctrl.nodeId)) try: - dev_ctrl.CommissionWithCode(self._setup_payload, self._node_id) + await dev_ctrl.CommissionWithCode(self._setup_payload, self._node_id) return _ActionResult(status=_ActionStatus.SUCCESS, response=None) except ChipStackError: return _ActionResult(status=_ActionStatus.ERROR, response=None) diff --git a/src/controller/python/py_matter_yamltest_repl_adapter/matter_yamltest_repl_adapter/runner.py b/src/controller/python/py_matter_yamltest_repl_adapter/matter_yamltest_repl_adapter/runner.py index aecba0b2c454e0..5da5035ae009d4 100644 --- a/src/controller/python/py_matter_yamltest_repl_adapter/matter_yamltest_repl_adapter/runner.py +++ b/src/controller/python/py_matter_yamltest_repl_adapter/matter_yamltest_repl_adapter/runner.py @@ -59,7 +59,7 @@ async def start(self): # device with the provided node id. if self._node_id_to_commission is not None: # Magic value is the defaults expected for YAML tests. - dev_ctrl.CommissionWithCode('MT:-24J0AFN00KA0648G00', self._node_id_to_commission) + await dev_ctrl.CommissionWithCode('MT:-24J0AFN00KA0648G00', self._node_id_to_commission) self._chip_stack = chip_stack self._certificate_authority_manager = certificate_authority_manager diff --git a/src/controller/python/test/test_scripts/base.py b/src/controller/python/test/test_scripts/base.py index 1861627c0cbff4..80aaf145d964f9 100644 --- a/src/controller/python/test/test_scripts/base.py +++ b/src/controller/python/test/test_scripts/base.py @@ -234,7 +234,7 @@ def CreateNewFabricController(self): async def TestRevokeCommissioningWindow(self, ip: str, setuppin: int, nodeid: int): await self.devCtrl.SendCommand( nodeid, 0, Clusters.AdministratorCommissioning.Commands.OpenBasicCommissioningWindow(180), timedRequestTimeoutMs=10000) - if not self.TestPaseOnly(ip=ip, setuppin=setuppin, nodeid=nodeid, devCtrl=self.devCtrl2): + if not await self.TestPaseOnly(ip=ip, setuppin=setuppin, nodeid=nodeid, devCtrl=self.devCtrl2): return False await self.devCtrl2.SendCommand( @@ -248,17 +248,17 @@ async def TestRevokeCommissioningWindow(self, ip: str, setuppin: int, nodeid: in nodeid, 0, Clusters.AdministratorCommissioning.Commands.RevokeCommissioning(), timedRequestTimeoutMs=10000) return True - def TestEnhancedCommissioningWindow(self, ip: str, nodeid: int): - params = self.devCtrl.OpenCommissioningWindow(nodeid=nodeid, timeout=600, iteration=10000, discriminator=3840, option=1) - return self.TestPaseOnly(ip=ip, nodeid=nodeid, setuppin=params.setupPinCode, devCtrl=self.devCtrl2) + async def TestEnhancedCommissioningWindow(self, ip: str, nodeid: int): + params = await self.devCtrl.OpenCommissioningWindow(nodeid=nodeid, timeout=600, iteration=10000, discriminator=3840, option=1) + return await self.TestPaseOnly(ip=ip, nodeid=nodeid, setuppin=params.setupPinCode, devCtrl=self.devCtrl2) - def TestPaseOnly(self, ip: str, setuppin: int, nodeid: int, devCtrl=None): + async def TestPaseOnly(self, ip: str, setuppin: int, nodeid: int, devCtrl=None): if devCtrl is None: devCtrl = self.devCtrl self.logger.info( "Attempting to establish PASE session with device id: {} addr: {}".format(str(nodeid), ip)) try: - devCtrl.EstablishPASESessionIP(ip, setuppin, nodeid) + await devCtrl.EstablishPASESessionIP(ip, setuppin, nodeid) except ChipStackException: self.logger.info( "Failed to establish PASE session with device id: {} addr: {}".format(str(nodeid), ip)) @@ -267,11 +267,11 @@ def TestPaseOnly(self, ip: str, setuppin: int, nodeid: int, devCtrl=None): "Successfully established PASE session with device id: {} addr: {}".format(str(nodeid), ip)) return True - def TestCommissionOnly(self, nodeid: int): + async def TestCommissionOnly(self, nodeid: int): self.logger.info( "Commissioning device with id {}".format(nodeid)) try: - self.devCtrl.Commission(nodeid) + await self.devCtrl.Commission(nodeid) except ChipStackException: self.logger.info( "Failed to commission device with id {}".format(str(nodeid))) @@ -280,17 +280,17 @@ def TestCommissionOnly(self, nodeid: int): "Successfully commissioned device with id {}".format(str(nodeid))) return True - def TestKeyExchangeBLE(self, discriminator: int, setuppin: int, nodeid: int): + async def TestKeyExchangeBLE(self, discriminator: int, setuppin: int, nodeid: int): self.logger.info( "Conducting key exchange with device {}".format(discriminator)) - if not self.devCtrl.ConnectBLE(discriminator, setuppin, nodeid): + if not await self.devCtrl.ConnectBLE(discriminator, setuppin, nodeid): self.logger.info( "Failed to finish key exchange with device {}".format(discriminator)) return False self.logger.info("Device finished key exchange.") return True - def TestCommissionFailure(self, nodeid: int, failAfter: int): + async def TestCommissionFailure(self, nodeid: int, failAfter: int): self.devCtrl.ResetTestCommissioner() a = self.devCtrl.SetTestCommissionerSimulateFailureOnStage(failAfter) if not a: @@ -299,10 +299,10 @@ def TestCommissionFailure(self, nodeid: int, failAfter: int): self.logger.info( "Commissioning device, expecting failure after stage {}".format(failAfter)) - self.devCtrl.Commission(nodeid) + await self.devCtrl.Commission(nodeid) return self.devCtrl.CheckTestCommissionerCallbacks() and self.devCtrl.CheckTestCommissionerPaseConnection(nodeid) - def TestCommissionFailureOnReport(self, nodeid: int, failAfter: int): + async def TestCommissionFailureOnReport(self, nodeid: int, failAfter: int): self.devCtrl.ResetTestCommissioner() a = self.devCtrl.SetTestCommissionerSimulateFailureOnReport(failAfter) if not a: @@ -310,13 +310,13 @@ def TestCommissionFailureOnReport(self, nodeid: int, failAfter: int): return True self.logger.info( "Commissioning device, expecting failure on report for stage {}".format(failAfter)) - self.devCtrl.Commission(nodeid) + await self.devCtrl.Commission(nodeid) return self.devCtrl.CheckTestCommissionerCallbacks() and self.devCtrl.CheckTestCommissionerPaseConnection(nodeid) - def TestCommissioning(self, ip: str, setuppin: int, nodeid: int): + async def TestCommissioning(self, ip: str, setuppin: int, nodeid: int): self.logger.info("Commissioning device {}".format(ip)) try: - self.devCtrl.CommissionIP(ip, setuppin, nodeid) + await self.devCtrl.CommissionIP(ip, setuppin, nodeid) except ChipStackException: self.logger.exception( "Failed to finish commissioning device {}".format(ip)) @@ -324,10 +324,10 @@ def TestCommissioning(self, ip: str, setuppin: int, nodeid: int): self.logger.info("Commissioning finished.") return True - def TestCommissioningWithSetupPayload(self, setupPayload: str, nodeid: int, discoveryType: int = 2): + async def TestCommissioningWithSetupPayload(self, setupPayload: str, nodeid: int, discoveryType: int = 2): self.logger.info("Commissioning device with setup payload {}".format(setupPayload)) try: - self.devCtrl.CommissionWithCode(setupPayload, nodeid, chip.discovery.DiscoveryType(discoveryType)) + await self.devCtrl.CommissionWithCode(setupPayload, nodeid, chip.discovery.DiscoveryType(discoveryType)) except ChipStackException: self.logger.exception( "Failed to finish commissioning device {}".format(setupPayload)) @@ -335,7 +335,7 @@ def TestCommissioningWithSetupPayload(self, setupPayload: str, nodeid: int, disc self.logger.info("Commissioning finished.") return True - def TestOnNetworkCommissioning(self, discriminator: int, setuppin: int, nodeid: int, ip_override: str = None): + async def TestOnNetworkCommissioning(self, discriminator: int, setuppin: int, nodeid: int, ip_override: str = None): self.logger.info("Testing discovery") device = self.TestDiscovery(discriminator=discriminator) if not device: @@ -345,7 +345,7 @@ def TestOnNetworkCommissioning(self, discriminator: int, setuppin: int, nodeid: if ip_override: address = ip_override self.logger.info("Testing commissioning") - if not self.TestCommissioning(address, setuppin, nodeid): + if not await self.TestCommissioning(address, setuppin, nodeid): self.logger.info("Failed to finish commissioning") return False return True @@ -792,7 +792,7 @@ async def TestMultiFabric(self, ip: str, setuppin: int, nodeid: int): self.controllerNodeId, self.paaTrustStorePath) try: - self.devCtrl2.CommissionIP(ip, setuppin, nodeid) + await self.devCtrl2.CommissionIP(ip, setuppin, nodeid) except ChipStackException: self.logger.exception( "Failed to finish key exchange with device {}".format(ip)) @@ -1313,15 +1313,15 @@ def TestNonControllerAPIs(self): return False return True - def TestFabricScopedCommandDuringPase(self, nodeid: int): + async def TestFabricScopedCommandDuringPase(self, nodeid: int): '''Validates that fabric-scoped commands fail during PASE with UNSUPPORTED_ACCESS The nodeid is the PASE pseudo-node-ID used during PASE establishment ''' status = None try: - asyncio.run(self.devCtrl.SendCommand( - nodeid, 0, Clusters.OperationalCredentials.Commands.UpdateFabricLabel("roboto"))) + await self.devCtrl.SendCommand( + nodeid, 0, Clusters.OperationalCredentials.Commands.UpdateFabricLabel("roboto")) except IM.InteractionModelError as ex: status = ex.status diff --git a/src/controller/python/test/test_scripts/commissioning_failure_test.py b/src/controller/python/test/test_scripts/commissioning_failure_test.py index d680682d567491..f082ae99628af3 100755 --- a/src/controller/python/test/test_scripts/commissioning_failure_test.py +++ b/src/controller/python/test/test_scripts/commissioning_failure_test.py @@ -46,7 +46,7 @@ GROUP_ID = 0 -def main(): +async def main(): optParser = OptionParser() optParser.add_option( "-t", @@ -98,32 +98,32 @@ def main(): # TODO: Start at stage 2 once handling for arming failsafe on pase is done. if options.report: for testFailureStage in range(3, 21): - FailIfNot(test.TestPaseOnly(ip=options.deviceAddress1, - setuppin=20202021, - nodeid=1), + FailIfNot(await test.TestPaseOnly(ip=options.deviceAddress1, + setuppin=20202021, + nodeid=1), "Failed to establish PASE connection with device") - FailIfNot(test.TestCommissionFailureOnReport(1, testFailureStage), + FailIfNot(await test.TestCommissionFailureOnReport(1, testFailureStage), "Commissioning failure tests failed for simulated report failure on stage {}".format(testFailureStage)) else: for testFailureStage in range(3, 21): - FailIfNot(test.TestPaseOnly(ip=options.deviceAddress1, - setuppin=20202021, - nodeid=1), + FailIfNot(await test.TestPaseOnly(ip=options.deviceAddress1, + setuppin=20202021, + nodeid=1), "Failed to establish PASE connection with device") - FailIfNot(test.TestCommissionFailure(1, testFailureStage), + FailIfNot(await test.TestCommissionFailure(1, testFailureStage), "Commissioning failure tests failed for simulated stage failure on stage {}".format(testFailureStage)) # Ensure we can still commission for real - FailIfNot(test.TestPaseOnly(ip=options.deviceAddress1, - setuppin=20202021, - nodeid=1), + FailIfNot(await test.TestPaseOnly(ip=options.deviceAddress1, + setuppin=20202021, + nodeid=1), "Failed to establish PASE connection with device") - FailIfNot(test.TestCommissionFailure(1, 0), "Failed to commission device") + FailIfNot(await test.TestCommissionFailure(1, 0), "Failed to commission device") logger.info("Testing on off cluster") - FailIfNot(asyncio.run(test.TestOnOffCluster(nodeid=1, - endpoint=LIGHTING_ENDPOINT_ID)), "Failed to test on off cluster") + FailIfNot(await test.TestOnOffCluster(nodeid=1, + endpoint=LIGHTING_ENDPOINT_ID), "Failed to test on off cluster") timeoutTicker.stop() @@ -136,7 +136,7 @@ def main(): if __name__ == "__main__": try: - main() + asyncio.run(main()) except Exception as ex: logger.exception(ex) TestFail("Exception occurred when running tests.") diff --git a/src/controller/python/test/test_scripts/commissioning_test.py b/src/controller/python/test/test_scripts/commissioning_test.py index 4a7f15d6c3b085..c53ab00f33489a 100755 --- a/src/controller/python/test/test_scripts/commissioning_test.py +++ b/src/controller/python/test/test_scripts/commissioning_test.py @@ -47,7 +47,7 @@ GROUP_ID = 0 -def main(): +async def main(): optParser = OptionParser() optParser.add_option( "-t", @@ -133,22 +133,22 @@ def main(): if options.deviceAddress: logger.info("Testing commissioning (IP)") - FailIfNot(test.TestCommissioning(ip=options.deviceAddress, - setuppin=20202021, - nodeid=options.nodeid), + FailIfNot(await test.TestCommissioning(ip=options.deviceAddress, + setuppin=20202021, + nodeid=options.nodeid), "Failed to finish commissioning") elif options.setupPayload: logger.info("Testing commissioning (w/ Setup Payload)") - FailIfNot(test.TestCommissioningWithSetupPayload(setupPayload=options.setupPayload, - nodeid=options.nodeid, - discoveryType=options.discoveryType), + FailIfNot(await test.TestCommissioningWithSetupPayload(setupPayload=options.setupPayload, + nodeid=options.nodeid, + discoveryType=options.discoveryType), "Failed to finish commissioning") else: TestFail("Must provide device address or setup payload to commissioning the device") logger.info("Testing on off cluster") - FailIfNot(asyncio.run(test.TestOnOffCluster(nodeid=options.nodeid, - endpoint=LIGHTING_ENDPOINT_ID)), "Failed to test on off cluster") + FailIfNot(await test.TestOnOffCluster(nodeid=options.nodeid, + endpoint=LIGHTING_ENDPOINT_ID), "Failed to test on off cluster") FailIfNot(test.TestUsedTestCommissioner(), "Test commissioner check failed") @@ -164,7 +164,7 @@ def main(): if __name__ == "__main__": try: - main() + asyncio.run(main()) except Exception as ex: logger.exception(ex) TestFail("Exception occurred when running tests.") diff --git a/src/controller/python/test/test_scripts/commissioning_window_test.py b/src/controller/python/test/test_scripts/commissioning_window_test.py index 6a113aede20baf..e146485aaaae31 100755 --- a/src/controller/python/test/test_scripts/commissioning_window_test.py +++ b/src/controller/python/test/test_scripts/commissioning_window_test.py @@ -89,9 +89,9 @@ async def main(): "Failed to finish network commissioning") logger.info("Commissioning DUT from first commissioner") - FailIfNot(test.TestPaseOnly(ip=options.deviceAddress, setuppin=20202021, nodeid=1), + FailIfNot(await test.TestPaseOnly(ip=options.deviceAddress, setuppin=20202021, nodeid=1), "Unable to establish PASE connection to device") - FailIfNot(test.TestCommissionOnly(nodeid=1), "Unable to commission device") + FailIfNot(await test.TestCommissionOnly(nodeid=1), "Unable to commission device") logger.info("Creating controller on a new fabric") FailIfNot(test.CreateNewFabricController(), "Unable to create new controller") @@ -103,7 +103,7 @@ async def main(): "RevokeCommissioning test failed") logger.info("Test Enhanced Commissioning Window") - FailIfNot(test.TestEnhancedCommissioningWindow(ip=options.deviceAddress, nodeid=1), "EnhancedCommissioningWindow open failed") + FailIfNot(await test.TestEnhancedCommissioningWindow(ip=options.deviceAddress, nodeid=1), "EnhancedCommissioningWindow open failed") timeoutTicker.stop() diff --git a/src/controller/python/test/test_scripts/example_python_commissioning_flow.py b/src/controller/python/test/test_scripts/example_python_commissioning_flow.py index b10269257f2b08..016825a6f8c1aa 100644 --- a/src/controller/python/test/test_scripts/example_python_commissioning_flow.py +++ b/src/controller/python/test/test_scripts/example_python_commissioning_flow.py @@ -32,7 +32,7 @@ def __init__(self, devCtrl: ChipDeviceCtrl.ChipDeviceControllerBase, credential_ async def commission(self, parameter: commissioning.Parameters): # The example uses PASE, however, the blocks uses a node_id, which supports both PASE and CASE. - with pase.establish_session(devCtrl=self._devCtrl, parameter=parameter.pase_param) as device: + with await pase.establish_session(devCtrl=self._devCtrl, parameter=parameter.pase_param) as device: node_id = device.node_id self._logger.info("Sending ArmFailSafe to device") @@ -68,7 +68,7 @@ async def get_csr_nonce(self) -> bytes: async def get_commissionee_credentials(self, request: commissioning.GetCommissioneeCredentialsRequest) -> commissioning.GetCommissioneeCredentialsResponse: node_id = random.randint(100000, 999999) - nocChain = self._devCtrl.IssueNOCChain(Clusters.OperationalCredentials.Commands.CSRResponse( + nocChain = await self._devCtrl.IssueNOCChain(Clusters.OperationalCredentials.Commands.CSRResponse( NOCSRElements=request.csr_elements, attestationSignature=request.attestation_signature), nodeId=node_id) return commissioning.GetCommissioneeCredentialsResponse( rcac=nocChain.rcacBytes, diff --git a/src/controller/python/test/test_scripts/failsafe_tests.py b/src/controller/python/test/test_scripts/failsafe_tests.py index d1a2034e7359d5..d27111cbf76354 100755 --- a/src/controller/python/test/test_scripts/failsafe_tests.py +++ b/src/controller/python/test/test_scripts/failsafe_tests.py @@ -46,7 +46,7 @@ GROUP_ID = 0 -def main(): +async def main(): optParser = OptionParser() optParser.add_option( "-t", @@ -95,12 +95,12 @@ def main(): "Failed to finish network commissioning") logger.info("Testing commissioning") - FailIfNot(test.TestCommissioning(ip=options.deviceAddress, - setuppin=20202021, - nodeid=1), + FailIfNot(await test.TestCommissioning(ip=options.deviceAddress, + setuppin=20202021, + nodeid=1), "Failed to finish key exchange") - FailIfNot(asyncio.run(test.TestFailsafe(nodeid=1)), "Failed failsafe test") + FailIfNot(await test.TestFailsafe(nodeid=1), "Failed failsafe test") timeoutTicker.stop() @@ -113,7 +113,7 @@ def main(): if __name__ == "__main__": try: - main() + asyncio.run(main()) except Exception as ex: logger.exception(ex) TestFail("Exception occurred when running tests.") diff --git a/src/controller/python/test/test_scripts/mobile-device-test.py b/src/controller/python/test/test_scripts/mobile-device-test.py index 8f6f534dcefb96..179dfa079a6614 100755 --- a/src/controller/python/test/test_scripts/mobile-device-test.py +++ b/src/controller/python/test/test_scripts/mobile-device-test.py @@ -57,7 +57,7 @@ ALL_TESTS = ['network_commissioning', 'datamodel'] -def ethernet_commissioning(test: BaseTestHelper, discriminator: int, setup_pin: int, address_override: str, device_nodeid: int): +async def ethernet_commissioning(test: BaseTestHelper, discriminator: int, setup_pin: int, address_override: str, device_nodeid: int): logger.info("Testing discovery") device = test.TestDiscovery(discriminator=discriminator) FailIfNot(device, "Failed to discover any devices.") @@ -71,27 +71,27 @@ def ethernet_commissioning(test: BaseTestHelper, discriminator: int, setup_pin: address = address_override logger.info("Testing commissioning") - FailIfNot(test.TestCommissioning(ip=address, - setuppin=setup_pin, - nodeid=device_nodeid), + FailIfNot(await test.TestCommissioning(ip=address, + setuppin=setup_pin, + nodeid=device_nodeid), "Failed to finish key exchange") logger.info("Testing multi-controller setup on the same fabric") - FailIfNot(asyncio.run(test.TestMultiControllerFabric(nodeid=device_nodeid)), "Failed the multi-controller test") + FailIfNot(await test.TestMultiControllerFabric(nodeid=device_nodeid), "Failed the multi-controller test") logger.info("Testing CATs used on controllers") - FailIfNot(asyncio.run(test.TestControllerCATValues(nodeid=device_nodeid)), "Failed the controller CAT test") + FailIfNot(await test.TestControllerCATValues(nodeid=device_nodeid), "Failed the controller CAT test") - ok = asyncio.run(test.TestMultiFabric(ip=address, - setuppin=20202021, - nodeid=1)) + ok = await test.TestMultiFabric(ip=address, + setuppin=20202021, + nodeid=1) FailIfNot(ok, "Failed to commission multi-fabric") - FailIfNot(asyncio.run(test.TestAddUpdateRemoveFabric(nodeid=device_nodeid)), + FailIfNot(await test.TestAddUpdateRemoveFabric(nodeid=device_nodeid), "Failed AddUpdateRemoveFabric test") logger.info("Testing CASE Eviction") - FailIfNot(asyncio.run(test.TestCaseEviction(device_nodeid)), "Failed TestCaseEviction") + FailIfNot(await test.TestCaseEviction(device_nodeid), "Failed TestCaseEviction") logger.info("Testing closing sessions") FailIfNot(test.TestCloseSession(nodeid=device_nodeid), "Failed to close sessions") @@ -163,8 +163,8 @@ def do_tests(controller_nodeid, device_nodeid, address, timeout, discriminator, chip.logging.RedirectToPythonLogging() - ethernet_commissioning(test, discriminator, setup_pin, address, - device_nodeid) + asyncio.run(ethernet_commissioning(test, discriminator, setup_pin, address, + device_nodeid)) logger.info("Testing resolve") FailIfNot(test.TestResolve(nodeid=device_nodeid), diff --git a/src/controller/python/test/test_scripts/python_commissioning_flow_test.py b/src/controller/python/test/test_scripts/python_commissioning_flow_test.py index 2317a5571e7257..0f76095a96bf95 100755 --- a/src/controller/python/test/test_scripts/python_commissioning_flow_test.py +++ b/src/controller/python/test/test_scripts/python_commissioning_flow_test.py @@ -126,7 +126,7 @@ async def get_csr_nonce(self) -> bytes: async def get_commissionee_credentials(self, request: commissioning.GetCommissioneeCredentialsRequest) -> commissioning.GetCommissioneeCredentialsResponse: node_id = random.randint(100000, 999999) - nocChain = self._devCtrl.IssueNOCChain(Clusters.OperationalCredentials.Commands.CSRResponse( + nocChain = await self._devCtrl.IssueNOCChain(Clusters.OperationalCredentials.Commands.CSRResponse( NOCSRElements=request.csr_elements, attestationSignature=request.attestation_signature), nodeId=node_id) return commissioning.GetCommissioneeCredentialsResponse( rcac=nocChain.rcacBytes[1:], diff --git a/src/controller/python/test/test_scripts/split_commissioning_test.py b/src/controller/python/test/test_scripts/split_commissioning_test.py index 9233d58b90377d..864a6f357dd434 100755 --- a/src/controller/python/test/test_scripts/split_commissioning_test.py +++ b/src/controller/python/test/test_scripts/split_commissioning_test.py @@ -46,7 +46,7 @@ GROUP_ID = 0 -def main(): +async def main(): optParser = OptionParser() optParser.add_option( "-t", @@ -97,34 +97,34 @@ def main(): "Failed to finish network commissioning") logger.info("Testing PASE connection to device 1") - FailIfNot(test.TestPaseOnly(ip=options.deviceAddress1, - setuppin=20202021, - nodeid=1), + FailIfNot(await test.TestPaseOnly(ip=options.deviceAddress1, + setuppin=20202021, + nodeid=1), "Failed to establish PASE connection with device 1") logger.info("Testing PASE connection to device 2") - FailIfNot(test.TestPaseOnly(ip=options.deviceAddress2, - setuppin=20202021, - nodeid=2), + FailIfNot(await test.TestPaseOnly(ip=options.deviceAddress2, + setuppin=20202021, + nodeid=2), "Failed to establish PASE connection with device 2") logger.info("Attempting to execute a fabric-scoped command during PASE before AddNOC") - FailIfNot(test.TestFabricScopedCommandDuringPase(nodeid=1), + FailIfNot(await test.TestFabricScopedCommandDuringPase(nodeid=1), "Did not get UNSUPPORTED_ACCESS for fabric-scoped command during PASE") - FailIfNot(test.TestCommissionOnly(nodeid=1), + FailIfNot(await test.TestCommissionOnly(nodeid=1), "Failed to commission device 1") - FailIfNot(test.TestCommissionOnly(nodeid=2), + FailIfNot(await test.TestCommissionOnly(nodeid=2), "Failed to commission device 2") logger.info("Testing on off cluster on device 1") - FailIfNot(asyncio.run(test.TestOnOffCluster(nodeid=1, - endpoint=LIGHTING_ENDPOINT_ID)), "Failed to test on off cluster on device 1") + FailIfNot(await test.TestOnOffCluster(nodeid=1, + endpoint=LIGHTING_ENDPOINT_ID), "Failed to test on off cluster on device 1") logger.info("Testing on off cluster on device 2") - FailIfNot(asyncio.run(test.TestOnOffCluster(nodeid=2, - endpoint=LIGHTING_ENDPOINT_ID)), "Failed to test on off cluster on device 2") + FailIfNot(await test.TestOnOffCluster(nodeid=2, + endpoint=LIGHTING_ENDPOINT_ID), "Failed to test on off cluster on device 2") timeoutTicker.stop() @@ -137,7 +137,7 @@ def main(): if __name__ == "__main__": try: - main() + asyncio.run(main()) except Exception as ex: logger.exception(ex) TestFail("Exception occurred when running tests.") diff --git a/src/controller/python/test/test_scripts/subscription_resumption_capacity_test_ctrl1.py b/src/controller/python/test/test_scripts/subscription_resumption_capacity_test_ctrl1.py index e02564e293c04a..dc126a1d0400c4 100755 --- a/src/controller/python/test/test_scripts/subscription_resumption_capacity_test_ctrl1.py +++ b/src/controller/python/test/test_scripts/subscription_resumption_capacity_test_ctrl1.py @@ -32,7 +32,7 @@ TEST_ENDPOINT_ID = 0 -def main(): +async def main(): optParser = OptionParser() optParser.add_option( "-t", @@ -110,12 +110,12 @@ def main(): nodeid=112233, paaTrustStorePath=options.paaTrustStorePath, testCommissioner=True) FailIfNot( - test.TestOnNetworkCommissioning(options.discriminator, options.setuppin, options.nodeid, options.deviceAddress), - "Failed on on-network commissioing") + await test.TestOnNetworkCommissioning(options.discriminator, options.setuppin, options.nodeid, options.deviceAddress), + "Failed on on-network commissioning") FailIfNot( - asyncio.run(test.TestSubscriptionResumptionCapacityStep1( - options.nodeid, TEST_ENDPOINT_ID, options.setuppin, options.subscriptionCapacity)), + await test.TestSubscriptionResumptionCapacityStep1( + options.nodeid, TEST_ENDPOINT_ID, options.setuppin, options.subscriptionCapacity), "Failed on step 1 of testing subscription resumption capacity") timeoutTicker.stop() @@ -129,7 +129,7 @@ def main(): if __name__ == "__main__": try: - main() + asyncio.run(main()) except Exception as ex: logger.exception(ex) TestFail("Exception occurred when running tests.") diff --git a/src/controller/python/test/test_scripts/subscription_resumption_capacity_test_ctrl2.py b/src/controller/python/test/test_scripts/subscription_resumption_capacity_test_ctrl2.py index ac449a9f5478ac..2f50e80bf2fa75 100755 --- a/src/controller/python/test/test_scripts/subscription_resumption_capacity_test_ctrl2.py +++ b/src/controller/python/test/test_scripts/subscription_resumption_capacity_test_ctrl2.py @@ -34,7 +34,7 @@ TEST_SSH_PORT = 2222 -def main(): +async def main(): optParser = OptionParser() optParser.add_option( "-t", @@ -122,13 +122,12 @@ def main(): nodeid=112244, paaTrustStorePath=options.paaTrustStorePath, testCommissioner=True) FailIfNot( - test.TestOnNetworkCommissioning(options.discriminator, options.setuppin, options.nodeid, options.deviceAddress), - "Failed on on-network commissioing") + await test.TestOnNetworkCommissioning(options.discriminator, options.setuppin, options.nodeid, options.deviceAddress), + "Failed on on-network commissioning") FailIfNot( - asyncio.run( - test.TestSubscriptionResumptionCapacityStep2(options.nodeid, TEST_ENDPOINT_ID, options.deviceAddress, - TEST_SSH_PORT, options.remoteServerApp, options.subscriptionCapacity)), + await test.TestSubscriptionResumptionCapacityStep2(options.nodeid, TEST_ENDPOINT_ID, options.deviceAddress, + TEST_SSH_PORT, options.remoteServerApp, options.subscriptionCapacity), "Failed on testing subscription resumption capacity") timeoutTicker.stop() @@ -142,7 +141,7 @@ def main(): if __name__ == "__main__": try: - main() + asyncio.run(main()) except Exception as ex: logger.exception(ex) TestFail("Exception occurred when running tests.") diff --git a/src/controller/python/test/test_scripts/subscription_resumption_test.py b/src/controller/python/test/test_scripts/subscription_resumption_test.py index 79edf6a2898d0e..b7420c8c17ee73 100755 --- a/src/controller/python/test/test_scripts/subscription_resumption_test.py +++ b/src/controller/python/test/test_scripts/subscription_resumption_test.py @@ -34,7 +34,7 @@ TEST_SSH_PORT = 2222 -def main(): +async def main(): optParser = OptionParser() optParser.add_option( "-t", @@ -112,12 +112,12 @@ def main(): nodeid=112233, paaTrustStorePath=options.paaTrustStorePath, testCommissioner=True) FailIfNot( - test.TestOnNetworkCommissioning(options.discriminator, options.setuppin, options.nodeid, options.deviceAddress), - "Failed on on-network commissioing") + await test.TestOnNetworkCommissioning(options.discriminator, options.setuppin, options.nodeid, options.deviceAddress), + "Failed on on-network commissioning") FailIfNot( - asyncio.run(test.TestSubscriptionResumption(options.nodeid, TEST_ENDPOINT_ID, options.deviceAddress, - TEST_SSH_PORT, options.remoteServerApp)), "Failed to resume subscription") + await test.TestSubscriptionResumption(options.nodeid, TEST_ENDPOINT_ID, options.deviceAddress, + TEST_SSH_PORT, options.remoteServerApp), "Failed to resume subscription") timeoutTicker.stop() @@ -130,7 +130,7 @@ def main(): if __name__ == "__main__": try: - main() + asyncio.run(main()) except Exception as ex: logger.exception(ex) TestFail("Exception occurred when running tests.") diff --git a/src/controller/python/test/test_scripts/subscription_resumption_timeout_test.py b/src/controller/python/test/test_scripts/subscription_resumption_timeout_test.py index 4932e5b4cc0582..f4809a28a8e7a8 100755 --- a/src/controller/python/test/test_scripts/subscription_resumption_timeout_test.py +++ b/src/controller/python/test/test_scripts/subscription_resumption_timeout_test.py @@ -33,7 +33,7 @@ TEST_ENDPOINT_ID = 0 -def main(): +async def main(): optParser = OptionParser() optParser.add_option( "-t", @@ -102,13 +102,13 @@ def main(): nodeid=112233, paaTrustStorePath=options.paaTrustStorePath, testCommissioner=True) FailIfNot( - test.TestOnNetworkCommissioning(options.discriminator, options.setuppin, options.nodeid, options.deviceAddress), + await test.TestOnNetworkCommissioning(options.discriminator, options.setuppin, options.nodeid, options.deviceAddress), "Failed on on-network commissioning") try: - asyncio.run(test.devCtrl.ReadAttribute(options.nodeid, - [(TEST_ENDPOINT_ID, Clusters.BasicInformation.Attributes.NodeLabel)], - None, False, reportInterval=(1, 2), keepSubscriptions=True, autoResubscribe=False)) + await test.devCtrl.ReadAttribute(options.nodeid, + [(TEST_ENDPOINT_ID, Clusters.BasicInformation.Attributes.NodeLabel)], + None, False, reportInterval=(1, 2), keepSubscriptions=True, autoResubscribe=False) except Exception as ex: TestFail(f"Failed to subscribe attribute: {ex}") @@ -123,7 +123,7 @@ def main(): if __name__ == "__main__": try: - main() + asyncio.run(main()) except Exception as ex: logger.exception(ex) TestFail("Exception occurred when running tests.") diff --git a/src/python_testing/TC_ACE_1_5.py b/src/python_testing/TC_ACE_1_5.py index bab70260fc6508..c8ef4109546e18 100644 --- a/src/python_testing/TC_ACE_1_5.py +++ b/src/python_testing/TC_ACE_1_5.py @@ -51,10 +51,10 @@ async def test_TC_ACE_1_5(self): self.th2 = new_fabric_admin.NewController(nodeId=TH2_nodeid, paaTrustStorePath=str(self.matter_test_config.paa_trust_store_path)) - params = self.openCommissioningWindow(self.th1, self.dut_node_id) + params = await self.openCommissioningWindow(self.th1, self.dut_node_id) self.print_step(2, "TH1 opens the commissioning window on the DUT") - self.th2.CommissionOnNetwork( + await self.th2.CommissionOnNetwork( nodeId=self.dut_node_id, setupPinCode=params.commissioningParameters.setupPinCode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=params.randomDiscriminator) logging.info('Commissioning complete done. Successful.') diff --git a/src/python_testing/TC_CGEN_2_4.py b/src/python_testing/TC_CGEN_2_4.py index e9ab9d85c28e73..469d97e39d7a38 100644 --- a/src/python_testing/TC_CGEN_2_4.py +++ b/src/python_testing/TC_CGEN_2_4.py @@ -42,9 +42,9 @@ class TC_CGEN_2_4(MatterBaseTest): - def OpenCommissioningWindow(self) -> CommissioningParameters: + async def OpenCommissioningWindow(self) -> CommissioningParameters: try: - params = self.th1.OpenCommissioningWindow( + params = await self.th1.OpenCommissioningWindow( nodeid=self.dut_node_id, timeout=600, iteration=10000, discriminator=self.discriminator, option=1) return params @@ -56,14 +56,14 @@ async def CommissionToStageSendCompleteAndCleanup( self, stage: int, expectedErrorPart: chip.native.ErrorSDKPart, expectedErrCode: int): logging.info("-----------------Fail on step {}-------------------------".format(stage)) - params = self.OpenCommissioningWindow() + params = await self.OpenCommissioningWindow() self.th2.ResetTestCommissioner() # This will run the commissioning up to the point where stage x is run and the # response is sent before the test commissioner simulates a failure self.th2.SetTestCommissionerPrematureCompleteAfter(stage) ctx = asserts.assert_raises(ChipStackError) with ctx: - self.th2.CommissionOnNetwork( + await self.th2.CommissionOnNetwork( nodeId=self.dut_node_id, setupPinCode=params.setupPinCode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=self.discriminator) errcode = ctx.exception.chip_error @@ -99,12 +99,12 @@ async def test_TC_CGEN_2_4(self): await self.CommissionToStageSendCompleteAndCleanup(kSendNOC, chip.native.ErrorSDKPart.IM_CLUSTER_STATUS, 0x02) logging.info('Step 15 - TH1 opens a commissioning window') - params = self.OpenCommissioningWindow() + params = await self.OpenCommissioningWindow() logging.info('Step 16 - TH2 fully commissions the DUT') self.th2.ResetTestCommissioner() - self.th2.CommissionOnNetwork( + await self.th2.CommissionOnNetwork( nodeId=self.dut_node_id, setupPinCode=params.setupPinCode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=self.discriminator) logging.info('Commissioning complete done.') diff --git a/src/python_testing/TC_DA_1_5.py b/src/python_testing/TC_DA_1_5.py index 17c6e3c16da0fb..e42b530057683e 100644 --- a/src/python_testing/TC_DA_1_5.py +++ b/src/python_testing/TC_DA_1_5.py @@ -162,7 +162,7 @@ async def test_TC_DA_1_5(self): await self.send_single_cmd(cmd=gcomm.Commands.ArmFailSafe(expiryLengthSeconds=0, breadcrumb=1)) self.print_step(13, "Open commissioning window") - params = self.default_controller.OpenCommissioningWindow( + params = await self.default_controller.OpenCommissioningWindow( nodeid=self.dut_node_id, timeout=600, iteration=10000, discriminator=1234, option=1) self.print_step(14, "Commission to TH2") @@ -170,7 +170,7 @@ async def test_TC_DA_1_5(self): new_fabric_admin = new_certificate_authority.NewFabricAdmin(vendorId=0xFFF1, fabricId=2) TH2 = new_fabric_admin.NewController(nodeId=112233) - TH2.CommissionOnNetwork( + await TH2.CommissionOnNetwork( nodeId=self.dut_node_id, setupPinCode=params.setupPinCode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=1234) diff --git a/src/python_testing/TC_IDM_1_2.py b/src/python_testing/TC_IDM_1_2.py index 87ede456dacb1a..92b30bd172320c 100644 --- a/src/python_testing/TC_IDM_1_2.py +++ b/src/python_testing/TC_IDM_1_2.py @@ -187,7 +187,7 @@ async def test_TC_IDM_1_2(self): # To get a PASE session, we need an open commissioning window discriminator = random.randint(0, 4095) - params = self.default_controller.OpenCommissioningWindow( + params = await self.default_controller.OpenCommissioningWindow( nodeid=self.dut_node_id, timeout=600, iteration=10000, discriminator=discriminator, option=1) # TH2 = new controller that's not connected over CASE @@ -201,14 +201,14 @@ async def test_TC_IDM_1_2(self): device = next(filter(lambda d: d.commissioningMode == 2 and d.longDiscriminator == discriminator, devices)) for a in device.addresses: try: - TH2.EstablishPASESessionIP(ipaddr=a, setupPinCode=params.setupPinCode, - nodeid=self.dut_node_id+1, port=device.port) + await TH2.EstablishPASESessionIP(ipaddr=a, setupPinCode=params.setupPinCode, + nodeid=self.dut_node_id+1, port=device.port) break except ChipStackError: continue try: - TH2.GetConnectedDeviceSync(nodeid=self.dut_node_id+1, allowPASE=True, timeoutMs=1000) + await TH2.GetConnectedDevice(nodeid=self.dut_node_id+1, allowPASE=True, timeoutMs=1000) except TimeoutError: asserts.fail("Unable to establish a PASE session to the device") @@ -263,7 +263,7 @@ async def test_TC_IDM_1_2(self): # Try with RevokeCommissioning # First open a commissioning window for us to revoke, so we know this command is able to succeed absent this error - _ = self.default_controller.OpenCommissioningWindow( + _ = await self.default_controller.OpenCommissioningWindow( nodeid=self.dut_node_id, timeout=600, iteration=10000, discriminator=discriminator, option=1) cmd = FakeRevokeCommissioning() try: diff --git a/src/python_testing/TC_OPCREDS_3_1.py b/src/python_testing/TC_OPCREDS_3_1.py index 661c3b0b9cd8fb..32f3ec7b1f4d20 100644 --- a/src/python_testing/TC_OPCREDS_3_1.py +++ b/src/python_testing/TC_OPCREDS_3_1.py @@ -30,7 +30,7 @@ class TC_OPCREDS_3_1(MatterBaseTest): - def FindAndEstablishPase(self, longDiscriminator: int, setupPinCode: int, nodeid: int, dev_ctrl: ChipDeviceCtrl = None): + async def FindAndEstablishPase(self, longDiscriminator: int, setupPinCode: int, nodeid: int, dev_ctrl: ChipDeviceCtrl = None): if dev_ctrl is None: dev_ctrl = self.default_controller @@ -41,8 +41,8 @@ def FindAndEstablishPase(self, longDiscriminator: int, setupPinCode: int, nodeid Discovery.FilterType.LONG_DISCRIMINATOR and d.longDiscriminator == longDiscriminator, devices)) for a in device.addresses: try: - dev_ctrl.EstablishPASESessionIP(ipaddr=a, setupPinCode=setupPinCode, - nodeid=nodeid, port=device.port) + await dev_ctrl.EstablishPASESessionIP(ipaddr=a, setupPinCode=setupPinCode, + nodeid=nodeid, port=device.port) break except ChipStackError: continue @@ -51,11 +51,11 @@ def FindAndEstablishPase(self, longDiscriminator: int, setupPinCode: int, nodeid except TimeoutError: asserts.fail("Unable to establish a PASE session to the device") - def OpenCommissioningWindow(self, dev_ctrl: ChipDeviceCtrl, node_id: int): + async def OpenCommissioningWindow(self, dev_ctrl: ChipDeviceCtrl, node_id: int): # TODO: abstract this in the base layer? Do we do this a lot? longDiscriminator = random.randint(0, 4095) try: - params = dev_ctrl.OpenCommissioningWindow( + params = await dev_ctrl.OpenCommissioningWindow( nodeid=node_id, timeout=600, iteration=10000, discriminator=longDiscriminator, option=ChipDeviceCtrl.ChipDeviceControllerBase.CommissioningWindowPasscode.kTokenWithRandomPin) except Exception as e: logging.exception('Error running OpenCommissioningWindow %s', e) @@ -85,7 +85,7 @@ async def test_TC_OPCREDS_3_1(self): "Device fabric table is full - please remove one fabric and retry") self.print_step(1, "TH0 opens a commissioning window on the DUT") - longDiscriminator, params = self.OpenCommissioningWindow(self.default_controller, self.dut_node_id) + longDiscriminator, params = await self.OpenCommissioningWindow(self.default_controller, self.dut_node_id) self.print_step( 2, "TH0 reads the BasicCommissioningInfo field from the General commissioning cluster saves MaxCumulativeFailsafeSeconds as `failsafe_max`") @@ -94,8 +94,8 @@ async def test_TC_OPCREDS_3_1(self): self.print_step(3, "TH1 opens a PASE connection to the DUT") newNodeId = self.dut_node_id + 1 - self.FindAndEstablishPase(dev_ctrl=TH1, longDiscriminator=longDiscriminator, - setupPinCode=params.setupPinCode, nodeid=newNodeId) + await self.FindAndEstablishPase(dev_ctrl=TH1, longDiscriminator=longDiscriminator, + setupPinCode=params.setupPinCode, nodeid=newNodeId) self.print_step(4, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to failsafe_max") resp = await self.send_single_cmd(dev_ctrl=TH1, node_id=newNodeId, cmd=Clusters.GeneralCommissioning.Commands.ArmFailSafe(failsafe_max)) @@ -109,7 +109,7 @@ async def test_TC_OPCREDS_3_1(self): self.print_step(6, "TH1 obtains or generates the NOC, the Root CA Certificate and ICAC using csrResponse and selects an IPK. The certificates shall have their subjects padded with additional data such that they are each the maximum certificate size of 400 bytes when encoded in the MatterCertificateEncoding.") # Our CA is set up to maximize cert chains already # Extract the RCAC public key and save as `Root_Public_Key_TH1` - TH1_certs_real = TH1.IssueNOCChain(csrResponse, newNodeId) + TH1_certs_real = await TH1.IssueNOCChain(csrResponse, newNodeId) if (TH1_certs_real.rcacBytes is None or TH1_certs_real.icacBytes is None or TH1_certs_real.nocBytes is None or TH1_certs_real.ipkBytes is None): @@ -125,7 +125,7 @@ async def test_TC_OPCREDS_3_1(self): TH1_CA_fake = self.certificate_authority_manager.NewCertificateAuthority() TH1_fabric_admin_fake = TH1_CA_fake.NewFabricAdmin(vendorId=0xFFF1, fabricId=2) TH1_fake = TH1_fabric_admin_fake.NewController(nodeId=self.default_controller.nodeId) - TH1_certs_fake = TH1_fake.IssueNOCChain(csrResponse, newNodeId) + TH1_certs_fake = await TH1_fake.IssueNOCChain(csrResponse, newNodeId) if (TH1_certs_fake.rcacBytes is None or TH1_certs_fake.icacBytes is None or TH1_certs_fake.nocBytes is None or TH1_certs_real.ipkBytes is None): @@ -361,7 +361,7 @@ async def test_TC_OPCREDS_3_1(self): asserts.assert_equal(len(fabrics), fabrics_original_size, "Fabric list size does not match original") self.print_step(37, "TH1 fully commissions DUT onto the fabric using a set of valid certificates") - TH1.Commission(newNodeId) + await TH1.Commission(newNodeId) self.print_step( 38, "TH1 reads the TrustedRootCertificates list from DUT and verify that there are trusted_root_original_size + 1 entries") @@ -404,7 +404,7 @@ async def test_TC_OPCREDS_3_1(self): resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kOk, "Failure on UpdateFabricLabel") self.print_step(44, "TH1 sends an OpenCommissioningWindow command to the Administrator Commissioning cluster") - longDiscriminator, params = self.OpenCommissioningWindow(TH1, newNodeId) + longDiscriminator, params = await self.OpenCommissioningWindow(TH1, newNodeId) self.print_step(45, "TH2 commissions the DUT") TH2_CA = self.certificate_authority_manager.NewCertificateAuthority(maximizeCertChains=True) @@ -413,7 +413,7 @@ async def test_TC_OPCREDS_3_1(self): TH2_nodeid = self.default_controller.nodeId+2 TH2 = TH2_fabric_admin.NewController(nodeId=TH2_nodeid) TH2_dut_nodeid = self.dut_node_id+2 - TH2.CommissionOnNetwork( + await TH2.CommissionOnNetwork( nodeId=TH2_dut_nodeid, setupPinCode=params.setupPinCode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=longDiscriminator) @@ -484,7 +484,7 @@ async def test_TC_OPCREDS_3_1(self): temp_CA = self.certificate_authority_manager.NewCertificateAuthority() temp_fabric_admin = temp_CA.NewFabricAdmin(vendorId=0xFFF1, fabricId=3) temp_controller = temp_fabric_admin.NewController(nodeId=self.default_controller.nodeId) - temp_certs = temp_controller.IssueNOCChain(csrResponse, newNodeId) + temp_certs = await temp_controller.IssueNOCChain(csrResponse, newNodeId) if (temp_certs.rcacBytes is None or temp_certs.icacBytes is None or temp_certs.nocBytes is None or temp_certs.ipkBytes is None): @@ -521,7 +521,7 @@ async def test_TC_OPCREDS_3_1(self): self.print_step(61, "TH1 obtains or generates a NOC and ICAC using the CSR elements from the previous step with a different NodeID, but the same Root CA Certificate and fabric ID as step <>. Save as `Node_Operational_Certificates_TH1_fabric_conflict` and `Intermediate_Certificate_TH1_fabric_conflict`|") anotherNodeId = newNodeId + 1 - TH1_certs_fabric_conflict = TH1.IssueNOCChain(csrResponse_new, anotherNodeId) + TH1_certs_fabric_conflict = await TH1.IssueNOCChain(csrResponse_new, anotherNodeId) if (TH1_certs_fabric_conflict.rcacBytes is None or TH1_certs_fabric_conflict.icacBytes is None or TH1_certs_fabric_conflict.nocBytes is None or TH1_certs_fabric_conflict.ipkBytes is None): @@ -565,7 +565,7 @@ async def test_TC_OPCREDS_3_1(self): "Unexpected response type for UpdateNOC csr request") self.print_step(68, "TH1 obtains or generates a NOC, Root CA Certificate, ICAC using the CSR elements from the previous step") - TH1_certs_3 = TH1.IssueNOCChain(csrResponse, anotherNodeId) + TH1_certs_3 = await TH1.IssueNOCChain(csrResponse, anotherNodeId) if (TH1_certs_3.rcacBytes is None or TH1_certs_3.icacBytes is None or TH1_certs_3.nocBytes is None or TH1_certs_3.ipkBytes is None): diff --git a/src/python_testing/TC_TIMESYNC_2_13.py b/src/python_testing/TC_TIMESYNC_2_13.py index fa43bbd00cffcb..dea41e505c31c8 100644 --- a/src/python_testing/TC_TIMESYNC_2_13.py +++ b/src/python_testing/TC_TIMESYNC_2_13.py @@ -45,7 +45,7 @@ async def test_TC_TIMESYNC_2_13(self): self.print_step(0, "Commissioning, already done") self.print_step(1, "TH1 opens a commissioning window") - params = self.default_controller.OpenCommissioningWindow( + params = await self.default_controller.OpenCommissioningWindow( nodeid=self.dut_node_id, timeout=600, iteration=10000, discriminator=1234, option=1) self.print_step(2, "Commission to TH2") @@ -53,7 +53,7 @@ async def test_TC_TIMESYNC_2_13(self): new_fabric_admin = new_certificate_authority.NewFabricAdmin(vendorId=0xFFF1, fabricId=2) TH2 = new_fabric_admin.NewController(nodeId=112233) - TH2.CommissionOnNetwork( + await TH2.CommissionOnNetwork( nodeId=self.dut_node_id, setupPinCode=params.setupPinCode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=1234) diff --git a/src/python_testing/TestCommissioningTimeSync.py b/src/python_testing/TestCommissioningTimeSync.py index 0fca7063fcc666..dfd03d957d4f0b 100644 --- a/src/python_testing/TestCommissioningTimeSync.py +++ b/src/python_testing/TestCommissioningTimeSync.py @@ -56,9 +56,9 @@ async def teardown_test(self): return super().teardown_test() async def commission_and_base_checks(self): - params = self.default_controller.OpenCommissioningWindow( + params = await self.default_controller.OpenCommissioningWindow( nodeid=self.dut_node_id, timeout=600, iteration=10000, discriminator=1234, option=1) - self.commissioner.CommissionOnNetwork( + await self.commissioner.CommissionOnNetwork( nodeId=self.dut_node_id, setupPinCode=params.setupPinCode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=1234) self.commissioned = True diff --git a/src/python_testing/basic_composition_support.py b/src/python_testing/basic_composition_support.py index 8cc958a7207b3d..69f9633962eaca 100644 --- a/src/python_testing/basic_composition_support.py +++ b/src/python_testing/basic_composition_support.py @@ -98,10 +98,10 @@ def ConvertValue(value) -> Any: class BasicCompositionTests: - def connect_over_pase(self, dev_ctrl): + async def connect_over_pase(self, dev_ctrl): setupCode = self.matter_test_config.qr_code_content if self.matter_test_config.qr_code_content is not None else self.matter_test_config.manual_code asserts.assert_true(setupCode, "Require either --qr-code or --manual-code.") - dev_ctrl.FindOrEstablishPASESession(setupCode, self.dut_node_id) + await dev_ctrl.FindOrEstablishPASESession(setupCode, self.dut_node_id) def dump_wildcard(self, dump_device_composition_path: typing.Optional[str]): node_dump_dict = {endpoint_id: MatterTlvToJson(self.endpoints_tlv[endpoint_id]) for endpoint_id in self.endpoints_tlv} @@ -121,7 +121,7 @@ async def setup_class_helper(self, default_to_pase: bool = True): dump_device_composition_path: Optional[str] = self.user_params.get("dump_device_composition_path", None) if do_test_over_pase: - self.connect_over_pase(dev_ctrl) + await self.connect_over_pase(dev_ctrl) node_id = self.dut_node_id else: # Using the already commissioned node diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index 231640f2c3ddf5..03d69e71566eaa 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -766,11 +766,11 @@ def check_pics(self, pics_key: str) -> bool: pics_key = pics_key.strip() return pics_key in picsd and picsd[pics_key] - def openCommissioningWindow(self, dev_ctrl: ChipDeviceCtrl, node_id: int) -> CustomCommissioningParameters: + async def openCommissioningWindow(self, dev_ctrl: ChipDeviceCtrl, node_id: int) -> CustomCommissioningParameters: rnd_discriminator = random.randint(0, 4095) try: - commissioning_params = dev_ctrl.OpenCommissioningWindow(nodeid=node_id, timeout=900, iteration=1000, - discriminator=rnd_discriminator, option=1) + commissioning_params = await dev_ctrl.OpenCommissioningWindow(nodeid=node_id, timeout=900, iteration=1000, + discriminator=rnd_discriminator, option=1) params = CustomCommissioningParameters(commissioning_params, rnd_discriminator) return params @@ -1524,10 +1524,10 @@ def test_run_commissioning(self): (conf.root_of_trust_index, conf.fabric_id, node_id)) logging.info("Commissioning method: %s" % conf.commissioning_method) - if not self._commission_device(commission_idx): + if not asyncio.run(self._commission_device(commission_idx)): raise signals.TestAbortAll("Failed to commission node") - def _commission_device(self, i) -> bool: + async def _commission_device(self, i) -> bool: dev_ctrl = self.default_controller conf = self.matter_test_config @@ -1543,7 +1543,7 @@ def _commission_device(self, i) -> bool: if conf.commissioning_method == "on-network": try: - dev_ctrl.CommissionOnNetwork( + await dev_ctrl.CommissionOnNetwork( nodeId=conf.dut_node_ids[i], setupPinCode=info.passcode, filterType=info.filter_type, @@ -1555,7 +1555,7 @@ def _commission_device(self, i) -> bool: return False elif conf.commissioning_method == "ble-wifi": try: - dev_ctrl.CommissionWiFi( + await dev_ctrl.CommissionWiFi( info.filter_value, info.passcode, conf.dut_node_ids[i], @@ -1569,7 +1569,7 @@ def _commission_device(self, i) -> bool: return False elif conf.commissioning_method == "ble-thread": try: - dev_ctrl.CommissionThread( + await dev_ctrl.CommissionThread( info.filter_value, info.passcode, conf.dut_node_ids[i], @@ -1583,7 +1583,7 @@ def _commission_device(self, i) -> bool: elif conf.commissioning_method == "on-network-ip": try: logging.warning("==== USING A DIRECT IP COMMISSIONING METHOD NOT SUPPORTED IN THE LONG TERM ====") - dev_ctrl.CommissionIP( + await dev_ctrl.CommissionIP( ipaddr=conf.commissionee_ip_address_just_for_testing, setupPinCode=info.passcode, nodeid=conf.dut_node_ids[i] )