From 65c76cf1cdb5d6ec46593f9767d407f51704f094 Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Tue, 21 May 2024 23:34:18 -0700 Subject: [PATCH 01/23] chore(TC_OPCREDS_3.4): skeleton class --- src/python_testing/TC_OPCREDS_3_4.py | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/python_testing/TC_OPCREDS_3_4.py diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py new file mode 100644 index 00000000000000..d42e25a4da9638 --- /dev/null +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -0,0 +1,31 @@ +# +# Copyright (c) 2024 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. +# + +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main + + +class TC_OPCREDS_3_4(MatterBaseTest): + # TODO: Implement + + @async_test_body + async def test_TC_OPCREDS_3_4(self): + # TODO: add steps + self.print_step(0, "Preconditions") + + +if __name__ == "__main__": + default_matter_test_main() From 440adc14f2fa1397fba027b3b674bed1c6ca182d Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Wed, 10 Jul 2024 02:15:31 -0700 Subject: [PATCH 02/23] chore(TC_OPCREDS_3.4): implementation until step CSRRequest IsForUpdatedNOC=True --- .../chip/utils/CommissioningBuildingBlocks.py | 7 +- src/python_testing/TC_OPCREDS_3_2.py | 4 +- src/python_testing/TC_OPCREDS_3_4.py | 108 ++++++++++++++++++ 3 files changed, 114 insertions(+), 5 deletions(-) diff --git a/src/controller/python/chip/utils/CommissioningBuildingBlocks.py b/src/controller/python/chip/utils/CommissioningBuildingBlocks.py index 4c3826fd6914ee..0ee291a7a20265 100644 --- a/src/controller/python/chip/utils/CommissioningBuildingBlocks.py +++ b/src/controller/python/chip/utils/CommissioningBuildingBlocks.py @@ -183,8 +183,9 @@ async def AddNOCForNewFabricFromExisting(commissionerDevCtrl, newFabricDevCtrl, chainForAddNOC.ipkBytes, newFabricDevCtrl.nodeId, newFabricDevCtrl.fabricAdmin.vendorId)) - - rcacResp = chainForAddNOC.rcacBytes + nocBytes = chainForAddNOC.nocBytes + icacBytes = chainForAddNOC.icacBytes + rcacBytes = chainForAddNOC.rcacBytes if nocResp.statusCode is not opCreds.Enums.NodeOperationalCertStatusEnum.kOk: # Expiring the failsafe timer in an attempt to clean up. @@ -201,7 +202,7 @@ async def AddNOCForNewFabricFromExisting(commissionerDevCtrl, newFabricDevCtrl, if not await _IsNodeInFabricList(newFabricDevCtrl, newNodeId): return False, nocResp - return True, nocResp, rcacResp + return True, nocResp, nocBytes, rcacBytes, icacBytes async def UpdateNOC(devCtrl, existingNodeId, newNodeId): diff --git a/src/python_testing/TC_OPCREDS_3_2.py b/src/python_testing/TC_OPCREDS_3_2.py index 5b7cd5bd59480e..4b0c9a8a1b7d34 100644 --- a/src/python_testing/TC_OPCREDS_3_2.py +++ b/src/python_testing/TC_OPCREDS_3_2.py @@ -74,7 +74,7 @@ async def test_TC_OPCREDS_3_2(self): cr2_new_admin_ctrl = cr2_new_fabric_admin.NewController( nodeId=cr2_nodeid) - success, nocResp, rcacResp = await CommissioningBuildingBlocks.AddNOCForNewFabricFromExisting( + success, nocResp, nocBytes, rcacResp, icacBytes = await CommissioningBuildingBlocks.AddNOCForNewFabricFromExisting( commissionerDevCtrl=dev_ctrl, newFabricDevCtrl=cr2_new_admin_ctrl, existingNodeId=self.dut_node_id, newNodeId=cr2_dut_node_id ) @@ -94,7 +94,7 @@ async def test_TC_OPCREDS_3_2(self): cr3_new_admin_ctrl = cr3_new_fabric_admin.NewController( nodeId=cr3_nodeid) - success, nocResp, rcacResp = await CommissioningBuildingBlocks.AddNOCForNewFabricFromExisting( + success, nocResp, nocBytes, rcacResp, icacBytes = await CommissioningBuildingBlocks.AddNOCForNewFabricFromExisting( commissionerDevCtrl=dev_ctrl, newFabricDevCtrl=cr3_new_admin_ctrl, existingNodeId=self.dut_node_id, newNodeId=cr3_dut_node_id ) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index d42e25a4da9638..f611ced5a7ff4e 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -15,7 +15,13 @@ # limitations under the License. # +import random + +import chip.clusters as Clusters +from chip.utils import CommissioningBuildingBlocks +from chip.interaction_model import InteractionModelError, Status from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts class TC_OPCREDS_3_4(MatterBaseTest): @@ -26,6 +32,108 @@ async def test_TC_OPCREDS_3_4(self): # TODO: add steps self.print_step(0, "Preconditions") + self.print_step(1, "TH1 fully commissions the DUT") + opcreds = Clusters.OperationalCredentials + dev_ctrl = self.default_controller + + new_certificate_authority = self.certificate_authority_manager.NewCertificateAuthority() + th1_vid = 0xFFF1 + th1_fabricId = 1111 + th1_new_fabric_admin = new_certificate_authority.NewFabricAdmin( + vendorId=th1_vid, fabricId=th1_fabricId) + th1_nodeId = self.default_controller.nodeId+1 + th1_dut_node_id = self.dut_node_id+1 + + th1_new_fabric_ctrl = th1_new_fabric_admin.NewController( + nodeId=th1_nodeId) + success, nocResp, noc_original, rcac_original, icac_original = await CommissioningBuildingBlocks.AddNOCForNewFabricFromExisting( + commissionerDevCtrl=dev_ctrl, newFabricDevCtrl=th1_new_fabric_ctrl, + existingNodeId=self.dut_node_id, newNodeId=th1_dut_node_id + ) + + self.print_step( + 2, "TH1 reads the NOCs attribute from the Node Operational Credentials cluster using a fabric-filtered read") + nocs = await self.read_single_attribute_check_success(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.NOCs, fabric_filtered=True) + + self.print_step( + 3, "TH1 reads the TrustedRootCertificates attribute from the Node Operational Credentials cluster") + trusted_root_original = await self.read_single_attribute_check_success( + dev_ctrl=th1_new_fabric_ctrl, + node_id=th1_dut_node_id, cluster=opcreds, + attribute=opcreds.Attributes.TrustedRootCertificates) + print("trusted_root_original: ", trusted_root_original) + + self.print_step( + 4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") + cmd = opcreds.Commands.UpdateNOC( + NOCValue=noc_original, ICACValue=icac_original) + try: + await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + asserts.fail("Unexpected error sending UpdateNOC command") + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.FailsafeRequired, "Unexpected Failsafe status") + + self.print_step( + 5, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900") + cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe( + expiryLengthSeconds=900) + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + print(resp) + asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, + "Failure status returned from arm failsafe") + + self.print_step( + 6, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") + cmd = opcreds.Commands.UpdateNOC( + NOCValue=noc_original, ICACValue=icac_original) + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr, + "Failure status returned from UpdateNOC") + + self.print_step( + 7, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to false") + cmd = opcreds.Commands.CSRRequest( + CSRNonce=random.randbytes(32), isForUpdateNOC=False) + csr_not_updated = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + print("csr_not_updated: ", csr_not_updated) + + self.print_step( + 8, "TH1 generates a new NOC chain with ICAC with the following properties") + new_noc_chain = th1_new_fabric_ctrl.IssueNOCChain( + csr_not_updated, th1_dut_node_id) + noc_not_for_update = csr_not_updated.NOCSRElements + icac_not_for_update = new_noc_chain.icacBytes + # TODO: Ask to @Cecille if ICACvalue should be get from new NOCchain or must be get from somewhere else? + + self.print_step( + 9, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") + cmd = opcreds.Commands.UpdateNOC( + NOCValue=noc_not_for_update, ICACValue=icac_not_for_update) + try: + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + asserts.fail("Unexpected error sending UpdateNOC command") + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.ConstraintError, "Failure status returned from UpdateNOC") + + self.print_step( + 10, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to true") + # resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=Clusters.GeneralCommissioning.Commands.ArmFailSafe(300)) + # print("ArmFailSafe 600: ", resp) + cmd = opcreds.Commands.CSRRequest( + CSRNonce=random.randbytes(32), isForUpdateNOC=True) + csr_update = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + # I don't know why but I received an FAILURE error if set the isForUpdateNOC with True instead if I use False I get ConstraintError + + # cmd = opcreds.Commands.AddTrustedRootCertificate(rcac_original) + # await self.send_single_cmd(cmd=cmd, dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id) + # temp_certs = th1_new_fabric_ctrl.IssueNOCChain(csr_update, th1_dut_node_id) + + cmd = opcreds.Commands.UpdateNOC( + NOCValue=noc_original, ICACValue=icac_original) + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + if __name__ == "__main__": default_matter_test_main() From c74e99b8268aa4a7a31c579153af76e9aca56ff7 Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Mon, 15 Jul 2024 15:27:03 -0700 Subject: [PATCH 03/23] chore(TC_OPCREDS_3.4): All test step are implement using the old way to printed them --- src/python_testing/TC_OPCREDS_3_4.py | 190 ++++++++++++++++++++------- 1 file changed, 139 insertions(+), 51 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index f611ced5a7ff4e..f8568a3342f20b 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -18,14 +18,38 @@ import random import chip.clusters as Clusters +import chip.discovery as Discovery +from chip import ChipDeviceCtrl +from chip.exceptions import ChipStackError from chip.utils import CommissioningBuildingBlocks from chip.interaction_model import InteractionModelError, Status +from chip.tlv import TLVReader, TLVWriter from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main from mobly import asserts class TC_OPCREDS_3_4(MatterBaseTest): - # TODO: Implement + # TODO: Implement the function FindAndEstablishPase + def FindAndEstablishPase(self, longDiscriminator: int, setupPinCode: int, nodeid: int, dev_ctrl: ChipDeviceCtrl = None): + if dev_ctrl is None: + dev_ctrl = self.default_controller + + devices = dev_ctrl.DiscoverCommissionableNodes( + filterType=Discovery.FilterType.LONG_DISCRIMINATOR, filter=longDiscriminator, stopOnFirst=False) + # For some reason, the devices returned here aren't filtered, so filter ourselves + device = next(filter(lambda d: d.commissioningMode == + 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) + break + except ChipStackError: + continue + try: + dev_ctrl.GetConnectedDeviceSync(nodeid=nodeid, allowPASE=True, timeoutMs=1000) + except TimeoutError: + asserts.fail("Unable to establish a PASE session to the device") @async_test_body async def test_TC_OPCREDS_3_4(self): @@ -51,89 +75,153 @@ async def test_TC_OPCREDS_3_4(self): existingNodeId=self.dut_node_id, newNodeId=th1_dut_node_id ) - self.print_step( - 2, "TH1 reads the NOCs attribute from the Node Operational Credentials cluster using a fabric-filtered read") + self.print_step(2, "TH1 reads the NOCs attribute from the Node Operational Credentials cluster using a fabric-filtered read") nocs = await self.read_single_attribute_check_success(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.NOCs, fabric_filtered=True) - self.print_step( - 3, "TH1 reads the TrustedRootCertificates attribute from the Node Operational Credentials cluster") + self.print_step(3, "TH1 reads the TrustedRootCertificates attribute from the Node Operational Credentials cluster") trusted_root_original = await self.read_single_attribute_check_success( dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates) print("trusted_root_original: ", trusted_root_original) - self.print_step( - 4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") - cmd = opcreds.Commands.UpdateNOC( - NOCValue=noc_original, ICACValue=icac_original) + self.print_step(4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") + cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) try: await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) asserts.fail("Unexpected error sending UpdateNOC command") except InteractionModelError as e: - asserts.assert_equal( - e.status, Status.FailsafeRequired, "Unexpected Failsafe status") + asserts.assert_equal(e.status, Status.FailsafeRequired, "Unexpected Failsafe status") - self.print_step( - 5, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900") - cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe( - expiryLengthSeconds=900) + self.print_step(5, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900") + cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=900) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) print(resp) - asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, - "Failure status returned from arm failsafe") + asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") - self.print_step( - 6, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") - cmd = opcreds.Commands.UpdateNOC( - NOCValue=noc_original, ICACValue=icac_original) + self.print_step(6, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") + cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr, - "Failure status returned from UpdateNOC") + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr, "Failure status returned from UpdateNOC") - self.print_step( - 7, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to false") - cmd = opcreds.Commands.CSRRequest( - CSRNonce=random.randbytes(32), isForUpdateNOC=False) + self.print_step(7, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to false") + cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32), isForUpdateNOC=False) csr_not_updated = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) print("csr_not_updated: ", csr_not_updated) - self.print_step( - 8, "TH1 generates a new NOC chain with ICAC with the following properties") - new_noc_chain = th1_new_fabric_ctrl.IssueNOCChain( - csr_not_updated, th1_dut_node_id) + self.print_step(8, "TH1 generates a new NOC chain with ICAC with the following properties") + new_noc_chain = th1_new_fabric_ctrl.IssueNOCChain(csr_not_updated, th1_dut_node_id) noc_not_for_update = csr_not_updated.NOCSRElements icac_not_for_update = new_noc_chain.icacBytes - # TODO: Ask to @Cecille if ICACvalue should be get from new NOCchain or must be get from somewhere else? - self.print_step( - 9, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") - cmd = opcreds.Commands.UpdateNOC( - NOCValue=noc_not_for_update, ICACValue=icac_not_for_update) + self.print_step(9, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") + cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_not_for_update, ICACValue=icac_not_for_update) try: resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) asserts.fail("Unexpected error sending UpdateNOC command") except InteractionModelError as e: - asserts.assert_equal( - e.status, Status.ConstraintError, "Failure status returned from UpdateNOC") - - self.print_step( - 10, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to true") - # resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=Clusters.GeneralCommissioning.Commands.ArmFailSafe(300)) - # print("ArmFailSafe 600: ", resp) - cmd = opcreds.Commands.CSRRequest( - CSRNonce=random.randbytes(32), isForUpdateNOC=True) + asserts.assert_equal(e.status, Status.ConstraintError, "Failure status returned from UpdateNOC") + + cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(0) + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") + + cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(900) + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") + + self.print_step(10, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to true") + cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32), isForUpdateNOC=True) csr_update = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - # I don't know why but I received an FAILURE error if set the isForUpdateNOC with True instead if I use False I get ConstraintError - # cmd = opcreds.Commands.AddTrustedRootCertificate(rcac_original) - # await self.send_single_cmd(cmd=cmd, dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id) - # temp_certs = th1_new_fabric_ctrl.IssueNOCChain(csr_update, th1_dut_node_id) + self.print_step(11, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") + cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidPublicKey, "Unexpected error code on AddNOC with mismatched CSR") + + self.print_step(12, "TH1 generates a new Trusted Root Certificate and Private Key and saves as new_root_cert and new_root_key so that TH can generate an NOC for UpdateNOC that doesn’t chain to the original root") + new_root_cert = new_noc_chain.rcacBytes + new_root_key = TLVReader(new_root_cert).get()["Any"][9] + print("new_root_key: ", new_root_key) + + self.print_step(13, "TH1 generates a new NOC and ICAC") + new_noc_chain = th1_new_fabric_ctrl.IssueNOCChain(csr_update, th1_dut_node_id) + noc_update_new_root = csr_update.NOCSRElements + icac_update_new_root = new_noc_chain.icacBytes + + self.print_step(14, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") + cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_new_root, ICACValue=icac_update_new_root) + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, "NOCResponse with the StatusCode InvalidNOC") + + self.print_step(15, "TH1 generates a new NOC and ICAC") + # new NOC is generated from the NOCSR returned in csr_update with the matter-fabric-id set to a different + # value than noc_original. The NOC is signed by new ICA. Save as noc_update_bad_fabric_on_noc. + noc_update_bad_fabric_on_noc = csr_update.NOCSRElements + # new ICAC is generated with the and matter-fabric-id omitted. ICAC is signed by the original key for + # trusted_root_original. Save as icac_update_bad_fabric_on_noc + icac_update_bad_fabric_on_noc = new_noc_chain.icacBytes + + self.print_step(16, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") + cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_bad_fabric_on_noc, ICACValue=icac_update_bad_fabric_on_noc) + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, "NOCResponse with the StatusCode InvalidNOC") + + self.print_step(17, "TH1 generates a new NOC and ICAC") + noc_update_bad_fabric_on_icac = csr_update.NOCSRElements + icac_update_bad_fabric_on_icac = new_noc_chain.icacBytes + + self.print_step(18, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") + cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_bad_fabric_on_icac, ICACValue=icac_update_bad_fabric_on_icac) + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, "NOCResponse with the StatusCode InvalidNOC") - cmd = opcreds.Commands.UpdateNOC( - NOCValue=noc_original, ICACValue=icac_original) + self.print_step(19, "TH1 sends AddTrustedRootCertificate command to DUT again with the RootCACertificate field set to new_root_cert") + cmd = opcreds.Commands.AddTrustedRootCertificate(new_root_cert) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + self.print_step(20, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") + # NOCValue is set to noc_update_new_root + # ICACValue is to set icac_update_new_root + cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_new_root, ICACValue=icac_update_new_root) + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + # 11.17.7.9 Test Step: Verify that the DUT responds with CONSTRAINT_ERROR + # TODO: Ask why we expected that error if there is not CSRRequest command previously? Also in the step 6 received and MissingCsr error. + #asserts.assert_equal(e.status, Status.ConstraintError, "Failure status returned from UpdateNOC") + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr, "Failure status returned from UpdateNOC") + + self.print_step(21, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 0") + cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(0) + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") + + self.print_step(22, "TH1 sends an OpenCommissioningWindow command to the DUT") + resp = self.openCommissioningWindow(th1_new_fabric_ctrl, th1_dut_node_id) + + self.print_step(23, "TH1 connects to the DUT over PASE and sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900. Steps 24-26 are all performed over the PASE connection.") + self.FindAndEstablishPase(dev_ctrl=th1_new_fabric_ctrl, longDiscriminator=resp.randomDiscriminator, + setupPinCode=resp.commissioningParameters.setupPinCode, nodeid=th1_dut_node_id) + + cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(900) + resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Error code status returned from arm failsafe") + + self.print_step(24, "TH1 Sends CSRRequest command over PASE with the IsForUpdateNOC field set to true") + cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32)) + csr_pase = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + + self.print_step(25, "TH1 Sends CSRRequest command over PASE with the IsForUpdateNOC field set to true") + new_noc_chain = th1_new_fabric_ctrl.IssueNOCChain(csr_pase, th1_dut_node_id) + noc_pase = csr_pase.NOCSRElements + icac_pase = new_noc_chain.icacBytes + + self.print_step(26, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster over PASE") + cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_pase, ICACValue=icac_pase) + try: + await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + asserts.fail("Unexpected error sending UpdateNOC command") + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.UnsupportedAccess, "Failure status returned from UpdateNOC") if __name__ == "__main__": default_matter_test_main() From 5c4222bbc0f0f0755c871d3c5255f66f842e247f Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Mon, 15 Jul 2024 15:48:35 -0700 Subject: [PATCH 04/23] chore(TC_OPCREDS_3.4): patch from restyled code --- src/python_testing/TC_OPCREDS_3_4.py | 46 ++++++++++++++++++---------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index f8568a3342f20b..79968e547ca1a0 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -21,9 +21,9 @@ import chip.discovery as Discovery from chip import ChipDeviceCtrl from chip.exceptions import ChipStackError -from chip.utils import CommissioningBuildingBlocks from chip.interaction_model import InteractionModelError, Status from chip.tlv import TLVReader, TLVWriter +from chip.utils import CommissioningBuildingBlocks from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main from mobly import asserts @@ -38,7 +38,7 @@ def FindAndEstablishPase(self, longDiscriminator: int, setupPinCode: int, nodeid filterType=Discovery.FilterType.LONG_DISCRIMINATOR, filter=longDiscriminator, stopOnFirst=False) # For some reason, the devices returned here aren't filtered, so filter ourselves device = next(filter(lambda d: d.commissioningMode == - Discovery.FilterType.LONG_DISCRIMINATOR and d.longDiscriminator == longDiscriminator, devices)) + Discovery.FilterType.LONG_DISCRIMINATOR and d.longDiscriminator == longDiscriminator, devices)) for a in device.addresses: try: dev_ctrl.EstablishPASESessionIP(ipaddr=a, setupPinCode=setupPinCode, @@ -83,9 +83,9 @@ async def test_TC_OPCREDS_3_4(self): dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates) - print("trusted_root_original: ", trusted_root_original) - self.print_step(4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") + self.print_step( + 4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) try: await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) @@ -96,13 +96,15 @@ async def test_TC_OPCREDS_3_4(self): self.print_step(5, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900") cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=900) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - print(resp) - asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") + asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, + "Failure status returned from arm failsafe") - self.print_step(6, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") + self.print_step( + 6, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr, "Failure status returned from UpdateNOC") + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr, + "Failure status returned from UpdateNOC") self.print_step(7, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to false") cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32), isForUpdateNOC=False) @@ -124,11 +126,13 @@ async def test_TC_OPCREDS_3_4(self): cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(0) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") + asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, + "Failure status returned from arm failsafe") cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(900) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") + asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, + "Failure status returned from arm failsafe") self.print_step(10, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to true") cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32), isForUpdateNOC=True) @@ -137,7 +141,8 @@ async def test_TC_OPCREDS_3_4(self): self.print_step(11, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidPublicKey, "Unexpected error code on AddNOC with mismatched CSR") + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidPublicKey, + "Unexpected error code on AddNOC with mismatched CSR") self.print_step(12, "TH1 generates a new Trusted Root Certificate and Private Key and saves as new_root_cert and new_root_key so that TH can generate an NOC for UpdateNOC that doesn’t chain to the original root") new_root_cert = new_noc_chain.rcacBytes @@ -152,7 +157,8 @@ async def test_TC_OPCREDS_3_4(self): self.print_step(14, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_new_root, ICACValue=icac_update_new_root) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, "NOCResponse with the StatusCode InvalidNOC") + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, + "NOCResponse with the StatusCode InvalidNOC") self.print_step(15, "TH1 generates a new NOC and ICAC") # new NOC is generated from the NOCSR returned in csr_update with the matter-fabric-id set to a different @@ -165,7 +171,8 @@ async def test_TC_OPCREDS_3_4(self): self.print_step(16, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_bad_fabric_on_noc, ICACValue=icac_update_bad_fabric_on_noc) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, "NOCResponse with the StatusCode InvalidNOC") + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, + "NOCResponse with the StatusCode InvalidNOC") self.print_step(17, "TH1 generates a new NOC and ICAC") noc_update_bad_fabric_on_icac = csr_update.NOCSRElements @@ -174,7 +181,8 @@ async def test_TC_OPCREDS_3_4(self): self.print_step(18, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_bad_fabric_on_icac, ICACValue=icac_update_bad_fabric_on_icac) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, "NOCResponse with the StatusCode InvalidNOC") + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, + "NOCResponse with the StatusCode InvalidNOC") self.print_step(19, "TH1 sends AddTrustedRootCertificate command to DUT again with the RootCACertificate field set to new_root_cert") cmd = opcreds.Commands.AddTrustedRootCertificate(new_root_cert) @@ -188,12 +196,14 @@ async def test_TC_OPCREDS_3_4(self): # 11.17.7.9 Test Step: Verify that the DUT responds with CONSTRAINT_ERROR # TODO: Ask why we expected that error if there is not CSRRequest command previously? Also in the step 6 received and MissingCsr error. #asserts.assert_equal(e.status, Status.ConstraintError, "Failure status returned from UpdateNOC") - asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr, "Failure status returned from UpdateNOC") + asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr, + "Failure status returned from UpdateNOC") self.print_step(21, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 0") cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(0) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") + asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, + "Failure status returned from arm failsafe") self.print_step(22, "TH1 sends an OpenCommissioningWindow command to the DUT") resp = self.openCommissioningWindow(th1_new_fabric_ctrl, th1_dut_node_id) @@ -204,7 +214,8 @@ async def test_TC_OPCREDS_3_4(self): cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(900) resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Error code status returned from arm failsafe") + asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, + "Error code status returned from arm failsafe") self.print_step(24, "TH1 Sends CSRRequest command over PASE with the IsForUpdateNOC field set to true") cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32)) @@ -223,5 +234,6 @@ async def test_TC_OPCREDS_3_4(self): except InteractionModelError as e: asserts.assert_equal(e.status, Status.UnsupportedAccess, "Failure status returned from UpdateNOC") + if __name__ == "__main__": default_matter_test_main() From 3987faba1d8d2a2bd24b43e8827bb5ecc4fe3ec1 Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Mon, 15 Jul 2024 15:50:26 -0700 Subject: [PATCH 05/23] chore(TC_OPCREDS_3.4): restyled by autopep8 --- src/python_testing/TC_OPCREDS_3_4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index 79968e547ca1a0..d6fd5399a8a75e 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -38,7 +38,7 @@ def FindAndEstablishPase(self, longDiscriminator: int, setupPinCode: int, nodeid filterType=Discovery.FilterType.LONG_DISCRIMINATOR, filter=longDiscriminator, stopOnFirst=False) # For some reason, the devices returned here aren't filtered, so filter ourselves device = next(filter(lambda d: d.commissioningMode == - Discovery.FilterType.LONG_DISCRIMINATOR and d.longDiscriminator == longDiscriminator, devices)) + Discovery.FilterType.LONG_DISCRIMINATOR and d.longDiscriminator == longDiscriminator, devices)) for a in device.addresses: try: dev_ctrl.EstablishPASESessionIP(ipaddr=a, setupPinCode=setupPinCode, From a371c5674ff204c6b21c32a4237bd3b6a3d2cd8e Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Tue, 16 Jul 2024 00:48:27 -0700 Subject: [PATCH 06/23] chore(TC_OPCREDS_3.4): fix code-lints --- src/python_testing/TC_OPCREDS_3_4.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index d6fd5399a8a75e..52aa05fe8f40f3 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -22,7 +22,7 @@ from chip import ChipDeviceCtrl from chip.exceptions import ChipStackError from chip.interaction_model import InteractionModelError, Status -from chip.tlv import TLVReader, TLVWriter +from chip.tlv import TLVReader from chip.utils import CommissioningBuildingBlocks from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main from mobly import asserts @@ -77,16 +77,18 @@ async def test_TC_OPCREDS_3_4(self): self.print_step(2, "TH1 reads the NOCs attribute from the Node Operational Credentials cluster using a fabric-filtered read") nocs = await self.read_single_attribute_check_success(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.NOCs, fabric_filtered=True) + noc_orig = nocs[0].noc self.print_step(3, "TH1 reads the TrustedRootCertificates attribute from the Node Operational Credentials cluster") trusted_root_original = await self.read_single_attribute_check_success( dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates) + print(trusted_root_original) self.print_step( 4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") - cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) + cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_orig, ICACValue=icac_original) try: await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) asserts.fail("Unexpected error sending UpdateNOC command") From c4f4ae6efa9fd0dc40272a38cd61e921703c17eb Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Tue, 20 Aug 2024 08:36:01 -0700 Subject: [PATCH 07/23] chore(TC_OPCREDS_3.4): add suggestions --- src/python_testing/TC_OPCREDS_3_4.py | 129 +++++++++++---------------- 1 file changed, 52 insertions(+), 77 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index 52aa05fe8f40f3..f49588584e80f6 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -15,150 +15,123 @@ # 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. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${TYPE_OF_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + import random import chip.clusters as Clusters -import chip.discovery as Discovery -from chip import ChipDeviceCtrl -from chip.exceptions import ChipStackError from chip.interaction_model import InteractionModelError, Status -from chip.tlv import TLVReader -from chip.utils import CommissioningBuildingBlocks from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main from mobly import asserts class TC_OPCREDS_3_4(MatterBaseTest): - # TODO: Implement the function FindAndEstablishPase - def FindAndEstablishPase(self, longDiscriminator: int, setupPinCode: int, nodeid: int, dev_ctrl: ChipDeviceCtrl = None): - if dev_ctrl is None: - dev_ctrl = self.default_controller - - devices = dev_ctrl.DiscoverCommissionableNodes( - filterType=Discovery.FilterType.LONG_DISCRIMINATOR, filter=longDiscriminator, stopOnFirst=False) - # For some reason, the devices returned here aren't filtered, so filter ourselves - device = next(filter(lambda d: d.commissioningMode == - 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) - break - except ChipStackError: - continue - try: - dev_ctrl.GetConnectedDeviceSync(nodeid=nodeid, allowPASE=True, timeoutMs=1000) - except TimeoutError: - asserts.fail("Unable to establish a PASE session to the device") - @async_test_body async def test_TC_OPCREDS_3_4(self): - # TODO: add steps self.print_step(0, "Preconditions") self.print_step(1, "TH1 fully commissions the DUT") opcreds = Clusters.OperationalCredentials - dev_ctrl = self.default_controller - - new_certificate_authority = self.certificate_authority_manager.NewCertificateAuthority() - th1_vid = 0xFFF1 - th1_fabricId = 1111 - th1_new_fabric_admin = new_certificate_authority.NewFabricAdmin( - vendorId=th1_vid, fabricId=th1_fabricId) - th1_nodeId = self.default_controller.nodeId+1 - th1_dut_node_id = self.dut_node_id+1 - - th1_new_fabric_ctrl = th1_new_fabric_admin.NewController( - nodeId=th1_nodeId) - success, nocResp, noc_original, rcac_original, icac_original = await CommissioningBuildingBlocks.AddNOCForNewFabricFromExisting( - commissionerDevCtrl=dev_ctrl, newFabricDevCtrl=th1_new_fabric_ctrl, - existingNodeId=self.dut_node_id, newNodeId=th1_dut_node_id - ) self.print_step(2, "TH1 reads the NOCs attribute from the Node Operational Credentials cluster using a fabric-filtered read") - nocs = await self.read_single_attribute_check_success(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.NOCs, fabric_filtered=True) - noc_orig = nocs[0].noc + nocs = await self.read_single_attribute_check_success(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.NOCs, fabric_filtered=True) + + if nocs[0].noc: + noc_original = nocs[0].noc + else: + asserts.assert_true(False, "Unexpected fail reading NOC Value on NOCs response") + + if nocs[0].icac: + icac_original = nocs[0].icac + else: + asserts.assert_true(False, "Unexpected fail reading ICAC Value on NOCs response") self.print_step(3, "TH1 reads the TrustedRootCertificates attribute from the Node Operational Credentials cluster") trusted_root_original = await self.read_single_attribute_check_success( - dev_ctrl=th1_new_fabric_ctrl, - node_id=th1_dut_node_id, cluster=opcreds, + dev_ctrl=self.default_controller, + node_id=self.dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates) - print(trusted_root_original) self.print_step( 4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") - cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_orig, ICACValue=icac_original) + cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) try: - await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.fail("Unexpected error sending UpdateNOC command") except InteractionModelError as e: asserts.assert_equal(e.status, Status.FailsafeRequired, "Unexpected Failsafe status") self.print_step(5, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900") cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=900) - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") self.print_step( 6, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr, "Failure status returned from UpdateNOC") self.print_step(7, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to false") cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32), isForUpdateNOC=False) - csr_not_updated = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) - print("csr_not_updated: ", csr_not_updated) + csr_not_updated = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) self.print_step(8, "TH1 generates a new NOC chain with ICAC with the following properties") - new_noc_chain = th1_new_fabric_ctrl.IssueNOCChain(csr_not_updated, th1_dut_node_id) + new_noc_chain = await self.default_controller.IssueNOCChain(csr_not_updated, self.dut_node_id) noc_not_for_update = csr_not_updated.NOCSRElements icac_not_for_update = new_noc_chain.icacBytes self.print_step(9, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_not_for_update, ICACValue=icac_not_for_update) try: - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.fail("Unexpected error sending UpdateNOC command") except InteractionModelError as e: asserts.assert_equal(e.status, Status.ConstraintError, "Failure status returned from UpdateNOC") cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(0) - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(900) - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") self.print_step(10, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to true") cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32), isForUpdateNOC=True) - csr_update = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + csr_update = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) self.print_step(11, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidPublicKey, "Unexpected error code on AddNOC with mismatched CSR") self.print_step(12, "TH1 generates a new Trusted Root Certificate and Private Key and saves as new_root_cert and new_root_key so that TH can generate an NOC for UpdateNOC that doesn’t chain to the original root") new_root_cert = new_noc_chain.rcacBytes - new_root_key = TLVReader(new_root_cert).get()["Any"][9] - print("new_root_key: ", new_root_key) self.print_step(13, "TH1 generates a new NOC and ICAC") - new_noc_chain = th1_new_fabric_ctrl.IssueNOCChain(csr_update, th1_dut_node_id) + new_noc_chain = await self.default_controller.IssueNOCChain(csr_update, self.dut_node_id) noc_update_new_root = csr_update.NOCSRElements icac_update_new_root = new_noc_chain.icacBytes self.print_step(14, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_new_root, ICACValue=icac_update_new_root) - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, "NOCResponse with the StatusCode InvalidNOC") @@ -172,7 +145,7 @@ async def test_TC_OPCREDS_3_4(self): self.print_step(16, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_bad_fabric_on_noc, ICACValue=icac_update_bad_fabric_on_noc) - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, "NOCResponse with the StatusCode InvalidNOC") @@ -182,19 +155,19 @@ async def test_TC_OPCREDS_3_4(self): self.print_step(18, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_bad_fabric_on_icac, ICACValue=icac_update_bad_fabric_on_icac) - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, "NOCResponse with the StatusCode InvalidNOC") self.print_step(19, "TH1 sends AddTrustedRootCertificate command to DUT again with the RootCACertificate field set to new_root_cert") cmd = opcreds.Commands.AddTrustedRootCertificate(new_root_cert) - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) self.print_step(20, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") # NOCValue is set to noc_update_new_root # ICACValue is to set icac_update_new_root cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_new_root, ICACValue=icac_update_new_root) - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) # 11.17.7.9 Test Step: Verify that the DUT responds with CONSTRAINT_ERROR # TODO: Ask why we expected that error if there is not CSRRequest command previously? Also in the step 6 received and MissingCsr error. #asserts.assert_equal(e.status, Status.ConstraintError, "Failure status returned from UpdateNOC") @@ -203,35 +176,37 @@ async def test_TC_OPCREDS_3_4(self): self.print_step(21, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 0") cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(0) - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") self.print_step(22, "TH1 sends an OpenCommissioningWindow command to the DUT") - resp = self.openCommissioningWindow(th1_new_fabric_ctrl, th1_dut_node_id) + resp = await self.openCommissioningWindow(self.default_controller, self.dut_node_id) self.print_step(23, "TH1 connects to the DUT over PASE and sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900. Steps 24-26 are all performed over the PASE connection.") - self.FindAndEstablishPase(dev_ctrl=th1_new_fabric_ctrl, longDiscriminator=resp.randomDiscriminator, - setupPinCode=resp.commissioningParameters.setupPinCode, nodeid=th1_dut_node_id) + #self.FindAndEstablishPase(dev_ctrl=th1_new_fabric_ctrl, longDiscriminator=resp.randomDiscriminator, + # setupPinCode=resp.commissioningParameters.setupPinCode, nodeid=th1_dut_node_id) + # setupCode = self.matter_test_config.qr_code_content + self.matter_test_config.manual_code + await self.default_controller.FindOrEstablishPASESession(setupCode=resp.commissioningParameters.setupQRCode, nodeid=self.dut_node_id) cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(900) - resp = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Error code status returned from arm failsafe") self.print_step(24, "TH1 Sends CSRRequest command over PASE with the IsForUpdateNOC field set to true") cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32)) - csr_pase = await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + csr_pase = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) self.print_step(25, "TH1 Sends CSRRequest command over PASE with the IsForUpdateNOC field set to true") - new_noc_chain = th1_new_fabric_ctrl.IssueNOCChain(csr_pase, th1_dut_node_id) + new_noc_chain = await self.default_controller.IssueNOCChain(csr_pase, self.dut_node_id) noc_pase = csr_pase.NOCSRElements icac_pase = new_noc_chain.icacBytes self.print_step(26, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster over PASE") cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_pase, ICACValue=icac_pase) try: - await self.send_single_cmd(dev_ctrl=th1_new_fabric_ctrl, node_id=th1_dut_node_id, cmd=cmd) + await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.fail("Unexpected error sending UpdateNOC command") except InteractionModelError as e: asserts.assert_equal(e.status, Status.UnsupportedAccess, "Failure status returned from UpdateNOC") From 1f25d318c24a770cd3b8726025686447c729630d Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Thu, 10 Oct 2024 08:57:25 -0700 Subject: [PATCH 08/23] chore(TC_OPCREDS_3.4): steps _method instead print each step and add suggestions --- src/python_testing/TC_OPCREDS_3_4.py | 117 ++++++++++++++++----------- 1 file changed, 72 insertions(+), 45 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index f49588584e80f6..218904f4294bfb 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -31,21 +31,52 @@ import chip.clusters as Clusters from chip.interaction_model import InteractionModelError, Status -from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts class TC_OPCREDS_3_4(MatterBaseTest): + def desc_TC_OPCREDS_3_4(self): + return " UpdateNOC-Error Condition [DUT-Server]" + + def steps_TC_OPCREDS_3_4(self): + return [TestStep(0, "Preconditions"), + TestStep(1, "TH1 fully commissions the DUT"), + TestStep(2, "TH1 reads the NOCs attribute from the Node Operational Credentials cluster using a fabric-filtered read"), + TestStep(3, "TH1 reads the TrustedRootCertificates attribute from the Node Operational Credentials cluster"), + TestStep(4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), + TestStep(5, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900"), + TestStep(6, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), + TestStep(7, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to false"), + TestStep(8, "TH1 generates a new NOC chain with ICAC with the following properties"), + TestStep(9, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), + TestStep(10, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to true"), + TestStep(11, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), + TestStep(12, "TH1 generates a new Trusted Root Certificate and Private Key and saves as new_root_cert and new_root_key so that TH can generate an NOC for UpdateNOC that doesn’t chain to the original root"), + TestStep(13, "TH1 generates a new NOC and ICAC"), + TestStep(14, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), + TestStep(15, "TH1 generates a new NOC and ICAC"), + TestStep(16, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), + TestStep(17, "TH1 generates a new NOC and ICAC"), + TestStep(18, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), + TestStep(19, "TH1 sends AddTrustedRootCertificate command to DUT again with the RootCACertificate field set to new_root_cert"), + TestStep(20, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), + TestStep(21, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 0"), + TestStep(22, "TH1 sends an OpenCommissioningWindow command to the DUT"), + TestStep(23, "TH1 connects to the DUT over PASE and sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900. Steps 24-26 are all performed over the PASE connection."), + TestStep(24, "TH1 Sends CSRRequest command over PASE with the IsForUpdateNOC field set to true"), + TestStep(25, "TH1 generates a new NOC chain with ICAC with the following properties: new NOC and ICAC using icac_pase"), + TestStep(26, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster over PASE")] + @async_test_body async def test_TC_OPCREDS_3_4(self): - self.print_step(0, "Preconditions") + self.step(0) - self.print_step(1, "TH1 fully commissions the DUT") + self.step(1) opcreds = Clusters.OperationalCredentials - self.print_step(2, "TH1 reads the NOCs attribute from the Node Operational Credentials cluster using a fabric-filtered read") + self.step(2) nocs = await self.read_single_attribute_check_success(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.NOCs, fabric_filtered=True) - if nocs[0].noc: noc_original = nocs[0].noc else: @@ -56,14 +87,13 @@ async def test_TC_OPCREDS_3_4(self): else: asserts.assert_true(False, "Unexpected fail reading ICAC Value on NOCs response") - self.print_step(3, "TH1 reads the TrustedRootCertificates attribute from the Node Operational Credentials cluster") + self.step(3) trusted_root_original = await self.read_single_attribute_check_success( dev_ctrl=self.default_controller, node_id=self.dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates) - self.print_step( - 4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") + self.step(4) cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) try: await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) @@ -71,29 +101,28 @@ async def test_TC_OPCREDS_3_4(self): except InteractionModelError as e: asserts.assert_equal(e.status, Status.FailsafeRequired, "Unexpected Failsafe status") - self.print_step(5, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900") + self.step(5) cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(expiryLengthSeconds=900) resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") - self.print_step( - 6, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue") + self.step(6) cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr, "Failure status returned from UpdateNOC") - self.print_step(7, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to false") + self.step(7) cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32), isForUpdateNOC=False) csr_not_updated = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) - self.print_step(8, "TH1 generates a new NOC chain with ICAC with the following properties") + self.step(8) new_noc_chain = await self.default_controller.IssueNOCChain(csr_not_updated, self.dut_node_id) - noc_not_for_update = csr_not_updated.NOCSRElements + noc_not_for_update = new_noc_chain.nocBytes icac_not_for_update = new_noc_chain.icacBytes - self.print_step(9, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") + self.step(9) cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_not_for_update, ICACValue=icac_not_for_update) try: resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) @@ -111,80 +140,79 @@ async def test_TC_OPCREDS_3_4(self): asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") - self.print_step(10, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to true") + self.step(10) cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32), isForUpdateNOC=True) csr_update = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) - self.print_step(11, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") + self.step(11) cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidPublicKey, "Unexpected error code on AddNOC with mismatched CSR") - self.print_step(12, "TH1 generates a new Trusted Root Certificate and Private Key and saves as new_root_cert and new_root_key so that TH can generate an NOC for UpdateNOC that doesn’t chain to the original root") - new_root_cert = new_noc_chain.rcacBytes + self.step(12) + th1_ca_new = self.certificate_authority_manager.NewCertificateAuthority() + th1_fabric_admin_new = th1_ca_new.NewFabricAdmin(vendorId=0xFFF1, fabricId=1) + th1_new = th1_fabric_admin_new.NewController(nodeId=self.default_controller.nodeId+1) - self.print_step(13, "TH1 generates a new NOC and ICAC") - new_noc_chain = await self.default_controller.IssueNOCChain(csr_update, self.dut_node_id) - noc_update_new_root = csr_update.NOCSRElements - icac_update_new_root = new_noc_chain.icacBytes + self.step(13) + th1_certs_new = await th1_new.IssueNOCChain(csr_update, self.dut_node_id+1) + new_root_cert = th1_certs_new.rcacBytes + noc_update_new_root = th1_certs_new.nocBytes + icac_update_new_root = th1_certs_new.icacBytes - self.print_step(14, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") + self.step(14) cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_new_root, ICACValue=icac_update_new_root) resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, "NOCResponse with the StatusCode InvalidNOC") - self.print_step(15, "TH1 generates a new NOC and ICAC") + self.step(15) + cmd = opcreds # new NOC is generated from the NOCSR returned in csr_update with the matter-fabric-id set to a different # value than noc_original. The NOC is signed by new ICA. Save as noc_update_bad_fabric_on_noc. - noc_update_bad_fabric_on_noc = csr_update.NOCSRElements + noc_update_bad_fabric_on_noc = th1_certs_new.nocBytes # new ICAC is generated with the and matter-fabric-id omitted. ICAC is signed by the original key for # trusted_root_original. Save as icac_update_bad_fabric_on_noc icac_update_bad_fabric_on_noc = new_noc_chain.icacBytes - self.print_step(16, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") + self.step(16) cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_bad_fabric_on_noc, ICACValue=icac_update_bad_fabric_on_noc) resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, "NOCResponse with the StatusCode InvalidNOC") - self.print_step(17, "TH1 generates a new NOC and ICAC") - noc_update_bad_fabric_on_icac = csr_update.NOCSRElements + self.step(17) + noc_update_bad_fabric_on_icac = th1_certs_new.nocBytes icac_update_bad_fabric_on_icac = new_noc_chain.icacBytes - self.print_step(18, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") + self.step(18) cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_bad_fabric_on_icac, ICACValue=icac_update_bad_fabric_on_icac) resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kInvalidNOC, "NOCResponse with the StatusCode InvalidNOC") - self.print_step(19, "TH1 sends AddTrustedRootCertificate command to DUT again with the RootCACertificate field set to new_root_cert") + self.step(19) cmd = opcreds.Commands.AddTrustedRootCertificate(new_root_cert) resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) - self.print_step(20, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster") - # NOCValue is set to noc_update_new_root - # ICACValue is to set icac_update_new_root + self.step(20) cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_update_new_root, ICACValue=icac_update_new_root) resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) - # 11.17.7.9 Test Step: Verify that the DUT responds with CONSTRAINT_ERROR - # TODO: Ask why we expected that error if there is not CSRRequest command previously? Also in the step 6 received and MissingCsr error. - #asserts.assert_equal(e.status, Status.ConstraintError, "Failure status returned from UpdateNOC") asserts.assert_equal(resp.statusCode, opcreds.Enums.NodeOperationalCertStatusEnum.kMissingCsr, "Failure status returned from UpdateNOC") - self.print_step(21, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 0") + self.step(21) cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(0) resp = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Failure status returned from arm failsafe") - self.print_step(22, "TH1 sends an OpenCommissioningWindow command to the DUT") + self.step(22) resp = await self.openCommissioningWindow(self.default_controller, self.dut_node_id) - self.print_step(23, "TH1 connects to the DUT over PASE and sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900. Steps 24-26 are all performed over the PASE connection.") - #self.FindAndEstablishPase(dev_ctrl=th1_new_fabric_ctrl, longDiscriminator=resp.randomDiscriminator, + self.step(23) + # self.FindAndEstablishPase(dev_ctrl=th1_new_fabric_ctrl, longDiscriminator=resp.randomDiscriminator, # setupPinCode=resp.commissioningParameters.setupPinCode, nodeid=th1_dut_node_id) # setupCode = self.matter_test_config.qr_code_content + self.matter_test_config.manual_code await self.default_controller.FindOrEstablishPASESession(setupCode=resp.commissioningParameters.setupQRCode, nodeid=self.dut_node_id) @@ -194,16 +222,16 @@ async def test_TC_OPCREDS_3_4(self): asserts.assert_equal(resp.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, "Error code status returned from arm failsafe") - self.print_step(24, "TH1 Sends CSRRequest command over PASE with the IsForUpdateNOC field set to true") + self.step(24) cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32)) csr_pase = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) - self.print_step(25, "TH1 Sends CSRRequest command over PASE with the IsForUpdateNOC field set to true") + self.step(25) new_noc_chain = await self.default_controller.IssueNOCChain(csr_pase, self.dut_node_id) noc_pase = csr_pase.NOCSRElements icac_pase = new_noc_chain.icacBytes - self.print_step(26, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster over PASE") + self.step(26) cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_pase, ICACValue=icac_pase) try: await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) @@ -211,6 +239,5 @@ async def test_TC_OPCREDS_3_4(self): except InteractionModelError as e: asserts.assert_equal(e.status, Status.UnsupportedAccess, "Failure status returned from UpdateNOC") - if __name__ == "__main__": default_matter_test_main() From 458d42b19b044d4c41333f81f2a1b8c1eac5f95e Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Thu, 10 Oct 2024 09:05:55 -0700 Subject: [PATCH 09/23] chore(TC_OPCREDS_3.4): fix restyled --- src/python_testing/TC_OPCREDS_3_4.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index 218904f4294bfb..167fa8835648c0 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -44,9 +44,11 @@ def steps_TC_OPCREDS_3_4(self): TestStep(1, "TH1 fully commissions the DUT"), TestStep(2, "TH1 reads the NOCs attribute from the Node Operational Credentials cluster using a fabric-filtered read"), TestStep(3, "TH1 reads the TrustedRootCertificates attribute from the Node Operational Credentials cluster"), - TestStep(4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), + TestStep( + 4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), TestStep(5, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900"), - TestStep(6, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), + TestStep( + 6, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), TestStep(7, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to false"), TestStep(8, "TH1 generates a new NOC chain with ICAC with the following properties"), TestStep(9, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), @@ -239,5 +241,6 @@ async def test_TC_OPCREDS_3_4(self): except InteractionModelError as e: asserts.assert_equal(e.status, Status.UnsupportedAccess, "Failure status returned from UpdateNOC") + if __name__ == "__main__": default_matter_test_main() From 2d8d3a3cb63861255d2bd0f8e7b5fc3d0ad68913 Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Mon, 21 Oct 2024 18:42:09 -0700 Subject: [PATCH 10/23] chore(TC_OPCREDS_3.4): fix re-implementation validate single entry certs --- src/python_testing/TC_OPCREDS_3_4.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index 167fa8835648c0..fd99e5896bd670 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -90,10 +90,11 @@ async def test_TC_OPCREDS_3_4(self): asserts.assert_true(False, "Unexpected fail reading ICAC Value on NOCs response") self.step(3) - trusted_root_original = await self.read_single_attribute_check_success( + trusted_root_list_original = await self.read_single_attribute_check_success( dev_ctrl=self.default_controller, node_id=self.dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates) + asserts.assert_equal(len(trusted_root_list_original), 1, "Unexpected number of entries in the TrustedRootCertificates table") self.step(4) cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) @@ -230,6 +231,12 @@ async def test_TC_OPCREDS_3_4(self): self.step(25) new_noc_chain = await self.default_controller.IssueNOCChain(csr_pase, self.dut_node_id) + # cmd = opcreds.Commands.AddTrustedRootCertificate(trusted_root_original) + # try: + # await self.send_single_cmd(dev_ctrl=th1_new, node_id=self.default_controller.nodeId+1, cmd=cmd) + # asserts.fail("Success when adding trusted root certificate") + # except InteractionModelError as e: + # asserts.assert_equal(e.status, Status.ConstraintError, "Unexpected when adding trusted root certificate") noc_pase = csr_pase.NOCSRElements icac_pase = new_noc_chain.icacBytes From 36a1fae46e39822883e62be4bbc9e7d5732c8aca Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Mon, 21 Oct 2024 18:46:29 -0700 Subject: [PATCH 11/23] chore(TC_OPCREDS_3.4): fix resyled --- src/python_testing/TC_OPCREDS_3_4.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index fd99e5896bd670..1b94d55c9e7f7a 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -94,7 +94,8 @@ async def test_TC_OPCREDS_3_4(self): dev_ctrl=self.default_controller, node_id=self.dut_node_id, cluster=opcreds, attribute=opcreds.Attributes.TrustedRootCertificates) - asserts.assert_equal(len(trusted_root_list_original), 1, "Unexpected number of entries in the TrustedRootCertificates table") + asserts.assert_equal(len(trusted_root_list_original), 1, + "Unexpected number of entries in the TrustedRootCertificates table") self.step(4) cmd = opcreds.Commands.UpdateNOC(NOCValue=noc_original, ICACValue=icac_original) From 334314a822c523260050caee08bf09c2067f9b25 Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Tue, 22 Oct 2024 05:59:05 -0700 Subject: [PATCH 12/23] chore(TC_OPCREDS_3.4): reverting commissioningBuilingBlocks without icac and nocBytes --- .../python/chip/utils/CommissioningBuildingBlocks.py | 7 +++---- src/python_testing/TC_OPCREDS_3_2.py | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/controller/python/chip/utils/CommissioningBuildingBlocks.py b/src/controller/python/chip/utils/CommissioningBuildingBlocks.py index 4645e4f7683ea3..b6dac307dfd997 100644 --- a/src/controller/python/chip/utils/CommissioningBuildingBlocks.py +++ b/src/controller/python/chip/utils/CommissioningBuildingBlocks.py @@ -183,9 +183,8 @@ async def AddNOCForNewFabricFromExisting(commissionerDevCtrl, newFabricDevCtrl, chainForAddNOC.ipkBytes, newFabricDevCtrl.nodeId, newFabricDevCtrl.fabricAdmin.vendorId)) - nocBytes = chainForAddNOC.nocBytes - icacBytes = chainForAddNOC.icacBytes - rcacBytes = chainForAddNOC.rcacBytes + + rcacResp = chainForAddNOC.rcacBytes if nocResp.statusCode is not opCreds.Enums.NodeOperationalCertStatusEnum.kOk: # Expiring the failsafe timer in an attempt to clean up. @@ -202,7 +201,7 @@ async def AddNOCForNewFabricFromExisting(commissionerDevCtrl, newFabricDevCtrl, if not await _IsNodeInFabricList(newFabricDevCtrl, newNodeId): return False, nocResp - return True, nocResp, nocBytes, rcacBytes, icacBytes + return True, nocResp, rcacResp async def UpdateNOC(devCtrl, existingNodeId, newNodeId): diff --git a/src/python_testing/TC_OPCREDS_3_2.py b/src/python_testing/TC_OPCREDS_3_2.py index 8006c5582d3fe1..3eab07bc9dae06 100644 --- a/src/python_testing/TC_OPCREDS_3_2.py +++ b/src/python_testing/TC_OPCREDS_3_2.py @@ -86,7 +86,7 @@ async def test_TC_OPCREDS_3_2(self): cr2_new_admin_ctrl = cr2_new_fabric_admin.NewController( nodeId=cr2_nodeid) - success, nocResp, nocBytes, rcacResp, icacBytes = await CommissioningBuildingBlocks.AddNOCForNewFabricFromExisting( + success, nocResp, rcacResp = await CommissioningBuildingBlocks.AddNOCForNewFabricFromExisting( commissionerDevCtrl=dev_ctrl, newFabricDevCtrl=cr2_new_admin_ctrl, existingNodeId=self.dut_node_id, newNodeId=cr2_dut_node_id ) @@ -106,7 +106,7 @@ async def test_TC_OPCREDS_3_2(self): cr3_new_admin_ctrl = cr3_new_fabric_admin.NewController( nodeId=cr3_nodeid) - success, nocResp, nocBytes, rcacResp, icacBytes = await CommissioningBuildingBlocks.AddNOCForNewFabricFromExisting( + success, nocResp, rcacResp = await CommissioningBuildingBlocks.AddNOCForNewFabricFromExisting( commissionerDevCtrl=dev_ctrl, newFabricDevCtrl=cr3_new_admin_ctrl, existingNodeId=self.dut_node_id, newNodeId=cr3_dut_node_id ) From 9b146834a9559836acfb4d59cca5487429c4f9ab Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Tue, 22 Oct 2024 06:16:51 -0700 Subject: [PATCH 13/23] chore(TC_OPCREDS_3.4): fix matter_testing_support ModuleNotError --- src/python_testing/TC_OPCREDS_3_4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index 1b94d55c9e7f7a..4d189d33a66820 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -31,7 +31,7 @@ import chip.clusters as Clusters from chip.interaction_model import InteractionModelError, Status -from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts From 92a29c74ad2a6e547d6a17713dc5d9be0052b2a9 Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Thu, 14 Nov 2024 09:33:03 -0800 Subject: [PATCH 14/23] chore(TC_OPCREDS_3.4): added and replaced some outcomes/methods for TestSteps --- src/python_testing/TC_OPCREDS_3_4.py | 76 ++++++++++++------------- src/python_testing/test_plan_support.py | 7 +++ 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index 4d189d33a66820..9d18cd1227c347 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -19,12 +19,20 @@ # for details about the block below. # # === BEGIN CI TEST ARGUMENTS === -# test-runner-runs: run1 -# test-runner-run/run1/app: ${TYPE_OF_APP} -# test-runner-run/run1/factoryreset: True -# test-runner-run/run1/quiet: True -# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# test-runner-runs: +# run1: +# app: ${ALL_CLUSTERS_APP} +# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# script-args: > +# --storage-path admin_storage.json +# --commissioning-method on-network +# --discriminator 1234 +# --passcode 20202021 +# --PICS src/app/tests/suites/certification/ci-pics-values +# --trace-to json:${TRACE_TEST_JSON}.json +# --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# factory-reset: true +# quiet: true # === END CI TEST ARGUMENTS === import random @@ -33,6 +41,7 @@ from chip.interaction_model import InteractionModelError, Status from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts +from test_plan_support import (commission_if_required, send_command, read_attribute) class TC_OPCREDS_3_4(MatterBaseTest): @@ -40,40 +49,37 @@ def desc_TC_OPCREDS_3_4(self): return " UpdateNOC-Error Condition [DUT-Server]" def steps_TC_OPCREDS_3_4(self): - return [TestStep(0, "Preconditions"), - TestStep(1, "TH1 fully commissions the DUT"), - TestStep(2, "TH1 reads the NOCs attribute from the Node Operational Credentials cluster using a fabric-filtered read"), - TestStep(3, "TH1 reads the TrustedRootCertificates attribute from the Node Operational Credentials cluster"), + return [TestStep(1, commission_if_required('TH1'), is_commissioning=True), + TestStep(2, f"TH1 {read_attribute('NOCs')} from the Node Operational Credentials cluster using a fabric-filtered read. Save the NOCs as `nocs`."), + TestStep(3, f"TH1 {read_attribute('TrustedRootCertificates')} attribute from the Node Operational Credentials cluster"), TestStep( - 4, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), - TestStep(5, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900"), + 4, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), + TestStep(5, f"TH1 {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 900"), TestStep( - 6, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), - TestStep(7, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to false"), + 6, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), + TestStep(7, f"TH1 {send_command('CSRRequest')} with the IsForUpdateNOC field set to false"), TestStep(8, "TH1 generates a new NOC chain with ICAC with the following properties"), - TestStep(9, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), - TestStep(10, "TH1 Sends CSRRequest command with the IsForUpdateNOC field set to true"), - TestStep(11, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), + TestStep(9, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), + TestStep(10, f"TH1 {send_command('CSRequest')} with the IsForUpdateNOC field set to true"), + TestStep(11, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), TestStep(12, "TH1 generates a new Trusted Root Certificate and Private Key and saves as new_root_cert and new_root_key so that TH can generate an NOC for UpdateNOC that doesn’t chain to the original root"), TestStep(13, "TH1 generates a new NOC and ICAC"), - TestStep(14, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), + TestStep(14, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), TestStep(15, "TH1 generates a new NOC and ICAC"), - TestStep(16, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), + TestStep(16, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), TestStep(17, "TH1 generates a new NOC and ICAC"), - TestStep(18, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), - TestStep(19, "TH1 sends AddTrustedRootCertificate command to DUT again with the RootCACertificate field set to new_root_cert"), - TestStep(20, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster"), - TestStep(21, "TH1 sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 0"), - TestStep(22, "TH1 sends an OpenCommissioningWindow command to the DUT"), - TestStep(23, "TH1 connects to the DUT over PASE and sends ArmFailSafe command to the DUT with the ExpiryLengthSeconds field set to 900. Steps 24-26 are all performed over the PASE connection."), - TestStep(24, "TH1 Sends CSRRequest command over PASE with the IsForUpdateNOC field set to true"), + TestStep(18, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), + TestStep(19, f"TH1 {send_command('AddTrustedRootCertificate')} to DUT again with the RootCACertificate field set to new_root_cert"), + TestStep(20, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), + TestStep(21, f"TH1 {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 0"), + TestStep(22, f"TH1 {send_command('OpenCommissioningWindow')} to the DUT"), + TestStep(23, f"TH1 connects to the DUT over PASE and {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 900. Steps 24-26 are all performed over the PASE connection."), + TestStep(24, f"TH1 {send_command('CSRequest')} over PASE with the IsForUpdateNOC field set to true"), TestStep(25, "TH1 generates a new NOC chain with ICAC with the following properties: new NOC and ICAC using icac_pase"), - TestStep(26, "TH1 sends the UpdateNOC command to the Node Operational Credentials cluster over PASE")] + TestStep(26, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster over PASE")] @async_test_body async def test_TC_OPCREDS_3_4(self): - self.step(0) - self.step(1) opcreds = Clusters.OperationalCredentials @@ -156,7 +162,7 @@ async def test_TC_OPCREDS_3_4(self): self.step(12) th1_ca_new = self.certificate_authority_manager.NewCertificateAuthority() - th1_fabric_admin_new = th1_ca_new.NewFabricAdmin(vendorId=0xFFF1, fabricId=1) + th1_fabric_admin_new = th1_ca_new.NewFabricAdmin(vendorId=0xFFF2, fabricId=self.matter_test_config.fabric_id) th1_new = th1_fabric_admin_new.NewController(nodeId=self.default_controller.nodeId+1) self.step(13) @@ -172,7 +178,6 @@ async def test_TC_OPCREDS_3_4(self): "NOCResponse with the StatusCode InvalidNOC") self.step(15) - cmd = opcreds # new NOC is generated from the NOCSR returned in csr_update with the matter-fabric-id set to a different # value than noc_original. The NOC is signed by new ICA. Save as noc_update_bad_fabric_on_noc. noc_update_bad_fabric_on_noc = th1_certs_new.nocBytes @@ -216,9 +221,6 @@ async def test_TC_OPCREDS_3_4(self): resp = await self.openCommissioningWindow(self.default_controller, self.dut_node_id) self.step(23) - # self.FindAndEstablishPase(dev_ctrl=th1_new_fabric_ctrl, longDiscriminator=resp.randomDiscriminator, - # setupPinCode=resp.commissioningParameters.setupPinCode, nodeid=th1_dut_node_id) - # setupCode = self.matter_test_config.qr_code_content + self.matter_test_config.manual_code await self.default_controller.FindOrEstablishPASESession(setupCode=resp.commissioningParameters.setupQRCode, nodeid=self.dut_node_id) cmd = Clusters.GeneralCommissioning.Commands.ArmFailSafe(900) @@ -232,12 +234,6 @@ async def test_TC_OPCREDS_3_4(self): self.step(25) new_noc_chain = await self.default_controller.IssueNOCChain(csr_pase, self.dut_node_id) - # cmd = opcreds.Commands.AddTrustedRootCertificate(trusted_root_original) - # try: - # await self.send_single_cmd(dev_ctrl=th1_new, node_id=self.default_controller.nodeId+1, cmd=cmd) - # asserts.fail("Success when adding trusted root certificate") - # except InteractionModelError as e: - # asserts.assert_equal(e.status, Status.ConstraintError, "Unexpected when adding trusted root certificate") noc_pase = csr_pase.NOCSRElements icac_pase = new_noc_chain.icacBytes diff --git a/src/python_testing/test_plan_support.py b/src/python_testing/test_plan_support.py index 3e332e143203b8..e12dfe6c1c1031 100644 --- a/src/python_testing/test_plan_support.py +++ b/src/python_testing/test_plan_support.py @@ -24,6 +24,13 @@ def read_attribute(attribute: str, cluster: typing.Optional[str] = None): else: return attr +def send_command(command: str, cluster: typing.Optional[str] = None): + cmd = f"sends the {command} command" + if cluster: + return f'{cmd} from {cluster}' + else: + return cmd + def save_as(val: str) -> str: return f' and saves the value as {val}' From edf05c7a267d7c4ab5108259b6045dfd7d22687f Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Thu, 14 Nov 2024 09:39:39 -0800 Subject: [PATCH 15/23] chore(TC_OPCREDS_3.4): fix restyled --- src/python_testing/TC_OPCREDS_3_4.py | 11 +++++++---- src/python_testing/test_plan_support.py | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index 9d18cd1227c347..82eff972c85707 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -41,7 +41,7 @@ from chip.interaction_model import InteractionModelError, Status from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts -from test_plan_support import (commission_if_required, send_command, read_attribute) +from test_plan_support import commission_if_required, send_command, read_attribute class TC_OPCREDS_3_4(MatterBaseTest): @@ -50,7 +50,8 @@ def desc_TC_OPCREDS_3_4(self): def steps_TC_OPCREDS_3_4(self): return [TestStep(1, commission_if_required('TH1'), is_commissioning=True), - TestStep(2, f"TH1 {read_attribute('NOCs')} from the Node Operational Credentials cluster using a fabric-filtered read. Save the NOCs as `nocs`."), + TestStep( + 2, f"TH1 {read_attribute('NOCs')} from the Node Operational Credentials cluster using a fabric-filtered read. Save the NOCs as `nocs`."), TestStep(3, f"TH1 {read_attribute('TrustedRootCertificates')} attribute from the Node Operational Credentials cluster"), TestStep( 4, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), @@ -69,11 +70,13 @@ def steps_TC_OPCREDS_3_4(self): TestStep(16, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), TestStep(17, "TH1 generates a new NOC and ICAC"), TestStep(18, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), - TestStep(19, f"TH1 {send_command('AddTrustedRootCertificate')} to DUT again with the RootCACertificate field set to new_root_cert"), + TestStep( + 19, f"TH1 {send_command('AddTrustedRootCertificate')} to DUT again with the RootCACertificate field set to new_root_cert"), TestStep(20, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), TestStep(21, f"TH1 {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 0"), TestStep(22, f"TH1 {send_command('OpenCommissioningWindow')} to the DUT"), - TestStep(23, f"TH1 connects to the DUT over PASE and {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 900. Steps 24-26 are all performed over the PASE connection."), + TestStep( + 23, f"TH1 connects to the DUT over PASE and {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 900. Steps 24-26 are all performed over the PASE connection."), TestStep(24, f"TH1 {send_command('CSRequest')} over PASE with the IsForUpdateNOC field set to true"), TestStep(25, "TH1 generates a new NOC chain with ICAC with the following properties: new NOC and ICAC using icac_pase"), TestStep(26, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster over PASE")] diff --git a/src/python_testing/test_plan_support.py b/src/python_testing/test_plan_support.py index e12dfe6c1c1031..6abaf72a2dd25d 100644 --- a/src/python_testing/test_plan_support.py +++ b/src/python_testing/test_plan_support.py @@ -24,6 +24,7 @@ def read_attribute(attribute: str, cluster: typing.Optional[str] = None): else: return attr + def send_command(command: str, cluster: typing.Optional[str] = None): cmd = f"sends the {command} command" if cluster: From 99a6829128e3a495deaeece993d2ffd735b4ab8e Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Thu, 14 Nov 2024 09:43:19 -0800 Subject: [PATCH 16/23] chore(TC_OPCREDS_3.4): fix restyled --- src/python_testing/TC_OPCREDS_3_4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index 82eff972c85707..afce79226fbf97 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -41,7 +41,7 @@ from chip.interaction_model import InteractionModelError, Status from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts -from test_plan_support import commission_if_required, send_command, read_attribute +from test_plan_support import commission_if_required, read_attribute, send_command class TC_OPCREDS_3_4(MatterBaseTest): From 5e358760d77b5663a799c1b36f9e95bb64045b76 Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Thu, 14 Nov 2024 15:46:35 -0800 Subject: [PATCH 17/23] chore(TC_OPCREDS_3.4): added suggestions --- src/python_testing/TC_OPCREDS_3_4.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index afce79226fbf97..eac08fcb0d51d6 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -96,7 +96,7 @@ async def test_TC_OPCREDS_3_4(self): if nocs[0].icac: icac_original = nocs[0].icac else: - asserts.assert_true(False, "Unexpected fail reading ICAC Value on NOCs response") + asserts.fail("Unexpected fail reading ICAC Value on NOCs response") self.step(3) trusted_root_list_original = await self.read_single_attribute_check_success( @@ -128,10 +128,10 @@ async def test_TC_OPCREDS_3_4(self): self.step(7) cmd = opcreds.Commands.CSRRequest(CSRNonce=random.randbytes(32), isForUpdateNOC=False) - csr_not_updated = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) + csr_not_update = await self.send_single_cmd(dev_ctrl=self.default_controller, node_id=self.dut_node_id, cmd=cmd) self.step(8) - new_noc_chain = await self.default_controller.IssueNOCChain(csr_not_updated, self.dut_node_id) + new_noc_chain = await self.default_controller.IssueNOCChain(csr_not_update, self.dut_node_id) noc_not_for_update = new_noc_chain.nocBytes icac_not_for_update = new_noc_chain.icacBytes From 8fe76389afcaed875a297181ec0ab03fc2225178 Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Thu, 14 Nov 2024 22:52:01 -0800 Subject: [PATCH 18/23] chore(TC_OPCREDS_3.4): added expected outcomes for some test step --- src/python_testing/TC_OPCREDS_3_4.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index eac08fcb0d51d6..ce6b35ac3c48d0 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -44,6 +44,14 @@ from test_plan_support import commission_if_required, read_attribute, send_command +def verify_noc() -> str: + return (f"- Verify that the returned list has a single entry.\n" + f"- Save the NOC field as noc_original and the ICAC field as icac_original.\n") + +def verify_trusted_root_original() -> str: + return (f"Verify that the returned list has a single entry. Save the entry as trusted_root_original") + + class TC_OPCREDS_3_4(MatterBaseTest): def desc_TC_OPCREDS_3_4(self): return " UpdateNOC-Error Condition [DUT-Server]" @@ -51,8 +59,9 @@ def desc_TC_OPCREDS_3_4(self): def steps_TC_OPCREDS_3_4(self): return [TestStep(1, commission_if_required('TH1'), is_commissioning=True), TestStep( - 2, f"TH1 {read_attribute('NOCs')} from the Node Operational Credentials cluster using a fabric-filtered read. Save the NOCs as `nocs`."), - TestStep(3, f"TH1 {read_attribute('TrustedRootCertificates')} attribute from the Node Operational Credentials cluster"), + 2, f"TH1 {read_attribute('NOCs')} from the Node Operational Credentials cluster using a fabric-filtered read. Save the NOCs as nocs.", verify_noc()), + TestStep( + 3, f"TH1 {read_attribute('TrustedRootCertificates')} attribute from the Node Operational Credentials cluster", verify_trusted_root_original), TestStep( 4, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), TestStep(5, f"TH1 {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 900"), From 88f542622b1bfb02080495be947914db2377bab4 Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Thu, 14 Nov 2024 22:54:22 -0800 Subject: [PATCH 19/23] chore(TC_OPCREDS_3.4): fix restyled --- src/python_testing/TC_OPCREDS_3_4.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index ce6b35ac3c48d0..5b86fbe2bace6b 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -48,6 +48,7 @@ def verify_noc() -> str: return (f"- Verify that the returned list has a single entry.\n" f"- Save the NOC field as noc_original and the ICAC field as icac_original.\n") + def verify_trusted_root_original() -> str: return (f"Verify that the returned list has a single entry. Save the entry as trusted_root_original") From a297071c1c4eb1d9abc317e792adf9946fbb1d94 Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Fri, 15 Nov 2024 06:55:19 -0800 Subject: [PATCH 20/23] chore(TC_OPCREDS_3.4): fix f-strings without any placeholder --- src/python_testing/TC_OPCREDS_3_4.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index 5b86fbe2bace6b..5b83d14b653df2 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -45,12 +45,12 @@ def verify_noc() -> str: - return (f"- Verify that the returned list has a single entry.\n" - f"- Save the NOC field as noc_original and the ICAC field as icac_original.\n") + return ("- Verify that the returned list has a single entry.\n" + "- Save the NOC field as noc_original and the ICAC field as icac_original.\n") def verify_trusted_root_original() -> str: - return (f"Verify that the returned list has a single entry. Save the entry as trusted_root_original") + return ("Verify that the returned list has a single entry. Save the entry as trusted_root_original") class TC_OPCREDS_3_4(MatterBaseTest): From da59243060d8f3c578382c07794959823fa966bc Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Fri, 15 Nov 2024 10:11:47 -0800 Subject: [PATCH 21/23] chore(TC_OPCREDS_3.4): implemented all expected outcomes for all steps --- src/python_testing/TC_OPCREDS_3_4.py | 60 ++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index 5b83d14b653df2..5f95aaeabf6afa 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -53,6 +53,32 @@ def verify_trusted_root_original() -> str: return ("Verify that the returned list has a single entry. Save the entry as trusted_root_original") +def verify_failsafe_status() -> str: + return ("Verify that the DUT responds with FAILSAFE_REQUIRED") + + +def verify_armfailsafe_response() -> str: + return ("Verify that DUT sends ArmFailSafeResponse with the ErrorCode set to OK") + + +def verify_noc_response(status) -> str: + return (f"Verify that the DUT responds with a NOCResponse with the StatusCode field set to {status}") + + +def verify_csr_not_update() -> str: + return ("Verify that the DUT returns a CSRResponse and save as csr_not_update") + + +def verify_constraint_error() -> str: + return ("Verify that the DUT responds with CONSTRAINT_ERROR") + +def verify_csr_pase() -> str: + return ("Verify that the DUT returns a CSRResponse and save as csr_pase") + +def verify_unsupported_access() -> str: + return ("Verify that the DUT responds with UNSUPPORTED_ACCESS") + + class TC_OPCREDS_3_4(MatterBaseTest): def desc_TC_OPCREDS_3_4(self): return " UpdateNOC-Error Condition [DUT-Server]" @@ -60,36 +86,36 @@ def desc_TC_OPCREDS_3_4(self): def steps_TC_OPCREDS_3_4(self): return [TestStep(1, commission_if_required('TH1'), is_commissioning=True), TestStep( - 2, f"TH1 {read_attribute('NOCs')} from the Node Operational Credentials cluster using a fabric-filtered read. Save the NOCs as nocs.", verify_noc()), + 2, f"TH1 {read_attribute('NOCs')} from the Node Operational Credentials cluster using a fabric-filtered read. Save the NOCs as nocs.", None, verify_noc()), TestStep( - 3, f"TH1 {read_attribute('TrustedRootCertificates')} attribute from the Node Operational Credentials cluster", verify_trusted_root_original), + 3, f"TH1 {read_attribute('TrustedRootCertificates')} attribute from the Node Operational Credentials cluster", None, verify_trusted_root_original()), TestStep( - 4, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), - TestStep(5, f"TH1 {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 900"), + 4, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue", None, verify_failsafe_status()), + TestStep(5, f"TH1 {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 900", None, verify_armfailsafe_response()), TestStep( - 6, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue"), - TestStep(7, f"TH1 {send_command('CSRRequest')} with the IsForUpdateNOC field set to false"), + 6, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue", None, verify_noc_response("MissingCsr")), + TestStep(7, f"TH1 {send_command('CSRRequest')} with the IsForUpdateNOC field set to false", None, verify_csr_not_update()), TestStep(8, "TH1 generates a new NOC chain with ICAC with the following properties"), - TestStep(9, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), - TestStep(10, f"TH1 {send_command('CSRequest')} with the IsForUpdateNOC field set to true"), - TestStep(11, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), + TestStep(9, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_constraint_error()), + TestStep(10, f"TH1 {send_command('CSRequest')} with the IsForUpdateNOC field set to true", None, verify_csr_not_update()), + TestStep(11, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_noc_response("InvalidPublicKey")), TestStep(12, "TH1 generates a new Trusted Root Certificate and Private Key and saves as new_root_cert and new_root_key so that TH can generate an NOC for UpdateNOC that doesn’t chain to the original root"), TestStep(13, "TH1 generates a new NOC and ICAC"), - TestStep(14, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), + TestStep(14, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_noc_response("InvalidNOC")), TestStep(15, "TH1 generates a new NOC and ICAC"), - TestStep(16, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), + TestStep(16, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_noc_response("InvalidNOC")), TestStep(17, "TH1 generates a new NOC and ICAC"), - TestStep(18, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), + TestStep(18, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_noc_response("InvalidNOC")), TestStep( 19, f"TH1 {send_command('AddTrustedRootCertificate')} to DUT again with the RootCACertificate field set to new_root_cert"), - TestStep(20, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster"), - TestStep(21, f"TH1 {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 0"), + TestStep(20, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_constraint_error()), + TestStep(21, f"TH1 {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 0", None, verify_armfailsafe_response()), TestStep(22, f"TH1 {send_command('OpenCommissioningWindow')} to the DUT"), TestStep( - 23, f"TH1 connects to the DUT over PASE and {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 900. Steps 24-26 are all performed over the PASE connection."), - TestStep(24, f"TH1 {send_command('CSRequest')} over PASE with the IsForUpdateNOC field set to true"), + 23, f"TH1 connects to the DUT over PASE and {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 900. Steps 24-26 are all performed over the PASE connection.", None, verify_armfailsafe_response()), + TestStep(24, f"TH1 {send_command('CSRequest')} over PASE with the IsForUpdateNOC field set to true", None, verify_csr_pase()), TestStep(25, "TH1 generates a new NOC chain with ICAC with the following properties: new NOC and ICAC using icac_pase"), - TestStep(26, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster over PASE")] + TestStep(26, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster over PASE", None, verify_unsupported_access())] @async_test_body async def test_TC_OPCREDS_3_4(self): From 96558a4ff72fd3ee3473d2b804a851f153a167e2 Mon Sep 17 00:00:00 2001 From: Gibran Vargas Date: Fri, 15 Nov 2024 10:26:12 -0800 Subject: [PATCH 22/23] chore(TC_OPCREDS_3.4): fix restyled --- src/python_testing/TC_OPCREDS_3_4.py | 35 +++++++++++++++++++--------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index 5f95aaeabf6afa..94e10b5c12d68a 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -72,9 +72,11 @@ def verify_csr_not_update() -> str: def verify_constraint_error() -> str: return ("Verify that the DUT responds with CONSTRAINT_ERROR") + def verify_csr_pase() -> str: return ("Verify that the DUT returns a CSRResponse and save as csr_pase") + def verify_unsupported_access() -> str: return ("Verify that the DUT responds with UNSUPPORTED_ACCESS") @@ -91,29 +93,40 @@ def steps_TC_OPCREDS_3_4(self): 3, f"TH1 {read_attribute('TrustedRootCertificates')} attribute from the Node Operational Credentials cluster", None, verify_trusted_root_original()), TestStep( 4, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue", None, verify_failsafe_status()), - TestStep(5, f"TH1 {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 900", None, verify_armfailsafe_response()), + TestStep( + 5, f"TH1 {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 900", None, verify_armfailsafe_response()), TestStep( 6, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster with the following fields: NOCValue and ICACValue", None, verify_noc_response("MissingCsr")), - TestStep(7, f"TH1 {send_command('CSRRequest')} with the IsForUpdateNOC field set to false", None, verify_csr_not_update()), + TestStep( + 7, f"TH1 {send_command('CSRRequest')} with the IsForUpdateNOC field set to false", None, verify_csr_not_update()), TestStep(8, "TH1 generates a new NOC chain with ICAC with the following properties"), - TestStep(9, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_constraint_error()), - TestStep(10, f"TH1 {send_command('CSRequest')} with the IsForUpdateNOC field set to true", None, verify_csr_not_update()), - TestStep(11, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_noc_response("InvalidPublicKey")), + TestStep( + 9, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_constraint_error()), + TestStep( + 10, f"TH1 {send_command('CSRequest')} with the IsForUpdateNOC field set to true", None, verify_csr_not_update()), + TestStep( + 11, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_noc_response("InvalidPublicKey")), TestStep(12, "TH1 generates a new Trusted Root Certificate and Private Key and saves as new_root_cert and new_root_key so that TH can generate an NOC for UpdateNOC that doesn’t chain to the original root"), TestStep(13, "TH1 generates a new NOC and ICAC"), - TestStep(14, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_noc_response("InvalidNOC")), + TestStep( + 14, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_noc_response("InvalidNOC")), TestStep(15, "TH1 generates a new NOC and ICAC"), - TestStep(16, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_noc_response("InvalidNOC")), + TestStep( + 16, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_noc_response("InvalidNOC")), TestStep(17, "TH1 generates a new NOC and ICAC"), - TestStep(18, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_noc_response("InvalidNOC")), + TestStep( + 18, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_noc_response("InvalidNOC")), TestStep( 19, f"TH1 {send_command('AddTrustedRootCertificate')} to DUT again with the RootCACertificate field set to new_root_cert"), - TestStep(20, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_constraint_error()), - TestStep(21, f"TH1 {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 0", None, verify_armfailsafe_response()), + TestStep( + 20, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster", None, verify_constraint_error()), + TestStep( + 21, f"TH1 {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 0", None, verify_armfailsafe_response()), TestStep(22, f"TH1 {send_command('OpenCommissioningWindow')} to the DUT"), TestStep( 23, f"TH1 connects to the DUT over PASE and {send_command('ArmFailSafe')} to the DUT with the ExpiryLengthSeconds field set to 900. Steps 24-26 are all performed over the PASE connection.", None, verify_armfailsafe_response()), - TestStep(24, f"TH1 {send_command('CSRequest')} over PASE with the IsForUpdateNOC field set to true", None, verify_csr_pase()), + TestStep( + 24, f"TH1 {send_command('CSRequest')} over PASE with the IsForUpdateNOC field set to true", None, verify_csr_pase()), TestStep(25, "TH1 generates a new NOC chain with ICAC with the following properties: new NOC and ICAC using icac_pase"), TestStep(26, f"TH1 {send_command('UpdateNOC')} to the Node Operational Credentials cluster over PASE", None, verify_unsupported_access())] From cd0c5c77e992858e59303ac353e07f7ca69b11a5 Mon Sep 17 00:00:00 2001 From: Gibran Vargas <131407127+gvargas-csa@users.noreply.github.com> Date: Thu, 21 Nov 2024 06:40:11 -0800 Subject: [PATCH 23/23] Update src/python_testing/TC_OPCREDS_3_4.py Needs the PICS function Co-authored-by: C Freeman --- src/python_testing/TC_OPCREDS_3_4.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/python_testing/TC_OPCREDS_3_4.py b/src/python_testing/TC_OPCREDS_3_4.py index 94e10b5c12d68a..e2657ba1604815 100644 --- a/src/python_testing/TC_OPCREDS_3_4.py +++ b/src/python_testing/TC_OPCREDS_3_4.py @@ -85,6 +85,9 @@ class TC_OPCREDS_3_4(MatterBaseTest): def desc_TC_OPCREDS_3_4(self): return " UpdateNOC-Error Condition [DUT-Server]" + def pics_OPCREDS_3_4(self): + return ['OPCREDS.S'] + def steps_TC_OPCREDS_3_4(self): return [TestStep(1, commission_if_required('TH1'), is_commissioning=True), TestStep(