github.com/onsi/ginkgo@v1.16.6-0.20211118180735-4e1925ba4c95/internal/internal_integration/parallel_test.go (about) 1 package internal_integration_test 2 3 import ( 4 "time" 5 6 . "github.com/onsi/ginkgo" 7 "github.com/onsi/ginkgo/internal" 8 . "github.com/onsi/ginkgo/internal/test_helpers" 9 "github.com/onsi/ginkgo/types" 10 . "github.com/onsi/gomega" 11 ) 12 13 var _ = Describe("Running tests in parallel", func() { 14 var conf2 types.SuiteConfig 15 var reporter2 *FakeReporter 16 var rt2 *RunTracker 17 var serialValidator chan interface{} 18 19 var fixture = func(rt *RunTracker, proc int) { 20 SynchronizedBeforeSuite(func() []byte { 21 rt.Run("before-suite-1") 22 return []byte("floop") 23 }, func(proc1Data []byte) { 24 rt.Run("before-suite-2 " + string(proc1Data)) 25 }) 26 27 It("A", rt.T("A", func() { 28 time.Sleep(10 * time.Millisecond) 29 })) 30 It("B", rt.T("B", func() { 31 time.Sleep(10 * time.Millisecond) 32 })) 33 It("C", rt.T("C", func() { 34 time.Sleep(10 * time.Millisecond) 35 })) 36 It("D", rt.T("D", func() { 37 time.Sleep(10 * time.Millisecond) 38 })) 39 It("E", rt.T("E", func() { 40 time.Sleep(10 * time.Millisecond) 41 })) 42 It("F", rt.T("F", func() { 43 time.Sleep(10 * time.Millisecond) 44 })) 45 Context("Ordered", Ordered, func() { 46 It("OA", rt.T("OA", func() { 47 time.Sleep(10 * time.Millisecond) 48 })) 49 It("OB", rt.T("OB", func() { 50 time.Sleep(10 * time.Millisecond) 51 })) 52 It("OC", rt.T("OC", func() { 53 time.Sleep(10 * time.Millisecond) 54 })) 55 }) 56 It("G", Serial, rt.T("G", func() { 57 Ω(serialValidator).Should(BeClosed()) 58 time.Sleep(10 * time.Millisecond) 59 })) 60 It("H", Serial, rt.T("H", func() { 61 Ω(serialValidator).Should(BeClosed()) 62 time.Sleep(10 * time.Millisecond) 63 })) 64 It("I", Serial, rt.T("I", func() { 65 Ω(serialValidator).Should(BeClosed()) 66 time.Sleep(10 * time.Millisecond) 67 })) 68 Context("Ordered and Serial", Ordered, Serial, func() { 69 It("OSA", rt.T("OSA", func() { 70 Ω(serialValidator).Should(BeClosed()) 71 time.Sleep(10 * time.Millisecond) 72 })) 73 It("OSB", rt.T("OSB", func() { 74 Ω(serialValidator).Should(BeClosed()) 75 time.Sleep(10 * time.Millisecond) 76 })) 77 }) 78 79 SynchronizedAfterSuite(rt.T("after-suite-1", func() { 80 if proc == 2 { 81 close(serialValidator) 82 } 83 }), rt.T("after-suite-2")) 84 } 85 86 BeforeEach(func() { 87 serialValidator = make(chan interface{}) 88 //set up configuration for proc 1 and proc 2 89 90 //SetUpForParallel starts up a server, sets up a client, and sets up the exitChannels map - they're all cleaned up automatically after the test 91 SetUpForParallel(2) 92 93 conf.ParallelProcess = 1 94 conf.RandomizeAllSpecs = true 95 conf.RandomSeed = 17 96 97 conf2 = conf //makes a copy 98 conf2.ParallelProcess = 2 99 100 // construct suite 1... 101 suite1 := internal.NewSuite() 102 WithSuite(suite1, func() { 103 fixture(rt, 1) 104 Ω(suite1.BuildTree()).Should(Succeed()) 105 }) 106 107 //now construct suite 2... 108 suite2 := internal.NewSuite() 109 rt2 = NewRunTracker() 110 WithSuite(suite2, func() { 111 fixture(rt2, 2) 112 Ω(suite2.BuildTree()).Should(Succeed()) 113 }) 114 115 finished := make(chan bool) 116 exit1 := exitChannels[1] //avoid a race around exitChannels access in a separate goroutine 117 //now launch suite 1... 118 go func() { 119 success, _ := suite1.Run("proc 1", Label("TopLevelLabel"), "/path/to/suite", failer, reporter, writer, outputInterceptor, interruptHandler, client, conf) 120 finished <- success 121 close(exit1) 122 }() 123 124 //and launch suite 2... 125 reporter2 = &FakeReporter{} 126 exit2 := exitChannels[2] //avoid a race around exitChannels access in a separate goroutine 127 go func() { 128 success, _ := suite2.Run("proc 2", Label("TopLevelLabel"), "/path/to/suite", internal.NewFailer(), reporter2, writer, outputInterceptor, interruptHandler, client, conf2) 129 finished <- success 130 close(exit2) 131 }() 132 133 // eventually both suites should finish (and succeed)... 134 Eventually(finished).Should(Receive(Equal(true))) 135 Eventually(finished).Should(Receive(Equal(true))) 136 // and now we're ready to make asserts on the various run trackers and reporters 137 }) 138 139 It("distributes tests across the parallel procs and runs them", func() { 140 Ω(rt).Should(HaveRun("before-suite-1")) 141 Ω(rt).Should(HaveRun("before-suite-2 floop")) 142 Ω(rt).Should(HaveRun("after-suite-1")) 143 Ω(rt).Should(HaveRun("after-suite-2")) 144 145 Ω(rt2).ShouldNot(HaveRun("before-suite-1")) 146 Ω(rt2).Should(HaveRun("before-suite-2 floop")) 147 Ω(rt2).Should(HaveRun("after-suite-1")) 148 Ω(rt2).ShouldNot(HaveRun("after-suite-2")) 149 150 allRuns := append(rt.TrackedRuns(), rt2.TrackedRuns()...) 151 Ω(allRuns).Should(ConsistOf( 152 "before-suite-1", "before-suite-2 floop", "after-suite-1", "after-suite-2", "before-suite-2 floop", "after-suite-1", 153 "A", "B", "C", "D", "E", "F", "G", "H", "I", "OA", "OB", "OC", "OSA", "OSB", //all ran 154 )) 155 156 Ω(reporter.Did.Names()).ShouldNot(BeEmpty()) 157 Ω(reporter2.Did.Names()).ShouldNot(BeEmpty()) 158 names := append(reporter.Did.Names(), reporter2.Did.Names()...) 159 Ω(names).Should(ConsistOf("A", "B", "C", "D", "E", "F", "G", "H", "I", "OA", "OB", "OC", "OSA", "OSB")) 160 }) 161 162 It("only runs serial tests on proc 1, after the other proc has finished", func() { 163 names := reporter.Did.Names() 164 Ω(names).Should(ContainElements("G", "H", "I", "OSA", "OSB")) 165 for idx, name := range names { 166 if name == "OSA" { 167 Ω(names[idx+1]).Should(Equal("OSB")) 168 break 169 } 170 } 171 Ω(reporter2.Did.Names()).ShouldNot(ContainElements("G", "H", "I", "OSA", "OSB")) 172 }) 173 174 It("it ensures specs in an ordered container run on the same process and are ordered", func() { 175 names1 := reporter.Did.Names() 176 names2 := reporter2.Did.Names() 177 in1, _ := ContainElement("OA").Match(names1) 178 winner := names1 179 if !in1 { 180 winner = names2 181 } 182 found := false 183 for idx, name := range winner { 184 if name == "OA" { 185 found = true 186 Ω(winner[idx+1]).Should(Equal("OB")) 187 Ω(winner[idx+2]).Should(Equal("OC")) 188 break 189 } 190 } 191 Ω(found).Should(BeTrue()) 192 }) 193 194 It("reports the correct statistics", func() { 195 Ω(reporter.End.PreRunStats.TotalSpecs).Should(Equal(14)) 196 Ω(reporter2.End.PreRunStats.TotalSpecs).Should(Equal(14)) 197 Ω(reporter.End.PreRunStats.SpecsThatWillRun).Should(Equal(14)) 198 Ω(reporter2.End.PreRunStats.SpecsThatWillRun).Should(Equal(14)) 199 200 Ω(reporter.End.SpecReports.WithLeafNodeType(types.NodeTypeIt).CountWithState(types.SpecStatePassed) + 201 reporter2.End.SpecReports.WithLeafNodeType(types.NodeTypeIt).CountWithState(types.SpecStatePassed)).Should(Equal(14)) 202 }) 203 })