diff --git a/src/python_testing/TC_CGEN_2_5.py b/src/python_testing/TC_CGEN_2_5.py new file mode 100644 index 00000000000000..c3edd6c3d265da --- /dev/null +++ b/src/python_testing/TC_CGEN_2_5.py @@ -0,0 +1,147 @@ +# +# 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. +# + +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${TERMS_AND_CONDITIONS_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --KVS kvs1 +# test-runner-run/run1/script-args: --in-test-commissioning-method on-network --qr-code MT:-24J0AFN00KA0648G00 --trace-to json:log +# === END CI TEST ARGUMENTS === + + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from chip.commissioning import ROOT_ENDPOINT_ID +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_CGEN_2_5(MatterBaseTest): + def desc_TC_CGEN_2_5(self) -> str: + return "[TC-CGEN-2.5] Verification For SetTCAcknowledgements [DUT as Server]" + + def steps_TC_CGEN_2_5(self) -> list[TestStep]: + return [ + TestStep(1, "TH starts commissioning the DUT. It performs all commissioning steps from ArmFailSafe, except SetTCAcknowledgements and CommissioningComplete.", is_commissioning=False), + TestStep(2, "TH reads TCAcknowledgementsRequired attribute from the DUT."), + TestStep(3, "TH sends SetTCAcknowledgements to DUT with the following values:\nTCVersion: Greater than or equal to TCMinRequiredVersion on DUT\nTCUserResponse: All terms required by DUT accepted"), + TestStep(4, "TH sends CommissioningComplete to DUT."), + TestStep(5, "TH reads TCAcceptedVersion attribute from the DUT."), + TestStep(6, "TH reads TCAcknowledgements attribute from the DUT."), + TestStep(7, "TH reads TCMinRequiredVersion attribute from the DUT."), + TestStep(8, "TH reads TCAcknowledgementsRequired attribute from the DUT."), + TestStep(9, "TH sends the SetTCAcknowledgements command to the DUT with the fields set as follows:\nTCVersion: 0\nTCUserResponse: 0"), + ] + + @async_test_body + async def test_TC_CGEN_2_5(self): + commissioner: ChipDeviceCtrl.ChipDeviceController = self.default_controller + + # Don't set TCs for the next commissioning and skip CommissioningComplete so we can manually call CommissioningComplete in order to check the response error code + self.step(1) + commissioner.SetTCRequired(False) + commissioner.SetSkipCommissioningComplete(True) + self.matter_test_config.commissioning_method = self.matter_test_config.in_test_commissioning_method + await self.commission_devices() + + self.step(2) + response: dict[int, Clusters.GeneralCommissioning] = await commissioner.ReadAttribute( + nodeid=self.dut_node_id, + attributes=[ + (ROOT_ENDPOINT_ID, Clusters.GeneralCommissioning.Attributes.TCAcceptedVersion), + (ROOT_ENDPOINT_ID, Clusters.GeneralCommissioning.Attributes.TCMinRequiredVersion), + (ROOT_ENDPOINT_ID, Clusters.GeneralCommissioning.Attributes.TCAcknowledgements), + (ROOT_ENDPOINT_ID, Clusters.GeneralCommissioning.Attributes.TCAcknowledgementsRequired), + ]) + tcAcceptedVersion = response[ROOT_ENDPOINT_ID][Clusters.GeneralCommissioning][Clusters.GeneralCommissioning.Attributes.TCAcceptedVersion] + tcMinRequiredVersion = response[ROOT_ENDPOINT_ID][Clusters.GeneralCommissioning][Clusters.GeneralCommissioning.Attributes.TCMinRequiredVersion] + tcAcknowledgements = response[ROOT_ENDPOINT_ID][Clusters.GeneralCommissioning][Clusters.GeneralCommissioning.Attributes.TCAcknowledgements] + tcAcknowledgementsRequired = response[ROOT_ENDPOINT_ID][Clusters.GeneralCommissioning][Clusters.GeneralCommissioning.Attributes.TCAcknowledgementsRequired] + + # Verify that TCAcknowledgementsRequired value is representable in the 'Bool' type + # Verify that TCAcknowledgementsRequired value is True + asserts.assert_equal(tcAcknowledgementsRequired, True, 'Incorrect TCAcknowledgementsRequired') + + self.step(3) + response: Clusters.GeneralCommissioning.Commands.SetTCAcknowledgementsResponse = await commissioner.SendCommand( + nodeid=self.dut_node_id, + endpoint=ROOT_ENDPOINT_ID, + payload=Clusters.GeneralCommissioning.Commands.SetTCAcknowledgements(TCVersion=2**16 - 1, TCUserResponse=2**16 - 1), + timedRequestTimeoutMs=1000) + # Verify that DUT sends SetTCAcknowledgementsResponse Command to TH With ErrorCode as 'OK'(0). + asserts.assert_equal(response.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, + 'Incorrect error code') + + self.step(4) + response: Clusters.GeneralCommissioning.Commands.CommissioningCompleteResponse = await commissioner.SendCommand( + nodeid=self.dut_node_id, + endpoint=ROOT_ENDPOINT_ID, + payload=Clusters.GeneralCommissioning.Commands.CommissioningComplete(), + timedRequestTimeoutMs=1000) + # Verify that DUT sends CommissioningCompleteResponse Command to TH With ErrorCode as 'OK'(0). + asserts.assert_equal(response.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kOk, + 'Incorrect error code') + + # Read attributes of interest + response: dict[int, Clusters.GeneralCommissioning] = await commissioner.ReadAttribute( + nodeid=self.dut_node_id, + attributes=[ + (ROOT_ENDPOINT_ID, Clusters.GeneralCommissioning.Attributes.TCAcceptedVersion), + (ROOT_ENDPOINT_ID, Clusters.GeneralCommissioning.Attributes.TCMinRequiredVersion), + (ROOT_ENDPOINT_ID, Clusters.GeneralCommissioning.Attributes.TCAcknowledgements), + (ROOT_ENDPOINT_ID, Clusters.GeneralCommissioning.Attributes.TCAcknowledgementsRequired), + ]) + tcAcceptedVersion = response[ROOT_ENDPOINT_ID][Clusters.GeneralCommissioning][Clusters.GeneralCommissioning.Attributes.TCAcceptedVersion] + tcMinRequiredVersion = response[ROOT_ENDPOINT_ID][Clusters.GeneralCommissioning][Clusters.GeneralCommissioning.Attributes.TCMinRequiredVersion] + tcAcknowledgements = response[ROOT_ENDPOINT_ID][Clusters.GeneralCommissioning][Clusters.GeneralCommissioning.Attributes.TCAcknowledgements] + tcAcknowledgementsRequired = response[ROOT_ENDPOINT_ID][Clusters.GeneralCommissioning][Clusters.GeneralCommissioning.Attributes.TCAcknowledgementsRequired] + + self.step(5) + # Verify that TCAcceptedVersion value fits in the 'uint16' type + asserts.assert_less(tcAcceptedVersion, 2**16, 'Incorrect TCAcceptedVersion') + # Verify that TCAcceptedVersion is the value sent in step 3 + asserts.assert_equal(tcAcceptedVersion, 2**16 - 1, 'Incorrect TCAcceptedVersion') + + self.step(6) + # Verify that TCAcknowledgements is a value representable in the map16 type + # Verify that TCAcknowledgements is the value sent in step 3 + asserts.assert_equal(tcAcknowledgements, 2**16 - 1, 'Incorrect TCAcknowledgements') + + self.step(7) + # Verify that TCMinRequiredVersion value fits in the 'uint16' type + asserts.assert_less(tcMinRequiredVersion, 2**16, 'Incorrect TCMinRequiredVersion') + + self.step(8) + # Verify that TCAcknowledgementsRequired value is False + asserts.assert_equal(tcAcknowledgementsRequired, False, 'Incorrect TCAcknowledgementsRequired') + + self.step(9) + response: Clusters.GeneralCommissioning.Commands.SetTCAcknowledgementsResponse = await commissioner.SendCommand( + nodeid=self.dut_node_id, + endpoint=ROOT_ENDPOINT_ID, + payload=Clusters.GeneralCommissioning.Commands.SetTCAcknowledgements(TCVersion=0, TCUserResponse=0), + timedRequestTimeoutMs=1000) + # Verify that DUT sends SetTCAcknowledgementsResponse Command to TH With ErrorCode as 'TCMinVersionNotMet'(7) + asserts.assert_equal(response.errorCode, + Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kTCMinVersionNotMet, 'Incorrect error code') + # Verify that TCAcceptedVersion and TCAcknowledgements still contain the values sent in step 3. + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_CGEN_2_6.py b/src/python_testing/TC_CGEN_2_6.py new file mode 100644 index 00000000000000..8f0ad7a6a8ae2a --- /dev/null +++ b/src/python_testing/TC_CGEN_2_6.py @@ -0,0 +1,66 @@ +# +# 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. +# + +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${TERMS_AND_CONDITIONS_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --KVS kvs1 +# test-runner-run/run1/script-args: --in-test-commissioning-method on-network --qr-code MT:-24J0AFN00KA0648G00 --trace-to json:log +# === END CI TEST ARGUMENTS === + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from chip.commissioning import ROOT_ENDPOINT_ID +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_CGEN_2_6(MatterBaseTest): + def desc_TC_CGEN_2_6(self) -> str: + return "[TC-CGEN-2.6] Verification For CommissioningComplete no terms accepted when required [DUT as Server]" + + def steps_TC_CGEN_2_6(self) -> list[TestStep]: + return [ + TestStep(1, "TH starts commissioning the DUT. It performs all commissioning steps from ArmFailSafe to CommissioningComplete, except for TC configuration with SetTCAcknowledgements.", is_commissioning=False), + ] + + @async_test_body + async def test_TC_CGEN_2_6(self): + commissioner: ChipDeviceCtrl.ChipDeviceController = self.default_controller + + # Don't set TCs for the next commissioning and skip CommissioningComplete so we can manually call CommissioningComplete in order to check the response error code + commissioner.SetTCRequired(False) + commissioner.SetSkipCommissioningComplete(True) + self.matter_test_config.commissioning_method = self.matter_test_config.in_test_commissioning_method + + self.step(1) + await self.commission_devices() + response: Clusters.GeneralCommissioning.Commands.CommissioningCompleteResponse = await commissioner.SendCommand( + nodeid=self.dut_node_id, + endpoint=ROOT_ENDPOINT_ID, + payload=Clusters.GeneralCommissioning.Commands.CommissioningComplete(), + timedRequestTimeoutMs=1000) + + # Verify that DUT sends CommissioningCompleteResponse Command to TH With ErrorCode as 'TCAcknowledgementsNotReceived'(6). + asserts.assert_equal( + response.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kTCAcknowledgementsNotReceived, 'Incorrect error code') + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_CGEN_2_7.py b/src/python_testing/TC_CGEN_2_7.py new file mode 100644 index 00000000000000..8903b5727c6ed6 --- /dev/null +++ b/src/python_testing/TC_CGEN_2_7.py @@ -0,0 +1,81 @@ +# +# 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. +# + +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${TERMS_AND_CONDITIONS_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --KVS kvs1 +# test-runner-run/run1/script-args: --in-test-commissioning-method on-network --qr-code MT:-24J0AFN00KA0648G00 --trace-to json:log +# === END CI TEST ARGUMENTS === + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from chip.commissioning import ROOT_ENDPOINT_ID +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_CGEN_2_7(MatterBaseTest): + def desc_TC_CGEN_2_7(self) -> str: + return "[TC-CGEN-2.7] Verification For CommissioningComplete when SetTCAcknowledgements provides invalid terms [DUT as Server]" + + def steps_TC_CGEN_2_7(self) -> list[TestStep]: + return [ + TestStep(1, "TH starts commissioning the DUT. It performs all commissioning steps from ArmFailSafe, except SetTCAcknowledgements and CommissioningComplete.", is_commissioning=False), + TestStep(2, "TH sends SetTCAcknowledgements to DUT with the following values:\nTCVersion: Greater than or equal to TCMinRequiredVersion on DUT\nTCUserResponse: 0"), + TestStep(3, "TH sends CommissioningComplete to DUT."), + ] + + @async_test_body + async def test_TC_CGEN_2_7(self): + commissioner: ChipDeviceCtrl.ChipDeviceController = self.default_controller + + # Don't set TCs for the next commissioning and skip CommissioningComplete so we can manually call CommissioningComplete in order to check the response error code + commissioner.SetTCRequired(False) + commissioner.SetSkipCommissioningComplete(True) + self.matter_test_config.commissioning_method = self.matter_test_config.in_test_commissioning_method + + self.step(1) + await self.commission_devices() + + self.step(2) + response: Clusters.GeneralCommissioning.Commands.SetTCAcknowledgementsResponse = await commissioner.SendCommand( + nodeid=self.dut_node_id, + endpoint=ROOT_ENDPOINT_ID, + payload=Clusters.GeneralCommissioning.Commands.SetTCAcknowledgements(TCVersion=2**16 - 1, TCUserResponse=0), + timedRequestTimeoutMs=1000) + + # Verify that DUT sends SetTCAcknowledgementsResponse Command to TH With ErrorCode as 'RequiredTCNotAccepted'(5). + asserts.assert_equal( + response.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kRequiredTCNotAccepted, 'Incorrect error code') + + self.step(3) + response: Clusters.GeneralCommissioning.Commands.CommissioningCompleteResponse = await commissioner.SendCommand( + nodeid=self.dut_node_id, + endpoint=ROOT_ENDPOINT_ID, + payload=Clusters.GeneralCommissioning.Commands.CommissioningComplete(), + timedRequestTimeoutMs=1000) + + # Verify that DUT sends CommissioningCompleteResponse Command to TH With ErrorCode as 'TCAcknowledgementsNotReceived'(6). + asserts.assert_equal( + response.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kTCAcknowledgementsNotReceived, 'Incorrect error code') + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_CGEN_2_8.py b/src/python_testing/TC_CGEN_2_8.py new file mode 100644 index 00000000000000..8b66357360a15b --- /dev/null +++ b/src/python_testing/TC_CGEN_2_8.py @@ -0,0 +1,98 @@ +# +# 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. +# + +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${TERMS_AND_CONDITIONS_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --KVS kvs1 +# test-runner-run/run1/script-args: --in-test-commissioning-method on-network --qr-code MT:-24J0AFN00KA0648G00 --trace-to json:log +# === END CI TEST ARGUMENTS === + +from typing import List + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from chip.commissioning import ROOT_ENDPOINT_ID +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_CGEN_2_8(MatterBaseTest): + + async def remove_commissioner_fabric(self): + commissioner: ChipDeviceCtrl.ChipDeviceController = self.default_controller + + fabrics: List[Clusters.OperationalCredentials.Structs.FabricDescriptorStruct] = await self.read_single_attribute( + dev_ctrl=commissioner, + node_id=self.dut_node_id, + endpoint=ROOT_ENDPOINT_ID, + attribute=Clusters.OperationalCredentials.Attributes.Fabrics) + + # Re-order the list of fabrics so that the test harness admin fabric is removed last + commissioner_fabric = next((fabric for fabric in fabrics if fabric.fabricIndex == commissioner.fabricId), None) + fabrics.remove(commissioner_fabric) + fabrics.append(commissioner_fabric) + + for fabric in fabrics: + response: Clusters.OperationalCredentials.Commands.NOCResponse = await commissioner.SendCommand( + nodeid=self.dut_node_id, + endpoint=ROOT_ENDPOINT_ID, + payload=Clusters.OperationalCredentials.Commands.RemoveFabric(fabric.fabricIndex), + timedRequestTimeoutMs=1000) + asserts.assert_equal(response.statusCode, Clusters.OperationalCredentials.Enums.NodeOperationalCertStatusEnum.kOk) + + def desc_TC_CGEN_2_8(self) -> str: + return "[TC-CGEN-2.8] Verification For Terms and Conditions Reset [DUT as Server]" + + def steps_TC_CGEN_2_8(self) -> list[TestStep]: + return [ + TestStep(1, "DUT requires terms and conditions. DUT has been successfully commissioned."), + TestStep(2, "User performs factory reset."), + TestStep(3, "User triggers USER INTENT to set the device to be in commissioning mode."), + TestStep(4, "TH starts commissioning the DUT. It performs all commissioning steps, except for TC configuration with SetTCAcknowledgements."), + ] + + @async_test_body + async def test_TC_CGEN_2_8(self): + commissioner: ChipDeviceCtrl.ChipDeviceController = self.default_controller + + self.step(1) + self.step(2) + self.step(3) + self.wait_for_user_input(prompt_msg="Set the DUT into commissioning mode") + + # Don't set TCs for the next commissioning and skip CommissioningComplete so we can manually call CommissioningComplete in order to check the response error code + commissioner.SetTCRequired(False) + commissioner.SetSkipCommissioningComplete(True) + self.matter_test_config.commissioning_method = self.matter_test_config.in_test_commissioning_method + await self.commission_devices() + + self.step(4) + response: Clusters.GeneralCommissioning.Commands.CommissioningCompleteResponse = await commissioner.SendCommand( + nodeid=self.dut_node_id, + endpoint=ROOT_ENDPOINT_ID, + payload=Clusters.GeneralCommissioning.Commands.CommissioningComplete(), + timedRequestTimeoutMs=1000) + # Verify that DUT sends CommissioningCompleteResponse Command to TH With ErrorCode as 'TCAcknowledgementsNotReceived'(6). + asserts.assert_equal( + response.errorCode, Clusters.GeneralCommissioning.Enums.CommissioningErrorEnum.kTCAcknowledgementsNotReceived, 'Incorrect error code') + + +if __name__ == "__main__": + default_matter_test_main()