github.com/onsi/ginkgo@v1.16.6-0.20211118180735-4e1925ba4c95/internal/internal_integration/ordered_test.go (about) 1 package internal_integration_test 2 3 import ( 4 "fmt" 5 "time" 6 7 . "github.com/onsi/ginkgo" 8 "github.com/onsi/ginkgo/internal/interrupt_handler" 9 . "github.com/onsi/ginkgo/internal/test_helpers" 10 "github.com/onsi/ginkgo/types" 11 . "github.com/onsi/gomega" 12 ) 13 14 const SKIP_DUE_TO_EARLIER_FAILURE = "Spec skipped because an earlier spec in an ordered container failed" 15 const SKIP_DUE_TO_BEFORE_ALL_SKIP = "Spec skipped because Skip() was called in BeforeAll" 16 17 var DC = func(label string, callback ...func()) func() { 18 return func() { 19 DeferCleanup(rt.T(label, callback...)) 20 } 21 } 22 23 var FlakeyFailer = func(n int) func() { 24 i := 0 25 return func() { 26 i += 1 27 if i <= n { 28 F("fail") 29 } 30 } 31 } 32 33 var FlakeyFailerWithCleanup = func(n int, cleanupLabel string) func() { 34 i := 0 35 return func() { 36 i += 1 37 DeferCleanup(rt.T(cleanupLabel + "-pre")) 38 if i <= n { 39 F("fail") 40 } 41 DeferCleanup(rt.T(cleanupLabel + "-post")) 42 } 43 } 44 45 var _ = DescribeTable("Ordered Containers", 46 func(expectedSuccess bool, fixture func(), runs []string, args ...interface{}) { 47 success, _ := RunFixture(CurrentSpecReport().LeafNodeText, fixture) 48 Ω(success).Should(Equal(expectedSuccess)) 49 Ω(rt).Should(HaveTracked(runs...)) 50 specs := Reports{} 51 for i := 0; i < len(args); i += 1 { 52 switch v := args[i].(type) { 53 case string: 54 specs = append(specs, reporter.Did.Find(v)) 55 case OmegaMatcher: 56 Ω(specs).ShouldNot(BeEmpty(), "Got a matcher but expected a spec to look up") 57 for _, spec := range specs { 58 Ω(spec).Should(v, "Spec that failed: %s", spec.LeafNodeText) 59 } 60 specs = Reports{} 61 default: 62 Fail(fmt.Sprintf("Unexpected type %T", args[i])) 63 } 64 } 65 Ω(specs).Should(BeEmpty(), "Trailing spec - missing a matcher") 66 }, 67 // basic ordering 68 Entry("simply happy path", true, func() { 69 Context("container", Ordered, func() { 70 It("A", rt.T("A")) 71 It("B", rt.T("B")) 72 It("C", rt.T("C")) 73 }) 74 }, []string{"A", "B", "C"}, 75 "A", "B", "C", HavePassed(), 76 ), 77 Entry("when a spec fails", false, func() { 78 Context("outer container", func() { 79 Context("container", Ordered, func() { 80 It("A", rt.T("A")) 81 It("B", rt.T("B")) 82 It("C", rt.T("C", func() { F("fail") })) 83 It("D", rt.T("D")) 84 It("E", rt.T("E")) 85 }) 86 Context("container", Ordered, func() { 87 It("F", FlakeAttempts(3), rt.T("F", FlakeyFailer(2))) 88 It("G", rt.T("G")) 89 }) 90 }) 91 }, []string{"A", "B", "C", "F", "F", "F", "G"}, 92 "A", "B", HavePassed(), 93 "C", HaveFailed(), 94 "D", "E", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 95 "F", HavePassed(NumAttempts(3)), 96 "G", HavePassed(NumAttempts(1)), 97 ), 98 // BeforeAll and AfterAll - happy paths 99 Entry("BeforeAll and AfterAll Happy Path", true, func() { 100 BeforeEach(rt.T("BE1")) 101 JustBeforeEach(rt.T("JBE1")) 102 AfterEach(rt.T("AE1")) 103 Context("container", Ordered, func() { 104 BeforeEach(rt.T("BE2")) 105 JustBeforeEach(rt.T("JBE2")) 106 BeforeAll(rt.T("BA1")) 107 BeforeEach(rt.T("BE3")) 108 JustBeforeEach(rt.T("JBE3")) 109 BeforeAll(rt.T("BA2")) 110 BeforeEach(rt.T("BE4")) 111 It("A", rt.T("A")) 112 It("B", rt.T("B")) 113 It("C", rt.T("C")) 114 JustAfterEach(rt.T("JAE1")) 115 AfterEach(rt.T("AE2")) 116 AfterAll(rt.T("AA1")) 117 AfterEach(rt.T("AE3")) 118 JustAfterEach(rt.T("JAE2")) 119 AfterAll(rt.T("AA2")) 120 AfterEach(rt.T("AE4")) 121 JustAfterEach(rt.T("JAE3")) 122 }) 123 JustAfterEach(rt.T("JAE4")) 124 AfterEach(rt.T("AE5")) 125 BeforeEach(rt.T("BE5")) 126 JustBeforeEach(rt.T("JBE4")) 127 }, []string{ 128 "BE1", "BE5", 129 "BA1", "BA2", "BE2", "BE3", "BE4", 130 "JBE1", "JBE4", "JBE2", "JBE3", 131 "A", 132 "JAE1", "JAE2", "JAE3", "JAE4", 133 "AE2", "AE3", "AE4", 134 "AE1", "AE5", 135 "BE1", "BE5", 136 "BE2", "BE3", "BE4", 137 "JBE1", "JBE4", "JBE2", "JBE3", 138 "B", 139 "JAE1", "JAE2", "JAE3", "JAE4", 140 "AE2", "AE3", "AE4", 141 "AE1", "AE5", 142 "BE1", "BE5", 143 "BE2", "BE3", "BE4", 144 "JBE1", "JBE4", "JBE2", "JBE3", 145 "C", 146 "JAE1", "JAE2", "JAE3", "JAE4", 147 "AE2", "AE3", "AE4", "AA1", "AA2", 148 "AE1", "AE5", 149 }), 150 Entry("when there is only one spec", true, func() { 151 Context("container", Ordered, func() { 152 BeforeEach(rt.T("BE")) 153 BeforeAll(rt.T("BA")) 154 It("A", rt.T("A")) 155 AfterAll(rt.T("AA")) 156 AfterEach(rt.T("AE")) 157 }) 158 }, []string{ 159 "BA", "BE", "A", "AE", "AA", 160 }), 161 Entry("when there are focused specs", true, func() { 162 Context("container", Ordered, func() { 163 BeforeEach(rt.T("BE")) 164 BeforeAll(rt.T("BA")) 165 It("A", rt.T("A")) 166 FIt("B", rt.T("B")) 167 FIt("C", rt.T("C")) 168 It("D", rt.T("D")) 169 AfterAll(rt.T("AA")) 170 AfterEach(rt.T("AE")) 171 }) 172 }, []string{ 173 "BA", "BE", "B", "AE", "BE", "C", "AE", "AA", 174 }, 175 "B", "C", HavePassed(), 176 "A", "D", HaveBeenSkipped(), 177 ), 178 Entry("when there is nothing to run", true, func() { 179 Context("container", Ordered, func() { 180 BeforeEach(rt.T("BE")) 181 BeforeAll(rt.T("BA")) 182 PIt("A", rt.T("A")) 183 PIt("B", rt.T("B")) 184 PIt("C", rt.T("C")) 185 AfterAll(rt.T("AA")) 186 AfterEach(rt.T("AE")) 187 }) 188 }, []string{}, "A", "B", "C", BePending()), 189 // BeforeAll and AfterAll - when skips are called 190 Entry("when a skip occurs in a BeforeAll, it skips the entire group", true, func() { 191 Context("container", Ordered, func() { 192 BeforeAll(rt.T("BA", func() { DeferCleanup(rt.T("DC")); Skip("skip") })) 193 It("A", FlakeAttempts(3), rt.T("A")) 194 It("B", rt.T("B")) 195 It("C", rt.T("C")) 196 AfterAll(rt.T("AA")) 197 }) 198 }, []string{"BA", "AA", "DC"}, 199 "A", HaveBeenSkippedWithMessage("skip", NumAttempts(1)), 200 "B", "C", HaveBeenSkippedWithMessage(SKIP_DUE_TO_BEFORE_ALL_SKIP), 201 ), 202 Entry("when a skip occurs in a test", true, func() { 203 Context("container", Ordered, func() { 204 BeforeAll(rt.T("BA")) 205 It("A", rt.T("A")) 206 It("B", rt.T("B", func() { Skip("skip") })) 207 It("C", rt.T("C")) 208 AfterAll(rt.T("AA")) 209 }) 210 }, []string{"BA", "A", "B", "C", "AA"}, 211 "A", "C", HavePassed(), 212 "B", HaveBeenSkippedWithMessage("skip"), 213 ), 214 Entry("when a skip occurs in the last test", true, func() { 215 Context("container", Ordered, func() { 216 BeforeAll(rt.T("BA")) 217 It("A", rt.T("A")) 218 It("B", rt.T("B")) 219 It("C", rt.T("C", func() { Skip("skip") })) 220 AfterAll(rt.T("AA")) 221 }) 222 }, []string{"BA", "A", "B", "C", "AA"}, 223 "A", "B", HavePassed(), 224 "C", HaveBeenSkippedWithMessage("skip"), 225 ), 226 // BeforeAll and AfterAll - when failures, panics, interrupts, and aborts happen 227 Entry("when a failure occurs prior to the BeforeAll, it doesn't run the Alls", false, func() { 228 BeforeEach(rt.T("BE-outer", func() { F("fail") })) 229 Context("container", Ordered, func() { 230 BeforeEach(rt.T("BE")) 231 BeforeAll(rt.T("BA")) 232 It("A", rt.T("A")) 233 AfterAll(rt.T("AA")) 234 AfterEach(rt.T("AE")) 235 }) 236 AfterEach(rt.T("AE-outer")) 237 }, []string{ 238 "BE-outer", "AE-outer", 239 }, "A", HaveFailed(types.FailureNodeAtTopLevel, FailureNodeType(types.NodeTypeBeforeEach), "fail")), 240 Entry("when a failure occurs in a spec, it runs the AfterAll and skips subsequent specs", false, func() { 241 BeforeEach(rt.T("BE-outer")) 242 Context("container", Ordered, func() { 243 BeforeEach(rt.T("BE")) 244 BeforeAll(rt.T("BA")) 245 It("A", rt.T("A", func() { F("fail") })) 246 It("B", rt.T("B")) 247 AfterAll(rt.T("AA")) 248 AfterEach(rt.T("AE")) 249 }) 250 AfterEach(rt.T("AE-outer")) 251 }, []string{"BE-outer", "BA", "BE", "A", "AE", "AA", "AE-outer"}, 252 "A", HaveFailed(types.FailureNodeIsLeafNode, FailureNodeType(types.NodeTypeIt), "fail"), 253 "B", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 254 ), 255 Entry("when a failure occurs in a BeforeAll", false, func() { 256 BeforeEach(rt.T("BE-outer")) 257 Context("container", Ordered, func() { 258 BeforeEach(rt.T("BE")) 259 BeforeAll(rt.T("BA", func() { F("fail") })) 260 It("A", rt.T("A")) 261 It("B", rt.T("B")) 262 AfterAll(rt.T("AA")) 263 AfterEach(rt.T("AE")) 264 }) 265 AfterEach(rt.T("AE-outer")) 266 }, []string{"BE-outer", "BA", "AE", "AA", "AE-outer"}, 267 "A", HaveFailed(types.FailureNodeInContainer, FailureNodeType(types.NodeTypeBeforeAll), "fail"), 268 "B", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 269 ), 270 Entry("when a failure occurs in an AfterAll", false, func() { 271 BeforeEach(rt.T("BE-outer")) 272 Context("container", Ordered, func() { 273 BeforeEach(rt.T("BE")) 274 BeforeAll(rt.T("BA")) 275 It("A", rt.T("A")) 276 It("B", rt.T("B")) 277 AfterAll(rt.T("AA", func() { F("fail") })) 278 AfterEach(rt.T("AE")) 279 }) 280 AfterEach(rt.T("AE-outer")) 281 }, []string{ 282 "BE-outer", "BA", "BE", "A", "AE", "AE-outer", 283 "BE-outer", "BE", "B", "AE", "AA", "AE-outer", 284 }, "A", HavePassed(), 285 "B", HaveFailed(types.FailureNodeInContainer, FailureNodeType(types.NodeTypeAfterAll), "fail"), 286 ), 287 Entry("when a panic occurs in a BeforeAll", false, func() { 288 BeforeEach(rt.T("BE-outer")) 289 Context("container", Ordered, func() { 290 BeforeEach(rt.T("BE")) 291 BeforeAll(rt.T("BA", func() { panic("boom") })) 292 It("A", rt.T("A")) 293 It("B", rt.T("B")) 294 AfterAll(rt.T("AA")) 295 AfterEach(rt.T("AE")) 296 }) 297 AfterEach(rt.T("AE-outer")) 298 }, []string{"BE-outer", "BA", "AE", "AA", "AE-outer"}, 299 "A", HavePanicked(types.FailureNodeInContainer, FailureNodeType(types.NodeTypeBeforeAll), "boom"), 300 "B", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 301 ), 302 Entry("when a panic occurs in an AfterAll", false, func() { 303 BeforeEach(rt.T("BE-outer")) 304 Context("container", Ordered, func() { 305 BeforeEach(rt.T("BE")) 306 BeforeAll(rt.T("BA")) 307 It("A", rt.T("A")) 308 It("B", rt.T("B")) 309 AfterAll(rt.T("AA", func() { panic("boom") })) 310 AfterEach(rt.T("AE")) 311 }) 312 AfterEach(rt.T("AE-outer")) 313 }, []string{ 314 "BE-outer", "BA", "BE", "A", "AE", "AE-outer", 315 "BE-outer", "BE", "B", "AE", "AA", "AE-outer", 316 }, "A", HavePassed(), 317 "B", HavePanicked(types.FailureNodeInContainer, FailureNodeType(types.NodeTypeAfterAll), "boom"), 318 ), 319 Entry("when a failure occurs in an AfterEach, it runs the AfterAll", false, func() { 320 BeforeEach(rt.T("BE-outer")) 321 Context("container", Ordered, func() { 322 BeforeEach(rt.T("BE")) 323 BeforeAll(rt.T("BA")) 324 It("A", rt.T("A")) 325 It("B", rt.T("B")) 326 AfterAll(rt.T("AA")) 327 AfterEach(rt.T("AE", func() { F("fail") })) 328 }) 329 AfterEach(rt.T("AE-outer")) 330 }, []string{"BE-outer", "BA", "BE", "A", "AE", "AE-outer", "AA"}, 331 "A", HaveFailed(types.FailureNodeInContainer, FailureNodeType(types.NodeTypeAfterEach), "fail"), 332 "B", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 333 ), 334 Entry("when a failure occurs in a DeferCleanup, it runs the AfterAll", false, func() { 335 BeforeEach(rt.T("BE-outer")) 336 Context("container", Ordered, func() { 337 BeforeEach(rt.T("BE")) 338 BeforeAll(rt.T("BA")) 339 It("A", rt.T("A", func() { 340 DeferCleanup(func() { 341 rt.Run("cleanup") 342 Fail("fail") 343 }) 344 })) 345 It("B", rt.T("B")) 346 AfterAll(rt.T("AA")) 347 AfterEach(rt.T("AE")) 348 }) 349 AfterEach(rt.T("AE-outer")) 350 }, []string{"BE-outer", "BA", "BE", "A", "AE", "AE-outer", "cleanup", "AA"}, 351 "A", HaveFailed(types.FailureNodeInContainer, FailureNodeType(types.NodeTypeCleanupAfterEach), "fail"), 352 "B", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 353 ), 354 Entry("when an interruption occurs, run the AfterAll and skip subsequent specs", false, func() { 355 BeforeEach(rt.T("BE-outer")) 356 Context("container", Ordered, FlakeAttempts(4), func() { 357 BeforeEach(rt.T("BE")) 358 BeforeAll(rt.T("BA")) 359 It("A", rt.T("A", func() { 360 interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) 361 time.Sleep(time.Minute) 362 })) 363 It("B", rt.T("B")) 364 AfterAll(rt.T("AA")) 365 AfterEach(rt.T("AE")) 366 }) 367 AfterEach(rt.T("AE-outer")) 368 }, []string{"BE-outer", "BA", "BE", "A", "AE", "AA", "AE-outer"}, 369 "A", HaveBeenInterrupted(interrupt_handler.InterruptCauseSignal), 370 "B", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 371 ), 372 Entry("when an interruption occurs in a BeforeAll, run the AfterAll and skip subsequent specs", false, func() { 373 BeforeEach(rt.T("BE-outer")) 374 Context("container", Ordered, FlakeAttempts(4), func() { 375 BeforeEach(rt.T("BE")) 376 BeforeAll(rt.T("BA", func() { 377 DeferCleanup(rt.T("DC-BA")) 378 interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) 379 time.Sleep(time.Minute) 380 })) 381 It("A", rt.T("A")) 382 It("B", rt.T("B")) 383 AfterAll(rt.T("AA")) 384 AfterEach(rt.T("AE")) 385 }) 386 AfterEach(rt.T("AE-outer")) 387 }, []string{"BE-outer", "BA", "AE", "AA", "AE-outer", "DC-BA"}, 388 "A", HaveBeenInterrupted(interrupt_handler.InterruptCauseSignal), 389 "B", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 390 ), 391 Entry("when an interruption occurs in an AfterAll, run any remaining cleanup", false, func() { 392 BeforeEach(rt.T("BE-outer")) 393 Context("container", Ordered, FlakeAttempts(4), func() { 394 BeforeEach(rt.T("BE")) 395 BeforeAll(rt.T("BA", DC("DC-BA"))) 396 It("A", rt.T("A")) 397 It("B", rt.T("B")) 398 AfterAll(rt.T("AA", func() { 399 DeferCleanup(rt.T("DC-AA")) 400 interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) 401 time.Sleep(time.Minute) 402 })) 403 AfterEach(rt.T("AE")) 404 }) 405 AfterEach(rt.T("AE-outer")) 406 }, []string{ 407 "BE-outer", "BA", "BE", "A", "AE", "AE-outer", 408 "BE-outer", "BE", "B", "AE", "AA", "AE-outer", 409 "DC-AA", "DC-BA", 410 }, 411 "A", HavePassed(), 412 "B", HaveBeenInterrupted(interrupt_handler.InterruptCauseSignal), 413 ), 414 Entry("when an abort occurs, run the AfterAll and skip subsequent specs", false, func() { 415 BeforeEach(rt.T("BE-outer")) 416 Context("container", Ordered, FlakeAttempts(4), func() { 417 BeforeEach(rt.T("BE")) 418 BeforeAll(rt.T("BA")) 419 It("A", rt.T("A", func() { 420 Abort("abort!") 421 })) 422 It("B", rt.T("B")) 423 AfterAll(rt.T("AA")) 424 AfterEach(rt.T("AE")) 425 }) 426 AfterEach(rt.T("AE-outer")) 427 }, []string{"BE-outer", "BA", "BE", "A", "AE", "AA", "AE-outer"}, 428 "A", HaveAborted("abort!"), 429 "B", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 430 ), 431 Entry("when an abort occurs in a BeforeAll, run the AfterAll and skip subsequent specs", false, func() { 432 BeforeEach(rt.T("BE-outer")) 433 Context("container", Ordered, FlakeAttempts(4), func() { 434 BeforeEach(rt.T("BE")) 435 BeforeAll(rt.T("BA", func() { 436 DeferCleanup(rt.T("DC-BA")) 437 Abort("abort!") 438 })) 439 It("A", rt.T("A")) 440 It("B", rt.T("B")) 441 AfterAll(rt.T("AA")) 442 AfterEach(rt.T("AE")) 443 }) 444 AfterEach(rt.T("AE-outer")) 445 }, []string{"BE-outer", "BA", "AE", "AA", "AE-outer", "DC-BA"}, 446 "A", HaveAborted("abort!"), 447 "B", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 448 ), 449 Entry("when an abort occurs in an AfterAll, run any remaining cleanup", false, func() { 450 BeforeEach(rt.T("BE-outer")) 451 Context("container", Ordered, FlakeAttempts(4), func() { 452 BeforeEach(rt.T("BE")) 453 BeforeAll(rt.T("BA", DC("DC-BA"))) 454 It("A", rt.T("A")) 455 It("B", rt.T("B")) 456 AfterAll(rt.T("AA", func() { 457 DeferCleanup(rt.T("DC-AA")) 458 Abort("abort!") 459 })) 460 AfterEach(rt.T("AE")) 461 }) 462 AfterEach(rt.T("AE-outer")) 463 }, []string{ 464 "BE-outer", "BA", "BE", "A", "AE", "AE-outer", 465 "BE-outer", "BE", "B", "AE", "AA", "AE-outer", 466 "DC-AA", "DC-BA", 467 }, 468 "A", HavePassed(), 469 "B", HaveAborted("abort!"), 470 ), 471 //here be dragons: the interplay between BeforeAll/AfterAll and FlakeAttempts 472 Entry("when the first spec is flaky, it runs the BeforeAll just once", true, func() { 473 Context("container", Ordered, FlakeAttempts(4), func() { 474 BeforeAll(rt.T("BA")) 475 It("A", rt.T("A", FlakeyFailer(2))) 476 It("B", rt.T("B")) 477 It("C", rt.T("C")) 478 AfterAll(rt.T("AA")) 479 }) 480 }, []string{"BA", "A", "A", "A", "B", "C", "AA"}, 481 "A", HavePassed(NumAttempts(3)), 482 "B", "C", HavePassed(NumAttempts(1)), 483 ), 484 Entry("when a spec is flaky and never succeeds, it runs the AfterAll (just once) when the spec ultimately fails", false, func() { 485 Context("container", Ordered, FlakeAttempts(4), func() { 486 BeforeAll(rt.T("BA")) 487 It("A", rt.T("A")) 488 It("B", rt.T("B", FlakeyFailer(4))) 489 It("C", rt.T("C")) 490 AfterAll(rt.T("AA")) 491 }) 492 }, []string{"BA", "A", "B", "B", "B", "B", "AA"}, 493 "A", HavePassed(), 494 "B", HaveFailed("fail", NumAttempts(4)), 495 "C", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 496 ), 497 Entry("when the last spec is flaky, it runs the AFterAll just once", true, func() { 498 Context("container", Ordered, FlakeAttempts(4), func() { 499 BeforeAll(rt.T("BA")) 500 It("A", rt.T("A")) 501 It("B", rt.T("B")) 502 It("C", rt.T("C", FlakeyFailer(2))) 503 AfterAll(rt.T("AA")) 504 }) 505 }, []string{"BA", "A", "B", "C", "C", "C", "AA"}, 506 "A", "B", HavePassed(NumAttempts(1)), 507 "C", HavePassed(NumAttempts(3)), 508 ), 509 Entry("When the BeforeAll is flaky", true, func() { 510 Context("container", Ordered, FlakeAttempts(5), func() { 511 BeforeAll(rt.T("BA", FlakeyFailerWithCleanup(2, "DC-BA"))) 512 It("A", rt.T("A", FlakeyFailer(2))) 513 It("B", rt.T("B")) 514 It("C", rt.T("C")) 515 AfterAll(rt.T("AA")) 516 }) 517 }, []string{ 518 "BA", "AA", "DC-BA-pre", 519 "BA", "AA", "DC-BA-pre", 520 "BA", "A", "A", "A", 521 "B", "C", 522 "AA", "DC-BA-post", "DC-BA-pre", 523 }, 524 "A", HavePassed(NumAttempts(5)), 525 "B", "C", HavePassed(), 526 ), 527 Entry("When the AFterAll is flaky", true, func() { 528 Context("container", Ordered, FlakeAttempts(4), func() { 529 BeforeAll(rt.T("BA", DC("DC-BA"))) 530 It("A", rt.T("A")) 531 It("B", rt.T("B")) 532 It("C", rt.T("C")) 533 AfterAll(rt.T("AA", FlakeyFailerWithCleanup(2, "DC-AA"))) 534 }) 535 }, []string{ 536 "BA", "A", "B", "C", "AA", "DC-AA-pre", 537 "C", "AA", "DC-AA-pre", 538 "C", "AA", "DC-AA-post", "DC-AA-pre", "DC-BA", 539 }, 540 "A", "B", HavePassed(), 541 "C", HavePassed(NumAttempts(3)), 542 ), 543 544 //Let's enter the dragons nest! 545 Entry("happy-path for nested containers", true, func() { 546 BeforeEach(rt.T("BE-L0")) 547 Context("container", Ordered, func() { 548 BeforeAll(rt.T("BA-1-L1", DC("DC-BA-L1"))) 549 BeforeAll(rt.T("BA-2-L1")) 550 BeforeEach(rt.T("BE-L1")) 551 It("A", rt.T("A")) 552 It("B", rt.T("B")) 553 Context("inner", func() { 554 BeforeAll(rt.T("BA-1-L2", DC("DC-BA-L2"))) 555 BeforeAll(rt.T("BA-2-L2")) 556 BeforeEach(rt.T("BE-L2")) 557 It("C", rt.T("C")) 558 It("D", rt.T("D")) 559 AfterEach(rt.T("AE-L2")) 560 AfterAll(rt.T("AA-1-L2", DC("DC-AA-L2"))) 561 AfterAll(rt.T("AA-2-L2")) 562 }) 563 It("E", rt.T("E")) 564 AfterEach(rt.T("AE-L1")) 565 AfterAll(rt.T("AA-1-L1", DC("DC-AA-L1"))) 566 AfterAll(rt.T("AA-2-L1")) 567 }) 568 AfterEach(rt.T("AE-L0")) 569 }, []string{ 570 "BE-L0", "BA-1-L1", "BA-2-L1", "BE-L1", "A", "AE-L1", "AE-L0", 571 "BE-L0", "BE-L1", "B", "AE-L1", "AE-L0", 572 "BE-L0", "BE-L1", "BA-1-L2", "BA-2-L2", "BE-L2", "C", "AE-L2", "AE-L1", "AE-L0", 573 "BE-L0", "BE-L1", "BE-L2", "D", "AE-L2", "AA-1-L2", "AA-2-L2", "AE-L1", "AE-L0", "DC-AA-L2", "DC-BA-L2", 574 "BE-L0", "BE-L1", "E", "AE-L1", "AA-1-L1", "AA-2-L1", "AE-L0", "DC-AA-L1", "DC-BA-L1", 575 }), 576 Entry("happy-path where last spec is in nested container", true, func() { 577 BeforeEach(rt.T("BE-L0")) 578 Context("container", Ordered, func() { 579 BeforeAll(rt.T("BA-1-L1", DC("DC-BA-L1"))) 580 BeforeAll(rt.T("BA-2-L1")) 581 BeforeEach(rt.T("BE-L1")) 582 It("A", rt.T("A")) 583 It("B", rt.T("B")) 584 Context("inner", func() { 585 BeforeAll(rt.T("BA-1-L2", DC("DC-BA-L2"))) 586 BeforeAll(rt.T("BA-2-L2")) 587 BeforeEach(rt.T("BE-L2")) 588 It("C", rt.T("C")) 589 It("D", rt.T("D")) 590 AfterEach(rt.T("AE-L2")) 591 AfterAll(rt.T("AA-1-L2", DC("DC-AA-L2"))) 592 AfterAll(rt.T("AA-2-L2")) 593 }) 594 AfterEach(rt.T("AE-L1")) 595 AfterAll(rt.T("AA-1-L1", DC("DC-AA-L1"))) 596 AfterAll(rt.T("AA-2-L1")) 597 }) 598 AfterEach(rt.T("AE-L0")) 599 }, []string{ 600 "BE-L0", "BA-1-L1", "BA-2-L1", "BE-L1", "A", "AE-L1", "AE-L0", 601 "BE-L0", "BE-L1", "B", "AE-L1", "AE-L0", 602 "BE-L0", "BE-L1", "BA-1-L2", "BA-2-L2", "BE-L2", "C", "AE-L2", "AE-L1", "AE-L0", 603 "BE-L0", "BE-L1", "BE-L2", "D", "AE-L2", "AA-1-L2", "AA-2-L2", "AE-L1", "AA-1-L1", "AA-2-L1", "AE-L0", "DC-AA-L1", "DC-AA-L2", "DC-BA-L2", "DC-BA-L1", 604 }), 605 Entry("when an outer spec is skipped", true, func() { 606 Context("container", Ordered, func() { 607 BeforeAll(rt.T("BA-O", DC("DC-O"))) 608 It("A", rt.T("A", func() { Skip("skip") })) 609 It("B", rt.T("B")) 610 Context("inner", func() { 611 BeforeAll(rt.T("BA-I", DC("DC-I"))) 612 It("C", rt.T("C")) 613 It("D", rt.T("D")) 614 AfterAll(rt.T("AA-I")) 615 }) 616 It("E", rt.T("E")) 617 AfterAll(rt.T("AA-O")) 618 }) 619 }, []string{"BA-O", "A", "B", "BA-I", "C", "D", "AA-I", "DC-I", "E", "AA-O", "DC-O"}, 620 "A", HaveBeenSkippedWithMessage("skip"), 621 "B", "C", "D", "E", HavePassed(), 622 ), 623 Entry("when an inner spec is skipped", true, func() { 624 Context("container", Ordered, func() { 625 BeforeAll(rt.T("BA-O", DC("DC-O"))) 626 It("A", rt.T("A")) 627 It("B", rt.T("B")) 628 Context("inner", func() { 629 BeforeAll(rt.T("BA-I", DC("DC-I"))) 630 It("C", rt.T("C", func() { Skip("skip") })) 631 It("D", rt.T("D")) 632 AfterAll(rt.T("AA-I")) 633 }) 634 It("E", rt.T("E")) 635 AfterAll(rt.T("AA-O")) 636 }) 637 }, []string{"BA-O", "A", "B", "BA-I", "C", "D", "AA-I", "DC-I", "E", "AA-O", "DC-O"}, 638 "C", HaveBeenSkippedWithMessage("skip"), 639 "A", "B", "D", "E", HavePassed(), 640 ), 641 Entry("when an outer BeforeAll is skipped", true, func() { 642 Context("container", Ordered, func() { 643 BeforeAll(rt.T("BA-O", func() { DeferCleanup(rt.T("DC-O")); Skip("skip") })) 644 It("A", rt.T("A")) 645 It("B", rt.T("B")) 646 Context("inner", func() { 647 BeforeAll(rt.T("BA-I")) 648 It("C", rt.T("C")) 649 It("D", rt.T("D")) 650 AfterAll(rt.T("AA-I")) 651 }) 652 It("E", rt.T("E")) 653 AfterAll(rt.T("AA-O")) 654 }) 655 }, []string{"BA-O", "AA-O", "DC-O"}, 656 "A", HaveBeenSkippedWithMessage("skip"), 657 "B", "C", "D", "E", HaveBeenSkippedWithMessage(SKIP_DUE_TO_BEFORE_ALL_SKIP), 658 ), 659 Entry("when an inner BeforeAll is skipped", true, func() { 660 Context("container", Ordered, func() { 661 BeforeAll(rt.T("BA-O", DC("DC-O"))) 662 It("A", rt.T("A")) 663 It("B", rt.T("B")) 664 Context("inner", func() { 665 BeforeAll(rt.T("BA-I", func() { DeferCleanup(rt.T("DC-I")); Skip("skip") })) 666 It("C", rt.T("C")) 667 It("D", rt.T("D")) 668 AfterAll(rt.T("AA-I")) 669 }) 670 It("E", rt.T("E")) 671 AfterAll(rt.T("AA-O")) 672 }) 673 }, []string{"BA-O", "A", "B", "BA-I", "AA-I", "DC-I", "E", "AA-O", "DC-O"}, 674 "A", "B", "E", HavePassed(), 675 "C", HaveBeenSkippedWithMessage("skip"), 676 "D", HaveBeenSkippedWithMessage(SKIP_DUE_TO_BEFORE_ALL_SKIP), 677 ), 678 Entry("when the last spec is marked as pending", true, func() { 679 Context("container", Ordered, func() { 680 BeforeAll(rt.T("BA-O", DC("DC-O"))) 681 FIt("A", rt.T("A")) 682 FIt("B", rt.T("B")) 683 FContext("inner", func() { 684 BeforeAll(rt.T("BA-I", DC("DC-I"))) 685 It("C", rt.T("C")) 686 PIt("D", rt.T("D")) 687 AfterAll(rt.T("AA-I")) 688 }) 689 FIt("E", rt.T("E")) 690 It("F", rt.T("F")) 691 AfterAll(rt.T("AA-O")) 692 }) 693 }, []string{"BA-O", "A", "B", "BA-I", "C", "AA-I", "DC-I", "E", "AA-O", "DC-O"}, 694 "A", "B", "C", "E", HavePassed(), 695 "D", BePending(), "F", HaveBeenSkipped(), 696 ), 697 Entry("when an outer spec fails", false, func() { 698 Context("container", Ordered, func() { 699 BeforeAll(rt.T("BA-O", DC("DC-O"))) 700 It("A", rt.T("A")) 701 It("B", rt.T("B", func() { F("fail") })) 702 Context("inner", func() { 703 BeforeAll(rt.T("BA-I", DC("DC-I"))) 704 It("C", rt.T("C")) 705 It("D", rt.T("D")) 706 AfterAll(rt.T("AA-I")) 707 }) 708 It("E", rt.T("E")) 709 AfterAll(rt.T("AA-O")) 710 }) 711 }, []string{"BA-O", "A", "B", "AA-O", "DC-O"}, 712 "A", HavePassed(), "B", HaveFailed("fail"), 713 "C", "D", "E", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 714 ), 715 Entry("when an inner spec fails", false, func() { 716 Context("container", Ordered, func() { 717 BeforeAll(rt.T("BA-O", DC("DC-O"))) 718 It("A", rt.T("A")) 719 It("B", rt.T("B")) 720 Context("inner", func() { 721 BeforeAll(rt.T("BA-I", DC("DC-I"))) 722 It("C", rt.T("C", func() { F("fail") })) 723 It("D", rt.T("D")) 724 AfterAll(rt.T("AA-I")) 725 }) 726 It("E", rt.T("E")) 727 AfterAll(rt.T("AA-O")) 728 }) 729 }, []string{"BA-O", "A", "B", "BA-I", "C", "AA-I", "AA-O", "DC-I", "DC-O"}, 730 "A", HavePassed(), "B", HavePassed(), "C", HaveFailed("fail"), 731 "D", "E", HaveBeenSkippedWithMessage(SKIP_DUE_TO_EARLIER_FAILURE), 732 ), 733 Entry("when flakey, and an outer BeforeAll flakes", true, func() { 734 i := 0 735 Context("container", Ordered, FlakeAttempts(4), func() { 736 BeforeAll(rt.T("BA-O", func() { 737 i += 1 738 DeferCleanup(rt.T("DC-O")) 739 if i < 3 { 740 F("fail") 741 } 742 })) 743 It("A", rt.T("A")) 744 It("B", rt.T("B")) 745 Context("inner", func() { 746 BeforeAll(rt.T("BA-I", DC("DC-I"))) 747 It("C", rt.T("C")) 748 It("D", rt.T("D")) 749 AfterAll(rt.T("AA-I")) 750 }) 751 It("E", rt.T("E")) 752 AfterAll(rt.T("AA-O")) 753 }) 754 }, []string{ 755 "BA-O", "AA-O", "DC-O", 756 "BA-O", "AA-O", "DC-O", 757 "BA-O", "A", "B", "BA-I", "C", "D", "AA-I", "DC-I", "E", "AA-O", "DC-O"}, 758 "A", HavePassed(NumAttempts(3)), 759 "B", "C", "D", "E", HavePassed(), 760 ), 761 Entry("when flakey, and an inner BeforeAll flakes", true, func() { 762 i := 0 763 Context("container", Ordered, FlakeAttempts(4), func() { 764 BeforeAll(rt.T("BA-O", DC("DC-O"))) 765 It("A", rt.T("A")) 766 It("B", rt.T("B")) 767 Context("inner", func() { 768 BeforeAll(rt.T("BA-I", func() { 769 i += 1 770 DeferCleanup(rt.T("DC-I")) 771 if i < 3 { 772 F("fail") 773 } 774 })) 775 It("C", rt.T("C")) 776 It("D", rt.T("D")) 777 AfterAll(rt.T("AA-I")) 778 }) 779 It("E", rt.T("E")) 780 AfterAll(rt.T("AA-O")) 781 }) 782 }, []string{ 783 "BA-O", "A", "B", 784 "BA-I", "AA-I", "DC-I", 785 "BA-I", "AA-I", "DC-I", 786 "BA-I", "C", "D", "AA-I", "DC-I", "E", "AA-O", "DC-O"}, 787 "A", "B", "D", "E", HavePassed(), 788 "C", HavePassed(NumAttempts(3)), 789 ), 790 Entry("when specs are flakey", true, func() { 791 Context("container", Ordered, FlakeAttempts(4), func() { 792 BeforeAll(rt.T("BA-O", DC("DC-O"))) 793 It("A", rt.T("A", FlakeyFailer(2))) 794 It("B", rt.T("B", FlakeyFailer(2))) 795 Context("inner", func() { 796 BeforeAll(rt.T("BA-I", DC("DC-I"))) 797 It("C", rt.T("C", FlakeyFailer(2))) 798 It("D", rt.T("D", FlakeyFailer(2))) 799 AfterAll(rt.T("AA-I")) 800 }) 801 It("E", rt.T("E", FlakeyFailer(2))) 802 AfterAll(rt.T("AA-O")) 803 }) 804 }, []string{ 805 "BA-O", "A", "A", "A", 806 "B", "B", "B", 807 "BA-I", "C", "C", "C", 808 "D", "D", "D", "AA-I", "DC-I", 809 "E", "E", "E", "AA-O", "DC-O", 810 }, 811 "A", "B", "C", "D", "E", HavePassed(NumAttempts(3)), 812 ), 813 Entry("when AfterAlls are flakey", true, func() { 814 Context("container", Ordered, FlakeAttempts(4), func() { 815 BeforeAll(rt.T("BA-O", DC("DC-O"))) 816 It("A", rt.T("A")) 817 It("B", rt.T("B")) 818 Context("inner", func() { 819 BeforeAll(rt.T("BA-I", DC("DC-I"))) 820 It("C", rt.T("C")) 821 It("D", rt.T("D")) 822 AfterAll(rt.T("AA-I", FlakeyFailer(2))) 823 }) 824 It("E", rt.T("E")) 825 AfterAll(rt.T("AA-O", FlakeyFailer(2))) 826 }) 827 }, []string{ 828 "BA-O", "A", "B", "BA-I", "C", 829 "D", "AA-I", "D", "AA-I", "D", "AA-I", "DC-I", 830 "E", "AA-O", "E", "AA-O", "E", "AA-O", "DC-O", 831 }, 832 "A", "B", "C", "D", "E", HavePassed(), 833 ), 834 //this behavior is a bit weird, but it's such an edge case that we're going to leave it 835 //unless an issue gets opened 836 Entry("when DeferCleanups are flakey", true, func() { 837 Context("container", Ordered, FlakeAttempts(4), func() { 838 BeforeAll(rt.T("BA-O", DC("DC-O", FlakeyFailer(2)))) 839 It("A", rt.T("A")) 840 It("B", rt.T("B")) 841 Context("inner", func() { 842 BeforeAll(rt.T("BA-I", DC("DC-I", FlakeyFailer(2)))) 843 It("C", rt.T("C")) 844 It("D", rt.T("D")) 845 AfterAll(rt.T("AA-I")) 846 }) 847 It("E", rt.T("E")) 848 AfterAll(rt.T("AA-O")) 849 }) 850 }, []string{ 851 "BA-O", "A", "B", "BA-I", "C", "D", "AA-I", "DC-I", "D", "AA-I", 852 "E", "AA-O", "DC-O", "E", "AA-O", 853 }, 854 "A", "B", "C", "D", "E", HavePassed(), 855 ), 856 )