From 842791dc8d3c60c1a2ea67c8396696c2f7acfdab Mon Sep 17 00:00:00 2001 From: Oleksandr Sirko <wisenss@gmail.com> Date: Fri, 7 Feb 2025 19:23:34 +0100 Subject: [PATCH 1/6] initial effort to write test --- src/python_testing/TC_DGETH_2_2.py | 143 +++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/python_testing/TC_DGETH_2_2.py diff --git a/src/python_testing/TC_DGETH_2_2.py b/src/python_testing/TC_DGETH_2_2.py new file mode 100644 index 00000000000000..1532005eb02195 --- /dev/null +++ b/src/python_testing/TC_DGETH_2_2.py @@ -0,0 +1,143 @@ +# +# Copyright (c) 2025 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: +# run1: +# app: ${ALL_CLUSTERS_APP} +# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# script-args: > +# --PICS src/app/tests/suites/certification/ci-pics-values +# --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 +# factory-reset: true +# quiet: true +# === END CI TEST ARGUMENTS === +# +import logging +import chip.clusters as Clusters + +from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main, run_if_endpoint_matches, has_feature, has_cluster + +from mobly import asserts + + +class TC_DGETH_2_2(MatterBaseTest): + """ + [TC-DGETH-2.2] Command Received [DUT as Server] + + This test case verifies the behavior of the commands received by the DUT as a server. + See the test plan steps for details on each command and expected outcome. + """ + + async def read_dgeth_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.EthernetNetworkDiagnostics + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def send_reset_counts_command(self): + cluster = Clusters.Objects.EthernetNetworkDiagnostics + return await self.send_single_cmd(cmd=cluster.Commands.ResetCounts(), endpoint=0) + + def desc_TC_DGETH_2_2(self) -> str: + return "[TC-DGETH-2.2] Command Received [DUT as Server]" + + def pics_TC_DGETH_2_2(self) -> list[str]: + return ["DGETH.S"] + + def steps_TC_DGETH_2_2(self) -> list[TestStep]: + return [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "Read PHYRate 10 times to generate traffic"), + TestStep(3, "Read initial PacketRxCount"), + TestStep(4, "Read initial PacketTxCount"), + TestStep(5, "Read initial TxErrCount"), + TestStep(6, "Read initial CollisionCount"), + TestStep(7, "Read initial OverrunCount"), + TestStep(8, "Send ResetCounts command"), + TestStep(9, "Verify PacketRxCount reset"), + TestStep(10, "Verify PacketTxCount reset"), + TestStep(11, "Verify TxErrCount reset"), + TestStep(12, "Verify CollisionCount reset"), + TestStep(13, "Verify OverrunCount reset") + ] + + @run_if_endpoint_matches(has_cluster(Clusters.Objects.EthernetNetworkDiagnostics)) + async def test_TC_DGETH_2_2(self): + endpoint = self.get_endpoint() + cluster = Clusters.Objects.EthernetNetworkDiagnostics + attributes = Clusters.EthernetNetworkDiagnostics.Attributes + + # Step 1: Commission DUT (already done) + self.step(1) + + attribute_list = await self.read_dgeth_attribute_expect_success(endpoint, attributes.AttributeList) + + # Step 2: Generate traffic with PHYRate reads + self.step(2) + if self.pics_guard(attributes.PHYRate.attribute_id in attribute_list): + for _ in range(10): + await self.read_dgeth_attribute_expect_success(endpoint, attributes.AttributeList) + + # Steps 3-7: Read initial values + initial_values = {} + for step, attr in [(3, attributes.PacketRxCount), + (4, attributes.PacketTxCount), + (5, attributes.TxErrCount), + (6, attributes.CollisionCount), + (7, attributes.OverrunCount)]: + self.step(step) + if self.pics_guard(attr.attribute_id in attribute_list): + initial_values[attr] = await self.read_dgeth_attribute_expect_success(endpoint, attr) + # Print initial values for debugging + self.step(8) + for attr, value in initial_values.items(): + logging.info(f"Initial {attr.__name__}: {value}") + + # Step 8: Send ResetCounts command + self.step(8) + await self.send_reset_counts_command() + + # Steps 9-13: Verify post-reset values + verification_map = { + 9: (attributes.PacketRxCount, lambda a, b: a < b), + 10: (attributes.PacketTxCount, lambda a, b: a < b), + 11: (attributes.TxErrCount, lambda a, b: a <= b), + 12: (attributes.CollisionCount, lambda a, b: a <= b), + 13: (attributes.OverrunCount, lambda a, b: a <= b) + } + + for step, (attr, comparator) in verification_map.items(): + self.step(step) + if self.pics_guard(attr.attribute_id in attribute_list): + post_value = await self.read_dgeth_attribute_expect_success(endpoint, attr) + initial_value = initial_values.get(attr) + + asserts.assert_true( + comparator(post_value, initial_value), + f"{attr.__name__} post-reset value {post_value} failed check against initial {initial_value}" + ) + + +if __name__ == "__main__": + default_matter_test_main() From 5c09a11be65a25a994f4bf97e093d86fc8c0c000 Mon Sep 17 00:00:00 2001 From: Oleksandr Sirko <wisenss@gmail.com> Date: Fri, 7 Feb 2025 22:04:00 +0100 Subject: [PATCH 2/6] remove debug step --- src/python_testing/TC_DGETH_2_2.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/python_testing/TC_DGETH_2_2.py b/src/python_testing/TC_DGETH_2_2.py index 1532005eb02195..cfe04d9392c4b4 100644 --- a/src/python_testing/TC_DGETH_2_2.py +++ b/src/python_testing/TC_DGETH_2_2.py @@ -35,11 +35,8 @@ # quiet: true # === END CI TEST ARGUMENTS === # -import logging import chip.clusters as Clusters - -from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main, run_if_endpoint_matches, has_feature, has_cluster - +from chip.testing.matter_testing import MatterBaseTest, TestStep, default_matter_test_main, has_cluster, run_if_endpoint_matches from mobly import asserts @@ -85,7 +82,6 @@ def steps_TC_DGETH_2_2(self) -> list[TestStep]: @run_if_endpoint_matches(has_cluster(Clusters.Objects.EthernetNetworkDiagnostics)) async def test_TC_DGETH_2_2(self): endpoint = self.get_endpoint() - cluster = Clusters.Objects.EthernetNetworkDiagnostics attributes = Clusters.EthernetNetworkDiagnostics.Attributes # Step 1: Commission DUT (already done) @@ -109,10 +105,6 @@ async def test_TC_DGETH_2_2(self): self.step(step) if self.pics_guard(attr.attribute_id in attribute_list): initial_values[attr] = await self.read_dgeth_attribute_expect_success(endpoint, attr) - # Print initial values for debugging - self.step(8) - for attr, value in initial_values.items(): - logging.info(f"Initial {attr.__name__}: {value}") # Step 8: Send ResetCounts command self.step(8) From 9e14c4af17eb9f3a40f25d135ec3f410b3607355 Mon Sep 17 00:00:00 2001 From: Oleksandr Sirko <wisenss@gmail.com> Date: Mon, 10 Feb 2025 11:28:47 +0100 Subject: [PATCH 3/6] remove yaml, now has a python implementation --- .../certification/Test_TC_DGETH_2_2.yaml | 234 ------------------ src/app/tests/suites/ciTests.json | 2 +- 2 files changed, 1 insertion(+), 235 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_DGETH_2_2.yaml diff --git a/src/app/tests/suites/certification/Test_TC_DGETH_2_2.yaml b/src/app/tests/suites/certification/Test_TC_DGETH_2_2.yaml deleted file mode 100644 index 8751ef754a552f..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DGETH_2_2.yaml +++ /dev/null @@ -1,234 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# 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. - -name: 47.2.2. [TC-DGETH-2.2] Command Received [DUT as Server] - -PICS: - - DGETH.S - -config: - nodeId: 0x12344321 - cluster: "Ethernet Network Diagnostics" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2a.1: TH reads PHYRate attribute from DUT" - PICS: DGETH.S.A0000 - command: "readAttribute" - attribute: "PHYRate" - response: - constraints: - type: enum8 - minValue: 0 - maxValue: 9 - - - label: "Step 2a.2: TH reads PHYRate attribute from DUT" - PICS: DGETH.S.A0000 - command: "readAttribute" - attribute: "PHYRate" - response: - constraints: - type: enum8 - minValue: 0 - maxValue: 9 - - - label: "Step 2a.3: TH reads PHYRate attribute from DUT" - PICS: DGETH.S.A0000 - command: "readAttribute" - attribute: "PHYRate" - response: - constraints: - type: enum8 - minValue: 0 - maxValue: 9 - - - label: "Step 2a.4: TH reads PHYRate attribute from DUT" - PICS: DGETH.S.A0000 - command: "readAttribute" - attribute: "PHYRate" - response: - constraints: - type: enum8 - minValue: 0 - maxValue: 9 - - - label: "Step 2a.5: TH reads PHYRate attribute from DUT" - PICS: DGETH.S.A0000 - command: "readAttribute" - attribute: "PHYRate" - response: - constraints: - type: enum8 - minValue: 0 - maxValue: 9 - - - label: "Step 2a.6: TH reads PHYRate attribute from DUT" - PICS: DGETH.S.A0000 - command: "readAttribute" - attribute: "PHYRate" - response: - constraints: - type: enum8 - minValue: 0 - maxValue: 9 - - - label: "Step 2a.7: TH reads PHYRate attribute from DUT" - PICS: DGETH.S.A0000 - command: "readAttribute" - attribute: "PHYRate" - response: - constraints: - type: enum8 - minValue: 0 - maxValue: 9 - - - label: "Step 2a.8: TH reads PHYRate attribute from DUT" - PICS: DGETH.S.A0000 - command: "readAttribute" - attribute: "PHYRate" - response: - constraints: - type: enum8 - minValue: 0 - maxValue: 9 - - - label: "Step 2a.9: TH reads PHYRate attribute from DUT" - PICS: DGETH.S.A0000 - command: "readAttribute" - attribute: "PHYRate" - response: - constraints: - type: enum8 - minValue: 0 - maxValue: 9 - - - label: "Step 2a.10: TH reads PHYRate attribute from DUT" - PICS: DGETH.S.A0000 - command: "readAttribute" - attribute: "PHYRate" - response: - constraints: - type: enum8 - minValue: 0 - maxValue: 9 - - - label: "Step 2b: TH reads PacketRxCount attribute value from DUT" - PICS: DGETH.S.A0002 - command: "readAttribute" - attribute: "PacketRxCount" - response: - saveAs: PacketRxCountValue - - - label: "Step 2c: TH reads PacketTxCount attribute value from DUT" - PICS: DGETH.S.A0003 - command: "readAttribute" - attribute: "PacketTxCount" - response: - saveAs: PacketTxCountValue - - - label: "Step 2d: TH reads TxErrCount attribute value from DUT" - PICS: DGETH.S.A0004 - command: "readAttribute" - attribute: "TxErrCount" - response: - saveAs: TxErrCountValue - - - label: "Step 2e: TH reads CollisionCount attribute value from DUT" - PICS: DGETH.S.A0005 - command: "readAttribute" - attribute: "CollisionCount" - response: - saveAs: CollisionCountValue - - - label: "Step 2f: TH reads OverrunCount attribute value from DUT" - PICS: DGETH.S.A0006 - command: "readAttribute" - attribute: "OverrunCount" - response: - saveAs: OverrunCountValue - - #issue #13648 - - label: "Step 2g: Sends ResetCounts command" - PICS: DGETH.S.C00.Rsp - command: "ResetCounts" - - #https://github.com/CHIP-Specifications/chip-certification-tool/issues/702#issuecomment-1427974329 - - label: "Step 2h: TH reads PacketRxCount attribute value from DUT" - PICS: DGETH.S.A0002 && PICS_SKIP_SAMPLE_APP - verification: | - ./chip-tool ethernetnetworkdiagnostics read packet-rx-count 1 0 - - Verify the value of PacketRxCount is less than the value from step 2b on TH(chip-tool) log - - [1657259203.212932][2661:2666] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0037 Attribute 0x0000_0002 DataVersion: 4077191321 - [1657259203.213000][2661:2666] CHIP:TOO: PacketRxCount: 30 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" - - #https://github.com/CHIP-Specifications/chip-certification-tool/issues/702#issuecomment-1427974329 - - label: "Step 2i: TH reads PacketTxCount attribute value from DUT" - PICS: DGETH.S.A0003 && PICS_SKIP_SAMPLE_APP - verification: | - ./chip-tool ethernetnetworkdiagnostics read packet-tx-count 1 0 - - Verify the value of PacketTxCount is less than the value from step 2c on TH(chip-tool) log - - [1657259233.211240][2668:2673] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0037 Attribute 0x0000_0003 DataVersion: 4077191321 - [1657259233.211315][2668:2673] CHIP:TOO: PacketTxCount: 96 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: "Step 2j: TH reads TxErrCount attribute value from DUT" - PICS: DGETH.S.A0004 - command: "readAttribute" - attribute: "TxErrCount" - response: - constraints: - maxValue: TxErrCountValue - - - label: "Step 2k: TH reads CollisionCount attribute value from DUT" - PICS: DGETH.S.A0005 - command: "readAttribute" - attribute: "CollisionCount" - response: - constraints: - maxValue: CollisionCountValue - - - label: "Step 2l: TH reads OverrunCount attribute value from DUT" - PICS: DGETH.S.A0006 - command: "readAttribute" - attribute: "OverrunCount" - response: - constraints: - maxValue: OverrunCountValue diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json index 9fa23f8a516aa5..b128a4a7d6d35e 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -47,7 +47,7 @@ ], "Descriptor": [], "DeviceEnergyManagementMode": ["Test_TC_DEMM_2_1"], - "EthernetNetworkDiagnostics": ["Test_TC_DGETH_2_1", "Test_TC_DGETH_2_2"], + "EthernetNetworkDiagnostics": ["Test_TC_DGETH_2_1"], "DiagnosticsLogs": [], "EnergyEVSE": ["Test_TC_EEVSE_2_1"], "EnergyEVSEMode": [ From 7924600bafca8fe871746c4387f1d2df9f2137e7 Mon Sep 17 00:00:00 2001 From: Oleksandr Sirko <wisenss@gmail.com> Date: Mon, 10 Feb 2025 14:04:02 +0100 Subject: [PATCH 4/6] endpoint flaf for CI --- src/python_testing/TC_DGETH_2_2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/python_testing/TC_DGETH_2_2.py b/src/python_testing/TC_DGETH_2_2.py index cfe04d9392c4b4..13bd586dabda4c 100644 --- a/src/python_testing/TC_DGETH_2_2.py +++ b/src/python_testing/TC_DGETH_2_2.py @@ -31,6 +31,7 @@ # --passcode 20202021 # --trace-to json:${TRACE_TEST_JSON}.json # --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# --endpoint 0 # factory-reset: true # quiet: true # === END CI TEST ARGUMENTS === From d68b2d31bd333610ec8b0261e752ba5188c0682c Mon Sep 17 00:00:00 2001 From: Oleksandr Sirko <wisenss@gmail.com> Date: Tue, 11 Feb 2025 12:29:04 +0100 Subject: [PATCH 5/6] debug log --- src/python_testing/TC_DGETH_2_2.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/python_testing/TC_DGETH_2_2.py b/src/python_testing/TC_DGETH_2_2.py index 13bd586dabda4c..79fc594f696485 100644 --- a/src/python_testing/TC_DGETH_2_2.py +++ b/src/python_testing/TC_DGETH_2_2.py @@ -37,9 +37,12 @@ # === END CI TEST ARGUMENTS === # import chip.clusters as Clusters +import logging from chip.testing.matter_testing import MatterBaseTest, TestStep, default_matter_test_main, has_cluster, run_if_endpoint_matches from mobly import asserts +logger = logging.getLogger(__name__) + class TC_DGETH_2_2(MatterBaseTest): """ @@ -106,10 +109,12 @@ async def test_TC_DGETH_2_2(self): self.step(step) if self.pics_guard(attr.attribute_id in attribute_list): initial_values[attr] = await self.read_dgeth_attribute_expect_success(endpoint, attr) + logger.info(f"Initial {attr.__name__} value: {initial_values[attr]}") # Step 8: Send ResetCounts command self.step(8) await self.send_reset_counts_command() + logger.info("Reset counts command sent") # Steps 9-13: Verify post-reset values verification_map = { @@ -125,6 +130,7 @@ async def test_TC_DGETH_2_2(self): if self.pics_guard(attr.attribute_id in attribute_list): post_value = await self.read_dgeth_attribute_expect_success(endpoint, attr) initial_value = initial_values.get(attr) + logger.info(f"Post-reset {attr.__name__} value: {post_value} (initial: {initial_value})") asserts.assert_true( comparator(post_value, initial_value), From 467ed3df8e90015a67941db344030384b54b6579 Mon Sep 17 00:00:00 2001 From: Oleksandr Sirko <wisenss@gmail.com> Date: Tue, 11 Feb 2025 12:33:33 +0100 Subject: [PATCH 6/6] isort --- src/python_testing/TC_DGETH_2_2.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python_testing/TC_DGETH_2_2.py b/src/python_testing/TC_DGETH_2_2.py index 79fc594f696485..3a5d63ededbe8e 100644 --- a/src/python_testing/TC_DGETH_2_2.py +++ b/src/python_testing/TC_DGETH_2_2.py @@ -15,6 +15,8 @@ # limitations under the License. # +import logging + # See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments # for details about the block below. # @@ -37,7 +39,6 @@ # === END CI TEST ARGUMENTS === # import chip.clusters as Clusters -import logging from chip.testing.matter_testing import MatterBaseTest, TestStep, default_matter_test_main, has_cluster, run_if_endpoint_matches from mobly import asserts