Skip to content

Commit 7fa5737

Browse files
committed
TC-CC-2.2: Add
1 parent 3263e40 commit 7fa5737

File tree

3 files changed

+292
-0
lines changed

3 files changed

+292
-0
lines changed

.github/workflows/tests.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ jobs:
509509
scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_ACE_1_4.py'
510510
scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_ACE_1_5.py'
511511
scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_AccessChecker.py'
512+
scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_CC_2_2.py'
512513
scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_CC_10_1.py'
513514
scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_CGEN_2_4.py'
514515
scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_CNET_1_4.py'

src/python_testing/TC_CC_2_2.py

+287
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
#
2+
# Copyright (c) 2024 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: run1
23+
# test-runner-run/run1/app: ${ALL_CLUSTERS_APP}
24+
# test-runner-run/run1/factoryreset: True
25+
# test-runner-run/run1/quiet: True
26+
# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json
27+
# test-runner-run/run1/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
28+
# === END CI TEST ARGUMENTS ===
29+
30+
import logging
31+
import time
32+
33+
import chip.clusters as Clusters
34+
from chip.clusters import ClusterObjects as ClusterObjects
35+
from matter_testing_support import ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, default_matter_test_main, has_cluster, per_endpoint_test
36+
from mobly import asserts
37+
from test_plan_support import read_attribute, commission_if_required, if_feature_supported, verify_success
38+
39+
40+
class TC_CC_2_3(MatterBaseTest):
41+
def steps_TC_CC_2_2(self):
42+
THcommand = "Test Harness sends the"
43+
44+
def store_values(attr: str) -> str:
45+
return f"TH stores the reported values of _{attr}_ in all incoming reports for _{attr}_ attribute, that contains data in _reportedCurrentHueValuesList_, over a period of 30 seconds."
46+
47+
def verify_entry_count(attr: str) -> str:
48+
return f'TH verifies that _reportedCurrentHueValuesList_ does not contain more than 10 entries for _{attr}_'
49+
50+
def entry_count_verification() -> str:
51+
return f'_reportedCurrentHueValuesList_ has 10 or less entries in the list'
52+
53+
return [TestStep(1, commission_if_required(), is_commissioning=True),
54+
TestStep(2, read_attribute('FeatureMap')),
55+
TestStep(3, read_attribute('AttributeList')),
56+
TestStep(4, read_attribute('ServerList', 'Descriptor')),
57+
TestStep(
58+
5, f"If OnOff cluster is present in _ServerList_, {THcommand} On command on OnOff cluster", verify_success()),
59+
TestStep(
60+
6, f'{if_feature_supported("HS")}, {THcommand} MoveHue with _MoveMode_ field set to Down, _Rate_ field set to 255 and remaining fields set to 0', verify_success()),
61+
TestStep(7, f'{if_feature_supported("HS")}, {THcommand} MoveSaturation with _MoveMode_ field set to Down, _Rate_ field set to 255 and remaining fields set to 0', verify_success()),
62+
TestStep(8, 'Set up a subscription wildcard subscription for the Color Control Cluster, with MinIntervalFloor set to 0, MaxIntervalCeiling set to 30 and KeepSubscriptions set to false',
63+
'Subscription successfully established'),
64+
TestStep(9, 'If the HS feature is not supported, skip step 10 to 15'),
65+
TestStep(10, f'{THcommand} MoveToHue with _Hue_ field set to 254, _TransitionTime_ field set to 100, _Direction_ field set to Shortest and remaining fields set to 0', verify_success()),
66+
TestStep(11, store_values('CurrentHue')),
67+
TestStep(12, verify_entry_count('CurrentHue'), entry_count_verification()),
68+
TestStep(
69+
13, f"{THcommand} MoveToSaturation with _Saturation_ field set to 254, _TransitionTime_ field set to 100 and remaining fields set to 0"),
70+
TestStep(14, store_values('CurrentSaturation')),
71+
TestStep(15, verify_entry_count('CurrentSaturation'), entry_count_verification()),
72+
TestStep(16, 'If XY feature is not supported, skip steps 17-21'),
73+
TestStep(
74+
17, f"{THcommand} MoveToColor with _ColorX_ field set to 65279, _ColorY_ set to 65279, _TransitionTime_ field set to 100 and remaining fields set to 0"),
75+
TestStep(18, store_values('CurrentX')),
76+
TestStep(19, store_values('CurrentY')),
77+
TestStep(20, verify_entry_count('CurrentX'), entry_count_verification()),
78+
TestStep(21, verify_entry_count('CurrentY'), entry_count_verification()),
79+
TestStep(22, "If the EHUE feature is not supported, skip steps 23 to 25"),
80+
TestStep(23, f"{THcommand} EnhancedMoveToHue with _EnhancedHue_ field set to 0, _TransitionTime_ field set to 100, _Direction_ field set to Shortest and remaining fields set to 0", verify_success()),
81+
TestStep(24, store_values('EnhancedCurrentHue')),
82+
TestStep(25, verify_entry_count('EnhancedCurrentHue'), entry_count_verification()),
83+
TestStep(26, "If the RemainingTime attribute is not supported, skip the remaining steps and end test case"),
84+
TestStep(27, store_values('RemainingTime')),
85+
TestStep(
86+
28, f"If HS feature is supported and XY feature is not supported, {THcommand} MoveToHue with _Hue_ field set to 254, _TransitionTime_ field set to 100, _Direction_ field set to Shortest and remaining fields set to 0", verify_success()),
87+
TestStep(
88+
29, f"If the XY feature is supported and the HS feature is not supported, {THcommand} MoveToColor with _ColorX_ field set to 65279, _ColorY_ set to 65279, _TransitionTime_ field set to 100 and remaining fields set to 0", verify_success()),
89+
TestStep(30, "Wait for 5 seconds"),
90+
TestStep(
91+
31, f"If HS feature is supported and XY feature is not supported, {THcommand} MoveToHue with _Hue_ field set to 254, _TransitionTime_ field set to 150, _Direction_ field set to Shortest and remaining fields set to 0", verify_success()),
92+
TestStep(
93+
32, f"If the XY feature is supported and the HS feature is not supported, {THcommand} MoveToColor with _ColorX_ field set to 65279, _ColorY_ set to 65279, _TransitionTime_ field set to 150 and remaining fields set to 0", verify_success()),
94+
TestStep(33, "Wait for 20 seconds"),
95+
TestStep(34, "TH verifies _reportedRemainingTimeValuesList_ contains three entries",
96+
"_reportedRemainingTimeValuesList_ has 3 entries in the list"),
97+
TestStep(35, "TH verifies the first entry in _reportedRemainingTimeValuesList_ is 100",
98+
"The first entry in _reportedRemainingTimeValuesList_ is equal to 100"),
99+
TestStep(36, "TH verifies the second entry in _reportedRemainingTimeValuesList_ is approximately 150",
100+
"The second entry in _reportedRemainingTimeValuesList_ is approximately equal to 150"),
101+
TestStep(37, "TH verifies the third entry in _reportedRemainingTimeValuesList_ is 0",
102+
"The third entry in _reportedRemainingTimeValuesList_ is equal to 0")
103+
]
104+
105+
@per_endpoint_test(has_cluster(Clusters.ColorControl))
106+
async def test_TC_CC_2_2(self):
107+
# TODO: make configurable for ci?
108+
is_ci = self.check_pics('PICS_SDK_CI_ONLY')
109+
gather_time = 10 if is_ci else 30
110+
111+
# commissioning - already done
112+
self.step(1)
113+
114+
cc = Clusters.ColorControl
115+
116+
self.step(2)
117+
feature_map = await self.read_single_attribute_check_success(cluster=cc, attribute=cc.Attributes.FeatureMap)
118+
supports_hs = (feature_map & cc.Bitmaps.Feature.kHueAndSaturation) != 0
119+
supports_xy = (feature_map & cc.Bitmaps.Feature.kXy) != 0
120+
supports_ehue = (feature_map & cc.Bitmaps.Feature.kEnhancedHue) != 0
121+
122+
self.step(3)
123+
attribute_list = await self.read_single_attribute_check_success(cluster=cc, attribute=cc.Attributes.AttributeList)
124+
125+
self.step(4)
126+
server_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, attribute=Clusters.Descriptor.Attributes.ServerList)
127+
128+
self.step(5)
129+
if Clusters.OnOff.id in server_list:
130+
cmd = Clusters.OnOff.Commands.On()
131+
await self.send_single_cmd(cmd)
132+
else:
133+
self.mark_current_step_skipped()
134+
135+
self.step(6)
136+
if supports_hs:
137+
cmd = cc.Commands.MoveHue(moveMode=cc.Enums.HueMoveMode.kDown, rate=225)
138+
await self.send_single_cmd(cmd)
139+
else:
140+
self.mark_current_step_skipped()
141+
142+
self.step(7)
143+
if supports_hs:
144+
cmd = cc.Commands.MoveSaturation(moveMode=cc.Enums.SaturationMoveMode.kDown, rate=225)
145+
await self.send_single_cmd(cmd)
146+
else:
147+
self.mark_current_step_skipped()
148+
149+
self.step(8)
150+
sub_handler = ClusterAttributeChangeAccumulator(cc)
151+
await sub_handler.start(self.default_controller, self.dut_node_id, self.matter_test_config.endpoint)
152+
153+
def accumulate_reports():
154+
sub_handler.reset()
155+
logging.info(f"Test will now wait {gather_time} seconds to accumulate reports")
156+
time.sleep(gather_time)
157+
158+
def check_report_counts(attr: ClusterObjects.ClusterAttributeDescriptor):
159+
count = sub_handler.attribute_report_counts[attr]
160+
# TODO: Test plan says 10, but I'm pretty sure this is supposed to be 30 since it's not more than once per second
161+
# asserts.assert_less_equal(count, 10, "More than 10 reports received")
162+
asserts.assert_less_equal(count, gather_time, f"More than {gather_time} reports received")
163+
164+
self.step(9)
165+
if not supports_hs:
166+
self.skip_step(10)
167+
self.skip_step(11)
168+
self.skip_step(12)
169+
self.skip_step(13)
170+
self.skip_step(14)
171+
self.skip_step(15)
172+
else:
173+
self.step(10)
174+
cmd = cc.Commands.MoveToHue(hue=254, transitionTime=100, direction=cc.Enums.HueDirection.kShortestDistance)
175+
await self.send_single_cmd(cmd)
176+
177+
self.step(11)
178+
accumulate_reports()
179+
180+
self.step(12)
181+
check_report_counts(cc.Attributes.CurrentHue)
182+
183+
self.step(13)
184+
cmd = cc.Commands.MoveToSaturation(saturation=254, transitionTime=100)
185+
await self.send_single_cmd(cmd)
186+
187+
self.step(14)
188+
accumulate_reports()
189+
190+
self.step(15)
191+
check_report_counts(cc.Attributes.CurrentSaturation)
192+
193+
self.step(16)
194+
if not supports_xy:
195+
self.skip_step(17)
196+
self.skip_step(18)
197+
self.skip_step(19)
198+
self.skip_step(20)
199+
self.skip_step(21)
200+
else:
201+
self.step(17)
202+
cmd = cc.Commands.MoveToColor(colorX=65279, colorY=65279, transitionTime=100)
203+
await self.send_single_cmd(cmd)
204+
205+
self.step(18)
206+
accumulate_reports()
207+
208+
self.step(19)
209+
# reports for x and y are both accumulated in a dict - done above
210+
211+
self.step(20)
212+
check_report_counts(cc.Attributes.CurrentX)
213+
214+
self.step(21)
215+
check_report_counts(cc.Attributes.CurrentY)
216+
217+
self.step(22)
218+
if not supports_ehue:
219+
self.skip_step(23)
220+
self.skip_step(24)
221+
self.skip_step(25)
222+
else:
223+
self.step(23)
224+
cmd = cc.Commands.EnhancedMoveToHue(enhancedHue=0, transitionTime=100,
225+
direction=cc.Enums.HueDirection.kShortestDistance)
226+
await self.send_single_cmd(cmd)
227+
228+
self.step(24)
229+
accumulate_reports()
230+
231+
self.step(25)
232+
check_report_counts(cc.Attributes.EnhancedCurrentHue)
233+
234+
self.step(26)
235+
if cc.Attributes.RemainingTime.attribute_id not in attribute_list:
236+
self.skip_all_remaining_steps(27)
237+
return
238+
239+
self.step(27)
240+
accumulate_reports()
241+
242+
self.step(28)
243+
if supports_hs and not supports_xy:
244+
cmd = cc.Commands.MoveToHue(hue=254, transitionTime=100, direction=cc.Enums.HueDirection.kShortestDistance)
245+
await self.send_single_cmd(cmd)
246+
247+
self.step(29)
248+
if supports_xy and not supports_hs:
249+
cmd = cc.Commands.MoveToColor(colorX=65279, colorY=65279, transitionTime=100)
250+
await self.send_single_cmd(cmd)
251+
252+
self.step(30)
253+
logging.info("Test will now wait for 5 seconds")
254+
time.sleep(5)
255+
256+
self.step(31)
257+
if supports_hs and not supports_xy:
258+
cmd = cc.Commands.MoveToHue(hue=254, transitionTime=150, direction=cc.Enums.HueDirection.kShortestDistance)
259+
await self.send_single_cmd(cmd)
260+
261+
self.step(32)
262+
if supports_xy and not supports_hs:
263+
cmd = cc.Commands.MoveToColor(colorX=65279, colorY=65279, transitionTime=150)
264+
await self.send_single_cmd(cmd)
265+
266+
self.step(33)
267+
logging.info("Test will now wait for 20 seconds")
268+
time.sleep(20)
269+
270+
self.step(34)
271+
count = sub_handler.attribute_report_counts[cc.Attributes.RemainingTime]
272+
# TODO: Re-enable checks 34, 34, 36 when #34643 is addressed
273+
# asserts.assert_equal(count, 3, "Unexpected number of reports received")
274+
275+
self.step(35)
276+
# asserts.assert_equal(sub_handler.attribute_reports[cc.Attributes.RemainingTime][0].value, 100, "Unexpected first report")
277+
278+
self.step(36)
279+
# asserts.assert_almost_equal(
280+
# sub_handler.attribute_reports[cc.Attributes.RemainingTime][1].value, 0, delta=10, msg="Unexpected second report")
281+
282+
self.step(37)
283+
asserts.assert_equal(sub_handler.attribute_reports[cc.Attributes.RemainingTime][-1].value, 0, "Unexpected last report")
284+
285+
286+
if __name__ == "__main__":
287+
default_matter_test_main()

src/python_testing/test_plan_support.py

+4
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,7 @@ def remove_fabric(index_var: str, controller: str):
7676

7777
def verify_commissioning_successful() -> str:
7878
return 'Verify the commissioning is successful.'
79+
80+
81+
def if_feature_supported(feature: str) -> str:
82+
return f"If the {feature} is supported"

0 commit comments

Comments
 (0)