@@ -4,7 +4,7 @@ import * as fs from "fs";
44import { fileURLToPath } from "url" ;
55import { createWebSocketServer } from "./ws-server.ts" ;
66import type { ManagedWebSocketServer } from "./ws-server.ts" ;
7- import { runTestCases , closeCTT , getTestCases } from "./ctt-client.ts" ;
7+ import { runTestCases , closeCTT , getTestCases , cancelTestRun } from "./ctt-client.ts" ;
88import { RunnerHost } from "./runner-host.ts" ;
99import { CTTDeviceProxy , type FrameHandler } from "./ctt-device-proxy.ts" ;
1010import c from "ansi-colors" ;
@@ -96,6 +96,7 @@ class ProcessManager {
9696 private wsServer ?: ManagedWebSocketServer ;
9797 private runnerHost ?: RunnerHost ;
9898 private deviceProxy ?: CTTDeviceProxy ;
99+ private isCleaningUp = false ;
99100
100101 /**
101102 * Load PID file data if it exists
@@ -242,7 +243,8 @@ class ProcessManager {
242243 } ) ;
243244
244245 proc . on ( "exit" , ( code ) => {
245- console . log ( `Z-Wave stack WSL process exited with code ${ code } ` ) ;
246+ console . error ( `Z-Wave stack WSL process exited with code ${ code } , aborting...` ) ;
247+ this . cleanup ( ) ;
246248 } ) ;
247249
248250 this . processes . push ( {
@@ -359,6 +361,7 @@ class ProcessManager {
359361
360362 this . runnerHost = new RunnerHost ( {
361363 runnerPath : DUT_PATH ,
364+ onUnexpectedExit : ( ) => this . cleanup ( ) ,
362365 } ) ;
363366
364367 // Initialize the runner (spawns process, waits for ready)
@@ -415,7 +418,8 @@ class ProcessManager {
415418 } ) ;
416419
417420 cttProcess . on ( "exit" , ( code ) => {
418- console . log ( `CTT-Remote exited with code ${ code } ` ) ;
421+ console . error ( `CTT-Remote exited with code ${ code } , aborting...` ) ;
422+ this . cleanup ( ) ;
419423 } ) ;
420424
421425 const managedProcess : ManagedProcess = {
@@ -670,8 +674,30 @@ class ProcessManager {
670674 }
671675
672676 async cleanup ( ) : Promise < void > {
677+ if ( this . isCleaningUp ) return ;
678+ this . isCleaningUp = true ;
679+
673680 console . log ( "Shutting down..." ) ;
674681
682+ // Cancel any running test and close CTT gracefully first
683+ try {
684+ await cancelTestRun ( ) ;
685+ // Wait for test to actually stop before trying to close
686+ await setTimeout ( 2000 ) ;
687+ } catch {
688+ // Ignore - test may not be running
689+ }
690+ try {
691+ await closeCTT ( ) ;
692+ } catch {
693+ // Ignore - CTT may already be closed
694+ }
695+
696+ // Close WebSocket server to stop incoming CTT messages
697+ if ( this . wsServer ) {
698+ await this . wsServer . close ( ) ;
699+ }
700+
675701 // Stop DUT runner
676702 await this . stopRunner ( ) ;
677703
@@ -692,11 +718,6 @@ class ProcessManager {
692718 // Ignore
693719 }
694720
695- // Close WebSocket server
696- if ( this . wsServer ) {
697- await this . wsServer . close ( ) ;
698- }
699-
700721 // Clean up PID file on successful shutdown
701722 this . deletePidFile ( ) ;
702723
0 commit comments