blob: a721d0cf7f2d9203cbf79bdfd83e291ef5ea0bdb [file] [log] [blame]
Matthias Andreas Benkard832a54e2019-01-29 09:27:38 +01001package leafnodes
2
3import (
4 "encoding/json"
5 "io/ioutil"
6 "net/http"
7 "time"
8
9 "github.com/onsi/ginkgo/internal/failer"
10 "github.com/onsi/ginkgo/types"
11)
12
13type synchronizedAfterSuiteNode struct {
14 runnerA *runner
15 runnerB *runner
16
17 outcome types.SpecState
18 failure types.SpecFailure
19 runTime time.Duration
20}
21
22func NewSynchronizedAfterSuiteNode(bodyA interface{}, bodyB interface{}, codeLocation types.CodeLocation, timeout time.Duration, failer *failer.Failer) SuiteNode {
23 return &synchronizedAfterSuiteNode{
24 runnerA: newRunner(bodyA, codeLocation, timeout, failer, types.SpecComponentTypeAfterSuite, 0),
25 runnerB: newRunner(bodyB, codeLocation, timeout, failer, types.SpecComponentTypeAfterSuite, 0),
26 }
27}
28
29func (node *synchronizedAfterSuiteNode) Run(parallelNode int, parallelTotal int, syncHost string) bool {
30 node.outcome, node.failure = node.runnerA.run()
31
32 if parallelNode == 1 {
33 if parallelTotal > 1 {
34 node.waitUntilOtherNodesAreDone(syncHost)
35 }
36
37 outcome, failure := node.runnerB.run()
38
39 if node.outcome == types.SpecStatePassed {
40 node.outcome, node.failure = outcome, failure
41 }
42 }
43
44 return node.outcome == types.SpecStatePassed
45}
46
47func (node *synchronizedAfterSuiteNode) Passed() bool {
48 return node.outcome == types.SpecStatePassed
49}
50
51func (node *synchronizedAfterSuiteNode) Summary() *types.SetupSummary {
52 return &types.SetupSummary{
53 ComponentType: node.runnerA.nodeType,
54 CodeLocation: node.runnerA.codeLocation,
55 State: node.outcome,
56 RunTime: node.runTime,
57 Failure: node.failure,
58 }
59}
60
61func (node *synchronizedAfterSuiteNode) waitUntilOtherNodesAreDone(syncHost string) {
62 for {
63 if node.canRun(syncHost) {
64 return
65 }
66
67 time.Sleep(50 * time.Millisecond)
68 }
69}
70
71func (node *synchronizedAfterSuiteNode) canRun(syncHost string) bool {
72 resp, err := http.Get(syncHost + "/RemoteAfterSuiteData")
73 if err != nil || resp.StatusCode != http.StatusOK {
74 return false
75 }
76
77 body, err := ioutil.ReadAll(resp.Body)
78 if err != nil {
79 return false
80 }
81 resp.Body.Close()
82
83 afterSuiteData := types.RemoteAfterSuiteData{}
84 err = json.Unmarshal(body, &afterSuiteData)
85 if err != nil {
86 return false
87 }
88
89 return afterSuiteData.CanRun
90}