Skip to content

Commit

Permalink
src: python_testing: minor changes regardin controllers' id and async
Browse files Browse the repository at this point in the history
* implementation of generate_random_node_id with exculdes values, the
method add possibilty to run multiple test cases within one test session
(the controllers' nodeid is the same for new controller in different
test cases)
* due to change in ChipDeviceController and usage of asyncio.Lock (which
use get_event_loop) may cause `RuntimeError: There is no current event
loop in thread 'MainThread'` while using multiple times `asyncio.run()`

Signed-off-by: Michał Szablowski <[email protected]>
  • Loading branch information
doublemis1 committed Jul 8, 2024
1 parent 6e31453 commit 9038d6d
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 15 deletions.
4 changes: 2 additions & 2 deletions src/python_testing/TC_ACE_1_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -136,7 +136,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=[self.matter_test_config.controller_node_id])

self.TH2 = fabric_admin.NewController(nodeId=TH2_nodeid,
paaTrustStorePath=str(self.matter_test_config.paa_trust_store_path))
Expand Down
23 changes: 19 additions & 4 deletions src/python_testing/TC_ACE_1_3.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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),
Expand Down
4 changes: 2 additions & 2 deletions src/python_testing/TC_ACE_1_5.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand All @@ -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))
Expand Down
4 changes: 2 additions & 2 deletions src/python_testing/TC_AccessChecker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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
Expand Down
8 changes: 6 additions & 2 deletions src/python_testing/TC_IDM_4_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

'''
Expand Down Expand Up @@ -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),
Expand Down
22 changes: 19 additions & 3 deletions src/python_testing/matter_testing_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -1492,19 +1492,35 @@ def parse_matter_test_args(argv: Optional[List[str]] = None) -> MatterTestConfig

return convert_args_to_matter_config(parser.parse_known_args(argv)[0])

def async_to_sync(awaitable):
"Call sync, the async function."
# Usage of new implementation of ChipDeviceController cause the necessary to not use asyncio.run,
# because the initialization of `asyncio.Lock` use the `asyncio.get_event_loop()` on init.
# Usage of `asyncio.run()` and `asyncio.get_event_loop()` are exclusive.
loop = asyncio.get_event_loop()
return loop.run_until_complete(awaitable)

def generate_random_nodeid(excluded_nodeid: typing.Optional[typing.List] = None) -> int:
if excluded_nodeid:
while True:
node_id=random.randint(0, 2^64-1)
if node_id not in excluded_nodeid:
return node_id
else:
return random.randint(0, 2^64-1)

def async_test_body(body):
"""Decorator required to be applied whenever a `test_*` method is `async def`.
Since Mobly doesn't support asyncio directly, and the test methods are called
synchronously, we need a mechanism to allow an `async def` to be converted to
a asyncio-run synchronous method. This decorator does the wrapping.
a synchronous method using asyncio's event loop. This decorator does the wrapping.
"""

def async_runner(self: MatterBaseTest, *args, **kwargs):
timeout = self.matter_test_config.timeout if self.matter_test_config.timeout is not None else self.default_timeout
runner_with_timeout = asyncio.wait_for(body(self, *args, **kwargs), timeout=timeout)
return asyncio.run(runner_with_timeout)
return async_to_sync(runner_with_timeout)

return async_runner

Expand All @@ -1523,7 +1539,7 @@ def test_run_commissioning(self):
(conf.root_of_trust_index, conf.fabric_id, node_id))
logging.info("Commissioning method: %s" % conf.commissioning_method)

if not asyncio.run(self._commission_device(commission_idx)):
if not async_to_sync(self._commission_device(commission_idx)):
raise signals.TestAbortAll("Failed to commission node")

async def _commission_device(self, i) -> bool:
Expand Down

0 comments on commit 9038d6d

Please sign in to comment.