Skip to content

Commit 87abdf2

Browse files
Min fixes
1 parent a38f2aa commit 87abdf2

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed

src/python_testing/TC_MOD_1_2.py

+166
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#
2+
# Copyright (c) 2023 Project CHIP Authors
3+
# All rights reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md"#defining-the-ci-test-arguments
19+
# for details about the block below.
20+
#
21+
# === BEGIN CI TEST ARGUMENTS ===
22+
# test-runner-runs:
23+
# run1:
24+
# app: ALL_CLUSTERS_APP
25+
# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:TRACE_APP.json
26+
# script-args: >
27+
# --storage-path admin_storage.json
28+
# --commissioning-method on-network
29+
# --discriminator 1234
30+
# --passcode 20202021
31+
# --PICS src/app/tests/suites/certification/ci-pics-values
32+
# --trace-to json:TRACE_TEST_JSON.json
33+
# --trace-to perfetto:TRACE_TEST_PERFETTO.perfetto
34+
# factory-reset: true
35+
# quiet: true
36+
# === END CI TEST ARGUMENTS ===""import typing
37+
38+
import logging
39+
import chip.clusters as Clusters
40+
from chip.testing.matter_testing import (MatterBaseTest, TestStep, async_test_body, default_matter_test_main)
41+
from mobly import asserts
42+
from chip.clusters.Types import Nullable
43+
44+
logger = logging.getLogger(__name__)
45+
46+
47+
class MOD_1_2(MatterBaseTest):
48+
"""Proposal test for Mode Select Cluster attributes as a server."""
49+
50+
def TC_MOD_1_2(self) -> str:
51+
return "80.2.1. [TC-MOD-1.2] Cluster attributes with DUT as Server"
52+
53+
def pics_MOD_1_2(self):
54+
"""Return PICS definitions asscociated with this test."""
55+
pics = [
56+
"MOD.S"
57+
]
58+
return pics
59+
60+
def steps_MOD_1_2(self) -> list[TestStep]:
61+
steps = [
62+
TestStep(1, "Commission DUT to TH (can be skipped if done in a preceding test).", is_commissioning=True),
63+
TestStep(2, "TH reads the SupportedModes attribute from DUT"),
64+
TestStep(3, "TH reads the CurrentMode attribute from the DUT"),
65+
TestStep(4, "TH reads the OnMode attribute from the DUT"),
66+
TestStep(5, "TH reads the StartUpMode attribute from the DUT"),
67+
TestStep(6, "TH reads the Description attribute from the DUT"),
68+
TestStep(7, "TH reads the StandardNamespace attribute from the DUT")
69+
]
70+
return steps
71+
72+
def _verify_supported_mode(self, supported_mode):
73+
"""Verify supported mode.
74+
Each mode should be a struct containing a label (user understandable string describing the mode), mode number (integer that identifies the mode and is unique within this SupportedMode list) and list of semantic tags
75+
MfgCode and Value fields present in the SemanticTags structs should be no larger than 16 bits on the TH (Chip-tool)."""
76+
if not hasattr(supported_mode, 'label') and not isinstance(supported_mode.label, str):
77+
asserts.fail("Supported mode struct does not have attribute label or does not contain string ")
78+
79+
if not hasattr(supported_mode, 'mode') and not isinstance(supported_mode.mode, int):
80+
asserts.fail("Supported modes struct does not have attribute mode or does not contain int")
81+
82+
if not hasattr(supported_mode, 'semanticTags'):
83+
asserts.fail("Supported mode struct does not have attribute semanticTags")
84+
85+
# veirfy if we have entries for semanticTags if there are any verfy values no larger that 16 bits
86+
# entries must have the value and manufacturer code.
87+
self._log_attribute("Semantic tags", supported_mode.semanticTags)
88+
89+
if isinstance(supported_mode.semanticTags, list) and len(supported_mode.semanticTags) > 0:
90+
logger.info(
91+
"SupportedMode.semanticTags contains values, verifying attributes for manufacturedcode and value are not longer than 16bits int")
92+
for semantictag in supported_mode.semanticTags:
93+
asserts.assert_true(semantictag.mfgCode <= self._16bitshex, "Element semantictag.Mfgcode is greater than 16 bits")
94+
asserts.assert_true(semantictag.value <= self._16bitshex, "Element semantictag.Value is greater than 16 bits")
95+
96+
def _log_attribute(self, name, value):
97+
logger.info(f"{name} attribute {value} with type {type(value)}")
98+
99+
@async_test_body
100+
async def test_MOD_1_2(self):
101+
self.cluster = Clusters.ModeSelect
102+
self.endpoint = self.get_endpoint(1)
103+
self._16bitshex = 0xFFFF
104+
105+
# commision device
106+
# in the test plan step 1 is defined as a precondition.
107+
self.step(1)
108+
109+
# veirfy the Supported modes
110+
# Verify contains attributes label and mode
111+
# Verify if semantic tags has elements in list , and if there are values assert the values
112+
self.step(2)
113+
supported_modes = await self.read_single_attribute_check_success(endpoint=1, cluster=self.cluster, attribute=self.cluster.Attributes.SupportedModes)
114+
logger.info(f"Supported modes {supported_modes}")
115+
# List must not be empty
116+
asserts.assert_true(len(supported_modes) > 0, "Supported modes can not be empty.")
117+
supported_modes_values = []
118+
for supported_mode in supported_modes:
119+
logger.info(
120+
f"Label {supported_mode} with type {type(supported_mode)} and {supported_mode.label} and {supported_mode.mode} and {supported_mode.semanticTags}")
121+
# verify the struct values
122+
self._verify_supported_mode(supported_mode=supported_mode)
123+
# after verifying the struct is correct append the mode value.
124+
supported_modes_values.append(supported_mode.mode)
125+
logger.info(f"Supported modes values {supported_modes_values}")
126+
127+
# Currentmode attribute check must be int and must be in the supported modes values.
128+
self.step(3)
129+
current_mode = await self.read_single_attribute_check_success(endpoint=1, cluster=self.cluster, attribute=self.cluster.Attributes.CurrentMode)
130+
self._log_attribute('CurrentMode', current_mode)
131+
asserts.assert_true(isinstance(current_mode, int), "Current mode is not int")
132+
asserts.assert_in(current_mode, supported_modes_values, f"Current mode {current_mode} is not in {supported_modes_values}")
133+
134+
# Onmode can be null
135+
self.step(4)
136+
on_mode = await self.read_single_attribute_check_success(endpoint=1, cluster=self.cluster, attribute=self.cluster.Attributes.OnMode)
137+
# on mode can be null
138+
self._log_attribute("OnMode", on_mode)
139+
asserts.assert_true((isinstance(on_mode, int) or isinstance(on_mode, Nullable)),
140+
"Onmode is not int or is not clusters.Types.Nullable")
141+
if not isinstance(on_mode, Nullable):
142+
asserts.assert_in(on_mode, supported_modes_values, f"Onmode {current_mode} is not in {supported_modes_values}")
143+
144+
# Validate startup mode
145+
self.step(5)
146+
startup_mode = await self.read_single_attribute_check_success(endpoint=1, cluster=self.cluster, attribute=self.cluster.Attributes.StartUpMode)
147+
self._log_attribute("StartupMode", startup_mode)
148+
asserts.assert_true(isinstance(startup_mode, int), "Startupmode is not int")
149+
asserts.assert_in(startup_mode, supported_modes_values, f"Startupmode {current_mode} is not in {supported_modes_values}")
150+
151+
# string and readable
152+
self.step(6)
153+
description = await self.read_single_attribute_check_success(endpoint=1, cluster=self.cluster, attribute=self.cluster.Attributes.Description)
154+
self._log_attribute("Description", description)
155+
asserts.assert_true(isinstance(description, str), "Description attribute is not instance of str")
156+
157+
# Verify the StandardNamespace can be 16bits integer or null
158+
self.step(7)
159+
standard_namepace = await self.read_single_attribute_check_success(endpoint=1, cluster=self.cluster, attribute=self.cluster.Attributes.StandardNamespace)
160+
self._log_attribute("StandardNamespace", standard_namepace)
161+
asserts.assert_true((isinstance(standard_namepace, Nullable) or (isinstance(standard_namepace, int) and standard_namepace <= self._16bitshex)),
162+
"Standard namespace is not 16bit or not nullable")
163+
164+
165+
if __name__ == "__main__":
166+
default_matter_test_main()

0 commit comments

Comments
 (0)