Skip to content

Commit 876fcf5

Browse files
[Test Update] Updating TC_CADMIN_1_3_4 and cadmin_support python3 modules for clock skew allowance subscription (project-chip#39756)
* Updating TC_CADMIN_1_3_4 and cadmin_support python3 modules: - Updated these to include new real-time commissioning window monitoring with subscriptions to remove prior hardcoded sleep - Added timing validation with clock skew tolerance - Provides detailed timing metrics to show exactly how long the commissioning window was open and how much clock skew applied - Removed test steps 10 and 11 as no longer using in TC_CADMIN_1_3_4 python3 test module, as we get the window closed status back in our subscription at the end of test step 9. * isort and autopep8 stylizered * Resolving broad exception, changed to asyncio.TimeoutError instead * Resolving linting errors * Updating cadmin_support python3 support module: - Created a new variable named monitoring_timeout which is max_allowed_duration + 10 seconds. - Updated the commissioning option var name to commissioning_option for clarity and now use a local CommissioningWindowOption enum as well as updated docstring - Updated expected_status from an int to a True or False bool value, changed expected_status to is_open_expected var name * Restyled by autopep8 * Restyled by isort * Updating cadmin_support python3 support module: - Changing "if is_open_expected=False" to "if not is_open_expected" in order to resolve linting error. * Update cadmin_support.py Changing import location of ClusterAttributeChangeAccumulator from chip.testing.matter_testing to chip.testing.event_attribute_reporting * remove get_txt_record function from cadmin_support support module as it is unused * Restyled by autopep8 * Restyled by isort * Updating cadmin_support support and TC_CADMIN_1_3_4 test modules: - Due to merge of AttributeChangeCallback and ClusterAttributeChangeAccumulator classes into AttributeSubscriptionHandler class in PR project-chip#39672 had to make some changes to get this working after that PR merged - Resolved some minor overlap with other CADMIN tests and some of the support functions for opening commissioning window in cadmin_support support module - Verified all CADMIN test modules are now passing * Restyled by isort * Updating TC_CADMIN_1_3_4 test module and cadmin_support modules: - Fixed the race condition in step 9 by using open_commissioning_window_with_subscription_monitoring to establish the subscription before opening the commissioning window, then using the monitor_commissioning_window_closure_with_subscription function to monitor the subscription until the commissioning window closes. - Fixed the AttributeError by replacing ._jsonData["sdk-config"]["f/1/r"] with the proper API call GetSdkKey("f/1/r") - Function wait_for_window_status_change now asserts on timeout, otherwise silently passes without a return as not needed since we know it passes if it doesnt experience a timeout - Removed the dead code from the log_timing_results function after changes made to wait_for_window_status_change function - Removed open_commissioning_window_with_full_args function as it is best to keep the code simple adding without unneccessary functionality. * Restyled by isort * Resolving linting issues and restyled by isort * Restyled by autopep8 * Restyled by autopep8 * Updating cadmin_support and TC_CADMIN_1_3_4 python3 test modules: - Removed unused get_all_txt_records function - Updated to using TimingResults dataclass instead of dictionary * Resolving linting error * Removed duplicated error logging for timing results in cadmin_support module --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent 22a2794 commit 876fcf5

2 files changed

Lines changed: 319 additions & 42 deletions

File tree

src/python_testing/TC_CADMIN_1_3_4.py

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
# quiet: true
4545
# === END CI TEST ARGUMENTS ===
4646

47-
import asyncio
4847
import logging
4948
import random
5049
from time import sleep
@@ -73,7 +72,8 @@ async def combined_commission_val_steps(self, commission_type: str):
7372
setupPayloadInfo = self.get_setup_payload_info()
7473
if not setupPayloadInfo:
7574
asserts.assert_true(
76-
False, 'passcode and discriminator must be provided values in order for this test to work due to using BCM, please rerun test with providing --passcode <value> and --discriminator <value>')
75+
False,
76+
'passcode and discriminator must be provided values in order for this test to work due to using BCM, please rerun test with providing --passcode <value> and --discriminator <value>')
7777

7878
# Establishing TH1
7979
self.th1 = self.default_controller
@@ -179,61 +179,59 @@ async def combined_commission_val_steps(self, commission_type: str):
179179
await self.read_nl_attr(dut_node_id=self.dut_node_id, th=self.th2, attr_val=self.nl_attribute)
180180

181181
self.step(9)
182-
# TH_CR2 opens a commissioning window on DUT_CE for 180 seconds using ECM
183-
await self.th2.OpenCommissioningWindow(nodeid=self.dut_node_id, timeout=180, iteration=1000, discriminator=0, option=1)
184-
185-
self.step(10)
186-
sleep(181)
187-
188-
self.step(11)
189-
# TH_CR2 reads the window status to verify the DUT_CE window is closed
190-
# TODO: Issue noticed when initially attempting to check window status, issue is detailed here: https://github.com/project-chip/connectedhomeip/issues/35983
191-
# Workaround in place until above issue resolved
192-
try:
193-
window_status = await self.th2.ReadAttribute(nodeid=self.dut_node_id, attributes=[(0, Clusters.AdministratorCommissioning.Attributes.WindowStatus)])
194-
except asyncio.CancelledError:
195-
window_status = await self.th2.ReadAttribute(nodeid=self.dut_node_id, attributes=[(0, Clusters.AdministratorCommissioning.Attributes.WindowStatus)])
182+
# TH_CR2 opens a commissioning window on DUT_CE for 180 seconds using ECM and monitors until it closes
183+
params, window_status_accumulator = await self.open_commissioning_window_with_subscription_monitoring(
184+
th=self.th2,
185+
timeout=180,
186+
node_id=self.dut_node_id,
187+
discriminator=0,
188+
iteration=1000
189+
)
196190

197-
window_status = window_status[0]
198-
outer_key = list(window_status.keys())[0]
199-
inner_key = list(window_status[outer_key].keys())[1]
200-
if window_status[outer_key][inner_key] != Clusters.AdministratorCommissioning.Enums.CommissioningWindowStatusEnum.kWindowNotOpen:
201-
asserts.fail("Commissioning window is expected to be closed, but was found to be open")
191+
results = await self.monitor_commissioning_window_closure_with_subscription(
192+
th=self.th2,
193+
node_id=self.dut_node_id,
194+
expected_duration_seconds=180,
195+
window_status_accumulator=window_status_accumulator
196+
)
197+
asserts.assert_true(results.window_closed, "Window should have closed")
198+
asserts.assert_true(results.timing_valid, "Window should have closed within timing constraints")
202199

203-
self.step(12)
200+
self.step(10)
204201
# TH_CR2 opens a commissioning window on DUT_CE using ECM
205202
self.discriminator = random.randint(0, 4095)
206-
# params2 = await self.openCommissioningWindow(dev_ctrl=self.th2, node_id=self.dut_node_id)
207-
params2 = await self.th2.OpenCommissioningWindow(nodeid=self.dut_node_id, timeout=self.max_window_duration, iteration=1000, discriminator=1234, option=1)
203+
params2 = await self.th2.OpenCommissioningWindow(nodeid=self.dut_node_id, timeout=self.max_window_duration, iteration=1000, discriminator=self.discriminator, option=1)
208204

209-
self.step(13)
210-
# TH_CR1 starts a commissioning process with DUT_CE before the timeout from step 12
205+
self.step(11)
206+
# TH_CR1 starts a commissioning process with DUT_CE before the timeout from step 10
211207
try:
212208
await self.th1.CommissionOnNetwork(
213209
nodeId=self.dut_node_id, setupPinCode=params2.setupPinCode,
214-
filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=1234)
210+
filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=self.discriminator)
215211
except ChipStackError as e: # chipstack-ok: This disables ChipStackError linter check. Error occurs if a NOC for the fabric already exists, which may depend on device state. Can not use assert_raises because it not always fails
216-
asserts.assert_equal(e.err, 0x0000007E,
212+
asserts.assert_equal(e.err, 0x0000007E,
217213
"Expected to return Trying to add NOC for fabric that already exists")
218214
"""
219215
expected error:
220216
[2024-10-08 11:57:43.144125][TEST][STDOUT][MatterTest] 10-08 11:57:42.777 INFO Device returned status 9 on receiving the NOC
221217
[2024-10-08 11:57:43.144365][TEST][STDOUT][MatterTest] 10-08 11:57:42.777 INFO Add NOC failed with error src/controller/CHIPDeviceController.cpp:1712: CHIP Error 0x0000007E: Trying to add a NOC for a fabric that already exists
222218
"""
223219

224-
self.step(14)
220+
self.step(12)
225221
revokeCmd = Clusters.AdministratorCommissioning.Commands.RevokeCommissioning()
226222
await self.th1.SendCommand(nodeid=self.dut_node_id, endpoint=0, payload=revokeCmd, timedRequestTimeoutMs=6000)
227223
# The failsafe cleanup is scheduled after the command completes, so give it a bit of time to do that
228224
sleep(1)
229225

230226
if commission_type == "ECM":
231-
self.step(15)
227+
self.step(13)
232228

233229
elif commission_type == "BCM":
234230
self.step(7)
235231

236-
# TH_CR2 reads the CurrentFabricIndex attribute from the Operational Credentials cluster and saves as th2_idx, TH_CR1 sends the RemoveFabric command to the DUT with the FabricIndex set to th2_idx
232+
# TH_CR2 reads the CurrentFabricIndex attribute from the Operational
233+
# Credentials cluster and saves as th2_idx, TH_CR1 sends the RemoveFabric
234+
# command to the DUT with the FabricIndex set to th2_idx
237235
th2_idx = await self.th2.ReadAttribute(nodeid=self.dut_node_id, attributes=[(0, Clusters.OperationalCredentials.Attributes.CurrentFabricIndex)])
238236
outer_key = list(th2_idx.keys())[0]
239237
inner_key = list(th2_idx[outer_key].keys())[0]
@@ -263,17 +261,15 @@ def steps_TC_CADMIN_1_3(self) -> list[TestStep]:
263261
"Verify DUT_CE responds to both write/read with a success"),
264262
TestStep(8, "TH_CR2 reads, writes and then reads the Basic Information Cluster’s NodeLabel mandatory attribute of DUT_CE",
265263
"Verify the initial read reflect the value written in the above step. Verify DUT_CE responds to both write/read with a success"),
266-
TestStep(9, "TH_CR2 opens a commissioning window on DUT_CE for 180 seconds using ECM"),
267-
TestStep(10, "Wait for the commissioning window in step 9 to timeout"),
268-
TestStep(11, "TH_CR2 reads the window status to verify the DUT_CE window is closed",
269-
"DUT_CE windows status shows the window is closed"),
270-
TestStep(12, "TH_CR2 opens a commissioning window on DUT_CE using ECM",
264+
TestStep(9, "TH_CR2 opens a commissioning window on DUT_CE for 180 seconds using ECM and monitors until the window closes to verify window timing",
265+
"Verify that the window closed within the expected duration of 180 seconds + 1.8 seconds of clock skew"),
266+
TestStep(10, "TH_CR2 opens a commissioning window on DUT_CE using ECM",
271267
"DUT_CE opens its Commissioning window to allow a new commissioning"),
272-
TestStep(13, "TH_CR1 starts a commissioning process with DUT_CE before the timeout from step 12",
268+
TestStep(11, "TH_CR1 starts a commissioning process with DUT_CE before the timeout from step 10",
273269
"Since DUT_CE was already commissioned by TH_CR1 in step 1, AddNOC fails with NOCResponse with StatusCode field set to FabricConflict (9)"),
274-
TestStep(14, "TH_CR1 sends an RevokeCommissioning command to the DUT to cleanup step 13",
270+
TestStep(12, "TH_CR1 sends an RevokeCommissioning command to the DUT to cleanup step 11",
275271
"Successfully revoked commissioning"),
276-
TestStep(15, "TH_CR2 reads the CurrentFabricIndex attribute from the Operational Credentials cluster and saves as th2_idx, TH_CR1 sends the RemoveFabric command to the DUT with the FabricIndex set to th2_idx",
272+
TestStep(13, "TH_CR2 reads the CurrentFabricIndex attribute from the Operational Credentials cluster and saves as th2_idx, TH_CR1 sends the RemoveFabric command to the DUT with the FabricIndex set to th2_idx",
277273
"TH_CR1 removes TH_CR2 fabric using th2_idx")
278274
]
279275

@@ -303,7 +299,8 @@ def steps_TC_CADMIN_1_4(self) -> list[TestStep]:
303299
async def test_TC_CADMIN_1_3(self):
304300
await self.combined_commission_val_steps(commission_type="ECM")
305301

306-
@run_if_endpoint_matches(has_feature(cluster=Clusters.AdministratorCommissioning, feature=Clusters.AdministratorCommissioning.Bitmaps.Feature.kBasic))
302+
@run_if_endpoint_matches(has_feature(cluster=Clusters.AdministratorCommissioning,
303+
feature=Clusters.AdministratorCommissioning.Bitmaps.Feature.kBasic))
307304
async def test_TC_CADMIN_1_4(self):
308305
await self.combined_commission_val_steps(commission_type="BCM")
309306

0 commit comments

Comments
 (0)