| # | |
| # Copyright (c) 2025 Project CHIP Authors | |
| # All rights reserved. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| # | |
| # See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments | |
| # for details about the block below. | |
| # | |
| import asyncio | |
| from mobly import asserts | |
| from matter.testing.decorators import async_test_body | |
| from matter.testing.matter_testing import CertificationUnitTestNoDevice, TestStep | |
| from matter.testing.runner import default_matter_test_main | |
| class TestCreateNewController(CertificationUnitTestNoDevice): | |
| # Using get_code and a modified version of setup_class_helper functions from chip.testing.basic_composition module | |
| def get_code(self, dev_ctrl): | |
| created_codes = [] | |
| for idx, discriminator in enumerate(self.matter_test_config.discriminators): | |
| created_codes.append(dev_ctrl.CreateManualCode(discriminator, self.matter_test_config.setup_passcodes[idx])) | |
| setup_codes = self.matter_test_config.qr_code_content + self.matter_test_config.manual_code + created_codes | |
| if not setup_codes: | |
| return None | |
| asserts.assert_equal(len(setup_codes), 1, | |
| "Require exactly one of either --qr-code, --manual-code or (--discriminator and --passcode).") | |
| return setup_codes[0] | |
| async def setup_class_helper(self, allow_pase: bool = True): | |
| dev_ctrl = self.default_controller | |
| self.problems = [] | |
| node_id = self.dut_node_id | |
| task_list = [] | |
| if allow_pase and self.get_code(dev_ctrl): | |
| setup_code = self.get_code(dev_ctrl) | |
| pase_future = dev_ctrl.EstablishPASESession(setup_code, self.dut_node_id) | |
| task_list.append(asyncio.create_task(pase_future)) | |
| case_future = dev_ctrl.GetConnectedDevice(nodeid=node_id, allowPASE=False) | |
| task_list.append(asyncio.create_task(case_future)) | |
| for task in task_list: | |
| asyncio.ensure_future(task) | |
| done, pending = await asyncio.wait(task_list, return_when=asyncio.FIRST_COMPLETED) | |
| for task in pending: | |
| try: | |
| task.cancel() | |
| await task | |
| except asyncio.CancelledError: | |
| pass | |
| wildcard_read = (await dev_ctrl.Read(node_id, [()])) | |
| # ======= State kept for use by all tests ======= | |
| # All endpoints in "full object" indexing format | |
| self.endpoints = wildcard_read.attributes | |
| def steps_TestCreateNewController(self) -> list[TestStep]: | |
| return [ | |
| TestStep(1, "Commissioning, already done"), | |
| TestStep(2, "Checking create new controller on new fabric"), | |
| TestStep(3, "Remove new fabric from TH to verify it can be removed after creation"), | |
| TestStep(4, "Checking create new controller on existing fabric"), | |
| TestStep(5, "Remove fabric from TH to verify it can be removed after creation") | |
| ] | |
| @async_test_body | |
| async def setup_class(self): | |
| self.commissioner = None | |
| self.commissioned = False | |
| return super().setup_class() | |
| # ======= START OF ACTUAL TESTS ======= | |
| @async_test_body | |
| async def test_TestCreateNewController(self): | |
| self.step(1) | |
| self.endpoint = self.get_endpoint() | |
| asserts.assert_false(self.endpoint is None, "--endpoint <endpoint> must be included on the command line in.") | |
| self.th1 = self.default_controller | |
| self.step(2) | |
| th2_fabric_admin = self.certificate_authority_manager.new_fabric_admin(vendorId=0xFFF1, fabricId=self.th1.fabricId + 1) | |
| self.th2 = th2_fabric_admin.NewController(nodeId=2) | |
| self.step(3) | |
| self.th2.Shutdown() | |
| self.step(4) | |
| self.th3 = self.certificate_authority_manager.activeCaList[0].adminList[0].NewController(nodeId=2) | |
| self.step(5) | |
| self.th3.Shutdown() | |
| if __name__ == "__main__": | |
| default_matter_test_main() |