@@ -241,6 +241,10 @@ def cmd_list(context: click.Context) -> None:
241241 print ("%s%s" % (test .name , tags ))
242242
243243
244+ class Terminatable (typing .Protocol ):
245+ def terminate (self ) -> None : ...
246+
247+
244248@main .command (
245249 'run' , help = 'Execute the tests' )
246250@click .option (
@@ -414,90 +418,94 @@ def build_app(arg_value: Path | None, kind: SubprocessKind, key: str) -> Subproc
414418
415419 ble_controller_app = None
416420 ble_controller_tool = None
417-
418- if sys .platform == 'linux' :
419- ns = chiptest .linux .IsolatedNetworkNamespace (
420- index = 0 ,
421- # Do not bring up the app interface link automatically when doing BLE-WiFi commissioning.
422- setup_app_link_up = not ble_wifi ,
423- # Change the app link name so the interface will be recognized as WiFi or Ethernet
424- # depending on the commissioning method used.
425- app_link_name = 'wlx-app' if ble_wifi else 'eth-app' ,
426- unshared = context .obj .in_unshare )
427-
428- if ble_wifi :
429- bus = chiptest .linux .DBusTestSystemBus ()
430- bluetooth = chiptest .linux .BluetoothMock ()
431- wifi = chiptest .linux .WpaSupplicantMock ("MatterAP" , "MatterAPPassword" , ns )
432- ble_controller_app = 0 # Bind app to the first BLE controller
433- ble_controller_tool = 1 # Bind tool to the second BLE controller
434-
435- executor = chiptest .linux .LinuxNamespacedExecutor (ns )
436- elif sys .platform == 'darwin' :
437- executor = chiptest .darwin .DarwinExecutor ()
438- else :
439- log .warning ("No platform-specific executor for '%s'" , sys .platform )
440- executor = Executor ()
441-
442- runner = chiptest .runner .Runner (executor = executor )
443-
444- log .info ("Each test will be executed %d times" , iterations )
445-
446- apps_register = AppsRegister ()
447- apps_register .init ()
421+ to_terminate : list [Terminatable ] = []
448422
449423 def cleanup () -> None :
450- apps_register .uninit ()
424+ for item in reversed (to_terminate ):
425+ try :
426+ log .info ("Cleaning up %s" , item .__class__ .__name__ )
427+ item .terminate ()
428+ except Exception as e :
429+ log .error ("Encountered error during cleanup: %s" , e , exc_info = True )
430+
431+ try :
451432 if sys .platform == 'linux' :
433+ to_terminate .append (ns := chiptest .linux .IsolatedNetworkNamespace (
434+ index = 0 ,
435+ # Do not bring up the app interface link automatically when doing BLE-WiFi commissioning.
436+ setup_app_link_up = not ble_wifi ,
437+ # Change the app link name so the interface will be recognized as WiFi or Ethernet
438+ # depending on the commissioning method used.
439+ app_link_name = 'wlx-app' if ble_wifi else 'eth-app' ,
440+ unshared = context .obj .in_unshare , wait_for_dad = False ))
441+ ns .wait_for_duplicate_address_detection ()
442+
452443 if ble_wifi :
453- wifi .terminate ()
454- bluetooth .terminate ()
455- bus .terminate ()
456- ns .terminate ()
457-
458- for i in range (iterations ):
459- log .info ("Starting iteration %d" , i + 1 )
460- observed_failures = 0
461- for test in context .obj .tests :
462- if context .obj .include_tags :
463- if not (test .tags & context .obj .include_tags ):
464- log .debug ("Test '%s' not included" , test .name )
465- continue
466-
467- if context .obj .exclude_tags :
468- if test .tags & context .obj .exclude_tags :
469- log .debug ("Test '%s' excluded" , test .name )
470- continue
471-
472- test_start = time .monotonic ()
473- try :
474- if context .obj .dry_run :
475- log .info ("Would run test: '%s'" , test .name )
476- else :
477- log .info ("%-20s - Starting test" , test .name )
478- test .Run (
479- runner , apps_register , paths , pics_file , test_timeout_seconds , context .obj .dry_run ,
480- test_runtime = context .obj .runtime ,
481- ble_controller_app = ble_controller_app ,
482- ble_controller_tool = ble_controller_tool ,
483- )
484- if not context .obj .dry_run :
444+ to_terminate .append (chiptest .linux .DBusTestSystemBus ())
445+ to_terminate .append (chiptest .linux .BluetoothMock ())
446+ to_terminate .append (chiptest .linux .WpaSupplicantMock ("MatterAP" , "MatterAPPassword" , ns ))
447+ ble_controller_app = 0 # Bind app to the first BLE controller
448+ ble_controller_tool = 1 # Bind tool to the second BLE controller
449+
450+ executor = chiptest .linux .LinuxNamespacedExecutor (ns )
451+ elif sys .platform == 'darwin' :
452+ executor = chiptest .darwin .DarwinExecutor ()
453+ else :
454+ log .warning ("No platform-specific executor for '%s'" , sys .platform )
455+ executor = Executor ()
456+
457+ runner = chiptest .runner .Runner (executor = executor )
458+
459+ log .info ("Each test will be executed %d times" , iterations )
460+
461+ to_terminate .append (apps_register := AppsRegister ())
462+ apps_register .init ()
463+
464+ for i in range (iterations ):
465+ log .info ("Starting iteration %d" , i + 1 )
466+ observed_failures = 0
467+ for test in context .obj .tests :
468+ if context .obj .include_tags :
469+ if not (test .tags & context .obj .include_tags ):
470+ log .debug ("Test '%s' not included" , test .name )
471+ continue
472+
473+ if context .obj .exclude_tags :
474+ if test .tags & context .obj .exclude_tags :
475+ log .debug ("Test '%s' excluded" , test .name )
476+ continue
477+
478+ test_start = time .monotonic ()
479+ try :
480+ if context .obj .dry_run :
481+ log .info ("Would run test: '%s'" , test .name )
482+ else :
483+ log .info ("%-20s - Starting test" , test .name )
484+ test .Run (
485+ runner , apps_register , paths , pics_file , test_timeout_seconds , context .obj .dry_run ,
486+ test_runtime = context .obj .runtime ,
487+ ble_controller_app = ble_controller_app ,
488+ ble_controller_tool = ble_controller_tool ,
489+ )
490+ if not context .obj .dry_run :
491+ test_end = time .monotonic ()
492+ log .info ("%-30s - Completed in %0.2f seconds" , test .name , test_end - test_start )
493+ except Exception :
485494 test_end = time .monotonic ()
486- log .info ("%-30s - Completed in %0.2f seconds" , test .name , test_end - test_start )
487- except Exception :
488- test_end = time .monotonic ()
489- log .exception ("%-30s - FAILED in %0.2f seconds" , test .name , test_end - test_start )
490- observed_failures += 1
491- if not keep_going :
492- cleanup ()
493- sys .exit (2 )
494-
495- if observed_failures != expected_failures :
496- log .error ("Iteration %d: expected failure count %d, but got %d" , i , expected_failures , observed_failures )
497- cleanup ()
498- sys .exit (2 )
499-
500- cleanup ()
495+ log .exception ("%-30s - FAILED in %0.2f seconds" , test .name , test_end - test_start )
496+ observed_failures += 1
497+ if not keep_going :
498+ cleanup ()
499+ sys .exit (2 )
500+
501+ if observed_failures != expected_failures :
502+ log .error ("Iteration %d: expected failure count %d, but got %d" , i , expected_failures , observed_failures )
503+ cleanup ()
504+ sys .exit (2 )
505+ except KeyboardInterrupt :
506+ log .info ("Interrupting execution on user request" )
507+ finally :
508+ cleanup ()
501509
502510
503511# On Linux, allow an execution shell to be prepared
0 commit comments