Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a8d5449

Browse files
committedMay 7, 2024
Make TestSubscriptionResumption an async test
The current test implementation starves the asyncio event loop by synchronously waiting for the threading.Condition. This prevents making the SubscriptionTransaction fully leveraging the async paradigm. It probably would be possible to mix asyncio.sleep() and threading, but instead embrace the async pradigm for this test.
1 parent 717ca4d commit a8d5449

File tree

2 files changed

+18
-19
lines changed

2 files changed

+18
-19
lines changed
 

‎src/controller/python/test/test_scripts/base.py

+15-17
Original file line numberDiff line numberDiff line change
@@ -1337,7 +1337,7 @@ def TestFabricScopedCommandDuringPase(self, nodeid: int):
13371337

13381338
return status == IM.Status.UnsupportedAccess
13391339

1340-
def TestSubscriptionResumption(self, nodeid: int, endpoint: int, remote_ip: str, ssh_port: int, remote_server_app: str):
1340+
async def TestSubscriptionResumption(self, nodeid: int, endpoint: int, remote_ip: str, ssh_port: int, remote_server_app: str):
13411341
'''
13421342
This test validates that the device can resume the subscriptions after restarting.
13431343
It is executed in Linux Cirque tests and the steps of this test are:
@@ -1346,42 +1346,40 @@ def TestSubscriptionResumption(self, nodeid: int, endpoint: int, remote_ip: str,
13461346
3. Validate that the controller can receive a report from the remote server app
13471347
'''
13481348
desiredPath = None
1349-
receivedUpdate = False
1350-
updateLock = threading.Lock()
1351-
updateCv = threading.Condition(updateLock)
1349+
updateEvent = asyncio.Event()
1350+
loop = asyncio.get_running_loop()
13521351

13531352
def OnValueReport(path: Attribute.TypedAttributePath, transaction: Attribute.SubscriptionTransaction) -> None:
1354-
nonlocal desiredPath, updateCv, updateLock, receivedUpdate
1353+
nonlocal desiredPath, updateEvent, receivedUpdate
13551354
if path.Path != desiredPath:
13561355
return
13571356

13581357
data = transaction.GetAttribute(path)
13591358
logger.info(
13601359
f"Received report from server: path: {path.Path}, value: {data}")
1361-
with updateLock:
1362-
receivedUpdate = True
1363-
updateCv.notify_all()
1360+
loop.call_soon_threadsafe(updateEvent.set)
13641361

13651362
try:
13661363
desiredPath = Clusters.Attribute.AttributePath(
13671364
EndpointId=0, ClusterId=0x28, AttributeId=5)
13681365
# BasicInformation Cluster, NodeLabel Attribute
1369-
subscription = self.devCtrl.ZCLSubscribeAttribute(
1370-
"BasicInformation", "NodeLabel", nodeid, endpoint, 1, 50, keepSubscriptions=True, autoResubscribe=False)
1366+
subscription = await self.devCtrl.ReadAttribute(nodeid, [(endpoint, Clusters.BasicInformation.Attributes.NodeLabel)], None, False, reportInterval=(1, 50),
1367+
keepSubscriptions=True, autoResubscribe=False)
13711368
subscription.SetAttributeUpdateCallback(OnValueReport)
13721369

1373-
self.logger.info("Restart remote deivce")
1370+
self.logger.info("Restart remote device")
13741371
restartRemoteThread = restartRemoteDevice(
13751372
remote_ip, ssh_port, "root", "admin", remote_server_app, "--thread --discriminator 3840")
13761373
restartRemoteThread.start()
13771374
# After device restarts, the attribute will be set dirty so the subscription can receive
13781375
# the update
1379-
with updateCv:
1380-
while receivedUpdate is False:
1381-
if not updateCv.wait(10.0):
1382-
self.logger.error(
1383-
"Failed to receive subscription resumption report")
1384-
break
1376+
receivedUpdate = False
1377+
try:
1378+
await asyncio.wait_for(updateEvent.wait(), 10)
1379+
receivedUpdate = True
1380+
except TimeoutError:
1381+
self.logger.error(
1382+
"Failed to receive subscription resumption report")
13851383

13861384
restartRemoteThread.join(10.0)
13871385

‎src/controller/python/test/test_scripts/subscription_resumption_test.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
# Commissioning test.
2121

22+
import asyncio
2223
import os
2324
import sys
2425
from optparse import OptionParser
@@ -115,8 +116,8 @@ def main():
115116
"Failed on on-network commissioing")
116117

117118
FailIfNot(
118-
test.TestSubscriptionResumption(options.nodeid, TEST_ENDPOINT_ID, options.deviceAddress,
119-
TEST_SSH_PORT, options.remoteServerApp), "Failed to resume subscription")
119+
asyncio.run(test.TestSubscriptionResumption(options.nodeid, TEST_ENDPOINT_ID, options.deviceAddress,
120+
TEST_SSH_PORT, options.remoteServerApp), "Failed to resume subscription"))
120121

121122
timeoutTicker.stop()
122123

0 commit comments

Comments
 (0)
Please sign in to comment.