Skip to content

Commit

Permalink
Rearrange code and reduce dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
tersal committed Dec 11, 2024
1 parent ff5e2eb commit bfa96d4
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 46 deletions.
31 changes: 17 additions & 14 deletions src/python_testing/TC_TCCM_1_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,19 @@
# === END CI TEST ARGUMENTS ===


from tc_mode_base import ClusterModeCheck
from modebase_cluster_check import ModeBaseClusterChecks

import chip.clusters as Clusters
from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main


class TC_TCCM_1_2(MatterBaseTest, ClusterModeCheck):
class TC_TCCM_1_2(MatterBaseTest, ModeBaseClusterChecks):

def __init__(self, *args):
self.cluster = Clusters.RefrigeratorAndTemperatureControlledCabinetMode
super().__init__(*args)
ClusterModeCheck.__init__(self,
requested_cluster=Clusters.RefrigeratorAndTemperatureControlledCabinetMode)
ModeBaseClusterChecks.__init__(self,
modebase_derived_cluster=self.cluster)

def desc_TC_TCCM_1_2(self) -> str:
return "[TC-TCCM-1.2] Cluster attributes with DUT as Server"
Expand Down Expand Up @@ -81,27 +82,29 @@ async def test_TC_TCCM_1_2(self):

self.step(2)
# Verify common checks for Mode Base as described in the TC-TCCM-1.2
await self.check_supported_modes_and_labels(endpoint=endpoint)
supported_modes = await self.check_supported_modes_and_labels(endpoint=endpoint)
# According to the spec, there should be at least one RapidCool or RapidFreeze tag in
# the ones supported.
additional_tags = [Clusters.RefrigeratorAndTemperatureControlledCabinetMode.Enums.ModeTag.kRapidCool,
Clusters.RefrigeratorAndTemperatureControlledCabinetMode.Enums.ModeTag.kRapidFreeze]
self.check_tags_in_lists(requiredtags=additional_tags)
additional_tags = [self.cluster.Enums.ModeTag.kRapidCool,
self.cluster.Enums.ModeTag.kRapidFreeze]
self.check_tags_in_lists(supported_modes=supported_modes, required_tags=additional_tags)

self.step(3)
# Verify that the CurrentMode attribute has a valid value.
mode = Clusters.RefrigeratorAndTemperatureControlledCabinetMode.Attributes.CurrentMode
await self.read_and_check_mode(endpoint=endpoint, mode=mode)
mode = self.cluster.Attributes.CurrentMode
await self.read_and_check_mode(endpoint=endpoint, mode=mode, supported_modes=supported_modes)

self.step(4)
# Verify that the OnMode attribute has a valid value or null.
mode = Clusters.RefrigeratorAndTemperatureControlledCabinetMode.Attributes.OnMode
await self.read_and_check_mode(endpoint=endpoint, mode=mode, is_nullable=True)
mode = self.cluster.Attributes.OnMode
await self.read_and_check_mode(endpoint=endpoint, mode=mode,
supported_modes=supported_modes, is_nullable=True)

self.step(5)
# Verify that the StartUpMode has a valid value or null
mode = Clusters.RefrigeratorAndTemperatureControlledCabinetMode.Attributes.StartUpMode
await self.read_and_check_mode(endpoint=endpoint, mode=mode, is_nullable=True)
mode = self.cluster.Attributes.StartUpMode
await self.read_and_check_mode(endpoint=endpoint, mode=mode,
supported_modes=supported_modes, is_nullable=True)


if __name__ == "__main__":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
END_MFGTAGS_RANGE = 0xBFFF


class ClusterModeCheck:
class ModeBaseClusterChecks:
""" Class that holds the common Mode checks between TCs
Several TCs have similar checks in place for functionality that is common among them.
Expand All @@ -40,15 +40,13 @@ class ClusterModeCheck:
Attributes:
requested_cluster: A reference to the cluster to be tested, it should be a derived from the Mode Base cluster.
modebase_derived_cluster: A reference to the cluster to be tested, it should be a derived from the Mode Base cluster.
"""

def __init__(self, requested_cluster):
self.modeTags = [tag.value for tag in requested_cluster.Enums.ModeTag]
self.requested_cluster = requested_cluster
self.attributes = requested_cluster.Attributes
self.supported_modes_dut = set()
self.supported_modes = None
def __init__(self, modebase_derived_cluster):
self.modeTags = [tag.value for tag in modebase_derived_cluster.Enums.ModeTag]
self.modebase_derived_cluster = modebase_derived_cluster
self.attributes = modebase_derived_cluster.Attributes

async def check_supported_modes_and_labels(self, endpoint):
""" Verifies the device supported modes and labels.
Expand All @@ -57,50 +55,63 @@ async def check_supported_modes_and_labels(self, endpoint):
- Between 2 and 255 entries.
- The Mode values of all entries are unique.
- The Label values of all entries are unique.
Args:
endpoint: The endpoint used for the requests to the cluster.
Returns:
A list of ModeOptionStruct supported by the cluster.
"""
# Get the supported modes
self.supported_modes = await self.read_single_attribute_check_success(endpoint=endpoint,
cluster=self.requested_cluster,
attribute=self.attributes.SupportedModes)
supported_modes = await self.read_single_attribute_check_success(endpoint=endpoint,
cluster=self.modebase_derived_cluster,
attribute=self.attributes.SupportedModes)

# Check if the list of supported modes is larger than 2
asserts.assert_greater_equal(len(self.supported_modes), 2, "SupportedModes must have at least 2 entries!")
asserts.assert_greater_equal(len(supported_modes), 2, "SupportedModes must have at least 2 entries!")
# Check that supported modes are less than 255
asserts.assert_less_equal(len(self.supported_modes), 255, "SupportedModes must have at most 255 entries!")
asserts.assert_less_equal(len(supported_modes), 255, "SupportedModes must have at most 255 entries!")

# Check for repeated labels or modes
labels = set()
for mode_options_struct in self.supported_modes:
# Verify that the modes in all ModeOptionsStruct in SupportedModes are unique.
if mode_options_struct.mode in self.supported_modes_dut:
modes = set()
for mode_option_struct in supported_modes:
# Verify that the modes in all ModeOptionStruct in SupportedModes are unique.
if mode_option_struct.mode in modes:
asserts.fail("SupportedModes can't have repeated Mode values")
else:
self.supported_modes_dut.add(mode_options_struct.mode)
# Verify that the labels in all ModeOptionsStruct in SupportedModes are unique.
if mode_options_struct.label in labels:
modes.add(mode_option_struct.mode)
# Verify that the labels in all ModeOptionStruct in SupportedModes are unique.
if mode_option_struct.label in labels:
asserts.fail("SupportedModes can't have repeated Label values")
else:
labels.add(mode_options_struct.label)
labels.add(mode_option_struct.label)

return supported_modes

def check_tags_in_lists(self, requiredtags=None):
def check_tags_in_lists(self, supported_modes, required_tags=None):
""" Validates the ModeTags values.
This function evaluates the ModeTags of each ModeOptionsStruct:
This function evaluates the ModeTags of each ModeOptionStruct:
- Should have at least one tag.
- Should be maximum 16bits in size.
- Should be a Mfg tag or one of the supported ones (either common or specific).
- Should have at least one common or specific tag.
- If defined, verify that at least one of the "requiredTags" exists.
Args:
supported_modes: A list of ModeOptionStruct.
required_tags: List of tags that are required according to the cluster spec.
"""
# Verify the ModeTags on each ModeOptionsStruct
for mode_options_struct in self.supported_modes:
# Verify the ModeTags on each ModeOptionStruct
for mode_option_struct in supported_modes:
# Shuld have at least one entry
if len(mode_options_struct.modeTags) == 0:
if len(mode_option_struct.modeTags) == 0:
asserts.fail("The ModeTags field should have at least one entry.")

# Check each ModelTag
at_least_one_common_or_derived = False
for tag in mode_options_struct.modeTags:
for tag in mode_option_struct.modeTags:
# Value should not larger than 16bits
if tag.value > MAX_MODE_TAG or tag.value < 0:
asserts.fail("Tag should not be larger than 16bits.")
Expand All @@ -118,22 +129,31 @@ def check_tags_in_lists(self, requiredtags=None):
if not at_least_one_common_or_derived:
asserts.fail("There should be at least one common or derived tag on each ModeOptionsStruct")

if requiredtags:
if required_tags:
has_required_tags = False
for mode_options_struct in self.supported_modes:
has_required_tags = any(tag.value in requiredtags for tag in mode_options_struct.modeTags)
for mode_options_struct in supported_modes:
has_required_tags = any(tag.value in required_tags for tag in mode_options_struct.modeTags)
if has_required_tags:
break
asserts.assert_true(has_required_tags, "No ModeOptionsStruct has the required tags.")

async def read_and_check_mode(self, endpoint, mode, is_nullable=False):
async def read_and_check_mode(self, endpoint, mode, supported_modes, is_nullable=False):
"""Evaluates the current mode
This functions checks if the requested mode attribute has a valid value from the SupportedModes,
supports optional nullable values.
Args:
endpoint: The endpoint used for the requests to the cluster.
mode: Mode that will be verified.
supported_modes: A list of ModeOptionStruct.
is_nullable: Optional argument to indicate if the tested mode allows NullValue
"""
mode_value = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=self.requested_cluster, attribute=mode)
is_valid = mode_value in self.supported_modes_dut
mode_value = await self.read_single_attribute_check_success(endpoint=endpoint,
cluster=self.modebase_derived_cluster,
attribute=mode)
supported_modes_dut = {mode_option_struct.mode for mode_option_struct in supported_modes}
is_valid = mode_value in supported_modes_dut
if is_nullable and mode_value == NullValue:
is_valid = True
asserts.assert_true(is_valid, f"{mode} not supported")

0 comments on commit bfa96d4

Please sign in to comment.