Skip to content

Commit 1ef89ea

Browse files
authored
Merge pull request #9 from KyleKincer/codex/fix-double-waiting-on-per-worker-signals
Refactor parallel runner waiting
2 parents 1a21f3c + 9d3e03f commit 1ef89ea

File tree

1 file changed

+69
-77
lines changed

1 file changed

+69
-77
lines changed

testing/Project/Sources/Classes/ParallelTestRunner.4dm

Lines changed: 69 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,20 @@ Class extends TestRunner
44
property parallelMode : Boolean
55
property maxWorkers : Integer
66
property workerProcesses : Collection // Collection of worker process names
7+
property workerSignals : Collection // Signals for worker completion
78
property sharedResults : Object // Shared storage for collecting results
89
property completedSuites : Integer // Counter for completed suites
910
property sequentialSuites : Collection // Suites that opted out of parallel execution
1011

1112
Class constructor($cs : 4D:C1709.Object)
1213
Super:C1705($cs)
1314
This:C1470.parallelMode:=False:C215
14-
This:C1470.maxWorkers:=This:C1470._getDefaultWorkerCount()
15-
This:C1470.workerProcesses:=[]
16-
This:C1470.completedSuites:=0
17-
This:C1470.sequentialSuites:=[]
18-
This:C1470._parseParallelOptions()
15+
This:C1470.maxWorkers:=This:C1470._getDefaultWorkerCount()
16+
This:C1470.workerProcesses:=[]
17+
This:C1470.workerSignals:=[]
18+
This:C1470.completedSuites:=0
19+
This:C1470.sequentialSuites:=[]
20+
This:C1470._parseParallelOptions()
1921

2022
Function run()
2123
If (This:C1470.parallelMode)
@@ -148,63 +150,39 @@ Function _executeTestSuitesInParallel()
148150
End if
149151
End for each
150152

151-
// Run parallel suites in workers with signals
152-
var $workerSignals : Collection
153-
$workerSignals:=[]
154-
var $parallelSuiteIndex : Integer
155-
$parallelSuiteIndex:=0
156-
157-
For each ($testSuite; $parallelSuites)
158-
$workerName:=This:C1470.workerProcesses[$parallelSuiteIndex % $workerCount]
159-
160-
// Create a signal for this worker task
161-
var $signal : 4D:C1709.Signal
162-
$signal:=New signal:C1641
163-
$workerSignals.push($signal)
164-
165-
// Send test suite to worker via CALL WORKER with signal
166-
var $suiteData : Object
167-
$suiteData:=New object:C1471(\
168-
"class"; $testSuite.class; \
169-
"outputFormat"; $testSuite.outputFormat; \
170-
"testPatterns"; $testSuite.testPatterns; \
171-
"testRunner"; This:C1470; \
172-
"suiteIndex"; $parallelSuiteIndex; \
173-
"signal"; $signal\
174-
)
175-
176-
CALL WORKER:C1389($workerName; "ParallelTestWorker"; "ExecuteTestSuite"; $suiteData)
177-
$parallelSuiteIndex:=$parallelSuiteIndex+1
178-
End for each
179-
180-
// Wait for all workers to complete and collect results
181-
var $workerSignal : 4D:C1709.Signal
182-
For each ($workerSignal; $workerSignals)
183-
// Wait with timeout to avoid hanging
184-
var $signaled : Boolean
185-
$signaled:=$workerSignal.wait(5) // 5 second timeout
186-
187-
If ($signaled)
188-
// Collect detailed results from the signal and display them
189-
If ($workerSignal.suiteResults#Null:C1517)
190-
This:C1470._processWorkerResults($workerSignal.suiteResults)
191-
Else
192-
If (This:C1470.outputFormat="human")
193-
LOG EVENT:C667(Into system standard outputs:K38:9; "Warning: Worker completed but no results received\r\n"; Information message:K38:1)
194-
End if
195-
End if
196-
Else
197-
If (This:C1470.outputFormat="human")
198-
LOG EVENT:C667(Into system standard outputs:K38:9; "Warning: Worker timeout after 5 seconds\r\n"; Error message:K38:3)
199-
End if
200-
End if
201-
End for each
202-
203-
// Run sequential suites in main process after parallel ones complete
204-
If ($sequentialSuites.length>0)
205-
// These will be run after parallel completion in _waitForCompletionAndCollectResults
206-
This:C1470.sequentialSuites:=$sequentialSuites
207-
End if
153+
// Run parallel suites in workers and store signals
154+
This:C1470.workerSignals:=New collection:C1472
155+
var $parallelSuiteIndex : Integer
156+
$parallelSuiteIndex:=0
157+
158+
For each ($testSuite; $parallelSuites)
159+
$workerName:=This:C1470.workerProcesses[$parallelSuiteIndex % $workerCount]
160+
161+
// Create a signal for this worker task
162+
var $signal : 4D:C1709.Signal
163+
$signal:=New signal:C1641
164+
This:C1470.workerSignals.push($signal)
165+
166+
// Send test suite to worker via CALL WORKER with signal
167+
var $suiteData : Object
168+
$suiteData:=New object:C1471(\
169+
"class"; $testSuite.class; \
170+
"outputFormat"; $testSuite.outputFormat; \
171+
"testPatterns"; $testSuite.testPatterns; \
172+
"testRunner"; This:C1470; \
173+
"suiteIndex"; $parallelSuiteIndex; \
174+
"signal"; $signal\
175+
)
176+
177+
CALL WORKER:C1389($workerName; "ParallelTestWorker"; "ExecuteTestSuite"; $suiteData)
178+
$parallelSuiteIndex:=$parallelSuiteIndex+1
179+
End for each
180+
181+
// Run sequential suites in main process after parallel ones complete
182+
If ($sequentialSuites.length>0)
183+
// These will be run after parallel completion in _waitForCompletionAndCollectResults
184+
This:C1470.sequentialSuites:=$sequentialSuites
185+
End if
208186

209187
Function _waitForCompletionAndCollectResults()
210188
// Wait for parallel test suites to complete
@@ -217,11 +195,11 @@ Function _waitForCompletionAndCollectResults()
217195

218196
$parallelSuiteCount:=$totalSuites-This:C1470.sequentialSuites.length
219197

220-
If ($parallelSuiteCount>0)
221-
var $startWait : Integer
222-
$startWait:=Milliseconds:C459
223-
var $timeout : Integer
224-
$timeout:=300000 // 5 minute timeout
198+
If ($parallelSuiteCount>0)
199+
var $startWait : Integer
200+
$startWait:=Milliseconds:C459
201+
var $timeout : Integer
202+
$timeout:=300000 // 5 minute timeout
225203

226204
var $completedCount : Integer
227205
$completedCount:=0
@@ -238,14 +216,17 @@ Function _waitForCompletionAndCollectResults()
238216
End if
239217

240218
DELAY PROCESS:C323(Current process:C322; 10) // Wait 10 ticks
241-
End while
242-
243-
End if
244-
245-
// Run sequential suites in main process
246-
If (This:C1470.sequentialSuites.length>0)
247-
If (This:C1470.outputFormat="human")
248-
LOG EVENT:C667(Into system standard outputs:K38:9; "Running "+String:C10(This:C1470.sequentialSuites.length)+" sequential test suite(s)\r\n"; Information message:K38:1)
219+
End while
220+
221+
End if
222+
223+
// Collect results from worker signals
224+
This:C1470._aggregateParallelResults()
225+
226+
// Run sequential suites in main process
227+
If (This:C1470.sequentialSuites.length>0)
228+
If (This:C1470.outputFormat="human")
229+
LOG EVENT:C667(Into system standard outputs:K38:9; "Running "+String:C10(This:C1470.sequentialSuites.length)+" sequential test suite(s)\r\n"; Information message:K38:1)
249230
End if
250231

251232
var $testSuite : cs:C1710._TestSuite
@@ -310,8 +291,19 @@ Function _processWorkerResults($suiteResults : Object)
310291
End if
311292

312293
Function _aggregateParallelResults()
313-
// Results are already processed by _processWorkerResults, this method is now just a placeholder
314-
// The individual test processing happens in _processWorkerResults for consistent output
294+
// Process results from all worker signals after completion
295+
If (This:C1470.workerSignals#Null:C1517)
296+
var $workerSignal : 4D:C1709.Signal
297+
For each ($workerSignal; This:C1470.workerSignals)
298+
If ($workerSignal.suiteResults#Null:C1517)
299+
This:C1470._processWorkerResults($workerSignal.suiteResults)
300+
Else
301+
If (This:C1470.outputFormat="human")
302+
LOG EVENT:C667(Into system standard outputs:K38:9; "Warning: Worker completed but no results received\r\n"; Information message:K38:1)
303+
End if
304+
End if
305+
End for each
306+
End if
315307

316308
Function _cleanupSharedStorage()
317309
// Clean up shared storage

0 commit comments

Comments
 (0)