From e8e86bc4a2dbbadba480010132ba7d3c63c4838c Mon Sep 17 00:00:00 2001
From: cecille <cecille@google.com>
Date: Mon, 15 Apr 2024 18:26:25 -0400
Subject: [PATCH 1/7] TC-DGGEN-3.2: Add

---
 src/python_testing/TC_DGGEN_3_2.py            | 47 ++++++++++++
 .../test_testing/MockTestRunner.py            |  4 +-
 .../test_testing/test_TC_DGGEN_3_2.py         | 72 +++++++++++++++++++
 .../test_testing/test_TC_TMP_2_1.py           |  2 +-
 4 files changed, 122 insertions(+), 3 deletions(-)
 create mode 100644 src/python_testing/TC_DGGEN_3_2.py
 create mode 100644 src/python_testing/test_testing/test_TC_DGGEN_3_2.py

diff --git a/src/python_testing/TC_DGGEN_3_2.py b/src/python_testing/TC_DGGEN_3_2.py
new file mode 100644
index 00000000000000..b27519cc3c9bb4
--- /dev/null
+++ b/src/python_testing/TC_DGGEN_3_2.py
@@ -0,0 +1,47 @@
+#
+#    Copyright (c) 2023 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.
+#
+
+import chip.clusters as Clusters
+from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
+from mobly import asserts
+
+
+class TC_DGGEN_3_2(MatterBaseTest):
+    def steps_TC_DGGEN_3_2(self):
+        return [TestStep(0, "Commission DUT (already done)", is_commissioning=True),
+                TestStep(1, "TH reads the MaxPathsPerInvoke attribute form the Basic Information Cluster from DUT",
+                         "Save the value as `max_paths_per_invoke`"),
+                TestStep(2, "TH reads FeatureMap attribute form the General Diagnostics Cluster from DUT",
+                         "Verify that the FeatureMap value has the DMTEST feature bit (0) set to 1 if `max_path_per_invoke` > 1")
+                ]
+
+    @async_test_body
+    async def test_TC_DGGEN_3_2(self):
+        # commissioning - already done
+        self.step(0)
+
+        self.step(1)
+        max_paths_per_invoke = await self.read_single_attribute_check_success(cluster=Clusters.BasicInformation, attribute=Clusters.BasicInformation.Attributes.MaxPathsPerInvoke)
+
+        self.step(2)
+        feature_map = await self.read_single_attribute_check_success(cluster=Clusters.GeneralDiagnostics, attribute=Clusters.GeneralDiagnostics.Attributes.FeatureMap)
+        if max_paths_per_invoke > 1:
+            asserts.assert_true(feature_map & Clusters.GeneralDiagnostics.Bitmaps.Feature.kDataModelTest, "DMTEST feature must be set if MaxPathsPerInvoke > 1")
+
+
+if __name__ == "__main__":
+    default_matter_test_main()
diff --git a/src/python_testing/test_testing/MockTestRunner.py b/src/python_testing/test_testing/MockTestRunner.py
index 79f6e21e2b434e..451e38d4660ac6 100644
--- a/src/python_testing/test_testing/MockTestRunner.py
+++ b/src/python_testing/test_testing/MockTestRunner.py
@@ -37,9 +37,9 @@ async def __call__(self, *args, **kwargs):
 
 
 class MockTestRunner():
-    def __init__(self, filename: str, classname: str, test: str):
+    def __init__(self, filename: str, classname: str, test: str, endpoint: int):
         self.config = MatterTestConfig(
-            tests=[test], endpoint=1, dut_node_ids=[1])
+            tests=[test], endpoint=endpoint, dut_node_ids=[1])
         self.stack = MatterStackState(self.config)
         self.default_controller = self.stack.certificate_authorities[0].adminList[0].NewController(
             nodeId=self.config.controller_node_id,
diff --git a/src/python_testing/test_testing/test_TC_DGGEN_3_2.py b/src/python_testing/test_testing/test_TC_DGGEN_3_2.py
new file mode 100644
index 00000000000000..a3f4ab307c2259
--- /dev/null
+++ b/src/python_testing/test_testing/test_TC_DGGEN_3_2.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env -S python3 -B
+#
+#    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.
+#
+
+import sys
+import typing
+from dataclasses import dataclass
+
+import chip.clusters as Clusters
+from chip.clusters import Attribute
+from chip.clusters.Types import NullValue
+from MockTestRunner import MockTestRunner
+
+
+@dataclass
+class TestSpec():
+    max_paths: int
+    dmtest_feature_map: int
+    expect_pass: bool
+
+
+TEST_CASES = [
+    TestSpec(1, 0, True),
+    TestSpec(1, 1, True),  # I think this is ok...to have the feature on when it's not needed?
+    TestSpec(2, 0, False),
+    TestSpec(2, 1, True),
+]
+
+
+def test_spec_to_attribute_cache(test_spec: TestSpec) -> Attribute.AsyncReadTransaction.ReadResponse:
+    bi = Clusters.BasicInformation
+    bi_attr = bi.Attributes
+    gd = Clusters.GeneralDiagnostics
+    gd_attr = gd.Attributes
+    resp = Attribute.AsyncReadTransaction.ReadResponse({}, [], {})
+    resp.attributes = {0: {bi: {bi_attr.MaxPathsPerInvoke: test_spec.max_paths}, gd: {gd_attr.FeatureMap: test_spec.dmtest_feature_map}}}
+    return resp
+
+
+def main():
+    test_runner = MockTestRunner('TC_DGGEN_3_2', 'TC_DGGEN_3_2', 'test_TC_DGGEN_3_2', 0)
+    failures = []
+    for idx, t in enumerate(TEST_CASES):
+        ok = test_runner.run_test_with_mock_read(test_spec_to_attribute_cache(t)) == t.expect_pass
+        if not ok:
+            failures.append(f"Test case failure: {idx} {t}")
+
+    test_runner.Shutdown()
+    print(
+        f"Test of tests: run {len(TEST_CASES)}, test response correct: {len(TEST_CASES) - len(failures)} test response incorrect: {len(failures)}")
+    for f in failures:
+        print(f)
+
+    return 1 if failures else 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/src/python_testing/test_testing/test_TC_TMP_2_1.py b/src/python_testing/test_testing/test_TC_TMP_2_1.py
index 5693aced8ba505..fe888a4896cb28 100644
--- a/src/python_testing/test_testing/test_TC_TMP_2_1.py
+++ b/src/python_testing/test_testing/test_TC_TMP_2_1.py
@@ -160,7 +160,7 @@ def test_spec_to_attribute_cache(test_spec: TestSpec) -> Attribute.AsyncReadTran
 
 
 def main():
-    test_runner = MockTestRunner('TC_TMP_2_1', 'TC_TMP_2_1', 'test_TC_TMP_2_1')
+    test_runner = MockTestRunner('TC_TMP_2_1', 'TC_TMP_2_1', 'test_TC_TMP_2_1', 1)
     failures = []
     for idx, t in enumerate(TEST_CASES):
         ok = test_runner.run_test_with_mock_read(test_spec_to_attribute_cache(t)) == t.expect_pass

From 76a760d58513835b7438a4eff197abab42f57982 Mon Sep 17 00:00:00 2001
From: C Freeman <cecille@google.com>
Date: Mon, 15 Apr 2024 18:27:45 -0400
Subject: [PATCH 2/7] Apply suggestions from code review

---
 src/python_testing/TC_DGGEN_3_2.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/python_testing/TC_DGGEN_3_2.py b/src/python_testing/TC_DGGEN_3_2.py
index b27519cc3c9bb4..e0bdc4b736557d 100644
--- a/src/python_testing/TC_DGGEN_3_2.py
+++ b/src/python_testing/TC_DGGEN_3_2.py
@@ -1,5 +1,5 @@
 #
-#    Copyright (c) 2023 Project CHIP Authors
+#    Copyright (c) 2024 Project CHIP Authors
 #    All rights reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License");

From 5041d15fa45d9854e3f43a267811905bfe6051ec Mon Sep 17 00:00:00 2001
From: cecille <cecille@google.com>
Date: Thu, 18 Apr 2024 15:01:05 -0400
Subject: [PATCH 3/7] lint

---
 src/python_testing/test_testing/test_TC_DGGEN_3_2.py | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/python_testing/test_testing/test_TC_DGGEN_3_2.py b/src/python_testing/test_testing/test_TC_DGGEN_3_2.py
index a3f4ab307c2259..68e616fee15807 100644
--- a/src/python_testing/test_testing/test_TC_DGGEN_3_2.py
+++ b/src/python_testing/test_testing/test_TC_DGGEN_3_2.py
@@ -17,12 +17,10 @@
 #
 
 import sys
-import typing
 from dataclasses import dataclass
 
 import chip.clusters as Clusters
 from chip.clusters import Attribute
-from chip.clusters.Types import NullValue
 from MockTestRunner import MockTestRunner
 
 

From b1384ffa9335b474f803d92e19c8a43850eb0b03 Mon Sep 17 00:00:00 2001
From: cecille <cecille@google.com>
Date: Thu, 18 Apr 2024 15:35:47 -0400
Subject: [PATCH 4/7] move save out of expected outcome

---
 src/python_testing/TC_DGGEN_3_2.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/python_testing/TC_DGGEN_3_2.py b/src/python_testing/TC_DGGEN_3_2.py
index e0bdc4b736557d..67fec65b57587f 100644
--- a/src/python_testing/TC_DGGEN_3_2.py
+++ b/src/python_testing/TC_DGGEN_3_2.py
@@ -23,8 +23,8 @@
 class TC_DGGEN_3_2(MatterBaseTest):
     def steps_TC_DGGEN_3_2(self):
         return [TestStep(0, "Commission DUT (already done)", is_commissioning=True),
-                TestStep(1, "TH reads the MaxPathsPerInvoke attribute form the Basic Information Cluster from DUT",
-                         "Save the value as `max_paths_per_invoke`"),
+                TestStep(1, "TH reads the MaxPathsPerInvoke attribute form the Basic Information Cluster from DUT. Save the value as `max_paths_per_invoke",
+                         "Read is successful"),
                 TestStep(2, "TH reads FeatureMap attribute form the General Diagnostics Cluster from DUT",
                          "Verify that the FeatureMap value has the DMTEST feature bit (0) set to 1 if `max_path_per_invoke` > 1")
                 ]

From 063f6b47bf17302c6aab3ebaa9dd39e59cbad0bc Mon Sep 17 00:00:00 2001
From: "Restyled.io" <commits@restyled.io>
Date: Thu, 18 Apr 2024 19:51:32 +0000
Subject: [PATCH 5/7] Restyled by autopep8

---
 src/python_testing/TC_DGGEN_3_2.py                   | 3 ++-
 src/python_testing/test_testing/test_TC_DGGEN_3_2.py | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/python_testing/TC_DGGEN_3_2.py b/src/python_testing/TC_DGGEN_3_2.py
index 67fec65b57587f..e35a22e179f047 100644
--- a/src/python_testing/TC_DGGEN_3_2.py
+++ b/src/python_testing/TC_DGGEN_3_2.py
@@ -40,7 +40,8 @@ async def test_TC_DGGEN_3_2(self):
         self.step(2)
         feature_map = await self.read_single_attribute_check_success(cluster=Clusters.GeneralDiagnostics, attribute=Clusters.GeneralDiagnostics.Attributes.FeatureMap)
         if max_paths_per_invoke > 1:
-            asserts.assert_true(feature_map & Clusters.GeneralDiagnostics.Bitmaps.Feature.kDataModelTest, "DMTEST feature must be set if MaxPathsPerInvoke > 1")
+            asserts.assert_true(feature_map & Clusters.GeneralDiagnostics.Bitmaps.Feature.kDataModelTest,
+                                "DMTEST feature must be set if MaxPathsPerInvoke > 1")
 
 
 if __name__ == "__main__":
diff --git a/src/python_testing/test_testing/test_TC_DGGEN_3_2.py b/src/python_testing/test_testing/test_TC_DGGEN_3_2.py
index 68e616fee15807..3ff12100ac82a5 100644
--- a/src/python_testing/test_testing/test_TC_DGGEN_3_2.py
+++ b/src/python_testing/test_testing/test_TC_DGGEN_3_2.py
@@ -45,7 +45,8 @@ def test_spec_to_attribute_cache(test_spec: TestSpec) -> Attribute.AsyncReadTran
     gd = Clusters.GeneralDiagnostics
     gd_attr = gd.Attributes
     resp = Attribute.AsyncReadTransaction.ReadResponse({}, [], {})
-    resp.attributes = {0: {bi: {bi_attr.MaxPathsPerInvoke: test_spec.max_paths}, gd: {gd_attr.FeatureMap: test_spec.dmtest_feature_map}}}
+    resp.attributes = {0: {bi: {bi_attr.MaxPathsPerInvoke: test_spec.max_paths},
+                           gd: {gd_attr.FeatureMap: test_spec.dmtest_feature_map}}}
     return resp
 
 

From b5804c1786c2f3beeeeda4bc65f30407acecce67 Mon Sep 17 00:00:00 2001
From: cecille <cecille@google.com>
Date: Fri, 19 Apr 2024 08:40:08 -0400
Subject: [PATCH 6/7] spelling

---
 src/python_testing/TC_DGGEN_3_2.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/python_testing/TC_DGGEN_3_2.py b/src/python_testing/TC_DGGEN_3_2.py
index e35a22e179f047..7e5af6c7a5ea73 100644
--- a/src/python_testing/TC_DGGEN_3_2.py
+++ b/src/python_testing/TC_DGGEN_3_2.py
@@ -23,9 +23,9 @@
 class TC_DGGEN_3_2(MatterBaseTest):
     def steps_TC_DGGEN_3_2(self):
         return [TestStep(0, "Commission DUT (already done)", is_commissioning=True),
-                TestStep(1, "TH reads the MaxPathsPerInvoke attribute form the Basic Information Cluster from DUT. Save the value as `max_paths_per_invoke",
+                TestStep(1, "TH reads the MaxPathsPerInvoke attribute from the Basic Information Cluster from DUT. Save the value as `max_paths_per_invoke",
                          "Read is successful"),
-                TestStep(2, "TH reads FeatureMap attribute form the General Diagnostics Cluster from DUT",
+                TestStep(2, "TH reads FeatureMap attribute from the General Diagnostics Cluster from DUT",
                          "Verify that the FeatureMap value has the DMTEST feature bit (0) set to 1 if `max_path_per_invoke` > 1")
                 ]
 

From 591730056e995e609ac19c6e6c1bda4ab0bba64f Mon Sep 17 00:00:00 2001
From: C Freeman <cecille@google.com>
Date: Thu, 25 Apr 2024 09:24:58 -0400
Subject: [PATCH 7/7] Apply suggestions from code review

---
 src/python_testing/test_testing/test_TC_DGGEN_3_2.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/python_testing/test_testing/test_TC_DGGEN_3_2.py b/src/python_testing/test_testing/test_TC_DGGEN_3_2.py
index 3ff12100ac82a5..34b80514035945 100644
--- a/src/python_testing/test_testing/test_TC_DGGEN_3_2.py
+++ b/src/python_testing/test_testing/test_TC_DGGEN_3_2.py
@@ -33,7 +33,7 @@ class TestSpec():
 
 TEST_CASES = [
     TestSpec(1, 0, True),
-    TestSpec(1, 1, True),  # I think this is ok...to have the feature on when it's not needed?
+    TestSpec(1, 1, True),
     TestSpec(2, 0, False),
     TestSpec(2, 1, True),
 ]