From acedec197c61d8b2b2bbe55fac16faf8a73b190e Mon Sep 17 00:00:00 2001 From: Hasty Granbery Date: Sun, 18 Feb 2024 04:45:59 +0900 Subject: [PATCH] Power Topology: add test scripts (#32114) * Initial XML for Power Topology cluster * Regen * Restyled really wants newlines at the end of every JSON file * Rename LeafTopology to TreeTopology * [Feature] Power Topology server & all-clusters-app stub * Make endpointId a constructor arg for PowerTopologyDelegate * Change PowerTopologyDelegate to not return std::vectors * Remove unneeded entries in attributeAccessInterfaceAttributes for Power Topology cluster * Typo in python/chip/clusters/__init__.py * Format zcl.json * Add DynamicPowerFlow feature to PowerTopology stub * Add Power Topology to client * Set CI PICS values * Python test script for Power Topology * Linted python script * Add Power Topology python script test * Add PWRTL_1_1 to ciTests.json * Restyled * Regen * Format PICS.yaml --- .github/workflows/tests.yaml | 1 + src/app/tests/suites/certification/PICS.yaml | 33 +++++ .../certification/Test_TC_PWRTL_1_1.yaml | 119 ++++++++++++++++++ .../tests/suites/certification/ci-pics-values | 12 ++ src/app/tests/suites/ciTests.json | 1 + src/app/tests/suites/manualTests.json | 2 + src/app/zap_cluster_list.json | 2 +- src/python_testing/TC_PWRTL_2_1.py | 69 ++++++++++ 8 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml create mode 100644 src/python_testing/TC_PWRTL_2_1.py diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 05d2670edd665e..f083cd70bccd7c 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -502,6 +502,7 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_IDM_1_2.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json --enable-key 000102030405060708090a0b0c0d0e0f" --script "src/python_testing/TC_IDM_1_4.py" --script-args "--hex-arg PIXIT.DGGEN.TEST_EVENT_TRIGGER_KEY:000102030405060708090a0b0c0d0e0f --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_IDM_4_2.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_PWRTL_2_1.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RR_1_1.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCCLEANM_1_2.py" --script-args "--int-arg PIXIT_ENDPOINT:1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCRUNM_1_2.py" --script-args "--int-arg PIXIT_ENDPOINT:1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index 068db7f0dfe525..49554c37f4e3b6 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -10160,3 +10160,36 @@ PICS: - label: "Can the mode change be manually controlled?" id: EEVSEM.S.M.CAN_MANUALLY_CONTROLLED + + # + # Power Topology Cluster + # + - label: "Does the device implement the Power Topology Cluster as a server?" + id: PWRTL.S + + # Features + + - label: + "Does the associated endpoint provide or consume power for the entire + node?" + id: PWRTL.S.F00 + + - label: + "Does the associated endpoint provide or consume power for itself and + its child endpoints?" + id: PWRTL.S.F01 + + - label: + "Does the associated endpoint provide or consume power for a provided + set of endpoints?" + id: PWRTL.S.F02 + + - label: "Can the provided set of endpoints change?" + id: PWRTL.S.F03 + + #Server attributes + - label: "Does the device implement the AvailableEndpoints attribute?" + id: PWRTL.S.A0000 + + - label: "Does the device implement the ActiveEndpoints attribute?" + id: PWRTL.S.A0001 diff --git a/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml new file mode 100644 index 00000000000000..cfe6fd860be240 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml @@ -0,0 +1,119 @@ +# 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. +# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default + +name: 44.1.1. [TC-PWRTL-1.1] Global Attributes with DUT as Server + +PICS: + - PWRTL.S + +config: + nodeId: 0x12344321 + cluster: "Power Topology" + endpoint: 1 + +tests: + - label: "Step 1: Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "Step 2: TH reads the ClusterRevision from DUT" + command: "readAttribute" + attribute: "ClusterRevision" + response: + value: 1 + constraints: + type: int16u + + - label: + "Step 3a: Given PWRTL.S.F00(Node) ensure featuremap has the correct + bit set" + PICS: PWRTL.S.F00 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x1] + hasMasksClear: [0x2, 0x4, 0x8] + + - label: + "Step 3b: Given PWRTL.S.F01(Leaf) ensure featuremap has the correct + bit set" + PICS: PWRTL.S.F01 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x2] + hasMasksClear: [0x1, 0x4, 0x8] + + - label: + "Step 3c: Given PWRTL.S.F02(Set) ensure featuremap has the correct bit + set" + PICS: PWRTL.S.F02 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x4] + hasMasksClear: [0x1, 0x2] + + - label: + "Step 3d: Given PWRTL.S.F03(Dynamic Power Flow) ensure featuremap has + the correct bit set" + PICS: PWRTL.S.F03 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x4, 0x8] + + - label: "Step 4a: TH reads AttributeList from DUT" + PICS: "!PICS_SF_SET && !PICS_SF_DYPF" + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [] + + - label: + "Step 4b: TH reads feature dependent attribute(AvailableEndpoints) + AttributeList from DUT" + PICS: "PICS_SF_SET && !PICS_SF_DYPF" + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [0] + + - label: + "Step 4c: TH reads feature dependent attribute(ActiveEndpoints) + AttributeList from DUT" + PICS: "PICS_SF_SET && PICS_SF_DYPF" + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [0, 1] diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index c710f846f0a13a..f200ad302931ff 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -2939,3 +2939,15 @@ DEMM.S.C01.Tx=1 #Manual controllable DEMM.S.M.CAN_TEST_MODE_FAILURE=1 DEMM.S.M.CAN_MANUALLY_CONTROLLED=1 + +#Power Topology Cluster +# Server +PWRTL.S=1 +PWRTL.S.A0000=1 +PWRTL.S.A0001=1 + +#Features +PWRTL.S.F00=0 +PWRTL.S.F01=0 +PWRTL.S.F02=1 +PWRTL.S.F03=1 \ No newline at end of file diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json index ee6b5436451a6f..26efd799ad7efd 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -191,6 +191,7 @@ "Test_TC_OO_2_4" ], "PowerSource": ["Test_TC_PS_1_1", "Test_TC_PS_2_1"], + "PowerTopology": ["Test_TC_PWRTL_1_1"], "PressureMeasurement": [ "Test_TC_PRS_1_1", "Test_TC_PRS_2_1", diff --git a/src/app/tests/suites/manualTests.json b/src/app/tests/suites/manualTests.json index 774b3d8dce35f3..d199a682492150 100644 --- a/src/app/tests/suites/manualTests.json +++ b/src/app/tests/suites/manualTests.json @@ -311,6 +311,7 @@ "AccessControlEnforcement": [], "OvenMode": ["Test_TC_OTCCM_1_1", "Test_TC_OTCCM_1_2"], "EnergyEVSE": ["Test_TC_EEVSE_1_1", "Test_TC_EEVSE_2_1"], + "PowerTopology": ["Test_TC_PWRTL_1_1"], "collection": [ "DeviceDiscovery", "Groups", @@ -338,6 +339,7 @@ "ModeSelect", "OTASoftwareUpdate", "PowerSourceConfiguration", + "PowerTopology", "PressureMeasurement", "SecureChannel", "SoftwareDiagnostics", diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index b3993634639869..56adf0a1126f95 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -68,7 +68,6 @@ "MESSAGES_CLUSTER": [], "MODE_SELECT_CLUSTER": [], "NETWORK_COMMISSIONING_CLUSTER": [], - "POWER_TOPOLOGY_CLUSTER": [], "SAMPLE_MEI_CLUSTER": [], "NITROGEN_DIOXIDE_CONCENTRATION_MEASUREMENT_CLUSTER": [], "OCCUPANCY_SENSING_CLUSTER": ["occupancy-sensor-server"], @@ -91,6 +90,7 @@ "POWER_PROFILE_CLUSTER": [], "POWER_SOURCE_CLUSTER": [], "POWER_SOURCE_CONFIGURATION_CLUSTER": [], + "POWER_TOPOLOGY_CLUSTER": [], "PRESSURE_MEASUREMENT_CLUSTER": [], "PROXY_CONFIGURATION_CLUSTER": [], "PROXY_DISCOVERY_CLUSTER": [], diff --git a/src/python_testing/TC_PWRTL_2_1.py b/src/python_testing/TC_PWRTL_2_1.py new file mode 100644 index 00000000000000..bd839cd5f072f4 --- /dev/null +++ b/src/python_testing/TC_PWRTL_2_1.py @@ -0,0 +1,69 @@ +# +# 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. +# + +import logging + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_PWRTL_2_1(MatterBaseTest): + + def pics_TC_PWRTL_2_1(self) -> list[str]: + return ["PWRTL.S"] + + @async_test_body + async def test_TC_PWRTL_2_1(self): + + attributes = Clusters.PowerTopology.Attributes + + endpoint = self.user_params.get("endpoint", 1) + + self.print_step(1, "Commissioning, already done") + + if not self.check_pics("PWRTL.S.A0000"): + logging.info("Test skipped because PICS PWRTL.S.A0000 is not set") + return + + self.print_step(2, "Read AvailableAttributes attribute") + available_endpoints = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=Clusters.Objects.PowerTopology, attribute=attributes.AvailableEndpoints) + + if available_endpoints == NullValue: + logging.info("AvailableEndpoints is null") + else: + logging.info("AvailableEndpoints: %s" % (available_endpoints)) + + asserts.assert_less_equal(len(available_endpoints), 21, + "AvailableEndpoints length %d must be less than 21!" % len(available_endpoints)) + + if not self.check_pics("PWRTL.S.A0001"): + logging.info("Test skipped because PICS PWRTL.S.A0001 is not set") + return + + self.print_step(3, "Read ActiveEndpoints attribute") + active_endpoints = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=Clusters.Objects.PowerTopology, attribute=attributes.ActiveEndpoints) + logging.info("ActiveEndpoints: %s" % (active_endpoints)) + + if available_endpoints == NullValue: + asserts.assert_true(active_endpoints == NullValue, + "ActiveEndpoints should be null when AvailableEndpoints is null: %s" % active_endpoints) + + +if __name__ == "__main__": + default_matter_test_main()