github.com/onsi/ginkgo@v1.16.6-0.20211118180735-4e1925ba4c95/internal/internal_integration/synchronized_suite_nodes_test.go (about) 1 package internal_integration_test 2 3 import ( 4 . "github.com/onsi/ginkgo" 5 . "github.com/onsi/ginkgo/internal/test_helpers" 6 "github.com/onsi/ginkgo/types" 7 . "github.com/onsi/gomega" 8 "github.com/onsi/gomega/gbytes" 9 ) 10 11 var _ = Describe("Synchronized Suite Nodes", func() { 12 var failInBeforeSuiteProc1, failInBeforeSuiteAllProcs, failInAfterSuiteAllProcs, failInAfterSuiteProc1 bool 13 var fixture func() 14 15 BeforeEach(func() { 16 failInBeforeSuiteProc1, failInBeforeSuiteAllProcs, failInAfterSuiteAllProcs, failInAfterSuiteProc1 = false, false, false, false 17 fixture = func() { 18 SynchronizedBeforeSuite(func() []byte { 19 outputInterceptor.AppendInterceptedOutput("before-suite-proc-1") 20 rt.Run("before-suite-proc-1") 21 if failInBeforeSuiteProc1 { 22 F("fail-in-before-suite-proc-1", cl) 23 } 24 return []byte("hey there") 25 }, func(data []byte) { 26 outputInterceptor.AppendInterceptedOutput("before-suite-all-procs") 27 rt.RunWithData("before-suite-all-procs", "data", string(data)) 28 if failInBeforeSuiteAllProcs { 29 F("fail-in-before-suite-all-procs", cl) 30 } 31 }) 32 It("test", rt.T("test")) 33 SynchronizedAfterSuite(func() { 34 outputInterceptor.AppendInterceptedOutput("after-suite-all-procs") 35 rt.Run("after-suite-all-procs") 36 if failInAfterSuiteAllProcs { 37 F("fail-in-after-suite-all-procs", cl) 38 } 39 }, func() { 40 outputInterceptor.AppendInterceptedOutput("after-suite-proc-1") 41 rt.Run("after-suite-proc-1") 42 if failInAfterSuiteProc1 { 43 F("fail-in-after-suite-proc-1", cl) 44 } 45 }) 46 } 47 }) 48 49 Describe("when running in series", func() { 50 BeforeEach(func() { 51 conf.ParallelTotal = 1 52 conf.ParallelProcess = 1 53 }) 54 55 Describe("happy path", func() { 56 BeforeEach(func() { 57 success, _ := RunFixture("happy-path", fixture) 58 Ω(success).Should(BeTrue()) 59 }) 60 61 It("runs all the functions", func() { 62 Ω(rt).Should(HaveTracked( 63 "before-suite-proc-1", "before-suite-all-procs", 64 "test", 65 "after-suite-all-procs", "after-suite-proc-1", 66 )) 67 }) 68 69 It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite as having passed", func() { 70 befReports := reporter.Did.WithLeafNodeType(types.NodeTypeSynchronizedBeforeSuite) 71 Ω(befReports).Should(HaveLen(1)) 72 Ω(befReports[0]).Should(HavePassed()) 73 74 aftReports := reporter.Did.WithLeafNodeType(types.NodeTypeSynchronizedAfterSuite) 75 Ω(aftReports).Should(HaveLen(1)) 76 Ω(aftReports[0]).Should(HavePassed()) 77 }) 78 79 It("passes data between the two SynchronizedBeforeSuite functions", func() { 80 Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hey there")) 81 }) 82 }) 83 84 Describe("when the SynchronizedBeforeSuite proc1 function fails", func() { 85 BeforeEach(func() { 86 failInBeforeSuiteProc1 = true 87 success, _ := RunFixture("fail in SynchronizedBeforeSuite proc1", fixture) 88 Ω(success).Should(BeFalse()) 89 }) 90 91 It("doens't run the allProcs function or any of the tests", func() { 92 Ω(rt).Should(HaveTracked( 93 "before-suite-proc-1", 94 "after-suite-all-procs", "after-suite-proc-1", 95 )) 96 }) 97 98 It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite correctly", func() { 99 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HaveFailed("fail-in-before-suite-proc-1")) 100 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HavePassed()) 101 }) 102 }) 103 104 Describe("when the SynchronizedBeforeSuite allProcs function fails", func() { 105 BeforeEach(func() { 106 failInBeforeSuiteAllProcs = true 107 success, _ := RunFixture("fail in SynchronizedBeforeSuite allProcs", fixture) 108 Ω(success).Should(BeFalse()) 109 }) 110 111 It("doesn't run the tests", func() { 112 Ω(rt).Should(HaveTracked( 113 "before-suite-proc-1", "before-suite-all-procs", 114 "after-suite-all-procs", "after-suite-proc-1", 115 )) 116 Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hey there")) 117 }) 118 119 It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite correctly", func() { 120 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HaveFailed("fail-in-before-suite-all-procs")) 121 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HavePassed()) 122 }) 123 }) 124 125 Describe("when the SynchronizedAfterSuite allProcs function fails", func() { 126 BeforeEach(func() { 127 failInAfterSuiteAllProcs = true 128 success, _ := RunFixture("fail in SynchronizedAfterSuite allProcs", fixture) 129 Ω(success).Should(BeFalse()) 130 }) 131 132 It("nonetheless runs the proc-1 function", func() { 133 Ω(rt).Should(HaveTracked( 134 "before-suite-proc-1", "before-suite-all-procs", 135 "test", 136 "after-suite-all-procs", "after-suite-proc-1", 137 )) 138 Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hey there")) 139 }) 140 141 It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite correctly", func() { 142 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HavePassed()) 143 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HaveFailed("fail-in-after-suite-all-procs")) 144 }) 145 }) 146 147 Describe("when the SynchronizedAfterSuite proc1 function fails", func() { 148 BeforeEach(func() { 149 failInAfterSuiteProc1 = true 150 success, _ := RunFixture("fail in SynchronizedAfterSuite proc1", fixture) 151 Ω(success).Should(BeFalse()) 152 }) 153 154 It("will have run everything", func() { 155 Ω(rt).Should(HaveTracked( 156 "before-suite-proc-1", "before-suite-all-procs", 157 "test", 158 "after-suite-all-procs", "after-suite-proc-1", 159 )) 160 Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hey there")) 161 }) 162 163 It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite correctly", func() { 164 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HavePassed()) 165 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HaveFailed("fail-in-after-suite-proc-1")) 166 }) 167 }) 168 }) 169 170 Describe("when running in parallel", func() { 171 var serverOutputBuffer *gbytes.Buffer 172 173 BeforeEach(func() { 174 SetUpForParallel(2) 175 serverOutputBuffer = gbytes.NewBuffer() 176 server.SetOutputDestination(serverOutputBuffer) 177 }) 178 179 Describe("when running as proc 1", func() { 180 BeforeEach(func() { 181 conf.ParallelProcess = 1 182 }) 183 184 Describe("happy path", func() { 185 BeforeEach(func() { 186 close(exitChannels[2]) //trigger proc 2 exiting so the proc1 after suite runs 187 success, _ := RunFixture("happy-path", fixture) 188 Ω(success).Should(BeTrue()) 189 }) 190 191 It("runs all the functions", func() { 192 Ω(rt).Should(HaveTracked( 193 "before-suite-proc-1", "before-suite-all-procs", 194 "test", 195 "after-suite-all-procs", "after-suite-proc-1", 196 )) 197 }) 198 199 It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite as having passed", func() { 200 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HavePassed()) 201 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HavePassed()) 202 }) 203 204 It("passes data between the two SynchronizedBeforeSuite functions and up to the server", func() { 205 Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hey there")) 206 state, data, err := client.BlockUntilSynchronizedBeforeSuiteData() 207 Ω(state).Should(Equal(types.SpecStatePassed)) 208 Ω(data).Should(Equal([]byte("hey there"))) 209 Ω(err).ShouldNot(HaveOccurred()) 210 }) 211 212 It("emits the output of the proc-1 BeforeSuite function and the proc-1 AfterSuite fnction", func() { 213 Ω(string(serverOutputBuffer.Contents())).Should(Equal("before-suite-proc-1after-suite-proc-1")) 214 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HavePassed(CapturedStdOutput("before-suite-proc-1before-suite-all-procs"))) 215 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HavePassed(CapturedStdOutput("after-suite-all-procsafter-suite-proc-1"))) 216 }) 217 }) 218 219 Describe("when the BeforeSuite proc1 function fails", func() { 220 BeforeEach(func() { 221 close(exitChannels[2]) //trigger proc 2 exiting so the proc1 after suite runs 222 failInBeforeSuiteProc1 = true 223 success, _ := RunFixture("happy-path", fixture) 224 Ω(success).Should(BeFalse()) 225 }) 226 227 It("tells the server", func() { 228 state, data, err := client.BlockUntilSynchronizedBeforeSuiteData() 229 Ω(state).Should(Equal(types.SpecStateFailed)) 230 Ω(data).Should(BeNil()) 231 Ω(err).ShouldNot(HaveOccurred()) 232 }) 233 }) 234 235 Describe("waiting for all procs to finish before running the AfterSuite proc 1 function", func() { 236 It("waits for the server to give it the all clear", func() { 237 done := make(chan interface{}) 238 go func() { 239 defer GinkgoRecover() 240 success, _ := RunFixture("happy-path", fixture) 241 Ω(success).Should(BeTrue()) 242 close(done) 243 }() 244 Consistently(done).ShouldNot(BeClosed()) 245 close(exitChannels[2]) 246 Eventually(done).Should(BeClosed()) 247 }) 248 }) 249 }) 250 251 Describe("when running as another proc", func() { 252 BeforeEach(func() { 253 conf.ParallelProcess = 2 254 }) 255 256 Describe("happy path", func() { 257 BeforeEach(func() { 258 client.PostSynchronizedBeforeSuiteCompleted(types.SpecStatePassed, []byte("hola hola")) 259 success, _ := RunFixture("happy-path", fixture) 260 Ω(success).Should(BeTrue()) 261 }) 262 263 It("runs all the all-procs functions", func() { 264 Ω(rt).Should(HaveTracked( 265 "before-suite-all-procs", 266 "test", 267 "after-suite-all-procs", 268 )) 269 }) 270 271 It("reports on the SynchronizedBeforeSuite and SynchronizedAfterSuite as having passed", func() { 272 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HavePassed()) 273 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedAfterSuite)).Should(HavePassed()) 274 }) 275 276 It("gets data for the SynchronizedBeforeSuite all procs function from the server", func() { 277 Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hola hola")) 278 }) 279 }) 280 281 Describe("waiting for the data from proc 1", func() { 282 It("waits for the server to give it the data", func() { 283 done := make(chan interface{}) 284 go func() { 285 defer GinkgoRecover() 286 success, _ := RunFixture("happy-path", fixture) 287 Ω(success).Should(BeTrue()) 288 close(done) 289 }() 290 Consistently(done).ShouldNot(BeClosed()) 291 client.PostSynchronizedBeforeSuiteCompleted(types.SpecStatePassed, []byte("hola hola")) 292 Eventually(done).Should(BeClosed()) 293 Ω(rt).Should(HaveRunWithData("before-suite-all-procs", "data", "hola hola")) 294 }) 295 }) 296 297 Describe("when proc 1 fails the SynchronizedBeforeSuite proc1 function", func() { 298 It("fails and only runs the after suite", func() { 299 done := make(chan interface{}) 300 go func() { 301 defer GinkgoRecover() 302 success, _ := RunFixture("happy-path", fixture) 303 Ω(success).Should(BeFalse()) 304 close(done) 305 }() 306 Consistently(done).ShouldNot(BeClosed()) 307 client.PostSynchronizedBeforeSuiteCompleted(types.SpecStateFailed, nil) 308 Eventually(done).Should(BeClosed()) 309 310 Ω(rt).Should(HaveTracked("after-suite-all-procs")) 311 312 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HaveFailed(types.GinkgoErrors.SynchronizedBeforeSuiteFailedOnProc1().Error())) 313 }) 314 }) 315 316 Describe("when the proc1 SynchronizedBeforeSuite function Skips()", func() { 317 It("fails and only runs the after suite", func() { 318 done := make(chan interface{}) 319 go func() { 320 defer GinkgoRecover() 321 success, _ := RunFixture("happy-path", fixture) 322 Ω(success).Should(BeTrue()) 323 close(done) 324 }() 325 Consistently(done).ShouldNot(BeClosed()) 326 client.PostSynchronizedBeforeSuiteCompleted(types.SpecStateSkipped, nil) 327 Eventually(done).Should(BeClosed()) 328 329 Ω(rt).Should(HaveTracked("after-suite-all-procs")) 330 331 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HaveBeenSkipped()) 332 }) 333 }) 334 335 Describe("when proc 1 disappears before the proc 1 function returns", func() { 336 It("fails and only runs the after suite", func() { 337 done := make(chan interface{}) 338 go func() { 339 defer GinkgoRecover() 340 success, _ := RunFixture("happy-path", fixture) 341 Ω(success).Should(BeFalse()) 342 close(done) 343 }() 344 Consistently(done).ShouldNot(BeClosed()) 345 close(exitChannels[1]) 346 Eventually(done).Should(BeClosed()) 347 348 Ω(rt).Should(HaveTracked("after-suite-all-procs")) 349 350 Ω(reporter.Did.FindByLeafNodeType(types.NodeTypeSynchronizedBeforeSuite)).Should(HaveFailed(types.GinkgoErrors.SynchronizedBeforeSuiteDisappearedOnProc1().Error())) 351 }) 352 }) 353 }) 354 }) 355 })