diff --git a/src/python_testing/TC_ACE_1_2.py b/src/python_testing/TC_ACE_1_2.py index 2c6f07a217183a..d1496c89f6d6ba 100644 --- a/src/python_testing/TC_ACE_1_2.py +++ b/src/python_testing/TC_ACE_1_2.py @@ -30,7 +30,7 @@ from chip.clusters.Attribute import EventReadResult, SubscriptionTransaction, TypedAttributePath from chip.exceptions import ChipStackError from chip.interaction_model import Status -from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, generate_random_nodeid from mobly import asserts @@ -87,8 +87,15 @@ def __init__(self, *args): self.breadcrumb = 1 self.breadcrumb_queue = queue.Queue() self.subscription_breadcrumb = None + self.subscriptions = [] super().__init__(*args) + def teardown_class(self): + for subscription in self.subscriptions: + subscription.Shutdown() + if self.subscription_breadcrumb is not None: + self.subscription_breadcrumb.Shutdown() + async def write_acl(self, acl): # This returns an attribute status result = await self.default_controller.WriteAttribute(self.dut_node_id, [(0, Clusters.AccessControl.Attributes.Acl(acl))]) @@ -97,6 +104,9 @@ async def write_acl(self, acl): async def steps_subscribe_breadcrumb(self, print_steps: bool): if print_steps: self.print_step(3, "TH2 subscribes to the Breadcrumb attribute") + if isinstance(self.subscription_breadcrumb, Clusters.Attribute.SubscriptionTransaction): + self.subscription_breadcrumb.Shutdown() + self.subscription_breadcrumb = await self.TH2.ReadAttribute(nodeid=self.dut_node_id, attributes=[(0, Clusters.GeneralCommissioning.Attributes.Breadcrumb)], reportInterval=(1, 5), keepSubscriptions=False, autoResubscribe=False) breadcrumb_cb = AttributeChangeCallback(Clusters.GeneralCommissioning.Attributes.Breadcrumb, self.breadcrumb_queue) self.subscription_breadcrumb.SetAttributeUpdateCallback(breadcrumb_cb) @@ -136,7 +146,7 @@ async def test_TC_ACE_1_2(self): fabric_admin = self.certificate_authority_manager.activeCaList[0].adminList[0] TH1_nodeid = self.matter_test_config.controller_node_id - TH2_nodeid = self.matter_test_config.controller_node_id + 1 + TH2_nodeid = generate_random_nodeid(excluded_nodeid={TH1_nodeid}) self.TH2 = fabric_admin.NewController(nodeId=TH2_nodeid, paaTrustStorePath=str(self.matter_test_config.paa_trust_store_path)) @@ -157,6 +167,7 @@ async def test_TC_ACE_1_2(self): acl_queue = queue.Queue() acl_cb = AttributeChangeCallback(Clusters.AccessControl.Attributes.Acl, acl_queue) subscription_acl.SetAttributeUpdateCallback(acl_cb) + self.subscriptions.append(subscription_acl) self.print_step(5, "TH2 subscribes to the AccessControlEntryChanged event") urgent = 1 @@ -164,6 +175,7 @@ async def test_TC_ACE_1_2(self): ace_queue = queue.Queue() ace_cb = EventChangeCallback(Clusters.AccessControl.Events.AccessControlEntryChanged, ace_queue) subscription_ace.SetEventUpdateCallback(ace_cb) + self.subscriptions.append(subscription_ace) self.print_step(6, "TH1 writes ACL attribute") acl = Clusters.AccessControl.Structs.AccessControlEntryStruct( diff --git a/src/python_testing/TC_ACE_1_3.py b/src/python_testing/TC_ACE_1_3.py index 150683357e1e9c..6d9090d494fe4f 100644 --- a/src/python_testing/TC_ACE_1_3.py +++ b/src/python_testing/TC_ACE_1_3.py @@ -26,7 +26,7 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main, generate_random_nodeid from mobly import asserts @@ -137,9 +137,24 @@ async def test_TC_ACE_1_3(self): fabric_admin = self.certificate_authority_manager.activeCaList[0].adminList[0] TH0_nodeid = self.matter_test_config.controller_node_id - TH1_nodeid = self.matter_test_config.controller_node_id + 1 - TH2_nodeid = self.matter_test_config.controller_node_id + 2 - TH3_nodeid = self.matter_test_config.controller_node_id + 3 + TH1_nodeid = generate_random_nodeid( + excluded_nodeid={ + TH0_nodeid + } + ) + TH2_nodeid = generate_random_nodeid( + excluded_nodeid={ + TH0_nodeid, + TH1_nodeid + } + ) + TH3_nodeid = generate_random_nodeid( + excluded_nodeid={ + TH0_nodeid, + TH1_nodeid, + TH2_nodeid + } + ) TH1 = fabric_admin.NewController(nodeId=TH1_nodeid, paaTrustStorePath=str(self.matter_test_config.paa_trust_store_path), diff --git a/src/python_testing/TC_ACE_1_5.py b/src/python_testing/TC_ACE_1_5.py index e88a040e31b983..292506b431fedb 100644 --- a/src/python_testing/TC_ACE_1_5.py +++ b/src/python_testing/TC_ACE_1_5.py @@ -27,7 +27,7 @@ import chip.clusters as Clusters from chip import ChipDeviceCtrl from chip.interaction_model import Status -from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, generate_random_nodeid from mobly import asserts @@ -53,7 +53,7 @@ async def test_TC_ACE_1_5(self): new_fabric_admin = new_certificate_authority.NewFabricAdmin(vendorId=0xFFF1, fabricId=self.matter_test_config.fabric_id + 1) TH1_nodeid = self.matter_test_config.controller_node_id - TH2_nodeid = self.matter_test_config.controller_node_id + 2 + TH2_nodeid = generate_random_nodeid(excluded_nodeid={TH1_nodeid}) self.th2 = new_fabric_admin.NewController(nodeId=TH2_nodeid, paaTrustStorePath=str(self.matter_test_config.paa_trust_store_path)) diff --git a/src/python_testing/TC_AccessChecker.py b/src/python_testing/TC_AccessChecker.py index f2bbf36330ec6a..2819ba86432b98 100644 --- a/src/python_testing/TC_AccessChecker.py +++ b/src/python_testing/TC_AccessChecker.py @@ -16,7 +16,7 @@ from chip.tlv import uint from global_attribute_ids import GlobalAttributeIds from matter_testing_support import (AttributePathLocation, ClusterPathLocation, MatterBaseTest, TestStep, async_test_body, - default_matter_test_main) + default_matter_test_main, generate_random_nodeid) from spec_parsing_support import XmlCluster, build_xml_clusters @@ -66,7 +66,7 @@ async def setup_class(self): self._record_errors() # We need to run this test from two controllers so we can test access to the ACL cluster while retaining access to the ACL cluster fabric_admin = self.certificate_authority_manager.activeCaList[0].adminList[0] - self.TH2_nodeid = self.matter_test_config.controller_node_id + 1 + self.TH2_nodeid = generate_random_nodeid(excluded_nodeid={self.matter_test_config.controller_node_id}) self.TH2 = fabric_admin.NewController(nodeId=self.TH2_nodeid) # Both the tests in this suite are potentially long-running if there are a large number of attributes on the DUT diff --git a/src/python_testing/TC_IDM_4_2.py b/src/python_testing/TC_IDM_4_2.py index 60016ba4dcf20a..acd31423f82f56 100644 --- a/src/python_testing/TC_IDM_4_2.py +++ b/src/python_testing/TC_IDM_4_2.py @@ -24,7 +24,7 @@ from chip.clusters.Attribute import AttributePath, TypedAttributePath from chip.exceptions import ChipStackError from chip.interaction_model import Status -from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, generate_random_nodeid from mobly import asserts ''' @@ -134,7 +134,11 @@ async def test_TC_IDM_4_2(self): # Subscriber/client with limited access to the DUT # Will validate error status codes fabric_admin = self.certificate_authority_manager.activeCaList[0].adminList[0] - CR2_nodeid = self.matter_test_config.controller_node_id + 1 + CR2_nodeid = generate_random_nodeid( + excluded_nodeid={ + self.matter_test_config.controller_node_id + } + ) CR2: ChipDeviceController = fabric_admin.NewController( nodeId=CR2_nodeid, paaTrustStorePath=str(self.matter_test_config.paa_trust_store_path), diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index dbf4e14905015a..f862ff88f7c512 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -1499,6 +1499,14 @@ def parse_matter_test_args(argv: Optional[List[str]] = None) -> MatterTestConfig return convert_args_to_matter_config(parser.parse_known_args(argv)[0]) +def generate_random_nodeid(excluded_nodeid: typing.Optional[typing.Set] = set()) -> int: + "Generate random complainat nodeid, excluding a set of provided nodeids." + nodeid = random.randint(1, 0xFFFF_FFEF_FFFF_FFFF) + if nodeid in excluded_nodeid: + return generate_random_nodeid(excluded_nodeid) + return nodeid + + def async_test_body(body): """Decorator required to be applied whenever a `test_*` method is `async def`.