Skip to content

Commit ae8c900

Browse files
committed
handle failures and panics in attached progress reporters
1 parent b670c81 commit ae8c900

5 files changed

+69
-21
lines changed

internal/internal_integration/progress_report_test.go

+23
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"time"
55

66
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/ginkgo/v2/internal/test_helpers"
78
"github.com/onsi/ginkgo/v2/types"
89
. "github.com/onsi/gomega"
910
)
@@ -478,4 +479,26 @@ var _ = Describe("Progress Reporting", func() {
478479
Ω(pr.AdditionalReports).Should(Equal([]string{"Some More (Never Cancelled) Global Information"}))
479480
})
480481
})
482+
483+
Context("when a global progress reporter fails", func() {
484+
BeforeEach(func() {
485+
success, _ := RunFixture("emitting spec progress", func() {
486+
Describe("a container", func() {
487+
It("A", func(ctx SpecContext) {
488+
AttachProgressReporter(func() string {
489+
F("bam")
490+
return "Some Global Information"
491+
})
492+
triggerProgressSignal()
493+
})
494+
})
495+
})
496+
Ω(success).Should(BeFalse())
497+
})
498+
499+
It("marks the spec as failed", func() {
500+
Ω(reporter.Did.Find("A")).Should(HaveFailed("bam"))
501+
})
502+
})
503+
481504
})

internal/progress_reporter_manager.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"context"
55
"sort"
66
"sync"
7+
8+
"github.com/onsi/ginkgo/v2/types"
79
)
810

911
type ProgressReporterManager struct {
@@ -33,7 +35,7 @@ func (prm *ProgressReporterManager) AttachProgressReporter(reporter func() strin
3335
}
3436
}
3537

36-
func (prm *ProgressReporterManager) QueryProgressReporters(ctx context.Context) []string {
38+
func (prm *ProgressReporterManager) QueryProgressReporters(ctx context.Context, failer *Failer) []string {
3739
prm.lock.Lock()
3840
keys := []int{}
3941
for key := range prm.progressReporters {
@@ -53,6 +55,13 @@ func (prm *ProgressReporterManager) QueryProgressReporters(ctx context.Context)
5355
for _, reporter := range reporters {
5456
reportC := make(chan string, 1)
5557
go func() {
58+
defer func() {
59+
e := recover()
60+
if e != nil {
61+
failer.Panic(types.NewCodeLocationWithStackTrace(1), e)
62+
reportC <- "failed to query attached progress reporter"
63+
}
64+
}()
5665
reportC <- reporter()
5766
}()
5867
var report string

internal/progress_reporter_manager_test.go

+23-8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"time"
66

77
. "github.com/onsi/ginkgo/v2"
8+
"github.com/onsi/ginkgo/v2/types"
89
. "github.com/onsi/gomega"
910
"github.com/onsi/gomega/gleak"
1011

@@ -19,19 +20,19 @@ var _ = Describe("ProgressReporterManager", func() {
1920
})
2021

2122
It("can attach and detach progress reporters", func() {
22-
Ω(manager.QueryProgressReporters(context.Background())).Should(BeEmpty())
23+
Ω(manager.QueryProgressReporters(context.Background(), nil)).Should(BeEmpty())
2324
cancelA := manager.AttachProgressReporter(func() string { return "A" })
24-
Ω(manager.QueryProgressReporters(context.Background())).Should(Equal([]string{"A"}))
25+
Ω(manager.QueryProgressReporters(context.Background(), nil)).Should(Equal([]string{"A"}))
2526
cancelB := manager.AttachProgressReporter(func() string { return "B" })
26-
Ω(manager.QueryProgressReporters(context.Background())).Should(Equal([]string{"A", "B"}))
27+
Ω(manager.QueryProgressReporters(context.Background(), nil)).Should(Equal([]string{"A", "B"}))
2728
cancelC := manager.AttachProgressReporter(func() string { return "C" })
28-
Ω(manager.QueryProgressReporters(context.Background())).Should(Equal([]string{"A", "B", "C"}))
29+
Ω(manager.QueryProgressReporters(context.Background(), nil)).Should(Equal([]string{"A", "B", "C"}))
2930
cancelB()
30-
Ω(manager.QueryProgressReporters(context.Background())).Should(Equal([]string{"A", "C"}))
31+
Ω(manager.QueryProgressReporters(context.Background(), nil)).Should(Equal([]string{"A", "C"}))
3132
cancelA()
32-
Ω(manager.QueryProgressReporters(context.Background())).Should(Equal([]string{"C"}))
33+
Ω(manager.QueryProgressReporters(context.Background(), nil)).Should(Equal([]string{"C"}))
3334
cancelC()
34-
Ω(manager.QueryProgressReporters(context.Background())).Should(BeEmpty())
35+
Ω(manager.QueryProgressReporters(context.Background(), nil)).Should(BeEmpty())
3536
})
3637

3738
It("bails if a progress reporter takes longer than the passed-in context's deadline", func() {
@@ -45,11 +46,25 @@ var _ = Describe("ProgressReporterManager", func() {
4546
})
4647
manager.AttachProgressReporter(func() string { return "D" })
4748
context, cancel := context.WithTimeout(context.Background(), time.Millisecond*100)
48-
result := manager.QueryProgressReporters(context)
49+
result := manager.QueryProgressReporters(context, nil)
4950
Ω(result).Should(Equal([]string{"A", "B"}))
5051
cancel()
5152
close(c)
5253

5354
Eventually(gleak.Goroutines).ShouldNot(gleak.HaveLeaked(startingGoroutines))
5455
})
56+
57+
It("catches panics and reports them as failures", func() {
58+
manager.AttachProgressReporter(func() string {
59+
panic("bam")
60+
})
61+
manager.AttachProgressReporter(func() string { return "B" })
62+
failer := internal.NewFailer()
63+
result := manager.QueryProgressReporters(context.Background(), failer)
64+
Ω(result).Should(Equal([]string{"failed to query attached progress reporter", "B"}))
65+
state, failure := failer.Drain()
66+
Ω(state).Should(Equal(types.SpecStatePanicked))
67+
Ω(failure.Message).Should(Equal("Test Panicked"))
68+
Ω(failure.ForwardedPanic).Should(Equal("bam"))
69+
})
5570
})

internal/spec_context_test.go

+11-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55

66
. "github.com/onsi/ginkgo/v2"
7+
"github.com/onsi/ginkgo/v2/internal"
78
. "github.com/onsi/gomega"
89
)
910

@@ -12,38 +13,38 @@ var _ = Describe("SpecContext", func() {
1213
Ω(c.SpecReport().LeafNodeText).Should(Equal("allows access to the current spec report"))
1314
})
1415

15-
It("can be wrapped and still retreived", func(c SpecContext) {
16+
It("can be wrapped and still retrieved", func(c SpecContext) {
1617
Ω(c.Value("GINKGO_SPEC_CONTEXT")).Should(Equal(c))
1718

1819
wrappedC := context.WithValue(c, "foo", "bar")
1920

2021
_, ok := wrappedC.(SpecContext)
2122
Ω(ok).Should(BeFalse())
22-
Ω(wrappedC.Value("GINKGO_SPEC_CONTEXT").(SpecContext).SpecReport().LeafNodeText).Should(Equal("can be wrapped and still retreived"))
23+
Ω(wrappedC.Value("GINKGO_SPEC_CONTEXT").(SpecContext).SpecReport().LeafNodeText).Should(Equal("can be wrapped and still retrieved"))
2324
})
2425

2526
It("can attach and detach progress reporters", func(c SpecContext) {
2627
type CompleteSpecContext interface {
2728
AttachProgressReporter(func() string) func()
28-
QueryProgressReporters(ctx context.Context) []string
29+
QueryProgressReporters(ctx context.Context, failer *internal.Failer) []string
2930
}
3031

3132
wrappedC := context.WithValue(c, "foo", "bar")
3233
ctx := wrappedC.Value("GINKGO_SPEC_CONTEXT").(CompleteSpecContext)
3334

34-
Ω(ctx.QueryProgressReporters(context.Background())).Should(BeEmpty())
35+
Ω(ctx.QueryProgressReporters(context.Background(), nil)).Should(BeEmpty())
3536

3637
cancelA := ctx.AttachProgressReporter(func() string { return "A" })
37-
Ω(ctx.QueryProgressReporters(context.Background())).Should(Equal([]string{"A"}))
38+
Ω(ctx.QueryProgressReporters(context.Background(), nil)).Should(Equal([]string{"A"}))
3839
cancelB := ctx.AttachProgressReporter(func() string { return "B" })
39-
Ω(ctx.QueryProgressReporters(context.Background())).Should(Equal([]string{"A", "B"}))
40+
Ω(ctx.QueryProgressReporters(context.Background(), nil)).Should(Equal([]string{"A", "B"}))
4041
cancelC := ctx.AttachProgressReporter(func() string { return "C" })
41-
Ω(ctx.QueryProgressReporters(context.Background())).Should(Equal([]string{"A", "B", "C"}))
42+
Ω(ctx.QueryProgressReporters(context.Background(), nil)).Should(Equal([]string{"A", "B", "C"}))
4243
cancelB()
43-
Ω(ctx.QueryProgressReporters(context.Background())).Should(Equal([]string{"A", "C"}))
44+
Ω(ctx.QueryProgressReporters(context.Background(), nil)).Should(Equal([]string{"A", "C"}))
4445
cancelA()
45-
Ω(ctx.QueryProgressReporters(context.Background())).Should(Equal([]string{"C"}))
46+
Ω(ctx.QueryProgressReporters(context.Background(), nil)).Should(Equal([]string{"C"}))
4647
cancelC()
47-
Ω(ctx.QueryProgressReporters(context.Background())).Should(BeEmpty())
48+
Ω(ctx.QueryProgressReporters(context.Background(), nil)).Should(BeEmpty())
4849
})
4950
})

internal/suite.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -348,9 +348,9 @@ func (suite *Suite) generateProgressReport(fullReport bool) types.ProgressReport
348348
defer cancel()
349349
var additionalReports []string
350350
if suite.currentSpecContext != nil {
351-
additionalReports = append(additionalReports, suite.currentSpecContext.QueryProgressReporters(deadline)...)
351+
additionalReports = append(additionalReports, suite.currentSpecContext.QueryProgressReporters(deadline, suite.failer)...)
352352
}
353-
additionalReports = append(additionalReports, suite.QueryProgressReporters(deadline)...)
353+
additionalReports = append(additionalReports, suite.QueryProgressReporters(deadline, suite.failer)...)
354354
gwOutput := suite.currentSpecReport.CapturedGinkgoWriterOutput + string(suite.writer.Bytes())
355355
pr, err := NewProgressReport(suite.isRunningInParallel(), suite.currentSpecReport, suite.currentNode, suite.currentNodeStartTime, suite.currentByStep, gwOutput, timelineLocation, additionalReports, suite.config.SourceRoots, fullReport)
356356

0 commit comments

Comments
 (0)