| package remote_test |
| |
| import ( |
| . "github.com/onsi/ginkgo" |
| . "github.com/onsi/gomega" |
| |
| "time" |
| |
| "github.com/onsi/ginkgo/config" |
| . "github.com/onsi/ginkgo/internal/remote" |
| st "github.com/onsi/ginkgo/reporters/stenographer" |
| "github.com/onsi/ginkgo/types" |
| ) |
| |
| var _ = Describe("Aggregator", func() { |
| var ( |
| aggregator *Aggregator |
| reporterConfig config.DefaultReporterConfigType |
| stenographer *st.FakeStenographer |
| result chan bool |
| |
| ginkgoConfig1 config.GinkgoConfigType |
| ginkgoConfig2 config.GinkgoConfigType |
| |
| suiteSummary1 *types.SuiteSummary |
| suiteSummary2 *types.SuiteSummary |
| |
| beforeSummary *types.SetupSummary |
| afterSummary *types.SetupSummary |
| specSummary *types.SpecSummary |
| |
| suiteDescription string |
| ) |
| |
| BeforeEach(func() { |
| reporterConfig = config.DefaultReporterConfigType{ |
| NoColor: false, |
| SlowSpecThreshold: 0.1, |
| NoisyPendings: true, |
| Succinct: false, |
| Verbose: true, |
| } |
| stenographer = st.NewFakeStenographer() |
| result = make(chan bool, 1) |
| aggregator = NewAggregator(2, result, reporterConfig, stenographer) |
| |
| // |
| // now set up some fixture data |
| // |
| |
| ginkgoConfig1 = config.GinkgoConfigType{ |
| RandomSeed: 1138, |
| RandomizeAllSpecs: true, |
| ParallelNode: 1, |
| ParallelTotal: 2, |
| } |
| |
| ginkgoConfig2 = config.GinkgoConfigType{ |
| RandomSeed: 1138, |
| RandomizeAllSpecs: true, |
| ParallelNode: 2, |
| ParallelTotal: 2, |
| } |
| |
| suiteDescription = "My Parallel Suite" |
| |
| suiteSummary1 = &types.SuiteSummary{ |
| SuiteDescription: suiteDescription, |
| |
| NumberOfSpecsBeforeParallelization: 30, |
| NumberOfTotalSpecs: 17, |
| NumberOfSpecsThatWillBeRun: 15, |
| NumberOfPendingSpecs: 1, |
| NumberOfSkippedSpecs: 1, |
| } |
| |
| suiteSummary2 = &types.SuiteSummary{ |
| SuiteDescription: suiteDescription, |
| |
| NumberOfSpecsBeforeParallelization: 30, |
| NumberOfTotalSpecs: 13, |
| NumberOfSpecsThatWillBeRun: 8, |
| NumberOfPendingSpecs: 2, |
| NumberOfSkippedSpecs: 3, |
| } |
| |
| beforeSummary = &types.SetupSummary{ |
| State: types.SpecStatePassed, |
| CapturedOutput: "BeforeSuiteOutput", |
| } |
| |
| afterSummary = &types.SetupSummary{ |
| State: types.SpecStatePassed, |
| CapturedOutput: "AfterSuiteOutput", |
| } |
| |
| specSummary = &types.SpecSummary{ |
| State: types.SpecStatePassed, |
| CapturedOutput: "SpecOutput", |
| } |
| }) |
| |
| call := func(method string, args ...interface{}) st.FakeStenographerCall { |
| return st.NewFakeStenographerCall(method, args...) |
| } |
| |
| beginSuite := func() { |
| stenographer.Reset() |
| aggregator.SpecSuiteWillBegin(ginkgoConfig2, suiteSummary2) |
| aggregator.SpecSuiteWillBegin(ginkgoConfig1, suiteSummary1) |
| Eventually(func() interface{} { |
| return len(stenographer.Calls()) |
| }).Should(BeNumerically(">=", 3)) |
| } |
| |
| Describe("Announcing the beginning of the suite", func() { |
| Context("When one of the parallel-suites starts", func() { |
| BeforeEach(func() { |
| aggregator.SpecSuiteWillBegin(ginkgoConfig2, suiteSummary2) |
| }) |
| |
| It("should be silent", func() { |
| Consistently(func() interface{} { return stenographer.Calls() }).Should(BeEmpty()) |
| }) |
| }) |
| |
| Context("once all of the parallel-suites have started", func() { |
| BeforeEach(func() { |
| aggregator.SpecSuiteWillBegin(ginkgoConfig2, suiteSummary2) |
| aggregator.SpecSuiteWillBegin(ginkgoConfig1, suiteSummary1) |
| Eventually(func() interface{} { |
| return stenographer.Calls() |
| }).Should(HaveLen(3)) |
| }) |
| |
| It("should announce the beginning of the suite", func() { |
| Ω(stenographer.Calls()).Should(HaveLen(3)) |
| Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceSuite", suiteDescription, ginkgoConfig1.RandomSeed, true, false))) |
| Ω(stenographer.Calls()[1]).Should(Equal(call("AnnounceTotalNumberOfSpecs", 30, false))) |
| Ω(stenographer.Calls()[2]).Should(Equal(call("AnnounceAggregatedParallelRun", 2, false))) |
| }) |
| }) |
| }) |
| |
| Describe("Announcing specs and before suites", func() { |
| Context("when the parallel-suites have not all started", func() { |
| BeforeEach(func() { |
| aggregator.BeforeSuiteDidRun(beforeSummary) |
| aggregator.AfterSuiteDidRun(afterSummary) |
| aggregator.SpecDidComplete(specSummary) |
| }) |
| |
| It("should not announce any specs", func() { |
| Consistently(func() interface{} { return stenographer.Calls() }).Should(BeEmpty()) |
| }) |
| |
| Context("when the parallel-suites subsequently start", func() { |
| BeforeEach(func() { |
| beginSuite() |
| }) |
| |
| It("should announce the specs, the before suites and the after suites", func() { |
| Eventually(func() interface{} { |
| return stenographer.Calls() |
| }).Should(ContainElement(call("AnnounceSuccesfulSpec", specSummary))) |
| |
| Ω(stenographer.Calls()).Should(ContainElement(call("AnnounceCapturedOutput", beforeSummary.CapturedOutput))) |
| Ω(stenographer.Calls()).Should(ContainElement(call("AnnounceCapturedOutput", afterSummary.CapturedOutput))) |
| }) |
| }) |
| }) |
| |
| Context("When the parallel-suites have all started", func() { |
| BeforeEach(func() { |
| beginSuite() |
| stenographer.Reset() |
| }) |
| |
| Context("When a spec completes", func() { |
| BeforeEach(func() { |
| aggregator.BeforeSuiteDidRun(beforeSummary) |
| aggregator.SpecDidComplete(specSummary) |
| aggregator.AfterSuiteDidRun(afterSummary) |
| Eventually(func() interface{} { |
| return stenographer.Calls() |
| }).Should(HaveLen(5)) |
| }) |
| |
| It("should announce the captured output of the BeforeSuite", func() { |
| Ω(stenographer.Calls()[0]).Should(Equal(call("AnnounceCapturedOutput", beforeSummary.CapturedOutput))) |
| }) |
| |
| It("should announce that the spec will run (when in verbose mode)", func() { |
| Ω(stenographer.Calls()[1]).Should(Equal(call("AnnounceSpecWillRun", specSummary))) |
| }) |
| |
| It("should announce the captured stdout of the spec", func() { |
| Ω(stenographer.Calls()[2]).Should(Equal(call("AnnounceCapturedOutput", specSummary.CapturedOutput))) |
| }) |
| |
| It("should announce completion", func() { |
| Ω(stenographer.Calls()[3]).Should(Equal(call("AnnounceSuccesfulSpec", specSummary))) |
| }) |
| |
| It("should announce the captured output of the AfterSuite", func() { |
| Ω(stenographer.Calls()[4]).Should(Equal(call("AnnounceCapturedOutput", afterSummary.CapturedOutput))) |
| }) |
| }) |
| }) |
| }) |
| |
| Describe("Announcing the end of the suite", func() { |
| BeforeEach(func() { |
| beginSuite() |
| stenographer.Reset() |
| }) |
| |
| Context("When one of the parallel-suites ends", func() { |
| BeforeEach(func() { |
| aggregator.SpecSuiteDidEnd(suiteSummary2) |
| }) |
| |
| It("should be silent", func() { |
| Consistently(func() interface{} { return stenographer.Calls() }).Should(BeEmpty()) |
| }) |
| |
| It("should not notify the channel", func() { |
| Ω(result).Should(BeEmpty()) |
| }) |
| }) |
| |
| Context("once all of the parallel-suites end", func() { |
| BeforeEach(func() { |
| time.Sleep(200 * time.Millisecond) |
| |
| suiteSummary1.SuiteSucceeded = true |
| suiteSummary1.NumberOfPassedSpecs = 15 |
| suiteSummary1.NumberOfFailedSpecs = 0 |
| suiteSummary1.NumberOfFlakedSpecs = 3 |
| suiteSummary2.SuiteSucceeded = false |
| suiteSummary2.NumberOfPassedSpecs = 5 |
| suiteSummary2.NumberOfFailedSpecs = 3 |
| suiteSummary2.NumberOfFlakedSpecs = 4 |
| |
| aggregator.SpecSuiteDidEnd(suiteSummary2) |
| aggregator.SpecSuiteDidEnd(suiteSummary1) |
| Eventually(func() interface{} { |
| return stenographer.Calls() |
| }).Should(HaveLen(2)) |
| }) |
| |
| It("should announce the end of the suite", func() { |
| compositeSummary := stenographer.Calls()[1].Args[0].(*types.SuiteSummary) |
| |
| Ω(compositeSummary.SuiteSucceeded).Should(BeFalse()) |
| Ω(compositeSummary.NumberOfSpecsThatWillBeRun).Should(Equal(23)) |
| Ω(compositeSummary.NumberOfTotalSpecs).Should(Equal(30)) |
| Ω(compositeSummary.NumberOfPassedSpecs).Should(Equal(20)) |
| Ω(compositeSummary.NumberOfFailedSpecs).Should(Equal(3)) |
| Ω(compositeSummary.NumberOfPendingSpecs).Should(Equal(3)) |
| Ω(compositeSummary.NumberOfSkippedSpecs).Should(Equal(4)) |
| Ω(compositeSummary.NumberOfFlakedSpecs).Should(Equal(7)) |
| Ω(compositeSummary.RunTime.Seconds()).Should(BeNumerically(">", 0.2)) |
| }) |
| }) |
| |
| Context("when all the parallel-suites pass", func() { |
| BeforeEach(func() { |
| suiteSummary1.SuiteSucceeded = true |
| suiteSummary2.SuiteSucceeded = true |
| |
| aggregator.SpecSuiteDidEnd(suiteSummary2) |
| aggregator.SpecSuiteDidEnd(suiteSummary1) |
| Eventually(func() interface{} { |
| return stenographer.Calls() |
| }).Should(HaveLen(2)) |
| }) |
| |
| It("should report success", func() { |
| compositeSummary := stenographer.Calls()[1].Args[0].(*types.SuiteSummary) |
| |
| Ω(compositeSummary.SuiteSucceeded).Should(BeTrue()) |
| }) |
| |
| It("should notify the channel that it succeded", func(done Done) { |
| Ω(<-result).Should(BeTrue()) |
| close(done) |
| }) |
| }) |
| |
| Context("when one of the parallel-suites fails", func() { |
| BeforeEach(func() { |
| suiteSummary1.SuiteSucceeded = true |
| suiteSummary2.SuiteSucceeded = false |
| |
| aggregator.SpecSuiteDidEnd(suiteSummary2) |
| aggregator.SpecSuiteDidEnd(suiteSummary1) |
| Eventually(func() interface{} { |
| return stenographer.Calls() |
| }).Should(HaveLen(2)) |
| }) |
| |
| It("should report failure", func() { |
| compositeSummary := stenographer.Calls()[1].Args[0].(*types.SuiteSummary) |
| |
| Ω(compositeSummary.SuiteSucceeded).Should(BeFalse()) |
| }) |
| |
| It("should notify the channel that it failed", func(done Done) { |
| Ω(<-result).Should(BeFalse()) |
| close(done) |
| }) |
| }) |
| }) |
| }) |