From 240d59d1ed91b84be48ad24f630fd1c985027867 Mon Sep 17 00:00:00 2001 From: cecille <cecille@google.com> Date: Fri, 17 May 2024 17:05:45 -0400 Subject: [PATCH 1/6] Python testing: id range check functions --- src/python_testing/TestIdChecks.py | 230 +++++++++++++++++++++ src/python_testing/global_attribute_ids.py | 93 +++++++++ 2 files changed, 323 insertions(+) create mode 100644 src/python_testing/TestIdChecks.py diff --git a/src/python_testing/TestIdChecks.py b/src/python_testing/TestIdChecks.py new file mode 100644 index 00000000000000..6356effd50a7a0 --- /dev/null +++ b/src/python_testing/TestIdChecks.py @@ -0,0 +1,230 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from global_attribute_ids import * +from matter_testing_support import MatterBaseTest, default_matter_test_main +from mobly import asserts + + +class TestIdChecks(MatterBaseTest): + def test_device_type_ids(self): + standard_good = [0x0000_0000, 0x0000_BFFF] + standard_bad = [0x0000_C000] + + manufacturer_good = [0x0001_0000, 0x0001_BFFF, 0xFFF0_0000, 0xFFF0_BFFF] + manufacturer_bad = [0x0001_C000, 0xFFF0_C000] + + test_good = [0xFFF1_0000, 0xFFF1_BFFF, 0xFFF4_0000, 0xFFF4_BFFF] + test_bad = [0xFFF1_C000, 0xFFF4_C000] + + prefix_bad = [0xFFF5_0000, 0xFFF5_BFFFF, 0xFFF5_C000] + + def check_standard(id): + msg = f"Incorrect device type range assessment, expecting standard {id:08x}" + asserts.assert_true(standard_device_type_range(id), msg) + asserts.assert_false(manufacturer_device_type_range(id), msg) + asserts.assert_false(test_device_type_range(id), msg) + asserts.assert_true(valid_device_type_range(id, allow_test=True), msg) + asserts.assert_true(valid_device_type_range(id, allow_test=False), msg) + + def check_manufacturer(id): + msg = f"Incorrect device type range assessment, expecting manufacturer {id:08x}" + asserts.assert_false(standard_device_type_range(id), msg) + asserts.assert_true(manufacturer_device_type_range(id), msg) + asserts.assert_false(test_device_type_range(id), msg) + asserts.assert_true(valid_device_type_range(id, allow_test=True), msg) + asserts.assert_true(valid_device_type_range(id, allow_test=False), msg) + + def check_test(id): + msg = f"Incorrect device type range assessment, expecting test {id:08x}" + asserts.assert_false(standard_device_type_range(id), msg) + asserts.assert_false(manufacturer_device_type_range(id), msg) + asserts.assert_true(test_device_type_range(id), msg) + asserts.assert_true(valid_device_type_range(id, allow_test=True), msg) + asserts.assert_false(valid_device_type_range(id, allow_test=False), msg) + + def check_all_bad(id): + msg = f"Incorrect device type range assessment, expecting invalid {id:08x}" + asserts.assert_false(standard_device_type_range(id), msg) + asserts.assert_false(manufacturer_device_type_range(id), msg) + asserts.assert_false(valid_device_type_range(id, allow_test=True), msg) + asserts.assert_false(valid_device_type_range(id, allow_test=False), msg) + + for id in standard_good: + check_standard(id) + + for id in standard_bad: + check_all_bad(id) + + for id in manufacturer_good: + check_manufacturer(id) + + for id in manufacturer_bad: + check_all_bad(id) + + for id in test_good: + check_test(id) + + for id in test_bad: + check_all_bad(id) + + for id in prefix_bad: + check_all_bad(id) + + def test_cluster_ids(self): + standard_good = [0x0000_0000, 0x0000_7FFF] + standard_bad = [0x0000_8000] + + manufacturer_good = [0x0001_FC00, 0x0001_FFFE, 0xFFF0_FC00, 0xFFF0_FFFE] + manufacturer_bad = [0x0001_0000, 0x0001_7FFF, 0x0001_FFFF, 0xFFF0_0000, 0xFFF0_7FFF, 0xFFF0_FFFF] + + test_good = [0xFFF1_FC00, 0xFFF1_FFFE, 0xFFF4_FC00, 0xFFF4_FFFE] + test_bad = [0xFFF1_0000, 0xFFF1_7FFF, 0xFFF1_FFFF, 0xFFF4_0000, 0xFFF4_7FFF, 0xFFF4_FFFF] + + prefix_bad = [0xFFF5_0000, 0xFFF5_FC00, 0xFFF5_FFFF] + + def check_standard(id): + msg = f"Incorrect cluster range assessment, expecting standard {id:08x}" + asserts.assert_true(standard_cluster_range(id), msg) + asserts.assert_false(manufacturer_cluster_range(id), msg) + asserts.assert_false(test_cluster_range(id), msg) + asserts.assert_true(valid_cluster_range(id, allow_test=True), msg) + asserts.assert_true(valid_cluster_range(id, allow_test=False), msg) + + def check_manufacturer(id): + msg = f"Incorrect cluster range assessment, expecting manufacturer {id:08x}" + asserts.assert_false(standard_cluster_range(id), msg) + asserts.assert_true(manufacturer_cluster_range(id), msg) + asserts.assert_false(test_cluster_range(id), msg) + asserts.assert_true(valid_cluster_range(id, allow_test=True), msg) + asserts.assert_true(valid_cluster_range(id, allow_test=False), msg) + + def check_test(id): + msg = f"Incorrect cluster range assessment, expecting test {id:08x}" + asserts.assert_false(standard_cluster_range(id), msg) + asserts.assert_false(manufacturer_cluster_range(id), msg) + asserts.assert_true(test_cluster_range(id), msg) + asserts.assert_true(valid_cluster_range(id, allow_test=True), msg) + asserts.assert_false(valid_cluster_range(id, allow_test=False), msg) + + def check_all_bad(id): + msg = f"Incorrect cluster range assessment, expecting invalid {id:08x}" + asserts.assert_false(standard_cluster_range(id), msg) + asserts.assert_false(manufacturer_cluster_range(id), msg) + asserts.assert_false(test_cluster_range(id), msg) + asserts.assert_false(valid_cluster_range(id, allow_test=True), msg) + asserts.assert_false(valid_cluster_range(id, allow_test=False), msg) + + for id in standard_good: + check_standard(id) + + for id in standard_bad: + check_all_bad(id) + + for id in manufacturer_good: + check_manufacturer(id) + + for id in manufacturer_bad: + check_all_bad(id) + + for id in test_good: + check_test(id) + + for id in test_bad: + check_all_bad(id) + + for id in prefix_bad: + check_all_bad(id) + + def test_attribute_ids(self): + standard_global_good = [0x0000_F000, 0x0000_FFFE] + standard_global_bad = [0x0000_FFFF] + standard_non_global_good = [0x0000_0000, 0x0000_4FFF] + standard_non_global_bad = [0x0000_5000] + manufacturer_good = [0x0001_0000, 0x0001_4FFF, 0xFFF0_0000, 0xFFF0_4FFF] + manufacturer_bad = [0x0001_5000, 0x0001_F000, 0x0001_FFFFF, 0xFFF0_5000, 0xFFF0_F000, 0xFFF0_FFFF] + test_good = [0xFFF1_0000, 0xFFF1_4FFF, 0xFFF4_0000, 0xFFF4_4FFF] + test_bad = [0xFFF1_5000, 0xFFF1_F000, 0xFFF1_FFFFF, 0xFFF4_5000, 0xFFF4_F000, 0xFFF4_FFFF] + prefix_bad = [0xFFF5_0000, 0xFFF5_4FFF, 0xFFF5_5000, 0xFFF5_F000, 0xFFF5_FFFF] + + def check_standard_global(id): + msg = f"Incorrect attribute range assessment, expecting standard global {id:08x}" + asserts.assert_true(standard_global_attribute_range(id), msg) + asserts.assert_false(standard_non_global_attribute_range(id), msg) + asserts.assert_false(manufacturer_attribute_range(id), msg) + asserts.assert_false(test_attribute_range(id), msg) + asserts.assert_true(valid_attribute_range(id, allow_test=True), msg) + asserts.assert_true(valid_attribute_range(id, allow_test=False), msg) + + def check_standard_non_global(id): + msg = f"Incorrect attribute range assessment, expecting standard non-global {id:08x}" + asserts.assert_false(standard_global_attribute_range(id), msg) + asserts.assert_true(standard_non_global_attribute_range(id), msg) + asserts.assert_false(manufacturer_attribute_range(id), msg) + asserts.assert_false(test_attribute_range(id), msg) + asserts.assert_true(valid_attribute_range(id, allow_test=True), msg) + asserts.assert_true(valid_attribute_range(id, allow_test=False), msg) + + def check_manufacturer(id): + msg = f"Incorrect attribute range assessment, expecting manufacturer {id:08x}" + asserts.assert_false(standard_global_attribute_range(id), msg) + asserts.assert_false(standard_non_global_attribute_range(id), msg) + asserts.assert_true(manufacturer_attribute_range(id), msg) + asserts.assert_false(test_attribute_range(id), msg) + asserts.assert_true(valid_attribute_range(id, allow_test=True), msg) + asserts.assert_true(valid_attribute_range(id, allow_test=False), msg) + + def check_test(id): + msg = f"Incorrect attribute range assessment, expecting test {id:08x}" + asserts.assert_false(standard_global_attribute_range(id), msg) + asserts.assert_false(standard_non_global_attribute_range(id), msg) + asserts.assert_false(manufacturer_attribute_range(id), msg) + asserts.assert_true(test_attribute_range(id), msg) + asserts.assert_true(valid_attribute_range(id, allow_test=True), msg) + asserts.assert_false(valid_attribute_range(id, allow_test=False), msg) + + def check_all_bad(id): + msg = f"Incorrect attribute range assessment, expecting invalid {id:08x}" + asserts.assert_false(standard_global_attribute_range(id), msg) + asserts.assert_false(standard_non_global_attribute_range(id), msg) + asserts.assert_false(manufacturer_attribute_range(id), msg) + asserts.assert_false(test_attribute_range(id), msg) + asserts.assert_false(valid_attribute_range(id, allow_test=True), msg) + asserts.assert_false(valid_attribute_range(id, allow_test=False), msg) + + for id in standard_global_good: + check_standard_global(id) + for id in standard_global_bad: + check_all_bad(id) + for id in standard_non_global_good: + check_standard_non_global(id) + for id in standard_non_global_bad: + check_all_bad(id) + for id in manufacturer_good: + check_manufacturer(id) + for id in manufacturer_bad: + check_all_bad(id) + for id in test_good: + check_test(id) + for id in test_bad: + check_all_bad(id) + for id in prefix_bad: + check_all_bad(id) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/global_attribute_ids.py b/src/python_testing/global_attribute_ids.py index 851148bd8f290f..1c0773d3bdbb63 100644 --- a/src/python_testing/global_attribute_ids.py +++ b/src/python_testing/global_attribute_ids.py @@ -17,6 +17,7 @@ # This file should be removed once we have a good way to get this from the codegen or XML +from dataclasses import dataclass from enum import IntEnum @@ -38,3 +39,95 @@ def to_name(self) -> str: return "FeatureMap" if self == GlobalAttributeIds.CLUSTER_REVISION_ID: return "ClusterRevision" + + +@dataclass +class IdRange: + min: int + max: int + + def _contains(self, id: int): + return id in range(self.min, self.max+1) + + +@dataclass +class PrefixIdRange(IdRange): + def contains(self, id: int): + return super()._contains(id >> 16) + + +class SuffixIdRange(IdRange): + def contains(self, id: int): + return super()._contains(id & 0xFFFF) + + +STANDARD_PREFIX = PrefixIdRange(0x0000, 0x0000) +MANUFACTURER_PREFIX = PrefixIdRange(0x0001, 0xFFF0) +TEST_PREFIX = PrefixIdRange(0xFFF1, 0xFFF4) + +DEVICE_TYPE_ID_RANGE_SUFFIX = SuffixIdRange(0x0000, 0xBFFF) +CLUSTER_ID_STANDARD_RANGE_SUFFIX = SuffixIdRange(0x0000, 0x7FFF) +CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX = SuffixIdRange(0xFC00, 0xFFFE) +ATTRIBUTE_ID_GLOBAL_RANGE_SUFFIX = SuffixIdRange(0xF000, 0xFFFE) +ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX = SuffixIdRange(0x0000, 0x4FFF) + + +def standard_device_type_range(id: int): + return STANDARD_PREFIX.contains(id) and DEVICE_TYPE_ID_RANGE_SUFFIX.contains(id) + + +def manufacturer_device_type_range(id: int): + return MANUFACTURER_PREFIX.contains(id) and DEVICE_TYPE_ID_RANGE_SUFFIX.contains(id) + + +def test_device_type_range(id: int): + return TEST_PREFIX.contains(id) and DEVICE_TYPE_ID_RANGE_SUFFIX.contains(id) + + +def valid_device_type_range(id: int, allow_test: bool = False): + ret = manufacturer_device_type_range(id) or standard_device_type_range(id) + if allow_test: + ret = ret or test_device_type_range(id) + return ret + + +def standard_cluster_range(id: int): + return STANDARD_PREFIX.contains(id) and CLUSTER_ID_STANDARD_RANGE_SUFFIX.contains(id) + + +def manufacturer_cluster_range(id: int): + return MANUFACTURER_PREFIX.contains(id) and CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX.contains(id) + + +def test_cluster_range(id: int): + return TEST_PREFIX.contains(id) and CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX.contains(id) + + +def valid_cluster_range(id: int, allow_test: bool = False): + ret = standard_cluster_range(id) or manufacturer_cluster_range(id) + if allow_test: + ret = ret or test_cluster_range(id) + return ret + + +def standard_non_global_attribute_range(id: int): + return STANDARD_PREFIX.contains(id) and ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX.contains(id) + + +def standard_global_attribute_range(id: str): + return STANDARD_PREFIX.contains(id) and ATTRIBUTE_ID_GLOBAL_RANGE_SUFFIX.contains(id) + + +def manufacturer_attribute_range(id: str): + return MANUFACTURER_PREFIX.contains(id) and ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX.contains(id) + + +def test_attribute_range(id: str): + return TEST_PREFIX.contains(id) and ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX.contains(id) + + +def valid_attribute_range(id: str, allow_test: bool = False): + ret = standard_global_attribute_range(id) or standard_non_global_attribute_range(id) or manufacturer_attribute_range(id) + if allow_test: + ret = ret or test_attribute_range(id) + return ret From 929bc7857e8c6112b767f24f3f733bda2c00c405 Mon Sep 17 00:00:00 2001 From: cecille <cecille@google.com> Date: Fri, 17 May 2024 17:13:42 -0400 Subject: [PATCH 2/6] add test to workflow --- .github/workflows/tests.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 57bc3971d44ea3..98c140a7d1afd9 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -562,6 +562,8 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCOPSTATE_2_4.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './src/python_testing/test_testing/test_TC_DA_1_2.py' scripts/run_in_python_env.sh out/venv './src/python_testing/test_testing/test_TC_ICDM_2_1.py' + scripts/run_in_python_env.sh out/venv './src/python_testing/TestIdChecks.py' + - name: Uploading core files uses: actions/upload-artifact@v4 if: ${{ failure() && !env.ACT }} From a031145cccf10d4fc6785ec761a59fe1c0fe03b5 Mon Sep 17 00:00:00 2001 From: cecille <cecille@google.com> Date: Wed, 22 May 2024 16:11:57 -0400 Subject: [PATCH 3/6] use range more directly --- src/python_testing/global_attribute_ids.py | 40 ++++++++++------------ 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/python_testing/global_attribute_ids.py b/src/python_testing/global_attribute_ids.py index 1c0773d3bdbb63..2849476057d0f0 100644 --- a/src/python_testing/global_attribute_ids.py +++ b/src/python_testing/global_attribute_ids.py @@ -41,24 +41,22 @@ def to_name(self) -> str: return "ClusterRevision" -@dataclass -class IdRange: - min: int - max: int +class IdRange(): + def __init__(self, min, max): + self.min_max = range(min, max+1) - def _contains(self, id: int): - return id in range(self.min, self.max+1) + def __contains__(self, key): + return key in self.min_max -@dataclass class PrefixIdRange(IdRange): - def contains(self, id: int): - return super()._contains(id >> 16) + def __contains__(self, id: int): + return super().__contains__(id >> 16) class SuffixIdRange(IdRange): - def contains(self, id: int): - return super()._contains(id & 0xFFFF) + def __contains__(self, id: int): + return super().__contains__(id & 0xFFFF) STANDARD_PREFIX = PrefixIdRange(0x0000, 0x0000) @@ -73,15 +71,15 @@ def contains(self, id: int): def standard_device_type_range(id: int): - return STANDARD_PREFIX.contains(id) and DEVICE_TYPE_ID_RANGE_SUFFIX.contains(id) + return id in STANDARD_PREFIX and id in DEVICE_TYPE_ID_RANGE_SUFFIX def manufacturer_device_type_range(id: int): - return MANUFACTURER_PREFIX.contains(id) and DEVICE_TYPE_ID_RANGE_SUFFIX.contains(id) + return id in MANUFACTURER_PREFIX and id in DEVICE_TYPE_ID_RANGE_SUFFIX def test_device_type_range(id: int): - return TEST_PREFIX.contains(id) and DEVICE_TYPE_ID_RANGE_SUFFIX.contains(id) + return id in TEST_PREFIX and id in DEVICE_TYPE_ID_RANGE_SUFFIX def valid_device_type_range(id: int, allow_test: bool = False): @@ -92,15 +90,15 @@ def valid_device_type_range(id: int, allow_test: bool = False): def standard_cluster_range(id: int): - return STANDARD_PREFIX.contains(id) and CLUSTER_ID_STANDARD_RANGE_SUFFIX.contains(id) + return id in STANDARD_PREFIX and id in CLUSTER_ID_STANDARD_RANGE_SUFFIX def manufacturer_cluster_range(id: int): - return MANUFACTURER_PREFIX.contains(id) and CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX.contains(id) + return id in MANUFACTURER_PREFIX and id in CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX def test_cluster_range(id: int): - return TEST_PREFIX.contains(id) and CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX.contains(id) + return id in TEST_PREFIX and id in CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX def valid_cluster_range(id: int, allow_test: bool = False): @@ -111,19 +109,19 @@ def valid_cluster_range(id: int, allow_test: bool = False): def standard_non_global_attribute_range(id: int): - return STANDARD_PREFIX.contains(id) and ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX.contains(id) + return id in STANDARD_PREFIX and id in ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX def standard_global_attribute_range(id: str): - return STANDARD_PREFIX.contains(id) and ATTRIBUTE_ID_GLOBAL_RANGE_SUFFIX.contains(id) + return id in STANDARD_PREFIX and id in ATTRIBUTE_ID_GLOBAL_RANGE_SUFFIX def manufacturer_attribute_range(id: str): - return MANUFACTURER_PREFIX.contains(id) and ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX.contains(id) + return id in MANUFACTURER_PREFIX and id in ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX def test_attribute_range(id: str): - return TEST_PREFIX.contains(id) and ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX.contains(id) + return id in TEST_PREFIX and id in ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX def valid_attribute_range(id: str, allow_test: bool = False): From 7b4d6e3869e8e6a256d903246ac95ee883d3de71 Mon Sep 17 00:00:00 2001 From: cecille <cecille@google.com> Date: Wed, 22 May 2024 17:19:57 -0400 Subject: [PATCH 4/6] change to enums --- src/python_testing/TestIdChecks.py | 149 +++++++++------------ src/python_testing/global_attribute_ids.py | 112 +++++++++------- 2 files changed, 130 insertions(+), 131 deletions(-) diff --git a/src/python_testing/TestIdChecks.py b/src/python_testing/TestIdChecks.py index 6356effd50a7a0..7084ea34365da3 100644 --- a/src/python_testing/TestIdChecks.py +++ b/src/python_testing/TestIdChecks.py @@ -15,7 +15,7 @@ # limitations under the License. # -from global_attribute_ids import * +from global_attribute_ids import (device_type_id_type, is_valid_device_type_id, cluster_id_type, is_valid_cluster_id, attribute_id_type, is_valid_attribute_id, DeviceTypeIdType, ClusterIdType, AttributeIdType) from matter_testing_support import MatterBaseTest, default_matter_test_main from mobly import asserts @@ -34,35 +34,32 @@ def test_device_type_ids(self): prefix_bad = [0xFFF5_0000, 0xFFF5_BFFFF, 0xFFF5_C000] def check_standard(id): - msg = f"Incorrect device type range assessment, expecting standard {id:08x}" - asserts.assert_true(standard_device_type_range(id), msg) - asserts.assert_false(manufacturer_device_type_range(id), msg) - asserts.assert_false(test_device_type_range(id), msg) - asserts.assert_true(valid_device_type_range(id, allow_test=True), msg) - asserts.assert_true(valid_device_type_range(id, allow_test=False), msg) + id_type = device_type_id_type(id) + msg = f"Incorrect device type range assessment, expecting standard {id:08x}, type = {id_type}" + asserts.assert_equal(device_type_id_type(id), DeviceTypeIdType.kStandard, msg) + asserts.assert_true(is_valid_device_type_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_device_type_id(id_type, allow_test=False), msg) def check_manufacturer(id): - msg = f"Incorrect device type range assessment, expecting manufacturer {id:08x}" - asserts.assert_false(standard_device_type_range(id), msg) - asserts.assert_true(manufacturer_device_type_range(id), msg) - asserts.assert_false(test_device_type_range(id), msg) - asserts.assert_true(valid_device_type_range(id, allow_test=True), msg) - asserts.assert_true(valid_device_type_range(id, allow_test=False), msg) + id_type = device_type_id_type(id) + msg = f"Incorrect device type range assessment, expecting manufacturer {id:08x}, type = {id_type}" + asserts.assert_equal(device_type_id_type(id), DeviceTypeIdType.kManufacturer, msg) + asserts.assert_true(is_valid_device_type_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_device_type_id(id_type, allow_test=False), msg) def check_test(id): - msg = f"Incorrect device type range assessment, expecting test {id:08x}" - asserts.assert_false(standard_device_type_range(id), msg) - asserts.assert_false(manufacturer_device_type_range(id), msg) - asserts.assert_true(test_device_type_range(id), msg) - asserts.assert_true(valid_device_type_range(id, allow_test=True), msg) - asserts.assert_false(valid_device_type_range(id, allow_test=False), msg) + id_type = device_type_id_type(id) + msg = f"Incorrect device type range assessment, expecting test {id:08x}, type = {id_type}" + asserts.assert_equal(device_type_id_type(id), DeviceTypeIdType.kTest, msg) + asserts.assert_true(is_valid_device_type_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_device_type_id(id_type, allow_test=False), msg) def check_all_bad(id): - msg = f"Incorrect device type range assessment, expecting invalid {id:08x}" - asserts.assert_false(standard_device_type_range(id), msg) - asserts.assert_false(manufacturer_device_type_range(id), msg) - asserts.assert_false(valid_device_type_range(id, allow_test=True), msg) - asserts.assert_false(valid_device_type_range(id, allow_test=False), msg) + id_type = device_type_id_type(id) + msg = f"Incorrect device type range assessment, expecting invalid {id:08x}, type = {id_type}" + asserts.assert_equal(device_type_id_type(id), DeviceTypeIdType.kInvalid, msg) + asserts.assert_false(is_valid_device_type_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_device_type_id(id_type, allow_test=False), msg) for id in standard_good: check_standard(id) @@ -98,36 +95,32 @@ def test_cluster_ids(self): prefix_bad = [0xFFF5_0000, 0xFFF5_FC00, 0xFFF5_FFFF] def check_standard(id): - msg = f"Incorrect cluster range assessment, expecting standard {id:08x}" - asserts.assert_true(standard_cluster_range(id), msg) - asserts.assert_false(manufacturer_cluster_range(id), msg) - asserts.assert_false(test_cluster_range(id), msg) - asserts.assert_true(valid_cluster_range(id, allow_test=True), msg) - asserts.assert_true(valid_cluster_range(id, allow_test=False), msg) + id_type = cluster_id_type(id) + msg = f"Incorrect cluster range assessment, expecting standard {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, ClusterIdType.kStandard, msg) + asserts.assert_true(is_valid_cluster_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_cluster_id(id_type, allow_test=False), msg) def check_manufacturer(id): - msg = f"Incorrect cluster range assessment, expecting manufacturer {id:08x}" - asserts.assert_false(standard_cluster_range(id), msg) - asserts.assert_true(manufacturer_cluster_range(id), msg) - asserts.assert_false(test_cluster_range(id), msg) - asserts.assert_true(valid_cluster_range(id, allow_test=True), msg) - asserts.assert_true(valid_cluster_range(id, allow_test=False), msg) + id_type = cluster_id_type(id) + msg = f"Incorrect cluster range assessment, expecting manufacturer {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, ClusterIdType.kManufacturer, msg) + asserts.assert_true(is_valid_cluster_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_cluster_id(id_type, allow_test=False), msg) def check_test(id): - msg = f"Incorrect cluster range assessment, expecting test {id:08x}" - asserts.assert_false(standard_cluster_range(id), msg) - asserts.assert_false(manufacturer_cluster_range(id), msg) - asserts.assert_true(test_cluster_range(id), msg) - asserts.assert_true(valid_cluster_range(id, allow_test=True), msg) - asserts.assert_false(valid_cluster_range(id, allow_test=False), msg) + id_type = cluster_id_type(id) + msg = f"Incorrect cluster range assessment, expecting test {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, ClusterIdType.kTest, msg) + asserts.assert_true(is_valid_cluster_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_cluster_id(id_type, allow_test=False), msg) def check_all_bad(id): - msg = f"Incorrect cluster range assessment, expecting invalid {id:08x}" - asserts.assert_false(standard_cluster_range(id), msg) - asserts.assert_false(manufacturer_cluster_range(id), msg) - asserts.assert_false(test_cluster_range(id), msg) - asserts.assert_false(valid_cluster_range(id, allow_test=True), msg) - asserts.assert_false(valid_cluster_range(id, allow_test=False), msg) + id_type = cluster_id_type(id) + msg = f"Incorrect cluster range assessment, expecting invalid {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, ClusterIdType.kInvalid, msg) + asserts.assert_false(is_valid_cluster_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_cluster_id(id_type, allow_test=False), msg) for id in standard_good: check_standard(id) @@ -162,49 +155,39 @@ def test_attribute_ids(self): prefix_bad = [0xFFF5_0000, 0xFFF5_4FFF, 0xFFF5_5000, 0xFFF5_F000, 0xFFF5_FFFF] def check_standard_global(id): - msg = f"Incorrect attribute range assessment, expecting standard global {id:08x}" - asserts.assert_true(standard_global_attribute_range(id), msg) - asserts.assert_false(standard_non_global_attribute_range(id), msg) - asserts.assert_false(manufacturer_attribute_range(id), msg) - asserts.assert_false(test_attribute_range(id), msg) - asserts.assert_true(valid_attribute_range(id, allow_test=True), msg) - asserts.assert_true(valid_attribute_range(id, allow_test=False), msg) + id_type = attribute_id_type(id) + msg = f"Incorrect attribute range assessment, expecting standard global {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, AttributeIdType.kStandardGlobal, msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=False), msg) def check_standard_non_global(id): - msg = f"Incorrect attribute range assessment, expecting standard non-global {id:08x}" - asserts.assert_false(standard_global_attribute_range(id), msg) - asserts.assert_true(standard_non_global_attribute_range(id), msg) - asserts.assert_false(manufacturer_attribute_range(id), msg) - asserts.assert_false(test_attribute_range(id), msg) - asserts.assert_true(valid_attribute_range(id, allow_test=True), msg) - asserts.assert_true(valid_attribute_range(id, allow_test=False), msg) + id_type = attribute_id_type(id) + msg = f"Incorrect attribute range assessment, expecting standard non-global {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, AttributeIdType.kStandardNonGlobal, msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=False), msg) def check_manufacturer(id): - msg = f"Incorrect attribute range assessment, expecting manufacturer {id:08x}" - asserts.assert_false(standard_global_attribute_range(id), msg) - asserts.assert_false(standard_non_global_attribute_range(id), msg) - asserts.assert_true(manufacturer_attribute_range(id), msg) - asserts.assert_false(test_attribute_range(id), msg) - asserts.assert_true(valid_attribute_range(id, allow_test=True), msg) - asserts.assert_true(valid_attribute_range(id, allow_test=False), msg) + id_type = attribute_id_type(id) + msg = f"Incorrect attribute range assessment, expecting manufacturer {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, AttributeIdType.kManufacturer, msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=False), msg) def check_test(id): - msg = f"Incorrect attribute range assessment, expecting test {id:08x}" - asserts.assert_false(standard_global_attribute_range(id), msg) - asserts.assert_false(standard_non_global_attribute_range(id), msg) - asserts.assert_false(manufacturer_attribute_range(id), msg) - asserts.assert_true(test_attribute_range(id), msg) - asserts.assert_true(valid_attribute_range(id, allow_test=True), msg) - asserts.assert_false(valid_attribute_range(id, allow_test=False), msg) + id_type = attribute_id_type(id) + msg = f"Incorrect attribute range assessment, expecting test {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, AttributeIdType.kTest, msg) + asserts.assert_true(is_valid_attribute_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_attribute_id(id_type, allow_test=False), msg) def check_all_bad(id): - msg = f"Incorrect attribute range assessment, expecting invalid {id:08x}" - asserts.assert_false(standard_global_attribute_range(id), msg) - asserts.assert_false(standard_non_global_attribute_range(id), msg) - asserts.assert_false(manufacturer_attribute_range(id), msg) - asserts.assert_false(test_attribute_range(id), msg) - asserts.assert_false(valid_attribute_range(id, allow_test=True), msg) - asserts.assert_false(valid_attribute_range(id, allow_test=False), msg) + id_type = attribute_id_type(id) + msg = f"Incorrect attribute range assessment, expecting invalid {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, AttributeIdType.kInvalid, msg) + asserts.assert_false(is_valid_attribute_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_attribute_id(id_type, allow_test=False), msg) for id in standard_global_good: check_standard_global(id) diff --git a/src/python_testing/global_attribute_ids.py b/src/python_testing/global_attribute_ids.py index 2849476057d0f0..e692adfdfb5a10 100644 --- a/src/python_testing/global_attribute_ids.py +++ b/src/python_testing/global_attribute_ids.py @@ -17,8 +17,7 @@ # This file should be removed once we have a good way to get this from the codegen or XML -from dataclasses import dataclass -from enum import IntEnum +from enum import Enum, IntEnum, auto class GlobalAttributeIds(IntEnum): @@ -41,6 +40,31 @@ def to_name(self) -> str: return "ClusterRevision" +class DeviceTypeIdType(Enum): + kInvalid = auto(), + kStandard = auto(), + kManufacturer = auto(), + kTest = auto(), + + +class ClusterIdType(Enum): + kInvalid = auto() + kStandard = auto(), + kManufacturer = auto(), + kTest = auto(), + + +class AttributeIdType(Enum): + kInvalid = auto() + kStandardGlobal = auto(), + kStandardNonGlobal = auto(), + kManufacturer = auto(), + kTest = auto(), + +# ID helper classes - this allows us to use the values from the prefix and suffix table directly +# because the class handles the non-inclusive range. + + class IdRange(): def __init__(self, min, max): self.min_max = range(min, max+1) @@ -70,62 +94,54 @@ def __contains__(self, id: int): ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX = SuffixIdRange(0x0000, 0x4FFF) -def standard_device_type_range(id: int): - return id in STANDARD_PREFIX and id in DEVICE_TYPE_ID_RANGE_SUFFIX - - -def manufacturer_device_type_range(id: int): - return id in MANUFACTURER_PREFIX and id in DEVICE_TYPE_ID_RANGE_SUFFIX - - -def test_device_type_range(id: int): - return id in TEST_PREFIX and id in DEVICE_TYPE_ID_RANGE_SUFFIX +def device_type_id_type(id: int) -> DeviceTypeIdType: + if id in STANDARD_PREFIX and id in DEVICE_TYPE_ID_RANGE_SUFFIX: + return DeviceTypeIdType.kStandard + if id in MANUFACTURER_PREFIX and id in DEVICE_TYPE_ID_RANGE_SUFFIX: + return DeviceTypeIdType.kManufacturer + if id in TEST_PREFIX and id in DEVICE_TYPE_ID_RANGE_SUFFIX: + return DeviceTypeIdType.kTest + return DeviceTypeIdType.kInvalid -def valid_device_type_range(id: int, allow_test: bool = False): - ret = manufacturer_device_type_range(id) or standard_device_type_range(id) +def is_valid_device_type_id(id_type: DeviceTypeIdType, allow_test=False) -> bool: + valid = [DeviceTypeIdType.kStandard, DeviceTypeIdType.kManufacturer] if allow_test: - ret = ret or test_device_type_range(id) - return ret + valid.append(DeviceTypeIdType.kTest) + return id_type in valid -def standard_cluster_range(id: int): - return id in STANDARD_PREFIX and id in CLUSTER_ID_STANDARD_RANGE_SUFFIX +def cluster_id_type(id: int) -> ClusterIdType: + if id in STANDARD_PREFIX and id in CLUSTER_ID_STANDARD_RANGE_SUFFIX: + return ClusterIdType.kStandard + if id in MANUFACTURER_PREFIX and id in CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX: + return ClusterIdType.kManufacturer + if id in TEST_PREFIX and id in CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX: + return ClusterIdType.kTest + return ClusterIdType.kInvalid -def manufacturer_cluster_range(id: int): - return id in MANUFACTURER_PREFIX and id in CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX - - -def test_cluster_range(id: int): - return id in TEST_PREFIX and id in CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX - - -def valid_cluster_range(id: int, allow_test: bool = False): - ret = standard_cluster_range(id) or manufacturer_cluster_range(id) +def is_valid_cluster_id(id_type: ClusterIdType, allow_test: bool = False) -> bool: + valid = [ClusterIdType.kStandard, ClusterIdType.kManufacturer] if allow_test: - ret = ret or test_cluster_range(id) - return ret - - -def standard_non_global_attribute_range(id: int): - return id in STANDARD_PREFIX and id in ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX - - -def standard_global_attribute_range(id: str): - return id in STANDARD_PREFIX and id in ATTRIBUTE_ID_GLOBAL_RANGE_SUFFIX - - -def manufacturer_attribute_range(id: str): - return id in MANUFACTURER_PREFIX and id in ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX + valid.append(ClusterIdType.kTest) + return id_type in valid -def test_attribute_range(id: str): - return id in TEST_PREFIX and id in ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX +def attribute_id_type(id: int) -> AttributeIdType: + if id in STANDARD_PREFIX and id in ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX: + return AttributeIdType.kStandardNonGlobal + if id in STANDARD_PREFIX and id in ATTRIBUTE_ID_GLOBAL_RANGE_SUFFIX: + return AttributeIdType.kStandardGlobal + if id in MANUFACTURER_PREFIX and id in ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX: + return AttributeIdType.kManufacturer + if id in TEST_PREFIX and id in ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX: + return AttributeIdType.kTest + return AttributeIdType.kInvalid -def valid_attribute_range(id: str, allow_test: bool = False): - ret = standard_global_attribute_range(id) or standard_non_global_attribute_range(id) or manufacturer_attribute_range(id) +def is_valid_attribute_id(id_type: AttributeIdType, allow_test: bool = False): + valid = [AttributeIdType.kStandardGlobal, AttributeIdType.kStandardNonGlobal, AttributeIdType.kManufacturer] if allow_test: - ret = ret or test_attribute_range(id) - return ret + valid.append(AttributeIdType.kTest) + return id_type in valid From 80e59bdd47e138230fc427c0b28f43ae721bee4b Mon Sep 17 00:00:00 2001 From: cecille <cecille@google.com> Date: Wed, 22 May 2024 17:20:19 -0400 Subject: [PATCH 5/6] isort --- src/python_testing/TestIdChecks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python_testing/TestIdChecks.py b/src/python_testing/TestIdChecks.py index 7084ea34365da3..8969807d5819e3 100644 --- a/src/python_testing/TestIdChecks.py +++ b/src/python_testing/TestIdChecks.py @@ -15,7 +15,8 @@ # limitations under the License. # -from global_attribute_ids import (device_type_id_type, is_valid_device_type_id, cluster_id_type, is_valid_cluster_id, attribute_id_type, is_valid_attribute_id, DeviceTypeIdType, ClusterIdType, AttributeIdType) +from global_attribute_ids import (AttributeIdType, ClusterIdType, DeviceTypeIdType, attribute_id_type, cluster_id_type, + device_type_id_type, is_valid_attribute_id, is_valid_cluster_id, is_valid_device_type_id) from matter_testing_support import MatterBaseTest, default_matter_test_main from mobly import asserts From c6ce4f8cb478b62d315fe64fcef2101769b3a8ad Mon Sep 17 00:00:00 2001 From: cecille <cecille@google.com> Date: Fri, 31 May 2024 15:52:54 -0400 Subject: [PATCH 6/6] fix workflow --- .github/workflows/tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 402e3a3b62303b..48de5615b0a2ba 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -563,7 +563,7 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-rvc-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-rvc-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCOPSTATE_2_4.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './src/python_testing/test_testing/test_TC_DA_1_2.py' scripts/run_in_python_env.sh out/venv './src/python_testing/test_testing/test_TC_ICDM_2_1.py' - scripts/run_in_python_env.sh out/venv './src/python_testing/TestIdChecks.py' + scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestIdChecks.py' - name: Uploading core files uses: actions/upload-artifact@v4