@@ -9,6 +9,8 @@ namespace Harness.Parallel.Host {
99 on ( event : "error" , listener : ( err : Error ) => void ) : this;
1010 on ( event : "exit" , listener : ( code : number , signal : string ) => void ) : this;
1111 on ( event : "message" , listener : ( message : ParallelClientMessage ) => void ) : this;
12+ kill ( signal ?: string ) : void ;
13+ currentTasks ?: { file : string } [ ] ; // Custom monkeypatch onto child process handle
1214 }
1315
1416 interface ProgressBarsOptions {
@@ -134,13 +136,26 @@ namespace Harness.Parallel.Host {
134136 const newPerfData : { [ testHash : string ] : number } = { } ;
135137
136138 const workers : ChildProcessPartial [ ] = [ ] ;
139+ const defaultTimeout = globalTimeout !== undefined
140+ ? globalTimeout
141+ : mocha && mocha . suite && mocha . suite . _timeout
142+ ? mocha . suite . _timeout
143+ : 20000 ; // 20 seconds
137144 let closedWorkers = 0 ;
138145 for ( let i = 0 ; i < workerCount ; i ++ ) {
139146 // TODO: Just send the config over the IPC channel or in the command line arguments
140147 const config : TestConfig = { light : Harness . lightMode , listenForWork : true , runUnitTests } ;
141148 const configPath = ts . combinePaths ( taskConfigsFolder , `task-config${ i } .json` ) ;
142149 Harness . IO . writeFile ( configPath , JSON . stringify ( config ) ) ;
143150 const child = fork ( __filename , [ `--config="${ configPath } "` ] ) ;
151+ let currentTimeout = defaultTimeout ;
152+ const killChild = ( ) => {
153+ child . kill ( ) ;
154+ console . error ( `Worker exceeded timeout ${ child . currentTasks && child . currentTasks . length ? `while running test '${ child . currentTasks [ 0 ] . file } '.` : `during test setup.` } ` ) ;
155+ return process . exit ( 2 ) ;
156+ } ;
157+ let timer = setTimeout ( killChild , currentTimeout ) ;
158+ const timeoutStack : number [ ] = [ ] ;
144159 child . on ( "error" , err => {
145160 console . error ( "Unexpected error in child process:" ) ;
146161 console . error ( err ) ;
@@ -160,8 +175,23 @@ namespace Harness.Parallel.Host {
160175 Stack: ${ data . payload . stack } ` ) ;
161176 return process . exit ( 2 ) ;
162177 }
178+ case "timeout" : {
179+ if ( data . payload . duration === "reset" ) {
180+ currentTimeout = timeoutStack . pop ( ) || defaultTimeout ;
181+ }
182+ else {
183+ timeoutStack . push ( currentTimeout ) ;
184+ currentTimeout = data . payload . duration ;
185+ }
186+ break ;
187+ }
163188 case "progress" :
164189 case "result" : {
190+ clearTimeout ( timer ) ;
191+ timer = setTimeout ( killChild , currentTimeout ) ;
192+ if ( child . currentTasks ) {
193+ child . currentTasks . shift ( ) ;
194+ }
165195 totalPassing += data . payload . passing ;
166196 if ( data . payload . errors . length ) {
167197 errorResults = errorResults . concat ( data . payload . errors ) ;
@@ -195,6 +225,7 @@ namespace Harness.Parallel.Host {
195225 while ( tasks . length && taskList . reduce ( ( p , c ) => p + c . size , 0 ) < chunkSize ) {
196226 taskList . push ( tasks . pop ( ) ) ;
197227 }
228+ child . currentTasks = taskList ;
198229 if ( taskList . length === 1 ) {
199230 child . send ( { type : "test" , payload : taskList [ 0 ] } ) ;
200231 }
@@ -252,18 +283,22 @@ namespace Harness.Parallel.Host {
252283 for ( const worker of workers ) {
253284 const payload = batches . pop ( ) ;
254285 if ( payload ) {
286+ worker . currentTasks = payload ;
255287 worker . send ( { type : "batch" , payload } ) ;
256288 }
257289 else { // Out of batches, send off just one test
258290 const payload = tasks . pop ( ) ;
259291 ts . Debug . assert ( ! ! payload ) ; // The reserve kept above should ensure there is always an initial task available, even in suboptimal scenarios
292+ worker . currentTasks = [ payload ] ;
260293 worker . send ( { type : "test" , payload } ) ;
261294 }
262295 }
263296 }
264297 else {
265298 for ( let i = 0 ; i < workerCount ; i ++ ) {
266- workers [ i ] . send ( { type : "test" , payload : tasks . pop ( ) } ) ;
299+ const task = tasks . pop ( ) ;
300+ workers [ i ] . currentTasks = [ task ] ;
301+ workers [ i ] . send ( { type : "test" , payload : task } ) ;
267302 }
268303 }
269304
0 commit comments