This repository has been archived by the owner on May 20, 2021. It is now read-only.
/
parallel_test_case_runner_master.go
83 lines (77 loc) · 2.62 KB
/
parallel_test_case_runner_master.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package runner
import (
dto "github.com/cucumber/cucumber-engine/src/dto"
messages "github.com/cucumber/cucumber-messages-go/v3"
)
type runNextTestCaseResult struct {
err error
testCaseResult *messages.TestResult
}
type parallelTestCaseRunnerMaster struct {
baseDirectory string
nextPickleIndex int
pickles []*messages.Pickle
runtimeConfig *messages.RuntimeConfig
sendCommand func(*messages.Envelope)
sendCommandAndAwaitResponse func(*messages.Envelope) *messages.Envelope
supportCodeLibrary *SupportCodeLibrary
}
func newParallelTestCaseRunnerMaster(opts *runTestCasesOptions) *parallelTestCaseRunnerMaster {
return ¶llelTestCaseRunnerMaster{
baseDirectory: opts.baseDirectory,
nextPickleIndex: 0,
pickles: opts.pickles,
runtimeConfig: opts.runtimeConfig,
sendCommand: opts.sendCommand,
sendCommandAndAwaitResponse: opts.sendCommandAndAwaitResponse,
supportCodeLibrary: opts.supportCodeLibrary,
}
}
func (p *parallelTestCaseRunnerMaster) run() (bool, error) {
testRunResult := dto.NewTestRunResult()
isSkipped := p.runtimeConfig.IsDryRun
numRunning := 0
toStart := int(p.runtimeConfig.MaxParallel)
if toStart == 0 || toStart > len(p.pickles) {
toStart = len(p.pickles)
}
onFinish := make(chan *runNextTestCaseResult, toStart)
for i := 1; i <= toStart; i++ {
p.runNextTestCase(isSkipped, onFinish)
numRunning++
}
for numRunning > 0 {
result := <-onFinish
if result.err != nil {
return false, result.err
}
testRunResult.Update(result.testCaseResult, p.runtimeConfig.IsStrict)
if !isSkipped && !testRunResult.Success && p.runtimeConfig.IsFailFast {
isSkipped = true
}
if p.nextPickleIndex == len(p.pickles) {
numRunning--
} else {
p.runNextTestCase(isSkipped, onFinish)
}
}
return testRunResult.Success, nil
}
func (p *parallelTestCaseRunnerMaster) runNextTestCase(isSkipped bool, onFinish chan *runNextTestCaseResult) {
pickle := p.pickles[p.nextPickleIndex]
p.nextPickleIndex++
go func() {
testCaseRunner, err := NewTestCaseRunner(&NewTestCaseRunnerOptions{
BaseDirectory: p.baseDirectory,
IsSkipped: isSkipped,
Pickle: pickle,
SendCommand: p.sendCommand,
SendCommandAndAwaitResponse: p.sendCommandAndAwaitResponse,
SupportCodeLibrary: p.supportCodeLibrary,
})
if err != nil {
onFinish <- &runNextTestCaseResult{err: err}
}
onFinish <- &runNextTestCaseResult{testCaseResult: testCaseRunner.Run()}
}()
}