38
38
from chip .clusters import ClusterObjects as ClusterObjects
39
39
from chip .clusters .Attribute import EventReadResult
40
40
from chip .tlv import uint
41
- from matter_testing_support import (ClusterAttributeChangeAccumulator , EventChangeCallback , MatterBaseTest , TestStep ,
42
- await_sequence_of_reports , default_matter_test_main , has_feature , per_endpoint_test )
41
+ from matter_testing_support import (AttributeValue , ClusterAttributeChangeAccumulator , EventChangeCallback , MatterBaseTest ,
42
+ TestStep , await_sequence_of_reports , default_matter_test_main , has_feature , per_endpoint_test )
43
43
from mobly import asserts
44
44
45
45
logger = logging .getLogger (__name__ )
@@ -70,6 +70,10 @@ def __init__(self, *args, **kwargs):
70
70
super ().__init__ (* args , ** kwargs )
71
71
self ._default_pressed_position = self .user_params .get ("default_pressed_position" , 1 )
72
72
73
+ def setup_test (self ):
74
+ super ().setup_test ()
75
+ self .is_ci = self ._use_button_simulator ()
76
+
73
77
def _send_named_pipe_command (self , command_dict : dict [str , Any ]):
74
78
app_pid = self .matter_test_config .app_pid
75
79
if app_pid == 0 :
@@ -259,32 +263,39 @@ def _received_event(self, event_listener: EventChangeCallback, target_event: Clu
259
263
260
264
def steps_TC_SWTCH_2_2 (self ):
261
265
return [TestStep (1 , test_plan_support .commission_if_required (), "" , is_commissioning = True ),
262
- TestStep (2 , "Set up subscription to all events of Switch cluster on the endpoint" ),
266
+ TestStep (2 , "Set up subscription to all events and attributes of Switch cluster on the endpoint" ),
263
267
TestStep (3 , "Operator sets switch to first position on the DUT" ),
264
- TestStep (4 , "TH reads the CurrentPosition attribute from the DUT" , "Verify that the value is 0" ),
268
+ TestStep (4 , "TH reads the CurrentPosition attribute from the DUT. " , "Verify that the value is 0. " ),
265
269
TestStep (5 , "Operator sets switch to second position (one) on the DUT" ,
266
- "Verify that the TH receives SwitchLatched event with NewPosition set to 1 from the DUT" ),
267
- TestStep (6 , "TH reads the CurrentPosition attribute from the DUT" , "Verify that the value is 1" ),
270
+ "Verify that the TH receives SwitchLatched event with NewPosition set to 1 from the DUT." ),
271
+ TestStep (6 , "TH reads the CurrentPosition attribute from the DUT" ,
272
+ "Verify that the value is 1, and that a subscription report was received for that change." ),
268
273
TestStep (7 , "If there are more than 2 positions, test subsequent positions of the DUT" ),
269
274
TestStep (8 , "Operator sets switch to first position on the DUT." ),
270
275
TestStep (9 , "Wait 10 seconds for event reports stable." "Verify that last SwitchLatched event received is for NewPosition 0." ),
271
- TestStep (10 , "TH reads the CurrentPosition attribute from the DUT" , "Verify that the value is 0" ),
276
+ TestStep (10 , "TH reads the CurrentPosition attribute from the DUT" ,
277
+ "Verify that the value is 0, and that a subscription report was received for that change." ),
272
278
]
273
279
274
280
@per_endpoint_test (has_feature (Clusters .Switch , Clusters .Switch .Bitmaps .Feature .kLatchingSwitch ))
275
281
async def test_TC_SWTCH_2_2 (self ):
276
282
post_prompt_settle_delay_seconds = 10.0
283
+ cluster = Clusters .Switch
284
+ endpoint_id = self .matter_test_config .endpoint
277
285
278
286
# Step 1: Commissioning - already done
279
287
self .step (1 )
280
288
281
- cluster = Clusters .Switch
282
- endpoint_id = self .matter_test_config .endpoint
283
-
284
289
# Step 2: Set up subscription to all events of Switch cluster on the endpoint.
285
290
self .step (2 )
286
291
event_listener = EventChangeCallback (cluster )
287
292
await event_listener .start (self .default_controller , self .dut_node_id , endpoint = endpoint_id )
293
+ attrib_listener = ClusterAttributeChangeAccumulator (cluster )
294
+ await attrib_listener .start (self .default_controller , self .dut_node_id , endpoint = endpoint_id )
295
+
296
+ # Pre-get number of positions for step 7 later.
297
+ num_positions = await self .read_single_attribute_check_success (cluster = cluster , attribute = cluster .Attributes .NumberOfPositions )
298
+ asserts .assert_greater (num_positions , 1 , "Latching switch has only 1 position, this is impossible." )
288
299
289
300
# Step 3: Operator sets switch to first position on the DUT.
290
301
self .step (3 )
@@ -296,25 +307,39 @@ async def test_TC_SWTCH_2_2(self):
296
307
button_val = await self .read_single_attribute_check_success (cluster = cluster , attribute = cluster .Attributes .CurrentPosition )
297
308
asserts .assert_equal (button_val , 0 , "Switch position value is not 0" )
298
309
299
- # Step 5: Operator sets switch to second position (one) on the DUT",
300
- # Verify that the TH receives SwitchLatched event with NewPosition set to 1 from the DUT
301
- self .step (5 )
302
- expected_switch_position = 1
303
- self ._ask_for_switch_position (endpoint_id , expected_switch_position )
304
-
305
- data = event_listener .wait_for_event_report (cluster .Events .SwitchLatched , timeout_sec = post_prompt_settle_delay_seconds )
306
- logging .info (f"-> SwitchLatched event last received: { data } " )
307
- asserts .assert_equal (data , cluster .Events .SwitchLatched (
308
- newPosition = expected_switch_position ), "Did not get expected switch position" )
309
-
310
- # Step 6: TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 1
311
- self .step (6 )
312
- button_val = await self .read_single_attribute_check_success (cluster = cluster , attribute = cluster .Attributes .CurrentPosition )
313
- asserts .assert_equal (button_val , expected_switch_position , f"Switch position is not { expected_switch_position } " )
314
-
315
- # Step 7: If there are more than 2 positions, test subsequent positions of the DUT
316
- # # TODO(#34656): Implement loop for > 2 total positions
317
- self .skip_step (7 )
310
+ attrib_listener .reset ()
311
+ event_listener .reset ()
312
+
313
+ for expected_switch_position in range (1 , num_positions ):
314
+ # Step 5: Operator sets switch to second position (one) on the DUT",
315
+ # Verify that the TH receives SwitchLatched event with NewPosition set to 1 from the DUT
316
+ if expected_switch_position == 1 :
317
+ self .step (5 )
318
+ self ._ask_for_switch_position (endpoint_id , expected_switch_position )
319
+
320
+ data = event_listener .wait_for_event_report (cluster .Events .SwitchLatched , timeout_sec = post_prompt_settle_delay_seconds )
321
+ logging .info (f"-> SwitchLatched event last received: { data } " )
322
+ asserts .assert_equal (data , cluster .Events .SwitchLatched (
323
+ newPosition = expected_switch_position ), "Did not get expected switch position" )
324
+
325
+ # Step 6: TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 1
326
+ if expected_switch_position == 1 : # Indicate step 7 only once
327
+ self .step (6 )
328
+ button_val = await self .read_single_attribute_check_success (cluster = cluster , attribute = cluster .Attributes .CurrentPosition )
329
+ asserts .assert_equal (button_val , expected_switch_position , f"Switch position is not { expected_switch_position } " )
330
+ logging .info (f"Checking to see if a report for { expected_switch_position } is received" )
331
+ attrib_listener .await_sequence_of_reports (attribute = cluster .Attributes .CurrentPosition , sequence = [
332
+ expected_switch_position ], timeout_sec = post_prompt_settle_delay_seconds )
333
+
334
+ # Step 7: If there are more than 2 positions, test subsequent positions of the DUT
335
+ if expected_switch_position == 1 :
336
+ if num_positions > 2 : # Indicate step 7 only once
337
+ self .step (7 )
338
+ else :
339
+ self .skip_step (7 )
340
+
341
+ if num_positions > 2 :
342
+ logging .info ("Looping for the other positions" )
318
343
319
344
# Step 8: Operator sets switch to first position on the DUT.
320
345
self .step (8 )
@@ -324,7 +349,7 @@ async def test_TC_SWTCH_2_2(self):
324
349
# Step 9: Wait 10 seconds for event reports stable.
325
350
# Verify that last SwitchLatched event received is for NewPosition 0.
326
351
self .step (9 )
327
- time .sleep (10.0 )
352
+ time .sleep (10.0 if not self . is_ci else 1.0 )
328
353
329
354
expected_switch_position = 0
330
355
last_event = event_listener .get_last_event ()
@@ -337,15 +362,21 @@ async def test_TC_SWTCH_2_2(self):
337
362
# Step 10: TH reads the CurrentPosition attribute from the DUT.
338
363
# Verify that the value is 0
339
364
self .step (10 )
365
+
340
366
button_val = await self .read_single_attribute_check_success (cluster = cluster , attribute = cluster .Attributes .CurrentPosition )
341
367
asserts .assert_equal (button_val , 0 , "Button value is not 0" )
342
368
369
+ logging .info (f"Checking to see if a report for { expected_switch_position } is received" )
370
+ expected_final_value = [AttributeValue (
371
+ endpoint_id , attribute = cluster .Attributes .CurrentPosition , value = expected_switch_position )]
372
+ attrib_listener .await_all_final_values_reported (expected_final_value , timeout_sec = post_prompt_settle_delay_seconds )
373
+
343
374
def steps_TC_SWTCH_2_3 (self ):
344
375
return [TestStep (1 , test_plan_support .commission_if_required (), "" , is_commissioning = True ),
345
376
TestStep (2 , "Set up subscription to all events of Switch cluster on the endpoint" ),
346
377
TestStep (3 , "Operator does not operate switch on the DUT" ),
347
378
TestStep (4 , "TH reads the CurrentPosition attribute from the DUT" , "Verify that the value is 0" ),
348
- TestStep (5 , "Operator operates switch (keep it pressed)" ,
379
+ TestStep (5 , "Operator operates switch (keep it pressed, and wait at least 5 seconds )" ,
349
380
"Verify that the TH receives InitialPress event with NewPosition set to 1 on the DUT" ),
350
381
TestStep (6 , "TH reads the CurrentPosition attribute from the DUT" , "Verify that the value is 1" ),
351
382
TestStep (7 , "Operator releases switch on the DUT" ),
@@ -421,15 +452,15 @@ def desc_TC_SWTCH_2_4(self) -> str:
421
452
422
453
def steps_TC_SWTCH_2_4 (self ):
423
454
return [TestStep (1 , test_plan_support .commission_if_required (), "" , is_commissioning = True ),
424
- TestStep (2 , "Set up subscription to all events of Switch cluster on the endpoint" ),
455
+ TestStep (2 , "Set up subscription to all events and attributes of Switch cluster on the endpoint" ),
425
456
TestStep (3 , "Operator does not operate switch on the DUT" ),
426
457
TestStep (4 , "TH reads the CurrentPosition attribute from the DUT" , "Verify that the value is 0" ),
427
- TestStep (5 , "Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT, the release it" ,
458
+ TestStep (5 , "Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT, then release it" ,
428
459
"""
429
460
* TH expects receiving a subscription report of CurrentPosition 1, followed by a report of Current Position 0.
430
461
* TH expects receiving at InitialPress event with NewPosition = 1.
431
- * if MSL or AS feature is supported, TH expect receiving LongPress/LongRelease in that order.
432
- * if MS & (!MSL & !AS & !MSR) features present, TH expects receiving no further events for 10 seconds after release.
462
+ * if MSL feature is supported, TH expect receiving LongPress/LongRelease in that order.
463
+ * if MS & (!MSL & !AS & !MSR & !MSM ) features present, TH expects receiving no further events for 10 seconds after release.
433
464
* if (MSR & !MSL) features present, TH expects receiving ShortRelease event.
434
465
""" )
435
466
]
@@ -451,17 +482,18 @@ async def test_TC_SWTCH_2_4(self):
451
482
has_ms_feature = (feature_map & cluster .Bitmaps .Feature .kMomentarySwitch ) != 0
452
483
has_msr_feature = (feature_map & cluster .Bitmaps .Feature .kMomentarySwitchRelease ) != 0
453
484
has_msl_feature = (feature_map & cluster .Bitmaps .Feature .kMomentarySwitchLongPress ) != 0
485
+ has_msm_feature = (feature_map & cluster .Bitmaps .Feature .kMomentarySwitchMultiPress ) != 0
454
486
has_as_feature = (feature_map & cluster .Bitmaps .Feature .kActionSwitch ) != 0
455
487
456
488
if not has_ms_feature :
457
489
logging .info ("Skipping rest of test: SWTCH.S.F01(MS) feature not present" )
458
490
self .skip_all_remaining_steps ("2" )
459
491
460
- # Step 2: Set up subscription to all events of Switch cluster on the endpoint
492
+ # Step 2: Set up subscription to all events and attributes of Switch cluster on the endpoint
461
493
self .step (2 )
462
494
event_listener = EventChangeCallback (cluster )
463
- attrib_listener = ClusterAttributeChangeAccumulator (cluster )
464
495
await event_listener .start (self .default_controller , self .dut_node_id , endpoint = endpoint_id )
496
+ attrib_listener = ClusterAttributeChangeAccumulator (cluster )
465
497
await attrib_listener .start (self .default_controller , self .dut_node_id , endpoint = endpoint_id )
466
498
467
499
# Step 3: Operator does not operate switch on the DUT
@@ -503,8 +535,8 @@ async def test_TC_SWTCH_2_4(self):
503
535
self ._await_sequence_of_events (event_queue = event_listener .event_queue , endpoint_id = endpoint_id ,
504
536
sequence = expected_events , timeout_sec = post_prompt_settle_delay_seconds )
505
537
506
- # - if MS & (!MSL & !AS & !MSR) features present, expect no further events for 10 seconds after release.
507
- if not has_msl_feature and not has_as_feature and not has_msr_feature :
538
+ # - if MS & (!MSL & !AS & !MSR & !MSM ) features present, expect no further events for 10 seconds after release.
539
+ if not has_msl_feature and not has_as_feature and not has_msr_feature and not has_msm_feature :
508
540
self ._expect_no_events_for_cluster (event_queue = event_listener .event_queue ,
509
541
endpoint_id = endpoint_id , expected_cluster = cluster , timeout_sec = 10.0 )
510
542
0 commit comments