Skip to content

Commit 59cd138

Browse files
TC-TMP-2.1: Fix (project-chip#32881)
* TC-TMP-2.1: Fix The constraints here are actually relatively complex because the min and max can be null and fall back to default values. Updated the automation to python so we can do the appropriate tests, added tests for the various scenarios becuase there are a LOT and we don't cover any of them with our current examples. Please see CHIP-Specifications/chip-test-plans#4096 for test plan updates * remove yaml * missed a change * Restyled by autopep8 * remove unused import * Apply suggestions from code review --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent d5d441e commit 59cd138

File tree

5 files changed

+352
-83
lines changed

5 files changed

+352
-83
lines changed

src/app/tests/suites/certification/Test_TC_TMP_2_1.yaml

-74
This file was deleted.

src/python_testing/TC_TMP_2_1.py

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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+
import chip.clusters as Clusters
18+
from chip.clusters.Types import NullValue
19+
from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
20+
from mobly import asserts
21+
22+
23+
class TC_TMP_2_1(MatterBaseTest):
24+
def desc_TC_TMP_2_1(self) -> str:
25+
return "[TC-TMP-2.1] Attributes with Server as DUT"
26+
27+
def pics_TC_TMP_2_1(self):
28+
return ["TMP.S"]
29+
30+
def steps_TC_TMP_2_1(self) -> list[TestStep]:
31+
return [
32+
TestStep(1, "Commissioning, already done", is_commissioning=True),
33+
TestStep(
34+
2, "Set default bounds `min_bound` = -27315, `max_bound` = 32767"),
35+
TestStep(3, "TH reads the MinMeasuredValue attribute from the DUT and saves as `min_measured_value`. If `min_measured_value` is not null, set `min_bound` to `min_measured_value`"),
36+
TestStep(4, "TH reads the MaxMeasuredValue attribute from the DUT and saves as `max_measured_value`. If `max_measured_value` is not null, set `max_bound` to `max_measured_value",
37+
"Verify that `max_measured_value` is either null or an int16 where min_bound < `max_measured_value` ≤ 32767."),
38+
TestStep(5, "If `min_measured_value` is not null, verify min measured value range",
39+
"Verify that -27315 ≤ `min_measured_value` < `max_bound`"),
40+
TestStep(6, "TH reads the MeasuredValue attribute from the DUT",
41+
"Verify that the DUT response contains either null or a int16 where `min_bound` ≤ MeasuredValue ≤ `max_bound`."),
42+
TestStep(7, "TH reads the Tolerance attribute from the DUT",
43+
"Verify that Tolerance is in the range of 0 to 2048"),
44+
]
45+
46+
@async_test_body
47+
async def test_TC_TMP_2_1(self):
48+
cluster = Clusters.TemperatureMeasurement
49+
attr = Clusters.TemperatureMeasurement.Attributes
50+
51+
# Commission DUT - already done
52+
self.step(1)
53+
54+
self.step(2)
55+
min_bound = -27315
56+
max_bound = 32767
57+
58+
self.step(3)
59+
min_measured_value = await self.read_single_attribute_check_success(cluster=cluster, attribute=attr.MinMeasuredValue)
60+
if min_measured_value != NullValue:
61+
min_bound = min_measured_value
62+
63+
self.step(4)
64+
max_measured_value = await self.read_single_attribute_check_success(cluster=cluster, attribute=attr.MaxMeasuredValue)
65+
if max_measured_value != NullValue:
66+
max_bound = max_measured_value
67+
asserts.assert_greater(max_measured_value, min_bound,
68+
"MaxMeasuredValue is not greater than the minimum bound")
69+
asserts.assert_less_equal(
70+
max_measured_value, 32767, "MaxMeasuredValue is not less than or equal to than 32767")
71+
72+
self.step(5)
73+
if min_measured_value != NullValue:
74+
asserts.assert_greater_equal(min_measured_value, -27315, "MinMeasuredValue is out of range")
75+
asserts.assert_less(min_measured_value, max_bound, "MinMeasuredValue is out of range")
76+
else:
77+
self.mark_current_step_skipped()
78+
79+
self.step(6)
80+
measured_value = await self.read_single_attribute_check_success(cluster=cluster, attribute=attr.MeasuredValue)
81+
if measured_value != NullValue:
82+
print(measured_value)
83+
print(min_bound)
84+
asserts.assert_greater_equal(
85+
measured_value, min_bound, "Measured value is less than min bound")
86+
asserts.assert_less_equal(
87+
measured_value, max_bound, "Measured value is greater than max bound")
88+
89+
self.step(7)
90+
tolerance = await self.read_single_attribute_check_success(cluster=cluster, attribute=attr.Tolerance)
91+
asserts.assert_greater_equal(tolerance, 0, "Tolerance is less than 0")
92+
asserts.assert_less_equal(
93+
tolerance, 2048, "Tolerance is greater than 2048")
94+
95+
96+
if __name__ == "__main__":
97+
default_matter_test_main()

src/python_testing/matter_testing_support.py

+18-9
Original file line numberDiff line numberDiff line change
@@ -1656,7 +1656,7 @@ def get_test_info(test_class: MatterBaseTest, matter_test_config: MatterTestConf
16561656
return info
16571657

16581658

1659-
def run_tests(test_class: MatterBaseTest, matter_test_config: MatterTestConfig, hooks: TestRunnerHooks) -> None:
1659+
def run_tests_no_exit(test_class: MatterBaseTest, matter_test_config: MatterTestConfig, hooks: TestRunnerHooks, default_controller=None, external_stack=None) -> bool:
16601660

16611661
get_test_info(test_class, matter_test_config)
16621662

@@ -1668,7 +1668,10 @@ def run_tests(test_class: MatterBaseTest, matter_test_config: MatterTestConfig,
16681668
if len(matter_test_config.tests) > 0:
16691669
tests = matter_test_config.tests
16701670

1671-
stack = MatterStackState(matter_test_config)
1671+
if external_stack:
1672+
stack = external_stack
1673+
else:
1674+
stack = MatterStackState(matter_test_config)
16721675

16731676
with TracingContext() as tracing_ctx:
16741677
for destination in matter_test_config.trace_to:
@@ -1678,12 +1681,12 @@ def run_tests(test_class: MatterBaseTest, matter_test_config: MatterTestConfig,
16781681

16791682
# TODO: Steer to right FabricAdmin!
16801683
# TODO: If CASE Admin Subject is a CAT tag range, then make sure to issue NOC with that CAT tag
1681-
1682-
default_controller = stack.certificate_authorities[0].adminList[0].NewController(
1683-
nodeId=matter_test_config.controller_node_id,
1684-
paaTrustStorePath=str(matter_test_config.paa_trust_store_path),
1685-
catTags=matter_test_config.controller_cat_tags
1686-
)
1684+
if not default_controller:
1685+
default_controller = stack.certificate_authorities[0].adminList[0].NewController(
1686+
nodeId=matter_test_config.controller_node_id,
1687+
paaTrustStorePath=str(matter_test_config.paa_trust_store_path),
1688+
catTags=matter_test_config.controller_cat_tags
1689+
)
16871690
test_config.user_params["default_controller"] = stash_globally(default_controller)
16881691

16891692
test_config.user_params["matter_test_config"] = stash_globally(matter_test_config)
@@ -1732,10 +1735,16 @@ def run_tests(test_class: MatterBaseTest, matter_test_config: MatterTestConfig,
17321735
hooks.stop(duration=duration)
17331736

17341737
# Shutdown the stack when all done
1735-
stack.Shutdown()
1738+
if not external_stack:
1739+
stack.Shutdown()
17361740

17371741
if ok:
17381742
logging.info("Final result: PASS !")
17391743
else:
17401744
logging.error("Final result: FAIL !")
1745+
return ok
1746+
1747+
1748+
def run_tests(test_class: MatterBaseTest, matter_test_config: MatterTestConfig, hooks: TestRunnerHooks, default_controller=None, external_stack=None) -> None:
1749+
if not run_tests_no_exit(test_class, matter_test_config, hooks, default_controller, external_stack):
17411750
sys.exit(1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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+
import importlib
19+
import os
20+
import sys
21+
from pathlib import Path
22+
from unittest.mock import MagicMock
23+
24+
from chip.clusters import Attribute
25+
26+
try:
27+
from matter_testing_support import MatterStackState, MatterTestConfig, run_tests_no_exit
28+
except ImportError:
29+
sys.path.append(os.path.abspath(
30+
os.path.join(os.path.dirname(__file__), '..')))
31+
from matter_testing_support import MatterStackState, MatterTestConfig, run_tests_no_exit
32+
33+
34+
class AsyncMock(MagicMock):
35+
async def __call__(self, *args, **kwargs):
36+
return super(AsyncMock, self).__call__(*args, **kwargs)
37+
38+
39+
class MockTestRunner():
40+
def __init__(self, filename: str, classname: str, test: str):
41+
self.config = MatterTestConfig(
42+
tests=[test], endpoint=1, dut_node_ids=[1])
43+
self.stack = MatterStackState(self.config)
44+
self.default_controller = self.stack.certificate_authorities[0].adminList[0].NewController(
45+
nodeId=self.config.controller_node_id,
46+
paaTrustStorePath=str(self.config.paa_trust_store_path),
47+
catTags=self.config.controller_cat_tags
48+
)
49+
module = importlib.import_module(Path(os.path.basename(filename)).stem)
50+
self.test_class = getattr(module, classname)
51+
52+
def Shutdown(self):
53+
self.stack.Shutdown()
54+
55+
def run_test_with_mock_read(self, read_cache: Attribute.AsyncReadTransaction.ReadResponse):
56+
self.default_controller.Read = AsyncMock(return_value=read_cache)
57+
return run_tests_no_exit(self.test_class, self.config, None, self.default_controller, self.stack)

0 commit comments

Comments
 (0)