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