|
| 1 | +package internal_integration_test |
| 2 | + |
| 3 | +import ( |
| 4 | + "time" |
| 5 | + |
| 6 | + . "github.com/onsi/ginkgo/v2" |
| 7 | + . "github.com/onsi/gomega" |
| 8 | + |
| 9 | + "github.com/onsi/ginkgo/v2/internal/interrupt_handler" |
| 10 | + . "github.com/onsi/ginkgo/v2/internal/test_helpers" |
| 11 | +) |
| 12 | + |
| 13 | +var _ = Describe("--sleep-on-failure", func() { |
| 14 | + Describe("when a spec fails", func() { |
| 15 | + BeforeEach(func() { |
| 16 | + conf.SleepOnFailure = 50 * time.Millisecond |
| 17 | + success, _ := RunFixture("sleep on failure - failing spec", func() { |
| 18 | + Context("container", func() { |
| 19 | + BeforeEach(rt.T("bef")) |
| 20 | + It("A", rt.T("A", func() { |
| 21 | + DeferCleanup(rt.T("cleanup")) |
| 22 | + F("boom", cl) |
| 23 | + })) |
| 24 | + JustAfterEach(rt.T("just-after")) |
| 25 | + AfterEach(rt.T("aft")) |
| 26 | + }) |
| 27 | + }) |
| 28 | + Ω(success).Should(BeFalse()) |
| 29 | + }) |
| 30 | + |
| 31 | + It("pauses at the moment of failure, before any teardown runs", func() { |
| 32 | + // The pause is hooked into runNode's failure path, so it happens the instant |
| 33 | + // the It fails - before any JustAfterEach/AfterEach/DeferCleanup nodes run. |
| 34 | + // Teardown then proceeds in the normal order once the pause elapses. |
| 35 | + Ω(rt).Should(HaveTracked("bef", "A", "just-after", "aft", "cleanup")) |
| 36 | + }) |
| 37 | + |
| 38 | + It("still runs teardown and cleanup after the pause", func() { |
| 39 | + Ω(rt).Should(HaveRun("aft")) |
| 40 | + Ω(rt).Should(HaveRun("cleanup")) |
| 41 | + }) |
| 42 | + |
| 43 | + It("emits the failure and then a progress report announcing the pause", func() { |
| 44 | + Ω(reporter.Did.Find("A")).Should(HaveFailed("boom", cl)) |
| 45 | + Ω(reporter.ProgressReports).ShouldNot(BeEmpty()) |
| 46 | + Ω(reporter.ProgressReports[0].Message).Should(ContainSubstring("Paused on failure")) |
| 47 | + }) |
| 48 | + }) |
| 49 | + |
| 50 | + Describe("when a failure occurs in a BeforeEach", func() { |
| 51 | + BeforeEach(func() { |
| 52 | + conf.SleepOnFailure = 50 * time.Millisecond |
| 53 | + success, _ := RunFixture("sleep on failure - failing beforeeach", func() { |
| 54 | + Context("container", func() { |
| 55 | + BeforeEach(rt.T("bef", func() { |
| 56 | + F("boom", cl) |
| 57 | + })) |
| 58 | + It("A", rt.T("A")) |
| 59 | + AfterEach(rt.T("aft")) |
| 60 | + }) |
| 61 | + }) |
| 62 | + Ω(success).Should(BeFalse()) |
| 63 | + }) |
| 64 | + |
| 65 | + It("pauses on the setup failure before teardown, and skips the It", func() { |
| 66 | + Ω(rt).Should(HaveTracked("bef", "aft")) |
| 67 | + Ω(reporter.ProgressReports).ShouldNot(BeEmpty()) |
| 68 | + Ω(reporter.ProgressReports[0].Message).Should(ContainSubstring("Paused on failure")) |
| 69 | + }) |
| 70 | + }) |
| 71 | + |
| 72 | + Describe("when a spec passes", func() { |
| 73 | + var start time.Time |
| 74 | + BeforeEach(func() { |
| 75 | + conf.SleepOnFailure = time.Hour // would hang if it ever fired on success |
| 76 | + start = time.Now() |
| 77 | + success, _ := RunFixture("sleep on failure - passing spec", func() { |
| 78 | + It("A", rt.T("A")) |
| 79 | + AfterEach(rt.T("aft")) |
| 80 | + }) |
| 81 | + Ω(success).Should(BeTrue()) |
| 82 | + }) |
| 83 | + |
| 84 | + It("does not pause and emits no pause progress report", func() { |
| 85 | + Ω(time.Since(start)).Should(BeNumerically("<", time.Second)) |
| 86 | + Ω(rt).Should(HaveTracked("A", "aft")) |
| 87 | + Ω(reporter.ProgressReports).Should(BeEmpty()) |
| 88 | + }) |
| 89 | + }) |
| 90 | + |
| 91 | + Describe("when a failure occurs in teardown", func() { |
| 92 | + var start time.Time |
| 93 | + BeforeEach(func() { |
| 94 | + conf.SleepOnFailure = time.Hour // would hang if the teardown failure paused |
| 95 | + start = time.Now() |
| 96 | + success, _ := RunFixture("sleep on failure - failing teardown", func() { |
| 97 | + It("A", rt.T("A")) |
| 98 | + AfterEach(rt.T("aft", func() { |
| 99 | + F("boom", cl) |
| 100 | + })) |
| 101 | + }) |
| 102 | + Ω(success).Should(BeFalse()) |
| 103 | + }) |
| 104 | + |
| 105 | + It("does not pause (teardown is already running, nothing to inspect)", func() { |
| 106 | + Ω(time.Since(start)).Should(BeNumerically("<", time.Second)) |
| 107 | + Ω(rt).Should(HaveTracked("A", "aft")) |
| 108 | + Ω(reporter.ProgressReports).Should(BeEmpty()) |
| 109 | + }) |
| 110 | + }) |
| 111 | + |
| 112 | + Describe("when the feature is disabled (duration is zero)", func() { |
| 113 | + BeforeEach(func() { |
| 114 | + conf.SleepOnFailure = 0 |
| 115 | + success, _ := RunFixture("sleep on failure - disabled", func() { |
| 116 | + It("A", rt.T("A", func() { |
| 117 | + F("boom", cl) |
| 118 | + })) |
| 119 | + AfterEach(rt.T("aft")) |
| 120 | + }) |
| 121 | + Ω(success).Should(BeFalse()) |
| 122 | + }) |
| 123 | + |
| 124 | + It("does not pause and emits no pause progress report", func() { |
| 125 | + Ω(rt).Should(HaveTracked("A", "aft")) |
| 126 | + Ω(reporter.ProgressReports).Should(BeEmpty()) |
| 127 | + }) |
| 128 | + }) |
| 129 | + |
| 130 | + Describe("when the user interrupts during the pause", func() { |
| 131 | + var start time.Time |
| 132 | + BeforeEach(func() { |
| 133 | + conf.SleepOnFailure = time.Hour // long enough that only the interrupt can end it |
| 134 | + start = time.Now() |
| 135 | + success, _ := RunFixture("sleep on failure - interrupted", func() { |
| 136 | + Context("container", func() { |
| 137 | + It("A", rt.T("A", func() { |
| 138 | + // fire the interrupt shortly after this node's body returns, so it |
| 139 | + // lands while the suite is paused waiting on the failure |
| 140 | + go func() { |
| 141 | + time.Sleep(100 * time.Millisecond) |
| 142 | + interruptHandler.Interrupt(interrupt_handler.InterruptCauseSignal) |
| 143 | + }() |
| 144 | + F("boom", cl) |
| 145 | + })) |
| 146 | + AfterEach(rt.T("aft")) |
| 147 | + }) |
| 148 | + }) |
| 149 | + Ω(success).Should(BeFalse()) |
| 150 | + }) |
| 151 | + |
| 152 | + It("ends the pause early and proceeds to run teardown", func() { |
| 153 | + Ω(time.Since(start)).Should(BeNumerically("<", time.Minute)) |
| 154 | + Ω(rt).Should(HaveTracked("A", "aft")) |
| 155 | + }) |
| 156 | + }) |
| 157 | +}) |
0 commit comments