diff --git a/go.mod b/go.mod index ceefa89ef..db772035b 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/go-logr/logr v1.4.3 github.com/go-logr/zapr v1.3.0 - github.com/onsi/ginkgo/v2 v2.28.3 + github.com/onsi/ginkgo/v2 v2.29.0 github.com/onsi/gomega v1.40.0 github.com/openshift/api v0.0.0-20260213204242-d34f11c515b3 github.com/openshift/client-go v0.0.0-20260213141500-06efc6dce93b diff --git a/go.sum b/go.sum index b26444861..867adf56d 100644 --- a/go.sum +++ b/go.sum @@ -160,8 +160,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/olareg/olareg v0.2.1 h1:RPHGIaqlVWPbKAsOYUj7e2WfEEW5M7F8I6hKMrwd4jU= github.com/olareg/olareg v0.2.1/go.mod h1:dhr8QetC7U7jJ2m93oxDhEEOKCRbPgOK1oGyKfB4QNo= -github.com/onsi/ginkgo/v2 v2.28.3 h1:4JvMdwtFU0imd8fHx25OJXoDMRexnf8v5NHKYSTTji4= -github.com/onsi/ginkgo/v2 v2.28.3/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44= +github.com/onsi/ginkgo/v2 v2.29.0 h1:rfh+ZFjgJhYWRoIqVf3Uwx/W20yLrcrE2h2GmYVRaag= +github.com/onsi/ginkgo/v2 v2.29.0/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44= github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc= github.com/onsi/gomega v1.40.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A= github.com/opencontainers/cgroups v0.0.6 h1:tfZFWTIIGaUUFImTyuTg+Mr5x8XRiSdZESgEBW7UxuI= diff --git a/vendor/github.com/onsi/ginkgo/v2/.gitignore b/vendor/github.com/onsi/ginkgo/v2/.gitignore index 6faaaf315..c9f054620 100644 --- a/vendor/github.com/onsi/ginkgo/v2/.gitignore +++ b/vendor/github.com/onsi/ginkgo/v2/.gitignore @@ -1,6 +1,7 @@ .DS_Store TODO tmp/**/* +integration/tmp_*/ *.coverprofile .vscode .idea/ diff --git a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md index d382b0640..224e8db5f 100644 --- a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md +++ b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.29.0 + +`GinkgoHelperGo` makes it easier to write test helpers that need to run in goroutines. Specifically, it makes managing the failure state and capturing failure panics correctly straightforward. + +`ginkgo outline` now includes entries defined in `DescribeTableSubtree` + ## 2.28.3 ### Maintenance diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go index 5d8d00bb1..c380bbf21 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go @@ -163,17 +163,17 @@ func ginkgoNodeFromCallExpr(fset *token.FileSet, ce *ast.CallExpr, ginkgoPackage n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) n.Labels = labelFromCallExpr(ce) return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "Context", "Describe", "When", "DescribeTable": + case "Context", "Describe", "When", "DescribeTable", "DescribeTableSubtree": n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) n.Labels = labelFromCallExpr(ce) n.Pending = pendingFromCallExpr(ce) return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "FContext", "FDescribe", "FWhen", "FDescribeTable": + case "FContext", "FDescribe", "FWhen", "FDescribeTable", "FDescribeTableSubtree": n.Focused = true n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) n.Labels = labelFromCallExpr(ce) return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "PContext", "PDescribe", "PWhen", "XContext", "XDescribe", "XWhen", "PDescribeTable", "XDescribeTable": + case "PContext", "PDescribe", "PWhen", "XContext", "XDescribe", "XWhen", "PDescribeTable", "XDescribeTable", "PDescribeTableSubtree", "XDescribeTableSubtree": n.Pending = true n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) n.Labels = labelFromCallExpr(ce) diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go index e99d557d1..206043f1d 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go @@ -54,6 +54,7 @@ func FromASTFile(fset *token.FileSet, src *ast.File) (*outline, error) { // Node is not a Ginkgo spec or container, so it was not pushed onto the stack, continue return true } + expandSubtree(lastVisitedGinkgoNode) stack = stack[0 : len(stack)-1] return true }) @@ -128,3 +129,29 @@ func (o *outline) StringIndent(width int) string { return b.String() } + +// expandSubtree restructures a DescribeTableSubtree node so that each Entry +// child gets a copy of the subtree's spec nodes as its children. This mirrors +// the runtime behavior where each Entry generates a container with the specs +// defined in the DescribeTableSubtree body. +func expandSubtree(gn *ginkgoNode) { + if !strings.Contains(gn.Name, "DescribeTableSubtree") { + return + } + subNodes, entries := splitSubtreeSubnodes(gn.Nodes) + gn.Nodes = entries + for _, entry := range entries { + entry.Nodes = subNodes + } +} + +// splitSubtreeSubnodes splits the child nodes of a DescribeTableSubtree into +// spec/container nodes (defined in the body) and Entry nodes. +func splitSubtreeSubnodes(nodes []*ginkgoNode) ([]*ginkgoNode, []*ginkgoNode) { + for i, node := range nodes { + if strings.Contains(node.Name, "Entry") { + return nodes[:i], nodes[i:] + } + } + return nodes, nil +} diff --git a/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go b/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go new file mode 100644 index 000000000..9d04cc845 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go @@ -0,0 +1,143 @@ +package ginkgo + +import ( + "github.com/onsi/ginkgo/v2/internal/global" + ginkgotypes "github.com/onsi/ginkgo/v2/types" +) + +// GinkgoHelperGo synchronously calls the specified “helper” function in a new +// go routine and with a “defer GinkgoRecover()” already in place, passing the +// function a “helper Fail”. GinkgoHelperGo is typically called from custom test +// helpers that in turn need to synchronously execute caller-supplied custom +// test code in a new Go routine while waiting for this new Go routine to +// terminate (either successfully or failing). +// +// GinkgoHelperGo hides the non-trivial details of correctly unblocking the +// caller's waiting go routine as well as reporting the correct call sites, +// depending on whether the test helper failed, or the caller-supplied function +// had its assertions failing or panicked. +// +// Let's take the following example of a test helper named “EnsureSprockets” +// that runs a set of caller-supplied assertions synchronously on a new Go +// routine and waits for the outcome before returning to the caller of the test +// helper. This is just using Ginkgo: +// +// func EnsureSprockets(sprockets int, assertions func()) { +// GinkgoHelper() +// GinkgoHelperGo(func(helperFail func(string, ...int)) { +// if sprockets == 0 { +// helperFail("sprockets must not be zero") +// } +// assertions() +// }) +// } +// +// And now for an example that additionally uses Gomega assertions. +// +// func EnsureSprockets(sprockets int, assertions func()) { +// GinkgoHelper() +// GinkgoHelperGo(func(helperFail func(string, ...int)) { +// g := gomega.NewGomega(helperFail) +// g.Expect(sprockets).Not(BeZero()) +// assertions() +// }) +// } +// +// The called helper function should make any custom helper-related assertions +// using the passed “helper Fail”. Gomega users will want to create a new Gomega +// wired into this helper Fail. It is expected for the helper function at some +// point to call into a user-supplied function that might contain its own +// assertions. In the example above, that would be the function passed as +// assertions. +// +// Any failing assertion using the helper Gomega in the helper function will be +// reported as a fail at the call site of GinkgoHelperGo. Preferably, only +// custom test helpers call GinkgoHelperGo and thus mark themselves as +// [GinkgoHelper] also: in this case, the fail will be shown at the call site of +// the custom test helper. +// +// Any other failing assertions inside the caller-supplied custom test code and +// thus inside the helper function will instead be reported at the location of +// the failed assertion. +// +// If the caller-supplied custom test code panics, GinkgoHelperGo will fail at +// its call site, or at the call site of the custom test helper if it uses +// GinkgoHelper, reporting the usual stack trace for the panic, as a plain +// GinkgoRecover would also do. +// +// Important: the Gomega passed to the called function must only be used in +// assertions belonging to the test helper, but not any user test code called +// from the test helper. Thus, do not pass the Gomega passed to the helper +// function further on to any user test code functions. +func GinkgoHelperGo(fn func(fail func(message string, callerSkip ...int))) { + // userPanicked signals that the called user code panicked, such as due to a + // failed Gomega assertion. + type userPanicked struct{} + + // helperPanicked signals that some helper code assertion panicked in the + // separate Go routine and we are expected to Fail the current test with that + // reason, but on the caller's Go routine. + type helperPanicked string + + GinkgoHelper() + + // possible types of values sent over the result channel: + // - nil (untyped): no problem at all, proceed. + // - helperPanicked: the message with which to (re)fail in the caller's + // go routine. + // - userPanicked: indication to (also) fail on the caller's go routine; + // the message doesn't matter as the user code fail takes precedence. + ch := make(chan any) + + go func() { + isHelperPanic := false + helperFail := func(message string, callerSkip ...int) { + isHelperPanic = true + Fail(message, callerSkip...) + } + // Please note that we cannot simply recover a helper panic before + // GinkgoRecover kicks in as then GinkgoRecover would always report the + // stack trace only from the place of rethrown panic ... and that's + // pretty useless, because it would just consist of the panic rethrow. + defer func() { + // We need to unblock and immediately fail the waiting caller's + // go routine either for a reason, or just "because" when + // GinkgoRecover has already failed the current test on the + // separate go routine. + if global.Failer.GetState() != ginkgotypes.SpecStatePassed { + if isHelperPanic { + _, failure := global.Failer.Drain() + ch <- helperPanicked(failure.Message) + } else { + // keep the panic failure already recorded by GinkgoRecover. + ch <- userPanicked{} + } + } + close(ch) // causes a nil in case there were no panics anywhere. + }() + // Nota bene: GinkgoRecover always eats any user panic and channel the + // panic value into Ginkgo's Failer.Panic(). We can peek at the last + // failure recorded, which should be nil if GinkgoRecover didn't swallow + // a user code panic. The "problem" with GinkgoRecover is that it turns + // any panic value into a string message, so we loose any specific + // typing. + defer GinkgoRecover() + + fn(helperFail) + }() + + // Did we run into trouble? + switch v := (<-ch).(type) { + case userPanicked: + // The message actually is irrelevant, as it comes only second to + // the already registered user panic message. We just need Fail to + // panic on the caller's go routine in order to unblock the test. + Fail("fn panicked", 1) + case helperPanicked: + // Report the failure on the new go routine instead on the caller's go + // routine. + Fail(string(v), 1) + default: + // It's all fine! + } +} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go index 4479578f9..003604bd8 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/version.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.28.3" +const VERSION = "2.29.0" diff --git a/vendor/modules.txt b/vendor/modules.txt index 1a0663b57..f97147bf0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -223,7 +223,7 @@ github.com/monochromegane/go-gitignore # github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 ## explicit github.com/munnerz/goautoneg -# github.com/onsi/ginkgo/v2 v2.28.3 +# github.com/onsi/ginkgo/v2 v2.29.0 ## explicit; go 1.25.0 github.com/onsi/ginkgo/v2 github.com/onsi/ginkgo/v2/config