From 598b349ec912ff45472f9e72f695f15fb62aa1b1 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Tue, 20 Feb 2024 18:27:52 +0100 Subject: [PATCH] [MatterYamlTests] Allow enum names in YAML instead of raw values (#32107) * [YAML] Allow the YAML tests to use the enum names instead of the raw value * Update the YAML tests * [MatterYamlTests] Get test_yaml_parser.py to be runned in CI * [MatterYamlTests] Add tests to test_yaml_parser.py * Update errors.py Co-authored-by: Boris Zbarsky --------- Co-authored-by: Boris Zbarsky --- scripts/py_matter_yamltests/BUILD.gn | 1 + .../matter_yamltests/errors.py | 42 ++++ .../matter_yamltests/parser.py | 179 +++++++++++++++-- .../py_matter_yamltests/test_yaml_parser.py | 180 ++++++++++++++++-- .../tests/suites/DL_UsersAndCredentials.yaml | 4 +- .../suites/TestAccessControlConstraints.yaml | 4 +- src/app/tests/suites/TestCluster.yaml | 4 +- src/app/tests/suites/TestDiagnosticLogs.yaml | 4 +- .../suites/certification/Test_TC_ACL_2_4.yaml | 4 +- .../suites/certification/Test_TC_ACL_2_9.yaml | 8 +- .../certification/Test_TC_DRLK_2_9.yaml | 2 +- .../suites/certification/Test_TC_ILL_2_1.yaml | 2 +- .../suites/certification/Test_TC_I_2_3.yaml | 2 +- .../certification/Test_TC_LTIME_3_1.yaml | 4 +- .../certification/Test_TC_LUNIT_3_1.yaml | 2 +- .../certification/Test_TC_TSTAT_2_1.yaml | 8 +- 16 files changed, 394 insertions(+), 56 deletions(-) diff --git a/scripts/py_matter_yamltests/BUILD.gn b/scripts/py_matter_yamltests/BUILD.gn index b886fb04132c37..f8fa027672b868 100644 --- a/scripts/py_matter_yamltests/BUILD.gn +++ b/scripts/py_matter_yamltests/BUILD.gn @@ -55,6 +55,7 @@ pw_python_package("matter_yamltests") { "test_pics_checker.py", "test_parser_builder.py", "test_pseudo_clusters.py", + "test_yaml_parser.py", "test_yaml_loader.py", ] diff --git a/scripts/py_matter_yamltests/matter_yamltests/errors.py b/scripts/py_matter_yamltests/matter_yamltests/errors.py index daa886573569c1..1f26ea4f8354bc 100644 --- a/scripts/py_matter_yamltests/matter_yamltests/errors.py +++ b/scripts/py_matter_yamltests/matter_yamltests/errors.py @@ -222,3 +222,45 @@ def __init__(self, content): self.tag_key_with_error(content, 'attribute') response = content.get('response') self.tag_key_with_error(response, 'saveAs') + + +class TestStepEnumError(TestStepError): + """ + Raise when an enum value or an enum name is not found in the definitions. + + Parameters: + - enum_name_or_value (str|int): The name (str) or value (int) of the enumeration in the step. + If a string is provided, it is considered the name of the enumeration; if an integer is provided, it is considered the value of the enumeration. + - enum_candidates (dict): A dictionary mapping enumeration names (as strings) to their corresponding values + (as integers). This dictionary represents all known values of the enumeration. + """ + + def __init__(self, enum_name_or_value, enum_candidates: dict): + if type(enum_name_or_value) is str: + message = f'Unknown enum name: "{enum_name_or_value}". The possible values are: "{enum_candidates}"' + + for enum_name in enum_candidates: + if enum_name.lower() == enum_name_or_value.lower(): + message = f'Unknown enum name: "{enum_name_or_value}". Did you mean "{enum_name}" ?' + break + + else: + message = f'Unknown enum value: "{enum_name_or_value}". The possible values are: "{enum_candidates}"' + + super().__init__(message) + + +class TestStepEnumSpecifierNotUnknownError(TestStepError): + """Raise when an enum value declared as unknown is in fact a known enum value from the definitions.""" + + def __init__(self, specified_value, enum_name): + message = f'The value "{specified_value}" is not unknown. It is the value of "{enum_name}"' + super().__init__(message) + + +class TestStepEnumSpecifierWrongError(TestStepError): + """Raise when an enum value is specified for a given enum name but it does not match the enum value from the definitions.""" + + def __init__(self, specified_value, enum_name, enum_value): + message = f'The value "{specified_value}" is not the value of "{enum_name}({enum_value})"' + super().__init__(message) diff --git a/scripts/py_matter_yamltests/matter_yamltests/parser.py b/scripts/py_matter_yamltests/matter_yamltests/parser.py index 16f98bcf96d800..cb0a89c6418756 100644 --- a/scripts/py_matter_yamltests/matter_yamltests/parser.py +++ b/scripts/py_matter_yamltests/matter_yamltests/parser.py @@ -15,6 +15,7 @@ import copy import logging +import re from dataclasses import dataclass, field from enum import Enum, auto from typing import Optional @@ -22,7 +23,8 @@ from . import fixes from .constraints import get_constraints, is_typed_constraint from .definitions import SpecDefinitions -from .errors import TestStepError, TestStepKeyError, TestStepValueNameError +from .errors import (TestStepEnumError, TestStepEnumSpecifierNotUnknownError, TestStepEnumSpecifierWrongError, TestStepError, + TestStepKeyError, TestStepValueNameError) from .pics_checker import PICSChecker from .yaml_loader import YamlLoader @@ -38,6 +40,9 @@ 'SubscribeAll', ] +# If True, enum values should use a valid name instead of a raw value +STRICT_ENUM_VALUE_CHECK = False + class UnknownPathQualifierError(TestStepError): """Raise when an attribute/command/event name is not found in the definitions.""" @@ -169,6 +174,99 @@ def _value_or_config(data, key, config): return data[key] if key in data else config.get(key) +class EnumType: + def __init__(self, enum: Enum): + self.type = enum.name + self.base_type = enum.base_type + + self._codes = {} + self.entries_by_name = {} + self.entries_by_code = {} + self._compute_entries(enum) + + def translate(self, key: str, value) -> int: + if self._codes.get(key) is not None and self._codes.get(key) == value: + return self._codes.get(key) + + if type(value) is str: + code = self._get_code_by_name(value) + else: + code = self._get_code_by_value(value) + + if code is None: + raise TestStepEnumError(value, self.entries_by_name) + + self._codes[key] = code + return code + + def _get_code_by_name(self, value): + # For readability the name could sometimes be written as "enum_name(enum_code)" instead of "enum_name" + # In this case the enum_code should be checked to ensure that it is correct, unless enum_name is UnknownEnumValue + # in which case only invalid enum_code are allowed. + specified_name, specified_code = self._extract_name_and_code(value) + if specified_name not in self.entries_by_name: + return None + + enum_code = self.entries_by_name.get(specified_name) + if specified_code is None or specified_code == enum_code: + return enum_code + + if specified_name != f'{self.type}.UnknownEnumValue': + raise TestStepEnumSpecifierWrongError( + specified_code, specified_name, enum_code) + + enum_name = self.entries_by_code.get(specified_code) + if enum_name: + raise TestStepEnumSpecifierNotUnknownError(value, enum_name) + + return specified_code + + def _get_code_by_value(self, value): + enum_name = self.entries_by_code.get(value) + if not enum_name: + return None + + if STRICT_ENUM_VALUE_CHECK: + raise TestStepEnumError(value, self.entries_by_name) + + return value + + def _compute_entries(self, enum: Enum): + enum_codes = [] + for enum_entry in enum.entries: + name = f'{self.type}.{enum_entry.name}' + code = enum_entry.code + + self.entries_by_name[name] = code + self.entries_by_code[code] = name + enum_codes.append(code) + + # search for the first invalid entry if any + max_code = 0xFF + 1 + if self.base_type == 'enum16': + max_code = 0xFFFF + 1 + + for code in range(0, max_code): + if code not in enum_codes: + name = f'{self.type}.UnknownEnumValue' + self.entries_by_name[name] = code + self.entries_by_code[code] = name + break + + def _extract_name_and_code(self, enum_name: str): + match = re.match(r"([\w.]+)(?:\((\w+)\))?", enum_name) + if match: + name = match.group(1) + code = int(match.group(2)) if match.group(2) else None + return name, code + + return None, None + + @staticmethod + def is_valid_type(target_type: str): + return target_type == 'enum8' or target_type == 'enum16' + + class _TestStepWithPlaceholders: '''A single YAML test parsed, as is, from YAML. @@ -441,7 +539,11 @@ def _as_mapping(self, definitions, cluster_name, target_name): element = definitions.get_type_by_name(cluster_name, target_name) if hasattr(element, 'base_type'): - target_name = element.base_type.lower() + if EnumType.is_valid_type(element.base_type): + target_name = EnumType(element) + else: + target_name = element.base_type + elif hasattr(element, 'fields'): target_name = {f.name: self._as_mapping( definitions, cluster_name, f.data_type.name) for f in element.fields} @@ -480,7 +582,11 @@ def _update_with_definition(self, container: dict, mapping_type): if key == 'value': value[key] = self._update_value_with_definition( - item_value, mapping) + value, + key, + item_value, + mapping + ) elif key == 'saveAs' and type(item_value) is str and item_value not in self._parsing_config_variable_storage: self._parsing_config_variable_storage[item_value] = None elif key == 'saveDataVersionAs' and type(item_value) is str and item_value not in self._parsing_config_variable_storage: @@ -491,37 +597,80 @@ def _update_with_definition(self, container: dict, mapping_type): # the the value type for the target field. if is_typed_constraint(constraint): value[key][constraint] = self._update_value_with_definition( - constraint_value, mapping) + item_value, + constraint, + constraint_value, + mapping + ) else: # This key, value pair does not rely on cluster specifications. pass - def _update_value_with_definition(self, value, mapping_type): + def _update_value_with_definition(self, container: dict, key: str, value, mapping_type): + """ + Processes a given value based on a specified mapping type and returns the updated value. + This method does not modify the container in place; rather, it returns a new value that should be + used to update or process further as necessary. + + The 'container' and 'key' parameters are primarily used for error tagging. If an error occurs + during the value processing, these parameters allow for the error to be precisely located and + reported, facilitating easier debugging and error tracking. + + Parameters: + - container (dict): A dictionary that serves as a context for the operation. It is used for error + tagging if processing fails, by associating errors with specific locations within the data structure. + - key (str): The key related to the value being processed. It is used alongside 'container' to tag + errors, enabling precise identification of the error source. + - value: The value to be processed according to the mapping type. + - mapping_type: Dictates the processing or mapping logic to be applied to 'value'. + + Returns: + The processed value, which is the result of applying the specified mapping type to the original 'value'. + This method does not update the 'container'; any necessary updates based on the processed value must + be handled outside this method. + + Raises: + - TestStepError: If an error occurs during the processing of the value. The error includes details + from the 'container' and 'key' to facilitate error tracing and debugging. + """ + if not mapping_type: return value if type(value) is dict: rv = {} - for key in value: + for item_key in value: # FabricIndex is a special case where the framework requires it to be passed even # if it is not part of the requested arguments per spec and not part of the XML # definition. - if key == 'FabricIndex' or key == 'fabricIndex': - rv[key] = value[key] # int64u + if item_key == 'FabricIndex' or item_key == 'fabricIndex': + rv[item_key] = value[item_key] # int64u else: - if not mapping_type.get(key): - raise TestStepKeyError(value, key) - mapping = mapping_type[key] - rv[key] = self._update_value_with_definition( - value[key], mapping) + if not mapping_type.get(item_key): + raise TestStepKeyError(value, item_key) + mapping = mapping_type[item_key] + rv[item_key] = self._update_value_with_definition( + value, + item_key, + value[item_key], + mapping + ) return rv + if type(value) is list: - return [self._update_value_with_definition(entry, mapping_type) for entry in value] + return [self._update_value_with_definition(container, key, entry, mapping_type) for entry in value] + # TODO currently unsure if the check of `value not in config` is sufficant. For # example let's say value = 'foo + 1' and map type is 'int64u', we would arguably do # the wrong thing below. if value is not None and value not in self._parsing_config_variable_storage: - if mapping_type == 'int64u' or mapping_type == 'int64s' or mapping_type == 'bitmap64' or mapping_type == 'epoch_us': + if type(mapping_type) is EnumType: + try: + value = mapping_type.translate(key, value) + except (TestStepEnumError, TestStepEnumSpecifierNotUnknownError, TestStepEnumSpecifierWrongError) as e: + e.tag_key_with_error(container, key) + raise e + elif mapping_type == 'int64u' or mapping_type == 'int64s' or mapping_type == 'bitmap64' or mapping_type == 'epoch_us': value = fixes.try_apply_float_to_integer_fix(value) value = fixes.try_apply_yaml_cpp_longlong_limitation_fix(value) value = fixes.try_apply_yaml_unrepresentable_integer_for_javascript_fixes( diff --git a/scripts/py_matter_yamltests/test_yaml_parser.py b/scripts/py_matter_yamltests/test_yaml_parser.py index 055f949773f9d3..27472572a96d6b 100644 --- a/scripts/py_matter_yamltests/test_yaml_parser.py +++ b/scripts/py_matter_yamltests/test_yaml_parser.py @@ -20,14 +20,22 @@ # is arguably better then no checks at all. import io -import tempfile import unittest +from unittest.mock import mock_open, patch from matter_yamltests.definitions import ParseSource, SpecDefinitions +from matter_yamltests.errors import TestStepEnumError, TestStepEnumSpecifierNotUnknownError, TestStepEnumSpecifierWrongError from matter_yamltests.parser import TestParser, TestParserConfig simple_test_description = ''' + + + + + + + @@ -36,8 +44,11 @@ Test 0x1234 - + test_enum + + + ''' @@ -52,43 +63,145 @@ tests: - label: "Send Test Command" command: "test" +''' + +enum_values_yaml = ''' +name: Test Enum Values + +config: + nodeId: 0x12344321 + cluster: "Test" + endpoint: 1 + +tests: + - label: "Read attribute test_enum Value" + command: "readAttribute" + attribute: "test_enum" + response: + value: 0 + + - label: "Read attribute test_enum Value" + command: "readAttribute" + attribute: "test_enum" + response: + value: TestEnum.A + + - label: "Read attribute test_enum Value" + command: "readAttribute" + attribute: "test_enum" + response: + value: TestEnum.A(0) + + - label: "Read attribute test_enum Value" + command: "readAttribute" + attribute: "test_enum" + response: + value: TestEnum.UnknownEnumValue + + - label: "Read attribute test_enum Value" + command: "readAttribute" + attribute: "test_enum" + response: + value: TestEnum.UnknownEnumValue(255) + + - label: "Write attribute test_enum Value" + command: "writeAttribute" + attribute: "test_enum" + arguments: + value: 0 + + - label: "Write attribute test_enum Value" + command: "writeAttribute" + attribute: "test_enum" + arguments: + value: TestEnum.A + + - label: "Write attribute test_enum Value" + command: "writeAttribute" + attribute: "test_enum" + arguments: + value: TestEnum.A(0) + + - label: "Write attribute test_enum Value" + command: "writeAttribute" + attribute: "test_enum" + arguments: + value: TestEnum.UnknownEnumValue + + - label: "Write attribute test_enum Value" + command: "writeAttribute" + attribute: "test_enum" + arguments: + value: TestEnum.UnknownEnumValue(255) +''' + +enum_value_read_response_wrong_code_yaml = ''' +tests: + - label: "Read attribute test_enum Value" + cluster: "Test" + command: "readAttribute" + attribute: "test_enum" + response: + value: 123 +''' + +enum_value_read_response_wrong_name_yaml = ''' +tests: + - label: "Read attribute test_enum Value" + cluster: "Test" + command: "readAttribute" + attribute: "test_enum" + response: + value: ThisIsWrong +''' - - label: "Send Test Not Handled Command" - command: "testNotHandled" +enum_value_read_response_wrong_code_specified_yaml = ''' +tests: + - label: "Read attribute test_enum Value" + cluster: "Test" + command: "readAttribute" + attribute: "test_enum" response: - error: INVALID_COMMAND + value: TestEnum.A(123) +''' - - label: "Send Test Specific Command" - command: "testSpecific" +enum_value_read_response_not_unknown_code_specified_yaml = ''' +tests: + - label: "Read attribute test_enum Value" + cluster: "Test" + command: "readAttribute" + attribute: "test_enum" response: - values: - - name: "returnValue" - value: 7 + value: TestEnum.UnknownEnumValue(0) ''' +def mock_open_with_parameter_content(content): + file_object = mock_open(read_data=content).return_value + file_object.__iter__.return_value = content.splitlines(True) + return file_object + + +@patch('builtins.open', new=mock_open_with_parameter_content) class TestYamlParser(unittest.TestCase): def setUp(self): self._definitions = SpecDefinitions( [ParseSource(source=io.StringIO(simple_test_description), name='simple_test_description')]) - self._temp_file = tempfile.NamedTemporaryFile(suffix='.yaml') - with open(self._temp_file.name, 'w') as f: - f.writelines(simple_test_yaml) def test_able_to_iterate_over_all_parsed_tests(self): # self._yaml_parser.tests implements `__next__`, which does value substitution. We are # simply ensure there is no exceptions raise. parser_config = TestParserConfig(None, self._definitions) - yaml_parser = TestParser(self._temp_file.name, parser_config) + yaml_parser = TestParser(simple_test_yaml, parser_config) count = 0 for idx, test_step in enumerate(yaml_parser.tests): count += 1 pass - self.assertEqual(count, 3) + self.assertEqual(count, 1) def test_config(self): parser_config = TestParserConfig(None, self._definitions) - yaml_parser = TestParser(self._temp_file.name, parser_config) + yaml_parser = TestParser(simple_test_yaml, parser_config) for idx, test_step in enumerate(yaml_parser.tests): self.assertEqual(test_step.node_id, 0x12344321) self.assertEqual(test_step.cluster, 'Test') @@ -99,7 +212,7 @@ def test_config_override(self): 'cluster': 'TestOverride', 'endpoint': 4} parser_config = TestParserConfig( None, self._definitions, config_override) - yaml_parser = TestParser(self._temp_file.name, parser_config) + yaml_parser = TestParser(simple_test_yaml, parser_config) for idx, test_step in enumerate(yaml_parser.tests): self.assertEqual(test_step.node_id, 12345) self.assertEqual(test_step.cluster, 'TestOverride') @@ -109,8 +222,37 @@ def test_config_override_unknown_field(self): config_override = {'unknown_field': 1} parser_config = TestParserConfig( None, self._definitions, config_override) - self.assertRaises(KeyError, TestParser, - self._temp_file.name, parser_config) + + yaml_parser = TestParser(simple_test_yaml, parser_config) + self.assertIsInstance(yaml_parser, TestParser) + + def test_config_valid_enum_values(self): + parser_config = TestParserConfig(None, self._definitions) + yaml_parser = TestParser(enum_values_yaml, parser_config) + self.assertIsInstance(yaml_parser, TestParser) + + for idx, test_step in enumerate(yaml_parser.tests): + pass + + def test_config_read_response_wrong_code(self): + parser_config = TestParserConfig(None, self._definitions) + self.assertRaises(TestStepEnumError, TestParser, + enum_value_read_response_wrong_code_yaml, parser_config) + + def test_config_read_response_wrong_name(self): + parser_config = TestParserConfig(None, self._definitions) + self.assertRaises(TestStepEnumError, TestParser, + enum_value_read_response_wrong_name_yaml, parser_config) + + def test_config_read_response_wrong_code_specified(self): + parser_config = TestParserConfig(None, self._definitions) + self.assertRaises(TestStepEnumSpecifierWrongError, TestParser, + enum_value_read_response_wrong_code_specified_yaml, parser_config) + + def test_config_read_response_not_unknown_code_specified(self): + parser_config = TestParserConfig(None, self._definitions) + self.assertRaises(TestStepEnumSpecifierNotUnknownError, TestParser, + enum_value_read_response_not_unknown_code_specified_yaml, parser_config) def main(): diff --git a/src/app/tests/suites/DL_UsersAndCredentials.yaml b/src/app/tests/suites/DL_UsersAndCredentials.yaml index 0a344d4883eba6..e86fbbe56dc053 100644 --- a/src/app/tests/suites/DL_UsersAndCredentials.yaml +++ b/src/app/tests/suites/DL_UsersAndCredentials.yaml @@ -562,7 +562,7 @@ tests: - name: "UserUniqueID" value: 0xBABA - name: "UserStatus" - value: 2 + value: UserStatusEnum.UnknownEnumValue(2) - name: "UserType" value: null - name: "CredentialRule" @@ -1031,7 +1031,7 @@ tests: - name: "UserIndex" value: null - name: "UserStatus" - value: 2 + value: UserStatusEnum.UnknownEnumValue(2) - name: "UserType" value: null response: diff --git a/src/app/tests/suites/TestAccessControlConstraints.yaml b/src/app/tests/suites/TestAccessControlConstraints.yaml index 82e66b8d347c10..1a54ea48f92365 100644 --- a/src/app/tests/suites/TestAccessControlConstraints.yaml +++ b/src/app/tests/suites/TestAccessControlConstraints.yaml @@ -130,7 +130,7 @@ tests: { FabricIndex: 0, Privilege: 3, - AuthMode: 4, # INVALID + AuthMode: AccessControlEntryAuthModeEnum.UnknownEnumValue, Subjects: [], Targets: null, }, @@ -231,7 +231,7 @@ tests: }, { FabricIndex: 0, - Privilege: 6, # INVALID + Privilege: AccessControlEntryPrivilegeEnum.UnknownEnumValue, AuthMode: 2, # CASE Subjects: null, Targets: null, diff --git a/src/app/tests/suites/TestCluster.yaml b/src/app/tests/suites/TestCluster.yaml index d51aea86b777f6..017d6ce6b6daf4 100644 --- a/src/app/tests/suites/TestCluster.yaml +++ b/src/app/tests/suites/TestCluster.yaml @@ -1066,7 +1066,7 @@ tests: - name: "arg1" value: 20003 - name: "arg2" - value: 101 + value: SimpleEnum.UnknownEnumValue response: # Attempting to echo back the invalid enum value should fail. error: FAILURE @@ -2814,7 +2814,7 @@ tests: command: "writeAttribute" attribute: "nullable_enum_attr" arguments: - value: 255 + value: SimpleEnum.UnknownEnumValue(255) response: error: CONSTRAINT_ERROR diff --git a/src/app/tests/suites/TestDiagnosticLogs.yaml b/src/app/tests/suites/TestDiagnosticLogs.yaml index 57ab8cb0fa04f8..2e512d962678c3 100644 --- a/src/app/tests/suites/TestDiagnosticLogs.yaml +++ b/src/app/tests/suites/TestDiagnosticLogs.yaml @@ -443,7 +443,7 @@ tests: arguments: values: - name: "Intent" - value: 128 # undefined value + value: IntentEnum.UnknownEnumValue(128) - name: "RequestedProtocol" value: 0 # ResponsePayload response: @@ -456,7 +456,7 @@ tests: - name: "Intent" value: 0 # EndUserSupport - name: "RequestedProtocol" - value: 128 # undefined value + value: TransferProtocolEnum.UnknownEnumValue(128) response: error: "INVALID_COMMAND" diff --git a/src/app/tests/suites/certification/Test_TC_ACL_2_4.yaml b/src/app/tests/suites/certification/Test_TC_ACL_2_4.yaml index bd173e7eb81427..12a6829c642048 100644 --- a/src/app/tests/suites/certification/Test_TC_ACL_2_4.yaml +++ b/src/app/tests/suites/certification/Test_TC_ACL_2_4.yaml @@ -1164,7 +1164,7 @@ tests: FabricIndex: CurrentFabricIndexValue, }, { - Privilege: 6, + Privilege: AccessControlEntryPrivilegeEnum.UnknownEnumValue, AuthMode: 2, Subjects: null, Targets: null, @@ -1192,7 +1192,7 @@ tests: }, { Privilege: 3, - AuthMode: 4, + AuthMode: AccessControlEntryAuthModeEnum.UnknownEnumValue, Subjects: null, Targets: null, FabricIndex: CurrentFabricIndexValue, diff --git a/src/app/tests/suites/certification/Test_TC_ACL_2_9.yaml b/src/app/tests/suites/certification/Test_TC_ACL_2_9.yaml index 22ce1c1451f5a4..d2db93f33b1cd8 100644 --- a/src/app/tests/suites/certification/Test_TC_ACL_2_9.yaml +++ b/src/app/tests/suites/certification/Test_TC_ACL_2_9.yaml @@ -66,8 +66,8 @@ tests: value: [ { - Privilege: "4", - AuthMode: "2", + Privilege: AccessControlEntryPrivilegeEnum.Manage, + AuthMode: AccessControlEntryAuthModeEnum.CASE, Subjects: [CommissionerNodeId], Targets: null, FabricIndex: CurrentFabricIndexValue, @@ -94,8 +94,8 @@ tests: value: [ { - Privilege: "5", - AuthMode: "2", + Privilege: AccessControlEntryPrivilegeEnum.Administer, + AuthMode: AccessControlEntryAuthModeEnum.CASE, Subjects: [CommissionerNodeId], Targets: null, FabricIndex: CurrentFabricIndexValue, diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_9.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_9.yaml index 9f2e34ea6d01ed..0c10f9fa7ba058 100644 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_9.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_9.yaml @@ -167,7 +167,7 @@ tests: - name: "UserIndex" value: null - name: "UserStatus" - value: 5 + value: UserStatusEnum.UnknownEnumValue(5) - name: "UserType" value: 10 response: diff --git a/src/app/tests/suites/certification/Test_TC_ILL_2_1.yaml b/src/app/tests/suites/certification/Test_TC_ILL_2_1.yaml index 6afdb920658f94..741fc878e8880f 100644 --- a/src/app/tests/suites/certification/Test_TC_ILL_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_ILL_2_1.yaml @@ -86,4 +86,4 @@ tests: constraints: type: enum8 minValue: 0 - maxValue: 254 + maxValue: LightSensorTypeEnum.UnknownEnumValue(254) diff --git a/src/app/tests/suites/certification/Test_TC_I_2_3.yaml b/src/app/tests/suites/certification/Test_TC_I_2_3.yaml index 379ed424638c9b..343539ce69e624 100644 --- a/src/app/tests/suites/certification/Test_TC_I_2_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_I_2_3.yaml @@ -237,7 +237,7 @@ tests: - name: "EffectIdentifier" value: 0 - name: "EffectVariant" - value: 66 + value: EffectVariantEnum.UnknownEnumValue(66) - label: "Check DUT executes a blink effect." cluster: "LogCommands" diff --git a/src/app/tests/suites/certification/Test_TC_LTIME_3_1.yaml b/src/app/tests/suites/certification/Test_TC_LTIME_3_1.yaml index ead4e9b246c853..b011a94ce9cef7 100644 --- a/src/app/tests/suites/certification/Test_TC_LTIME_3_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_LTIME_3_1.yaml @@ -352,7 +352,7 @@ tests: command: "writeAttribute" attribute: "ActiveCalendarType" arguments: - value: 50 + value: CalendarTypeEnum.UnknownEnumValue(50) response: error: CONSTRAINT_ERROR @@ -361,6 +361,6 @@ tests: command: "writeAttribute" attribute: "HourFormat" arguments: - value: 5 + value: HourFormatEnum.UnknownEnumValue(5) response: error: CONSTRAINT_ERROR diff --git a/src/app/tests/suites/certification/Test_TC_LUNIT_3_1.yaml b/src/app/tests/suites/certification/Test_TC_LUNIT_3_1.yaml index a572f7e143dc43..b67c22a871ced9 100644 --- a/src/app/tests/suites/certification/Test_TC_LUNIT_3_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_LUNIT_3_1.yaml @@ -94,6 +94,6 @@ tests: arguments: # Per spec, if [TEMP] feature is enabled, then this attribute can be # one of 0 (Farenheit), 1 (Celsius) or 2 (Kelvin) - value: 5 # INVALID + value: TempUnitEnum.UnknownEnumValue(5) response: error: CONSTRAINT_ERROR diff --git a/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml b/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml index 63aba52fe3f3f6..faf34fdea43e92 100644 --- a/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml @@ -468,8 +468,12 @@ tests: response: constraints: type: enum8 - minValue: 0 - maxValue: 9 + anyOf: + [ + ThermostatRunningModeEnum.Off(0), + ThermostatRunningModeEnum.Cool(3), + ThermostatRunningModeEnum.Heat(4), + ] - label: "Step 27: TH reads the StartOfWeek attribute from the DUT" PICS: TSTAT.S.F03