1package leafnodes_test 2 3import ( 4 "sync" 5 6 . "github.com/onsi/ginkgo" 7 . "github.com/onsi/ginkgo/internal/leafnodes" 8 "github.com/onsi/ginkgo/types" 9 . "github.com/onsi/gomega" 10 11 "net/http" 12 13 "github.com/onsi/gomega/ghttp" 14 15 "time" 16 17 "github.com/onsi/ginkgo/internal/codelocation" 18 Failer "github.com/onsi/ginkgo/internal/failer" 19) 20 21var _ = Describe("SynchronizedAfterSuiteNode", func() { 22 var failer *Failer.Failer 23 var node SuiteNode 24 var codeLocation types.CodeLocation 25 var innerCodeLocation types.CodeLocation 26 var outcome bool 27 var server *ghttp.Server 28 var things []string 29 var lock *sync.Mutex 30 31 BeforeEach(func() { 32 things = []string{} 33 server = ghttp.NewServer() 34 codeLocation = codelocation.New(0) 35 innerCodeLocation = codelocation.New(0) 36 failer = Failer.New() 37 lock = &sync.Mutex{} 38 }) 39 40 AfterEach(func() { 41 server.Close() 42 }) 43 44 newNode := func(bodyA interface{}, bodyB interface{}) SuiteNode { 45 return NewSynchronizedAfterSuiteNode(bodyA, bodyB, codeLocation, time.Millisecond, failer) 46 } 47 48 ranThing := func(thing string) { 49 lock.Lock() 50 defer lock.Unlock() 51 things = append(things, thing) 52 } 53 54 thingsThatRan := func() []string { 55 lock.Lock() 56 defer lock.Unlock() 57 return things 58 } 59 60 Context("when not running in parallel", func() { 61 Context("when all is well", func() { 62 BeforeEach(func() { 63 node = newNode(func() { 64 ranThing("A") 65 }, func() { 66 ranThing("B") 67 }) 68 69 outcome = node.Run(1, 1, server.URL()) 70 }) 71 72 It("should run A, then B", func() { 73 Ω(thingsThatRan()).Should(Equal([]string{"A", "B"})) 74 }) 75 76 It("should report success", func() { 77 Ω(outcome).Should(BeTrue()) 78 Ω(node.Passed()).Should(BeTrue()) 79 Ω(node.Summary().State).Should(Equal(types.SpecStatePassed)) 80 }) 81 }) 82 83 Context("when A fails", func() { 84 BeforeEach(func() { 85 node = newNode(func() { 86 ranThing("A") 87 failer.Fail("bam", innerCodeLocation) 88 }, func() { 89 ranThing("B") 90 }) 91 92 outcome = node.Run(1, 1, server.URL()) 93 }) 94 95 It("should still run B", func() { 96 Ω(thingsThatRan()).Should(Equal([]string{"A", "B"})) 97 }) 98 99 It("should report failure", func() { 100 Ω(outcome).Should(BeFalse()) 101 Ω(node.Passed()).Should(BeFalse()) 102 Ω(node.Summary().State).Should(Equal(types.SpecStateFailed)) 103 }) 104 }) 105 106 Context("when B fails", func() { 107 BeforeEach(func() { 108 node = newNode(func() { 109 ranThing("A") 110 }, func() { 111 ranThing("B") 112 failer.Fail("bam", innerCodeLocation) 113 }) 114 115 outcome = node.Run(1, 1, server.URL()) 116 }) 117 118 It("should run all the things", func() { 119 Ω(thingsThatRan()).Should(Equal([]string{"A", "B"})) 120 }) 121 122 It("should report failure", func() { 123 Ω(outcome).Should(BeFalse()) 124 Ω(node.Passed()).Should(BeFalse()) 125 Ω(node.Summary().State).Should(Equal(types.SpecStateFailed)) 126 }) 127 }) 128 }) 129 130 Context("when running in parallel", func() { 131 Context("as the first node", func() { 132 BeforeEach(func() { 133 server.AppendHandlers(ghttp.CombineHandlers( 134 ghttp.VerifyRequest("GET", "/RemoteAfterSuiteData"), 135 func(writer http.ResponseWriter, request *http.Request) { 136 ranThing("Request1") 137 }, 138 ghttp.RespondWithJSONEncoded(200, types.RemoteAfterSuiteData{CanRun: false}), 139 ), ghttp.CombineHandlers( 140 ghttp.VerifyRequest("GET", "/RemoteAfterSuiteData"), 141 func(writer http.ResponseWriter, request *http.Request) { 142 ranThing("Request2") 143 }, 144 ghttp.RespondWithJSONEncoded(200, types.RemoteAfterSuiteData{CanRun: false}), 145 ), ghttp.CombineHandlers( 146 ghttp.VerifyRequest("GET", "/RemoteAfterSuiteData"), 147 func(writer http.ResponseWriter, request *http.Request) { 148 ranThing("Request3") 149 }, 150 ghttp.RespondWithJSONEncoded(200, types.RemoteAfterSuiteData{CanRun: true}), 151 )) 152 153 node = newNode(func() { 154 ranThing("A") 155 }, func() { 156 ranThing("B") 157 }) 158 159 outcome = node.Run(1, 3, server.URL()) 160 }) 161 162 It("should run A and, when the server says its time, run B", func() { 163 Ω(thingsThatRan()).Should(Equal([]string{"A", "Request1", "Request2", "Request3", "B"})) 164 }) 165 166 It("should report success", func() { 167 Ω(outcome).Should(BeTrue()) 168 Ω(node.Passed()).Should(BeTrue()) 169 Ω(node.Summary().State).Should(Equal(types.SpecStatePassed)) 170 }) 171 }) 172 173 Context("as any other node", func() { 174 BeforeEach(func() { 175 node = newNode(func() { 176 ranThing("A") 177 }, func() { 178 ranThing("B") 179 }) 180 181 outcome = node.Run(2, 3, server.URL()) 182 }) 183 184 It("should run A, and not run B", func() { 185 Ω(thingsThatRan()).Should(Equal([]string{"A"})) 186 }) 187 188 It("should not talk to the server", func() { 189 Ω(server.ReceivedRequests()).Should(BeEmpty()) 190 }) 191 192 It("should report success", func() { 193 Ω(outcome).Should(BeTrue()) 194 Ω(node.Passed()).Should(BeTrue()) 195 Ω(node.Summary().State).Should(Equal(types.SpecStatePassed)) 196 }) 197 }) 198 }) 199}) 200