diff --git a/vendor/github.com/onsi/ginkgo/v2/core_dsl.go b/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
index 1c5a39a1f5..a3e8237e93 100644
--- a/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
@@ -20,7 +20,6 @@ import (
"io"
"os"
"path/filepath"
- "slices"
"strings"
"github.com/go-logr/logr"
@@ -84,9 +83,9 @@ func exitIfErrors(errors []error) {
type GinkgoWriterInterface interface {
io.Writer
- Print(a ...any)
- Printf(format string, a ...any)
- Println(a ...any)
+ Print(a ...interface{})
+ Printf(format string, a ...interface{})
+ Println(a ...interface{})
TeeTo(writer io.Writer)
ClearTeeWriters()
@@ -187,20 +186,6 @@ func GinkgoLabelFilter() string {
return suiteConfig.LabelFilter
}
-/*
-GinkgoSemVerFilter() returns the semantic version filter configured for this suite via `--sem-ver-filter`.
-
-You can use this to manually check if a set of semantic version constraints would satisfy the filter via:
-
- if (SemVerConstraint("> 2.6.0", "< 2.8.0").MatchesSemVerFilter(GinkgoSemVerFilter())) {
- //...
- }
-*/
-func GinkgoSemVerFilter() string {
- suiteConfig, _ := GinkgoConfiguration()
- return suiteConfig.SemVerFilter
-}
-
/*
PauseOutputInterception() pauses Ginkgo's output interception. This is only relevant
when running in parallel and output to stdout/stderr is being intercepted. You generally
@@ -258,7 +243,7 @@ for more on how specs are parallelized in Ginkgo.
You can also pass suite-level Label() decorators to RunSpecs. The passed-in labels will apply to all specs in the suite.
*/
-func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
+func RunSpecs(t GinkgoTestingT, description string, args ...interface{}) bool {
if suiteDidRun {
exitIfErr(types.GinkgoErrors.RerunningSuite())
}
@@ -269,7 +254,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
}
defer global.PopClone()
- suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
+ suiteLabels := extractSuiteConfiguration(args)
var reporter reporters.Reporter
if suiteConfig.ParallelTotal == 1 {
@@ -312,7 +297,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
suitePath, err = filepath.Abs(suitePath)
exitIfErr(err)
- passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
+ passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
outputInterceptor.Shutdown()
flagSet.ValidateDeprecations(deprecationTracker)
@@ -331,11 +316,8 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
return passed
}
-func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, ComponentSemVerConstraints, types.AroundNodes) {
+func extractSuiteConfiguration(args []interface{}) Labels {
suiteLabels := Labels{}
- suiteSemVerConstraints := SemVerConstraints{}
- suiteComponentSemVerConstraints := ComponentSemVerConstraints{}
- aroundNodes := types.AroundNodes{}
configErrors := []error{}
for _, arg := range args {
switch arg := arg.(type) {
@@ -345,15 +327,6 @@ func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, Component
reporterConfig = arg
case Labels:
suiteLabels = append(suiteLabels, arg...)
- case SemVerConstraints:
- suiteSemVerConstraints = append(suiteSemVerConstraints, arg...)
- case ComponentSemVerConstraints:
- for component, constraints := range arg {
- suiteComponentSemVerConstraints[component] = append(suiteComponentSemVerConstraints[component], constraints...)
- suiteComponentSemVerConstraints[component] = slices.Compact(suiteComponentSemVerConstraints[component])
- }
- case types.AroundNodeDecorator:
- aroundNodes = append(aroundNodes, arg)
default:
configErrors = append(configErrors, types.GinkgoErrors.UnknownTypePassedToRunSpecs(arg))
}
@@ -362,14 +335,14 @@ func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, Component
configErrors = types.VetConfig(flagSet, suiteConfig, reporterConfig)
if len(configErrors) > 0 {
- fmt.Fprint(formatter.ColorableStdErr, formatter.F("{{red}}Ginkgo detected configuration issues:{{/}}\n"))
+ fmt.Fprintf(formatter.ColorableStdErr, formatter.F("{{red}}Ginkgo detected configuration issues:{{/}}\n"))
for _, err := range configErrors {
- fmt.Fprint(formatter.ColorableStdErr, err.Error())
+ fmt.Fprintf(formatter.ColorableStdErr, err.Error())
}
os.Exit(1)
}
- return suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, aroundNodes
+ return suiteLabels
}
func getwd() (string, error) {
@@ -392,7 +365,7 @@ func PreviewSpecs(description string, args ...any) Report {
}
defer global.PopClone()
- suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
+ suiteLabels := extractSuiteConfiguration(args)
priorDryRun, priorParallelTotal, priorParallelProcess := suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess
suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess = true, 1, 1
defer func() {
@@ -410,7 +383,7 @@ func PreviewSpecs(description string, args ...any) Report {
suitePath, err = filepath.Abs(suitePath)
exitIfErr(err)
- global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
+ global.Suite.Run(description, suiteLabels, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
return global.Suite.GetPreviewReport()
}
@@ -508,38 +481,6 @@ func pushNode(node internal.Node, errors []error) bool {
return true
}
-// NodeArgsTransformer is a hook which is called by the test construction DSL methods
-// before creating the new node. If it returns any error, the test suite
-// prints those errors and exits. The text and arguments can be modified,
-// which includes directly changing the args slice that is passed in.
-// Arguments have been flattened already, i.e. none of the entries in args is another []any.
-// The result may be nested.
-//
-// The node type is provided for information and remains the same.
-//
-// The offset is valid for calling NewLocation directly in the
-// implementation of TransformNodeArgs to find the location where
-// the Ginkgo DSL function is called. An additional offset supplied
-// by the caller via args is already included.
-//
-// A NodeArgsTransformer can be registered with AddTreeConstructionNodeArgsTransformer.
-type NodeArgsTransformer func(nodeType types.NodeType, offset Offset, text string, args []any) (string, []any, []error)
-
-// AddTreeConstructionNodeArgsTransformer registers a NodeArgsTransformer.
-// Only nodes which get created after registering a NodeArgsTransformer
-// are transformed by it. The returned function can be called to
-// unregister the transformer.
-//
-// Both may only be called during the construction phase.
-//
-// If there is more than one registered transformer, then the most
-// recently added ones get called first.
-func AddTreeConstructionNodeArgsTransformer(transformer NodeArgsTransformer) func() {
- // This conversion could be avoided with a type alias, but type aliases make
- // developer documentation less useful.
- return internal.AddTreeConstructionNodeArgsTransformer(internal.NodeArgsTransformer(transformer))
-}
-
/*
Describe nodes are Container nodes that allow you to organize your specs. A Describe node's closure can contain any number of
Setup nodes (e.g. BeforeEach, AfterEach, JustBeforeEach), and Subject nodes (i.e. It).
@@ -550,24 +491,24 @@ to Describe the behavior of an object or function and, within that Describe, out
You can learn more at https://onsi.github.io/ginkgo/#organizing-specs-with-container-nodes
In addition, container nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference
*/
-func Describe(text string, args ...any) bool {
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, text, args...)))
+func Describe(text string, args ...interface{}) bool {
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
}
/*
FDescribe focuses specs within the Describe block.
*/
-func FDescribe(text string, args ...any) bool {
+func FDescribe(text string, args ...interface{}) bool {
args = append(args, internal.Focus)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, text, args...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
}
/*
PDescribe marks specs within the Describe block as pending.
*/
-func PDescribe(text string, args ...any) bool {
+func PDescribe(text string, args ...interface{}) bool {
args = append(args, internal.Pending)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, text, args...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
}
/*
@@ -580,21 +521,21 @@ var XDescribe = PDescribe
/* Context is an alias for Describe - it generates the exact same kind of Container node */
var Context, FContext, PContext, XContext = Describe, FDescribe, PDescribe, XDescribe
-/* When is an alias for Describe - it generates the exact same kind of Container node with "when " as prefix for the text. */
-func When(text string, args ...any) bool {
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, "when "+text, args...)))
+/* When is an alias for Describe - it generates the exact same kind of Container node */
+func When(text string, args ...interface{}) bool {
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
}
-/* When is an alias for Describe - it generates the exact same kind of Container node with "when " as prefix for the text. */
-func FWhen(text string, args ...any) bool {
+/* When is an alias for Describe - it generates the exact same kind of Container node */
+func FWhen(text string, args ...interface{}) bool {
args = append(args, internal.Focus)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, "when "+text, args...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
}
/* When is an alias for Describe - it generates the exact same kind of Container node */
-func PWhen(text string, args ...any) bool {
+func PWhen(text string, args ...interface{}) bool {
args = append(args, internal.Pending)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, "when "+text, args...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
}
var XWhen = PWhen
@@ -609,24 +550,24 @@ You can pass It nodes bare functions (func() {}) or functions that receive a Spe
You can learn more at https://onsi.github.io/ginkgo/#spec-subjects-it
In addition, subject nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference
*/
-func It(text string, args ...any) bool {
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeIt, text, args...)))
+func It(text string, args ...interface{}) bool {
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
}
/*
FIt allows you to focus an individual It.
*/
-func FIt(text string, args ...any) bool {
+func FIt(text string, args ...interface{}) bool {
args = append(args, internal.Focus)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeIt, text, args...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
}
/*
PIt allows you to mark an individual It as pending.
*/
-func PIt(text string, args ...any) bool {
+func PIt(text string, args ...interface{}) bool {
args = append(args, internal.Pending)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeIt, text, args...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
}
/*
@@ -670,10 +611,10 @@ BeforeSuite can take a func() body, or an interruptible func(SpecContext)/func(c
You cannot nest any other Ginkgo nodes within a BeforeSuite node's closure.
You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite
*/
-func BeforeSuite(body any, args ...any) bool {
- combinedArgs := []any{body}
+func BeforeSuite(body interface{}, args ...interface{}) bool {
+ combinedArgs := []interface{}{body}
combinedArgs = append(combinedArgs, args...)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeBeforeSuite, "", combinedArgs...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeSuite, "", combinedArgs...))
}
/*
@@ -689,10 +630,10 @@ AfterSuite can take a func() body, or an interruptible func(SpecContext)/func(co
You cannot nest any other Ginkgo nodes within an AfterSuite node's closure.
You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-beforesuite-and-aftersuite
*/
-func AfterSuite(body any, args ...any) bool {
- combinedArgs := []any{body}
+func AfterSuite(body interface{}, args ...interface{}) bool {
+ combinedArgs := []interface{}{body}
combinedArgs = append(combinedArgs, args...)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeAfterSuite, "", combinedArgs...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterSuite, "", combinedArgs...))
}
/*
@@ -726,11 +667,11 @@ If either function receives a context.Context/SpecContext it is considered inter
You cannot nest any other Ginkgo nodes within an SynchronizedBeforeSuite node's closure.
You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite
*/
-func SynchronizedBeforeSuite(process1Body any, allProcessBody any, args ...any) bool {
- combinedArgs := []any{process1Body, allProcessBody}
+func SynchronizedBeforeSuite(process1Body interface{}, allProcessBody interface{}, args ...interface{}) bool {
+ combinedArgs := []interface{}{process1Body, allProcessBody}
combinedArgs = append(combinedArgs, args...)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeSynchronizedBeforeSuite, "", combinedArgs...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeSynchronizedBeforeSuite, "", combinedArgs...))
}
/*
@@ -746,11 +687,11 @@ Note that you can also use DeferCleanup() in SynchronizedBeforeSuite to accompli
You cannot nest any other Ginkgo nodes within an SynchronizedAfterSuite node's closure.
You can learn more, and see some examples, here: https://onsi.github.io/ginkgo/#parallel-suite-setup-and-cleanup-synchronizedbeforesuite-and-synchronizedaftersuite
*/
-func SynchronizedAfterSuite(allProcessBody any, process1Body any, args ...any) bool {
- combinedArgs := []any{allProcessBody, process1Body}
+func SynchronizedAfterSuite(allProcessBody interface{}, process1Body interface{}, args ...interface{}) bool {
+ combinedArgs := []interface{}{allProcessBody, process1Body}
combinedArgs = append(combinedArgs, args...)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeSynchronizedAfterSuite, "", combinedArgs...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeSynchronizedAfterSuite, "", combinedArgs...))
}
/*
@@ -762,8 +703,8 @@ BeforeEach can take a func() body, or an interruptible func(SpecContext)/func(co
You cannot nest any other Ginkgo nodes within a BeforeEach node's closure.
You can learn more here: https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach
*/
-func BeforeEach(args ...any) bool {
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeBeforeEach, "", args...)))
+func BeforeEach(args ...interface{}) bool {
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeEach, "", args...))
}
/*
@@ -775,8 +716,8 @@ JustBeforeEach can take a func() body, or an interruptible func(SpecContext)/fun
You cannot nest any other Ginkgo nodes within a JustBeforeEach node's closure.
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-creation-and-configuration-justbeforeeach
*/
-func JustBeforeEach(args ...any) bool {
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeJustBeforeEach, "", args...)))
+func JustBeforeEach(args ...interface{}) bool {
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeJustBeforeEach, "", args...))
}
/*
@@ -790,8 +731,8 @@ AfterEach can take a func() body, or an interruptible func(SpecContext)/func(con
You cannot nest any other Ginkgo nodes within an AfterEach node's closure.
You can learn more here: https://onsi.github.io/ginkgo/#spec-cleanup-aftereach-and-defercleanup
*/
-func AfterEach(args ...any) bool {
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeAfterEach, "", args...)))
+func AfterEach(args ...interface{}) bool {
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterEach, "", args...))
}
/*
@@ -802,8 +743,8 @@ JustAfterEach can take a func() body, or an interruptible func(SpecContext)/func
You cannot nest any other Ginkgo nodes within a JustAfterEach node's closure.
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-diagnostics-collection-and-teardown-justaftereach
*/
-func JustAfterEach(args ...any) bool {
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeJustAfterEach, "", args...)))
+func JustAfterEach(args ...interface{}) bool {
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeJustAfterEach, "", args...))
}
/*
@@ -817,8 +758,8 @@ You cannot nest any other Ginkgo nodes within a BeforeAll node's closure.
You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers
And you can learn more about BeforeAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
*/
-func BeforeAll(args ...any) bool {
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeBeforeAll, "", args...)))
+func BeforeAll(args ...interface{}) bool {
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeAll, "", args...))
}
/*
@@ -834,8 +775,8 @@ You cannot nest any other Ginkgo nodes within an AfterAll node's closure.
You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#ordered-containers
And you can learn more about AfterAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
*/
-func AfterAll(args ...any) bool {
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeAfterAll, "", args...)))
+func AfterAll(args ...interface{}) bool {
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterAll, "", args...))
}
/*
@@ -877,7 +818,7 @@ When DeferCleanup is called in BeforeSuite, SynchronizedBeforeSuite, AfterSuite,
Note that DeferCleanup does not represent a node but rather dynamically generates the appropriate type of cleanup node based on the context in which it is called. As such you must call DeferCleanup within a Setup or Subject node, and not within a Container node.
You can learn more about DeferCleanup here: https://onsi.github.io/ginkgo/#cleaning-up-our-cleanup-code-defercleanup
*/
-func DeferCleanup(args ...any) {
+func DeferCleanup(args ...interface{}) {
fail := func(message string, cl types.CodeLocation) {
global.Failer.Fail(message, cl)
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/core_dsl_patch.go b/vendor/github.com/onsi/ginkgo/v2/core_dsl_patch.go
new file mode 100644
index 0000000000..bf60ceb522
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/v2/core_dsl_patch.go
@@ -0,0 +1,33 @@
+package ginkgo
+
+import (
+ "io"
+
+ "github.com/onsi/ginkgo/v2/internal"
+ "github.com/onsi/ginkgo/v2/internal/global"
+ "github.com/onsi/ginkgo/v2/types"
+)
+
+func AppendSpecText(test *internal.Spec, text string) {
+ test.AppendText(text)
+}
+
+func GetSuite() *internal.Suite {
+ return global.Suite
+}
+
+func GetFailer() *internal.Failer {
+ return global.Failer
+}
+
+func NewWriter(w io.Writer) *internal.Writer {
+ return internal.NewWriter(w)
+}
+
+func GetWriter() *internal.Writer {
+ return GinkgoWriter.(*internal.Writer)
+}
+
+func SetReporterConfig(r types.ReporterConfig) {
+ reporterConfig = r
+}
diff --git a/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go b/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go
index ce1d71cec8..c65af4ce1c 100644
--- a/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go
@@ -2,7 +2,6 @@ package ginkgo
import (
"github.com/onsi/ginkgo/v2/internal"
- "github.com/onsi/ginkgo/v2/types"
)
/*
@@ -100,44 +99,6 @@ You can learn more here: https://onsi.github.io/ginkgo/#spec-labels
*/
type Labels = internal.Labels
-/*
-SemVerConstraint decorates specs with SemVerConstraints. Multiple semantic version constraints can be passed to SemVerConstraint and these strings must follow the semantic version constraint rules.
-SemVerConstraints can be applied to container and subject nodes, but not setup nodes. You can provide multiple SemVerConstraints to a given node and a spec's semantic version constraints is the union of all semantic version constraints in its node hierarchy.
-
-You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-filtering
-You can learn more about decorators here: https://onsi.github.io/ginkgo/#decorator-reference
-*/
-func SemVerConstraint(semVerConstraints ...string) SemVerConstraints {
- return SemVerConstraints(semVerConstraints)
-}
-
-/*
-SemVerConstraints are the type for spec SemVerConstraint decorators. Use SemVerConstraint(...) to construct SemVerConstraints.
-You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-filtering
-*/
-type SemVerConstraints = internal.SemVerConstraints
-
-/*
-ComponentSemVerConstraint decorates specs with ComponentSemVerConstraints. Multiple components semantic version constraints can be passed to ComponentSemVerConstraint and the component can't be empy, also the version strings must follow the semantic version constraint rules.
-ComponentSemVerConstraints can be applied to container and subject nodes, but not setup nodes. You can provide multiple ComponentSemVerConstraints to a given node and a spec's component semantic version constraints is the union of all component semantic version constraints in its node hierarchy.
-
-You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-filtering
-You can learn more about decorators here: https://onsi.github.io/ginkgo/#decorator-reference
-*/
-func ComponentSemVerConstraint(component string, semVerConstraints ...string) ComponentSemVerConstraints {
- componentSemVerConstraints := ComponentSemVerConstraints{
- component: semVerConstraints,
- }
-
- return componentSemVerConstraints
-}
-
-/*
-ComponentSemVerConstraints are the type for spec ComponentSemVerConstraint decorators. Use ComponentSemVerConstraint(...) to construct ComponentSemVerConstraints.
-You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-filtering
-*/
-type ComponentSemVerConstraints = internal.ComponentSemVerConstraints
-
/*
PollProgressAfter allows you to override the configured value for --poll-progress-after for a particular node.
@@ -175,40 +136,8 @@ Nodes that do not finish within a GracePeriod will be leaked and Ginkgo will pro
*/
type GracePeriod = internal.GracePeriod
-/*
-SpecPriority allows you to assign a priority to a spec or container.
-
-Specs with higher priority will be scheduled to run before specs with lower priority. The default priority is 0 and negative priorities are allowed.
-*/
-type SpecPriority = internal.SpecPriority
-
/*
SuppressProgressReporting is a decorator that allows you to disable progress reporting of a particular node. This is useful if `ginkgo -v -progress` is generating too much noise; particularly
if you have a `ReportAfterEach` node that is running for every skipped spec and is generating lots of progress reports.
*/
const SuppressProgressReporting = internal.SuppressProgressReporting
-
-/*
-AroundNode registers a function that runs before each individual node. This is considered a more advanced decorator.
-
-Please read the [docs](https://onsi.github.io/ginkgo/#advanced-around-node) for more information.
-
-Allowed signatures:
-
-- AroundNode(func()) - func will be called before the node is run.
-- AroundNode(func(ctx context.Context) context.Context) - func can wrap the passed in context and return a new one which will be passed on to the node.
-- AroundNode(func(ctx context.Context, body func(ctx context.Context))) - ctx is the context for the node and body is a function that must be called to run the node. This gives you complete control over what runs before and after the node.
-
-Multiple AroundNode decorators can be applied to a single node and they will run in the order they are applied.
-
-Unlike setup nodes like BeforeEach and DeferCleanup, AroundNode is guaranteed to run in the same goroutine as the decorated node. This is necessary when working with lower-level libraries that must run on a single thread (you can call runtime.LockOSThread() in the AroundNode to ensure that the node runs on a single thread).
-
-Since AroundNode allows you to modify the context you can also use AroundNode to implement shared setup that attaches values to the context. You must return a context that inherits from the passed in context.
-
-If applied to a container, AroundNode will run before every node in the container. Including setup nodes like BeforeEach and DeferCleanup.
-
-AroundNode can also be applied to RunSpecs to run before every node in the suite.
-*/
-func AroundNode[F types.AroundNodeAllowedFuncs](f F) types.AroundNodeDecorator {
- return types.AroundNode(f, types.NewCodeLocation(1))
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/deprecated_dsl.go b/vendor/github.com/onsi/ginkgo/v2/deprecated_dsl.go
index fd45b8beab..f912bbec65 100644
--- a/vendor/github.com/onsi/ginkgo/v2/deprecated_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/deprecated_dsl.go
@@ -118,9 +118,9 @@ Use Gomega's gmeasure package instead.
You can learn more here: https://onsi.github.io/ginkgo/#benchmarking-code
*/
type Benchmarker interface {
- Time(name string, body func(), info ...any) (elapsedTime time.Duration)
- RecordValue(name string, value float64, info ...any)
- RecordValueWithPrecision(name string, value float64, units string, precision int, info ...any)
+ Time(name string, body func(), info ...interface{}) (elapsedTime time.Duration)
+ RecordValue(name string, value float64, info ...interface{})
+ RecordValueWithPrecision(name string, value float64, units string, precision int, info ...interface{})
}
/*
@@ -129,7 +129,7 @@ Deprecated: Measure() has been removed from Ginkgo 2.0
Use Gomega's gmeasure package instead.
You can learn more here: https://onsi.github.io/ginkgo/#benchmarking-code
*/
-func Measure(_ ...any) bool {
+func Measure(_ ...interface{}) bool {
deprecationTracker.TrackDeprecation(types.Deprecations.Measure(), types.NewCodeLocation(1))
return true
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go b/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go
index f61356db19..4d5749114c 100644
--- a/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go
+++ b/vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go
@@ -24,15 +24,15 @@ const (
var SingletonFormatter = New(ColorModeTerminal)
-func F(format string, args ...any) string {
+func F(format string, args ...interface{}) string {
return SingletonFormatter.F(format, args...)
}
-func Fi(indentation uint, format string, args ...any) string {
+func Fi(indentation uint, format string, args ...interface{}) string {
return SingletonFormatter.Fi(indentation, format, args...)
}
-func Fiw(indentation uint, maxWidth uint, format string, args ...any) string {
+func Fiw(indentation uint, maxWidth uint, format string, args ...interface{}) string {
return SingletonFormatter.Fiw(indentation, maxWidth, format, args...)
}
@@ -115,15 +115,15 @@ func New(colorMode ColorMode) Formatter {
return f
}
-func (f Formatter) F(format string, args ...any) string {
+func (f Formatter) F(format string, args ...interface{}) string {
return f.Fi(0, format, args...)
}
-func (f Formatter) Fi(indentation uint, format string, args ...any) string {
+func (f Formatter) Fi(indentation uint, format string, args ...interface{}) string {
return f.Fiw(indentation, 0, format, args...)
}
-func (f Formatter) Fiw(indentation uint, maxWidth uint, format string, args ...any) string {
+func (f Formatter) Fiw(indentation uint, maxWidth uint, format string, args ...interface{}) string {
out := f.style(format)
if len(args) > 0 {
out = fmt.Sprintf(out, args...)
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs.go
deleted file mode 100644
index ee6ac7b5f3..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs.go
+++ /dev/null
@@ -1,8 +0,0 @@
-//go:build !go1.25
-// +build !go1.25
-
-package main
-
-import (
- _ "github.com/onsi/ginkgo/v2/ginkgo/automaxprocs"
-)
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/README.md b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/README.md
deleted file mode 100644
index e249ebe8b3..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-This entire directory is a lightly modified clone of https://github.com/uber-go/automaxprocs
-
-It will be removed when Go 1.26 ships and we no longer need to support Go 1.24 (which does not correctly autodetect maxprocs in containers).
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/automaxprocs.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/automaxprocs.go
deleted file mode 100644
index 8a762b51d6..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/automaxprocs.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Package maxprocs lets Go programs easily configure runtime.GOMAXPROCS to
-// match the configured Linux CPU quota. Unlike the top-level automaxprocs
-// package, it lets the caller configure logging and handle errors.
-package automaxprocs
-
-import (
- "os"
- "runtime"
-)
-
-func init() {
- Set()
-}
-
-const _maxProcsKey = "GOMAXPROCS"
-
-type config struct {
- procs func(int, func(v float64) int) (int, CPUQuotaStatus, error)
- minGOMAXPROCS int
- roundQuotaFunc func(v float64) int
-}
-
-// Set GOMAXPROCS to match the Linux container CPU quota (if any), returning
-// any error encountered and an undo function.
-//
-// Set is a no-op on non-Linux systems and in Linux environments without a
-// configured CPU quota.
-func Set() error {
- cfg := &config{
- procs: CPUQuotaToGOMAXPROCS,
- roundQuotaFunc: DefaultRoundFunc,
- minGOMAXPROCS: 1,
- }
-
- // Honor the GOMAXPROCS environment variable if present. Otherwise, amend
- // `runtime.GOMAXPROCS()` with the current process' CPU quota if the OS is
- // Linux, and guarantee a minimum value of 1. The minimum guaranteed value
- // can be overridden using `maxprocs.Min()`.
- if _, exists := os.LookupEnv(_maxProcsKey); exists {
- return nil
- }
- maxProcs, status, err := cfg.procs(cfg.minGOMAXPROCS, cfg.roundQuotaFunc)
- if err != nil {
- return err
- }
- if status == CPUQuotaUndefined {
- return nil
- }
- runtime.GOMAXPROCS(maxProcs)
- return nil
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroup.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroup.go
deleted file mode 100644
index a4676933e8..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroup.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-//go:build linux
-// +build linux
-
-package automaxprocs
-
-import (
- "bufio"
- "io"
- "os"
- "path/filepath"
- "strconv"
-)
-
-// CGroup represents the data structure for a Linux control group.
-type CGroup struct {
- path string
-}
-
-// NewCGroup returns a new *CGroup from a given path.
-func NewCGroup(path string) *CGroup {
- return &CGroup{path: path}
-}
-
-// Path returns the path of the CGroup*.
-func (cg *CGroup) Path() string {
- return cg.path
-}
-
-// ParamPath returns the path of the given cgroup param under itself.
-func (cg *CGroup) ParamPath(param string) string {
- return filepath.Join(cg.path, param)
-}
-
-// readFirstLine reads the first line from a cgroup param file.
-func (cg *CGroup) readFirstLine(param string) (string, error) {
- paramFile, err := os.Open(cg.ParamPath(param))
- if err != nil {
- return "", err
- }
- defer paramFile.Close()
-
- scanner := bufio.NewScanner(paramFile)
- if scanner.Scan() {
- return scanner.Text(), nil
- }
- if err := scanner.Err(); err != nil {
- return "", err
- }
- return "", io.ErrUnexpectedEOF
-}
-
-// readInt parses the first line from a cgroup param file as int.
-func (cg *CGroup) readInt(param string) (int, error) {
- text, err := cg.readFirstLine(param)
- if err != nil {
- return 0, err
- }
- return strconv.Atoi(text)
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroups.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroups.go
deleted file mode 100644
index ed384891ef..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroups.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-//go:build linux
-// +build linux
-
-package automaxprocs
-
-const (
- // _cgroupFSType is the Linux CGroup file system type used in
- // `/proc/$PID/mountinfo`.
- _cgroupFSType = "cgroup"
- // _cgroupSubsysCPU is the CPU CGroup subsystem.
- _cgroupSubsysCPU = "cpu"
- // _cgroupSubsysCPUAcct is the CPU accounting CGroup subsystem.
- _cgroupSubsysCPUAcct = "cpuacct"
- // _cgroupSubsysCPUSet is the CPUSet CGroup subsystem.
- _cgroupSubsysCPUSet = "cpuset"
- // _cgroupSubsysMemory is the Memory CGroup subsystem.
- _cgroupSubsysMemory = "memory"
-
- // _cgroupCPUCFSQuotaUsParam is the file name for the CGroup CFS quota
- // parameter.
- _cgroupCPUCFSQuotaUsParam = "cpu.cfs_quota_us"
- // _cgroupCPUCFSPeriodUsParam is the file name for the CGroup CFS period
- // parameter.
- _cgroupCPUCFSPeriodUsParam = "cpu.cfs_period_us"
-)
-
-const (
- _procPathCGroup = "/proc/self/cgroup"
- _procPathMountInfo = "/proc/self/mountinfo"
-)
-
-// CGroups is a map that associates each CGroup with its subsystem name.
-type CGroups map[string]*CGroup
-
-// NewCGroups returns a new *CGroups from given `mountinfo` and `cgroup` files
-// under for some process under `/proc` file system (see also proc(5) for more
-// information).
-func NewCGroups(procPathMountInfo, procPathCGroup string) (CGroups, error) {
- cgroupSubsystems, err := parseCGroupSubsystems(procPathCGroup)
- if err != nil {
- return nil, err
- }
-
- cgroups := make(CGroups)
- newMountPoint := func(mp *MountPoint) error {
- if mp.FSType != _cgroupFSType {
- return nil
- }
-
- for _, opt := range mp.SuperOptions {
- subsys, exists := cgroupSubsystems[opt]
- if !exists {
- continue
- }
-
- cgroupPath, err := mp.Translate(subsys.Name)
- if err != nil {
- return err
- }
- cgroups[opt] = NewCGroup(cgroupPath)
- }
-
- return nil
- }
-
- if err := parseMountInfo(procPathMountInfo, newMountPoint); err != nil {
- return nil, err
- }
- return cgroups, nil
-}
-
-// NewCGroupsForCurrentProcess returns a new *CGroups instance for the current
-// process.
-func NewCGroupsForCurrentProcess() (CGroups, error) {
- return NewCGroups(_procPathMountInfo, _procPathCGroup)
-}
-
-// CPUQuota returns the CPU quota applied with the CPU cgroup controller.
-// It is a result of `cpu.cfs_quota_us / cpu.cfs_period_us`. If the value of
-// `cpu.cfs_quota_us` was not set (-1), the method returns `(-1, nil)`.
-func (cg CGroups) CPUQuota() (float64, bool, error) {
- cpuCGroup, exists := cg[_cgroupSubsysCPU]
- if !exists {
- return -1, false, nil
- }
-
- cfsQuotaUs, err := cpuCGroup.readInt(_cgroupCPUCFSQuotaUsParam)
- if defined := cfsQuotaUs > 0; err != nil || !defined {
- return -1, defined, err
- }
-
- cfsPeriodUs, err := cpuCGroup.readInt(_cgroupCPUCFSPeriodUsParam)
- if defined := cfsPeriodUs > 0; err != nil || !defined {
- return -1, defined, err
- }
-
- return float64(cfsQuotaUs) / float64(cfsPeriodUs), true, nil
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroups2.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroups2.go
deleted file mode 100644
index 69a0be6b71..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroups2.go
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2022 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-//go:build linux
-// +build linux
-
-package automaxprocs
-
-import (
- "bufio"
- "errors"
- "fmt"
- "io"
- "os"
- "path"
- "strconv"
- "strings"
-)
-
-const (
- // _cgroupv2CPUMax is the file name for the CGroup-V2 CPU max and period
- // parameter.
- _cgroupv2CPUMax = "cpu.max"
- // _cgroupFSType is the Linux CGroup-V2 file system type used in
- // `/proc/$PID/mountinfo`.
- _cgroupv2FSType = "cgroup2"
-
- _cgroupv2MountPoint = "/sys/fs/cgroup"
-
- _cgroupV2CPUMaxDefaultPeriod = 100000
- _cgroupV2CPUMaxQuotaMax = "max"
-)
-
-const (
- _cgroupv2CPUMaxQuotaIndex = iota
- _cgroupv2CPUMaxPeriodIndex
-)
-
-// ErrNotV2 indicates that the system is not using cgroups2.
-var ErrNotV2 = errors.New("not using cgroups2")
-
-// CGroups2 provides access to cgroups data for systems using cgroups2.
-type CGroups2 struct {
- mountPoint string
- groupPath string
- cpuMaxFile string
-}
-
-// NewCGroups2ForCurrentProcess builds a CGroups2 for the current process.
-//
-// This returns ErrNotV2 if the system is not using cgroups2.
-func NewCGroups2ForCurrentProcess() (*CGroups2, error) {
- return newCGroups2From(_procPathMountInfo, _procPathCGroup)
-}
-
-func newCGroups2From(mountInfoPath, procPathCGroup string) (*CGroups2, error) {
- isV2, err := isCGroupV2(mountInfoPath)
- if err != nil {
- return nil, err
- }
-
- if !isV2 {
- return nil, ErrNotV2
- }
-
- subsystems, err := parseCGroupSubsystems(procPathCGroup)
- if err != nil {
- return nil, err
- }
-
- // Find v2 subsystem by looking for the `0` id
- var v2subsys *CGroupSubsys
- for _, subsys := range subsystems {
- if subsys.ID == 0 {
- v2subsys = subsys
- break
- }
- }
-
- if v2subsys == nil {
- return nil, ErrNotV2
- }
-
- return &CGroups2{
- mountPoint: _cgroupv2MountPoint,
- groupPath: v2subsys.Name,
- cpuMaxFile: _cgroupv2CPUMax,
- }, nil
-}
-
-func isCGroupV2(procPathMountInfo string) (bool, error) {
- var (
- isV2 bool
- newMountPoint = func(mp *MountPoint) error {
- isV2 = isV2 || (mp.FSType == _cgroupv2FSType && mp.MountPoint == _cgroupv2MountPoint)
- return nil
- }
- )
-
- if err := parseMountInfo(procPathMountInfo, newMountPoint); err != nil {
- return false, err
- }
-
- return isV2, nil
-}
-
-// CPUQuota returns the CPU quota applied with the CPU cgroup2 controller.
-// It is a result of reading cpu quota and period from cpu.max file.
-// It will return `cpu.max / cpu.period`. If cpu.max is set to max, it returns
-// (-1, false, nil)
-func (cg *CGroups2) CPUQuota() (float64, bool, error) {
- cpuMaxParams, err := os.Open(path.Join(cg.mountPoint, cg.groupPath, cg.cpuMaxFile))
- if err != nil {
- if os.IsNotExist(err) {
- return -1, false, nil
- }
- return -1, false, err
- }
- defer cpuMaxParams.Close()
-
- scanner := bufio.NewScanner(cpuMaxParams)
- if scanner.Scan() {
- fields := strings.Fields(scanner.Text())
- if len(fields) == 0 || len(fields) > 2 {
- return -1, false, fmt.Errorf("invalid format")
- }
-
- if fields[_cgroupv2CPUMaxQuotaIndex] == _cgroupV2CPUMaxQuotaMax {
- return -1, false, nil
- }
-
- max, err := strconv.Atoi(fields[_cgroupv2CPUMaxQuotaIndex])
- if err != nil {
- return -1, false, err
- }
-
- var period int
- if len(fields) == 1 {
- period = _cgroupV2CPUMaxDefaultPeriod
- } else {
- period, err = strconv.Atoi(fields[_cgroupv2CPUMaxPeriodIndex])
- if err != nil {
- return -1, false, err
- }
-
- if period == 0 {
- return -1, false, errors.New("zero value for period is not allowed")
- }
- }
-
- return float64(max) / float64(period), true, nil
- }
-
- if err := scanner.Err(); err != nil {
- return -1, false, err
- }
-
- return 0, false, io.ErrUnexpectedEOF
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cpu_quota_linux.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cpu_quota_linux.go
deleted file mode 100644
index 2d83343bd9..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cpu_quota_linux.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-//go:build linux
-// +build linux
-
-package automaxprocs
-
-import (
- "errors"
-)
-
-// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
-// to a valid GOMAXPROCS value. The quota is converted from float to int using round.
-// If round == nil, DefaultRoundFunc is used.
-func CPUQuotaToGOMAXPROCS(minValue int, round func(v float64) int) (int, CPUQuotaStatus, error) {
- if round == nil {
- round = DefaultRoundFunc
- }
- cgroups, err := _newQueryer()
- if err != nil {
- return -1, CPUQuotaUndefined, err
- }
-
- quota, defined, err := cgroups.CPUQuota()
- if !defined || err != nil {
- return -1, CPUQuotaUndefined, err
- }
-
- maxProcs := round(quota)
- if minValue > 0 && maxProcs < minValue {
- return minValue, CPUQuotaMinUsed, nil
- }
- return maxProcs, CPUQuotaUsed, nil
-}
-
-type queryer interface {
- CPUQuota() (float64, bool, error)
-}
-
-var (
- _newCgroups2 = NewCGroups2ForCurrentProcess
- _newCgroups = NewCGroupsForCurrentProcess
- _newQueryer = newQueryer
-)
-
-func newQueryer() (queryer, error) {
- cgroups, err := _newCgroups2()
- if err == nil {
- return cgroups, nil
- }
- if errors.Is(err, ErrNotV2) {
- return _newCgroups()
- }
- return nil, err
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cpu_quota_unsupported.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cpu_quota_unsupported.go
deleted file mode 100644
index d2d61e8941..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cpu_quota_unsupported.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-//go:build !linux
-// +build !linux
-
-package automaxprocs
-
-// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
-// to a valid GOMAXPROCS value. This is Linux-specific and not supported in the
-// current OS.
-func CPUQuotaToGOMAXPROCS(_ int, _ func(v float64) int) (int, CPUQuotaStatus, error) {
- return -1, CPUQuotaUndefined, nil
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/errors.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/errors.go
deleted file mode 100644
index 2e235d7d65..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/errors.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-//go:build linux
-// +build linux
-
-package automaxprocs
-
-import "fmt"
-
-type cgroupSubsysFormatInvalidError struct {
- line string
-}
-
-type mountPointFormatInvalidError struct {
- line string
-}
-
-type pathNotExposedFromMountPointError struct {
- mountPoint string
- root string
- path string
-}
-
-func (err cgroupSubsysFormatInvalidError) Error() string {
- return fmt.Sprintf("invalid format for CGroupSubsys: %q", err.line)
-}
-
-func (err mountPointFormatInvalidError) Error() string {
- return fmt.Sprintf("invalid format for MountPoint: %q", err.line)
-}
-
-func (err pathNotExposedFromMountPointError) Error() string {
- return fmt.Sprintf("path %q is not a descendant of mount point root %q and cannot be exposed from %q", err.path, err.root, err.mountPoint)
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/mountpoint.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/mountpoint.go
deleted file mode 100644
index 7c3fa306ef..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/mountpoint.go
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-//go:build linux
-// +build linux
-
-package automaxprocs
-
-import (
- "bufio"
- "os"
- "path/filepath"
- "strconv"
- "strings"
-)
-
-const (
- _mountInfoSep = " "
- _mountInfoOptsSep = ","
- _mountInfoOptionalFieldsSep = "-"
-)
-
-const (
- _miFieldIDMountID = iota
- _miFieldIDParentID
- _miFieldIDDeviceID
- _miFieldIDRoot
- _miFieldIDMountPoint
- _miFieldIDOptions
- _miFieldIDOptionalFields
-
- _miFieldCountFirstHalf
-)
-
-const (
- _miFieldOffsetFSType = iota
- _miFieldOffsetMountSource
- _miFieldOffsetSuperOptions
-
- _miFieldCountSecondHalf
-)
-
-const _miFieldCountMin = _miFieldCountFirstHalf + _miFieldCountSecondHalf
-
-// MountPoint is the data structure for the mount points in
-// `/proc/$PID/mountinfo`. See also proc(5) for more information.
-type MountPoint struct {
- MountID int
- ParentID int
- DeviceID string
- Root string
- MountPoint string
- Options []string
- OptionalFields []string
- FSType string
- MountSource string
- SuperOptions []string
-}
-
-// NewMountPointFromLine parses a line read from `/proc/$PID/mountinfo` and
-// returns a new *MountPoint.
-func NewMountPointFromLine(line string) (*MountPoint, error) {
- fields := strings.Split(line, _mountInfoSep)
-
- if len(fields) < _miFieldCountMin {
- return nil, mountPointFormatInvalidError{line}
- }
-
- mountID, err := strconv.Atoi(fields[_miFieldIDMountID])
- if err != nil {
- return nil, err
- }
-
- parentID, err := strconv.Atoi(fields[_miFieldIDParentID])
- if err != nil {
- return nil, err
- }
-
- for i, field := range fields[_miFieldIDOptionalFields:] {
- if field == _mountInfoOptionalFieldsSep {
- // End of optional fields.
- fsTypeStart := _miFieldIDOptionalFields + i + 1
-
- // Now we know where the optional fields end, split the line again with a
- // limit to avoid issues with spaces in super options as present on WSL.
- fields = strings.SplitN(line, _mountInfoSep, fsTypeStart+_miFieldCountSecondHalf)
- if len(fields) != fsTypeStart+_miFieldCountSecondHalf {
- return nil, mountPointFormatInvalidError{line}
- }
-
- miFieldIDFSType := _miFieldOffsetFSType + fsTypeStart
- miFieldIDMountSource := _miFieldOffsetMountSource + fsTypeStart
- miFieldIDSuperOptions := _miFieldOffsetSuperOptions + fsTypeStart
-
- return &MountPoint{
- MountID: mountID,
- ParentID: parentID,
- DeviceID: fields[_miFieldIDDeviceID],
- Root: fields[_miFieldIDRoot],
- MountPoint: fields[_miFieldIDMountPoint],
- Options: strings.Split(fields[_miFieldIDOptions], _mountInfoOptsSep),
- OptionalFields: fields[_miFieldIDOptionalFields:(fsTypeStart - 1)],
- FSType: fields[miFieldIDFSType],
- MountSource: fields[miFieldIDMountSource],
- SuperOptions: strings.Split(fields[miFieldIDSuperOptions], _mountInfoOptsSep),
- }, nil
- }
- }
-
- return nil, mountPointFormatInvalidError{line}
-}
-
-// Translate converts an absolute path inside the *MountPoint's file system to
-// the host file system path in the mount namespace the *MountPoint belongs to.
-func (mp *MountPoint) Translate(absPath string) (string, error) {
- relPath, err := filepath.Rel(mp.Root, absPath)
-
- if err != nil {
- return "", err
- }
- if relPath == ".." || strings.HasPrefix(relPath, "../") {
- return "", pathNotExposedFromMountPointError{
- mountPoint: mp.MountPoint,
- root: mp.Root,
- path: absPath,
- }
- }
-
- return filepath.Join(mp.MountPoint, relPath), nil
-}
-
-// parseMountInfo parses procPathMountInfo (usually at `/proc/$PID/mountinfo`)
-// and yields parsed *MountPoint into newMountPoint.
-func parseMountInfo(procPathMountInfo string, newMountPoint func(*MountPoint) error) error {
- mountInfoFile, err := os.Open(procPathMountInfo)
- if err != nil {
- return err
- }
- defer mountInfoFile.Close()
-
- scanner := bufio.NewScanner(mountInfoFile)
-
- for scanner.Scan() {
- mountPoint, err := NewMountPointFromLine(scanner.Text())
- if err != nil {
- return err
- }
- if err := newMountPoint(mountPoint); err != nil {
- return err
- }
- }
-
- return scanner.Err()
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/runtime.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/runtime.go
deleted file mode 100644
index b8ec7e502a..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/runtime.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package automaxprocs
-
-import "math"
-
-// CPUQuotaStatus presents the status of how CPU quota is used
-type CPUQuotaStatus int
-
-const (
- // CPUQuotaUndefined is returned when CPU quota is undefined
- CPUQuotaUndefined CPUQuotaStatus = iota
- // CPUQuotaUsed is returned when a valid CPU quota can be used
- CPUQuotaUsed
- // CPUQuotaMinUsed is returned when CPU quota is smaller than the min value
- CPUQuotaMinUsed
-)
-
-// DefaultRoundFunc is the default function to convert CPU quota from float to int. It rounds the value down (floor).
-func DefaultRoundFunc(v float64) int {
- return int(math.Floor(v))
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/subsys.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/subsys.go
deleted file mode 100644
index 881ebd5902..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/subsys.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-//go:build linux
-// +build linux
-
-package automaxprocs
-
-import (
- "bufio"
- "os"
- "strconv"
- "strings"
-)
-
-const (
- _cgroupSep = ":"
- _cgroupSubsysSep = ","
-)
-
-const (
- _csFieldIDID = iota
- _csFieldIDSubsystems
- _csFieldIDName
- _csFieldCount
-)
-
-// CGroupSubsys represents the data structure for entities in
-// `/proc/$PID/cgroup`. See also proc(5) for more information.
-type CGroupSubsys struct {
- ID int
- Subsystems []string
- Name string
-}
-
-// NewCGroupSubsysFromLine returns a new *CGroupSubsys by parsing a string in
-// the format of `/proc/$PID/cgroup`
-func NewCGroupSubsysFromLine(line string) (*CGroupSubsys, error) {
- fields := strings.SplitN(line, _cgroupSep, _csFieldCount)
-
- if len(fields) != _csFieldCount {
- return nil, cgroupSubsysFormatInvalidError{line}
- }
-
- id, err := strconv.Atoi(fields[_csFieldIDID])
- if err != nil {
- return nil, err
- }
-
- cgroup := &CGroupSubsys{
- ID: id,
- Subsystems: strings.Split(fields[_csFieldIDSubsystems], _cgroupSubsysSep),
- Name: fields[_csFieldIDName],
- }
-
- return cgroup, nil
-}
-
-// parseCGroupSubsystems parses procPathCGroup (usually at `/proc/$PID/cgroup`)
-// and returns a new map[string]*CGroupSubsys.
-func parseCGroupSubsystems(procPathCGroup string) (map[string]*CGroupSubsys, error) {
- cgroupFile, err := os.Open(procPathCGroup)
- if err != nil {
- return nil, err
- }
- defer cgroupFile.Close()
-
- scanner := bufio.NewScanner(cgroupFile)
- subsystems := make(map[string]*CGroupSubsys)
-
- for scanner.Scan() {
- cgroup, err := NewCGroupSubsysFromLine(scanner.Text())
- if err != nil {
- return nil, err
- }
- for _, subsys := range cgroup.Subsystems {
- subsystems[subsys] = cgroup
- }
- }
-
- if err := scanner.Err(); err != nil {
- return nil, err
- }
-
- return subsystems, nil
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go
index 3021dfec2e..fd17260843 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go
@@ -29,6 +29,7 @@ func BuildBuildCommand() command.Command {
var errors []error
cliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig)
command.AbortIfErrors("Ginkgo detected configuration issues:", errors)
+
buildSpecs(args, cliConfig, goFlagsConfig)
},
}
@@ -43,7 +44,7 @@ func buildSpecs(args []string, cliConfig types.CLIConfig, goFlagsConfig types.Go
internal.VerifyCLIAndFrameworkVersion(suites)
opc := internal.NewOrderedParallelCompiler(cliConfig.ComputedNumCompilers())
- opc.StartCompiling(suites, goFlagsConfig, true)
+ opc.StartCompiling(suites, goFlagsConfig)
for {
suiteIdx, suite := opc.Next()
@@ -54,22 +55,18 @@ func buildSpecs(args []string, cliConfig types.CLIConfig, goFlagsConfig types.Go
if suite.State.Is(internal.TestSuiteStateFailedToCompile) {
fmt.Println(suite.CompilationError.Error())
} else {
- var testBinPath string
- if len(goFlagsConfig.O) != 0 {
+ if len(goFlagsConfig.O) == 0 {
+ goFlagsConfig.O = path.Join(suite.Path, suite.PackageName+".test")
+ } else {
stat, err := os.Stat(goFlagsConfig.O)
if err != nil {
panic(err)
}
if stat.IsDir() {
- testBinPath = goFlagsConfig.O + "/" + suite.PackageName + ".test"
- } else {
- testBinPath = goFlagsConfig.O
+ goFlagsConfig.O += "/" + suite.PackageName + ".test"
}
}
- if len(testBinPath) == 0 {
- testBinPath = path.Join(suite.Path, suite.PackageName+".test")
- }
- fmt.Printf("Compiled %s\n", testBinPath)
+ fmt.Printf("Compiled %s\n", goFlagsConfig.O)
}
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/abort.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/abort.go
index f0e7331f7d..2efd286088 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/abort.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/abort.go
@@ -12,7 +12,7 @@ func Abort(details AbortDetails) {
panic(details)
}
-func AbortGracefullyWith(format string, args ...any) {
+func AbortGracefullyWith(format string, args ...interface{}) {
Abort(AbortDetails{
ExitCode: 0,
Error: fmt.Errorf(format, args...),
@@ -20,7 +20,7 @@ func AbortGracefullyWith(format string, args ...any) {
})
}
-func AbortWith(format string, args ...any) {
+func AbortWith(format string, args ...interface{}) {
Abort(AbortDetails{
ExitCode: 1,
Error: fmt.Errorf(format, args...),
@@ -28,7 +28,7 @@ func AbortWith(format string, args ...any) {
})
}
-func AbortWithUsage(format string, args ...any) {
+func AbortWithUsage(format string, args ...interface{}) {
Abort(AbortDetails{
ExitCode: 1,
Error: fmt.Errorf(format, args...),
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go
index a30a2ecc92..12e0e56591 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go
@@ -22,13 +22,9 @@ type Command struct {
func (c Command) Run(args []string, additionalArgs []string) {
args, err := c.Flags.Parse(args)
if err != nil {
- AbortWithUsage("%s", err.Error())
- }
- for _, arg := range args {
- if len(arg) > 1 && strings.HasPrefix(arg, "-") {
- AbortWith("%s", types.GinkgoErrors.FlagAfterPositionalParameter().Error())
- }
+ AbortWithUsage(err.Error())
}
+
c.Command(args, additionalArgs)
}
@@ -49,6 +45,6 @@ func (c Command) EmitUsage(writer io.Writer) {
}
flagUsage := c.Flags.Usage()
if flagUsage != "" {
- fmt.Fprint(writer, formatter.F(flagUsage))
+ fmt.Fprintf(writer, formatter.F(flagUsage))
}
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go
index c3f6d3a11e..88dd8d6b07 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go
@@ -68,6 +68,7 @@ func (p Program) RunAndExit(osArgs []string) {
fmt.Fprintln(p.ErrWriter, deprecationTracker.DeprecationsReport())
}
p.Exiter(exitCode)
+ return
}()
args, additionalArgs := []string{}, []string{}
@@ -156,6 +157,7 @@ func (p Program) handleHelpRequestsAndExit(writer io.Writer, args []string) {
p.EmitUsage(writer)
Abort(AbortDetails{ExitCode: 1})
}
+ return
}
func (p Program) EmitUsage(writer io.Writer) {
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/compile.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/compile.go
index 7bbe6be0fc..48827cc5ef 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/compile.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/compile.go
@@ -11,7 +11,7 @@ import (
"github.com/onsi/ginkgo/v2/types"
)
-func CompileSuite(suite TestSuite, goFlagsConfig types.GoFlagsConfig, preserveSymbols bool) TestSuite {
+func CompileSuite(suite TestSuite, goFlagsConfig types.GoFlagsConfig) TestSuite {
if suite.PathToCompiledTest != "" {
return suite
}
@@ -46,7 +46,7 @@ func CompileSuite(suite TestSuite, goFlagsConfig types.GoFlagsConfig, preserveSy
suite.CompilationError = fmt.Errorf("Failed to get relative path from package to the current working directory:\n%s", err.Error())
return suite
}
- args, err := types.GenerateGoTestCompileArgs(goFlagsConfig, "./", pathToInvocationPath, preserveSymbols)
+ args, err := types.GenerateGoTestCompileArgs(goFlagsConfig, "./", pathToInvocationPath)
if err != nil {
suite.State = TestSuiteStateFailedToCompile
suite.CompilationError = fmt.Errorf("Failed to generate go test compile flags:\n%s", err.Error())
@@ -120,7 +120,7 @@ func NewOrderedParallelCompiler(numCompilers int) *OrderedParallelCompiler {
}
}
-func (opc *OrderedParallelCompiler) StartCompiling(suites TestSuites, goFlagsConfig types.GoFlagsConfig, preserveSymbols bool) {
+func (opc *OrderedParallelCompiler) StartCompiling(suites TestSuites, goFlagsConfig types.GoFlagsConfig) {
opc.stopped = false
opc.idx = 0
opc.numSuites = len(suites)
@@ -135,7 +135,7 @@ func (opc *OrderedParallelCompiler) StartCompiling(suites TestSuites, goFlagsCon
stopped := opc.stopped
opc.mutex.Unlock()
if !stopped {
- suite = CompileSuite(suite, goFlagsConfig, preserveSymbols)
+ suite = CompileSuite(suite, goFlagsConfig)
}
c <- suite
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/gocovmerge.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/gocovmerge.go
index 87cfa11194..3c5079ff4c 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/gocovmerge.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/gocovmerge.go
@@ -89,7 +89,7 @@ func mergeProfileBlock(p *cover.Profile, pb cover.ProfileBlock, startIndex int)
}
i := 0
- if !sortFunc(i) {
+ if sortFunc(i) != true {
i = sort.Search(len(p.Blocks)-startIndex, sortFunc)
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/profiles_and_reports.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/profiles_and_reports.go
index f3439a3f0c..8e16d2bb03 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/profiles_and_reports.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/profiles_and_reports.go
@@ -90,9 +90,6 @@ func FinalizeProfilesAndReportsForSuites(suites TestSuites, cliConfig types.CLIC
if reporterConfig.JSONReport != "" {
reportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.JSONReport, GenerateFunc: reporters.GenerateJSONReport, MergeFunc: reporters.MergeAndCleanupJSONReports})
}
- if reporterConfig.GoJSONReport != "" {
- reportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.GoJSONReport, GenerateFunc: reporters.GenerateGoTestJSONReport, MergeFunc: reporters.MergeAndCleanupGoTestJSONReports})
- }
if reporterConfig.JUnitReport != "" {
reportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.JUnitReport, GenerateFunc: reporters.GenerateJUnitReport, MergeFunc: reporters.MergeAndCleanupJUnitReports})
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go
index 68830d9ae2..41052ea19d 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go
@@ -9,7 +9,6 @@ import (
"path/filepath"
"regexp"
"strings"
- "sync/atomic"
"syscall"
"time"
@@ -108,9 +107,6 @@ func runSerial(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig t
if reporterConfig.JSONReport != "" {
reporterConfig.JSONReport = AbsPathForGeneratedAsset(reporterConfig.JSONReport, suite, cliConfig, 0)
}
- if reporterConfig.GoJSONReport != "" {
- reporterConfig.GoJSONReport = AbsPathForGeneratedAsset(reporterConfig.GoJSONReport, suite, cliConfig, 0)
- }
if reporterConfig.JUnitReport != "" {
reporterConfig.JUnitReport = AbsPathForGeneratedAsset(reporterConfig.JUnitReport, suite, cliConfig, 0)
}
@@ -160,15 +156,12 @@ func runSerial(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig t
func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig types.ReporterConfig, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig, additionalArgs []string) TestSuite {
type procResult struct {
- proc int
- exitResult string
passed bool
hasProgrammaticFocus bool
}
numProcs := cliConfig.ComputedProcs()
procOutput := make([]*bytes.Buffer, numProcs)
- procExitResult := make([]string, numProcs)
coverProfiles := []string{}
blockProfiles := []string{}
@@ -186,9 +179,6 @@ func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig
if reporterConfig.JSONReport != "" {
reporterConfig.JSONReport = AbsPathForGeneratedAsset(reporterConfig.JSONReport, suite, cliConfig, 0)
}
- if reporterConfig.GoJSONReport != "" {
- reporterConfig.GoJSONReport = AbsPathForGeneratedAsset(reporterConfig.GoJSONReport, suite, cliConfig, 0)
- }
if reporterConfig.JUnitReport != "" {
reporterConfig.JUnitReport = AbsPathForGeneratedAsset(reporterConfig.JUnitReport, suite, cliConfig, 0)
}
@@ -228,20 +218,16 @@ func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig
args = append(args, additionalArgs...)
cmd, buf := buildAndStartCommand(suite, args, false)
- var exited atomic.Bool
procOutput[proc-1] = buf
- server.RegisterAlive(proc, func() bool { return !exited.Load() })
+ server.RegisterAlive(proc, func() bool { return cmd.ProcessState == nil || !cmd.ProcessState.Exited() })
go func() {
cmd.Wait()
exitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
procResults <- procResult{
- proc: proc,
- exitResult: cmd.ProcessState.String(),
passed: (exitStatus == 0) || (exitStatus == types.GINKGO_FOCUS_EXIT_CODE),
hasProgrammaticFocus: exitStatus == types.GINKGO_FOCUS_EXIT_CODE,
}
- exited.Store(true)
}()
}
@@ -250,7 +236,6 @@ func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig
result := <-procResults
passed = passed && result.passed
suite.HasProgrammaticFocus = suite.HasProgrammaticFocus || result.hasProgrammaticFocus
- procExitResult[result.proc-1] = result.exitResult
}
if passed {
suite.State = TestSuiteStatePassed
@@ -268,10 +253,8 @@ func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig
fmt.Fprint(formatter.ColorableStdErr, formatter.Fiw(0, formatter.COLS, "This occurs if a parallel process exits before it reports its results to the Ginkgo CLI. The CLI will now print out all the stdout/stderr output it's collected from the running processes. However you may not see anything useful in these logs because the individual test processes usually intercept output to stdout/stderr in order to capture it in the spec reports.\n\nYou may want to try rerunning your test suite with {{light-gray}}--output-interceptor-mode=none{{/}} to see additional output here and debug your suite.\n"))
fmt.Fprintln(formatter.ColorableStdErr, " ")
for proc := 1; proc <= cliConfig.ComputedProcs(); proc++ {
- fmt.Fprint(formatter.ColorableStdErr, formatter.F("{{bold}}Output from proc %d:{{/}}\n", proc))
+ fmt.Fprintf(formatter.ColorableStdErr, formatter.F("{{bold}}Output from proc %d:{{/}}\n", proc))
fmt.Fprintln(os.Stderr, formatter.Fi(1, "%s", procOutput[proc-1].String()))
- fmt.Fprint(formatter.ColorableStdErr, formatter.F("{{bold}}Exit result of proc %d:{{/}}\n", proc))
- fmt.Fprintln(os.Stderr, formatter.Fi(1, "%s\n", procExitResult[proc-1]))
}
fmt.Fprintf(os.Stderr, "** End **")
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go
index 419589b48c..e9abb27d8b 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go
@@ -3,6 +3,7 @@ package main
import (
"fmt"
"os"
+
"github.com/onsi/ginkgo/v2/ginkgo/build"
"github.com/onsi/ginkgo/v2/ginkgo/command"
"github.com/onsi/ginkgo/v2/ginkgo/generators"
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 e99d557d1f..c2327cda8c 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go
@@ -1,13 +1,10 @@
package outline
import (
- "bytes"
- "encoding/csv"
"encoding/json"
"fmt"
"go/ast"
"go/token"
- "strconv"
"strings"
"golang.org/x/tools/go/ast/inspector"
@@ -87,11 +84,9 @@ func (o *outline) String() string {
// StringIndent returns a CSV-formated outline, but every line is indented by
// one 'width' of spaces for every level of nesting.
func (o *outline) StringIndent(width int) string {
- var b bytes.Buffer
+ var b strings.Builder
b.WriteString("Name,Text,Start,End,Spec,Focused,Pending,Labels\n")
- csvWriter := csv.NewWriter(&b)
-
currentIndent := 0
pre := func(n *ginkgoNode) {
b.WriteString(fmt.Sprintf("%*s", currentIndent, ""))
@@ -101,22 +96,8 @@ func (o *outline) StringIndent(width int) string {
} else {
labels = strings.Join(n.Labels, ", ")
}
-
- row := []string{
- n.Name,
- n.Text,
- strconv.Itoa(n.Start),
- strconv.Itoa(n.End),
- strconv.FormatBool(n.Spec),
- strconv.FormatBool(n.Focused),
- strconv.FormatBool(n.Pending),
- labels,
- }
- csvWriter.Write(row)
-
- // Ensure we write to `b' before the next `b.WriteString()', which might be adding indentation
- csvWriter.Flush()
-
+ //enclosing labels in a double quoted comma separate listed so that when inmported into a CSV app the Labels column has comma separate strings
+ b.WriteString(fmt.Sprintf("%s,%s,%d,%d,%t,%t,%t,\"%s\"\n", n.Name, n.Text, n.Start, n.End, n.Spec, n.Focused, n.Pending, labels))
currentIndent += width
}
post := func(n *ginkgoNode) {
@@ -125,6 +106,5 @@ func (o *outline) StringIndent(width int) string {
for _, n := range o.Nodes {
n.Walk(pre, post)
}
-
return b.String()
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go
index c5091e6de8..aaed4d570e 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go
@@ -33,7 +33,7 @@ func BuildRunCommand() command.Command {
Usage: "ginkgo run -- ",
ShortDoc: "Run the tests in the passed in (or the package in the current directory if left blank)",
Documentation: "Any arguments after -- will be passed to the test.",
- DocLink: "running-specs",
+ DocLink: "running-tests",
Command: func(args []string, additionalArgs []string) {
var errors []error
cliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig)
@@ -107,7 +107,7 @@ OUTER_LOOP:
}
opc := internal.NewOrderedParallelCompiler(r.cliConfig.ComputedNumCompilers())
- opc.StartCompiling(suites, r.goFlagsConfig, false)
+ opc.StartCompiling(suites, r.goFlagsConfig)
SUITE_LOOP:
for {
@@ -142,7 +142,7 @@ OUTER_LOOP:
}
if !endTime.IsZero() {
- r.suiteConfig.Timeout = time.Until(endTime)
+ r.suiteConfig.Timeout = endTime.Sub(time.Now())
if r.suiteConfig.Timeout <= 0 {
suites[suiteIdx].State = internal.TestSuiteStateFailedDueToTimeout
opc.StopAndDrain()
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/dependencies.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/dependencies.go
index 75cbdb4962..a34d94354d 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/dependencies.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/dependencies.go
@@ -2,9 +2,12 @@ package watch
import (
"go/build"
- "strings"
+ "regexp"
)
+var ginkgoAndGomegaFilter = regexp.MustCompile(`github\.com/onsi/ginkgo|github\.com/onsi/gomega`)
+var ginkgoIntegrationTestFilter = regexp.MustCompile(`github\.com/onsi/ginkgo/integration`) //allow us to integration test this thing
+
type Dependencies struct {
deps map[string]int
}
@@ -75,7 +78,7 @@ func (d Dependencies) resolveAndAdd(deps []string, depth int) {
if err != nil {
continue
}
- if !pkg.Goroot && (!matchesGinkgoOrGomega(pkg.Dir) || matchesGinkgoIntegration(pkg.Dir)) {
+ if !pkg.Goroot && (!ginkgoAndGomegaFilter.MatchString(pkg.Dir) || ginkgoIntegrationTestFilter.MatchString(pkg.Dir)) {
d.addDepIfNotPresent(pkg.Dir, depth)
}
}
@@ -87,11 +90,3 @@ func (d Dependencies) addDepIfNotPresent(dep string, depth int) {
d.deps[dep] = depth
}
}
-
-func matchesGinkgoOrGomega(s string) bool {
- return strings.Contains(s, "github.com/onsi/ginkgo") || strings.Contains(s, "github.com/onsi/gomega")
-}
-
-func matchesGinkgoIntegration(s string) bool {
- return strings.Contains(s, "github.com/onsi/ginkgo/integration") // allow us to integration test this thing
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go
index fe1ca30519..bde4193ce7 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go
@@ -153,7 +153,7 @@ func (w *SpecWatcher) WatchSpecs(args []string, additionalArgs []string) {
}
func (w *SpecWatcher) compileAndRun(suite internal.TestSuite, additionalArgs []string) internal.TestSuite {
- suite = internal.CompileSuite(suite, w.goFlagsConfig, false)
+ suite = internal.CompileSuite(suite, w.goFlagsConfig)
if suite.State.Is(internal.TestSuiteStateFailedToCompile) {
fmt.Println(suite.CompilationError.Error())
return suite
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go
index 40d1e1ab5c..02c6739e5b 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go
@@ -1,8 +1,6 @@
package ginkgo
import (
- "context"
- "io"
"testing"
"github.com/onsi/ginkgo/v2/internal/testingtproxy"
@@ -50,8 +48,6 @@ The portion of the interface returned by GinkgoT() that maps onto methods in the
*/
type GinkgoTInterface interface {
Cleanup(func())
- Chdir(dir string)
- Context() context.Context
Setenv(kev, value string)
Error(args ...any)
Errorf(format string, args ...any)
@@ -70,8 +66,6 @@ type GinkgoTInterface interface {
Skipf(format string, args ...any)
Skipped() bool
TempDir() string
- Attr(key, value string)
- Output() io.Writer
}
/*
@@ -133,12 +127,6 @@ type GinkgoTBWrapper struct {
func (g *GinkgoTBWrapper) Cleanup(f func()) {
g.GinkgoT.Cleanup(f)
}
-func (g *GinkgoTBWrapper) Chdir(dir string) {
- g.GinkgoT.Chdir(dir)
-}
-func (g *GinkgoTBWrapper) Context() context.Context {
- return g.GinkgoT.Context()
-}
func (g *GinkgoTBWrapper) Error(args ...any) {
g.GinkgoT.Error(args...)
}
@@ -190,9 +178,3 @@ func (g *GinkgoTBWrapper) Skipped() bool {
func (g *GinkgoTBWrapper) TempDir() string {
return g.GinkgoT.TempDir()
}
-func (g *GinkgoTBWrapper) Attr(key, value string) {
- g.GinkgoT.Attr(key, value)
-}
-func (g *GinkgoTBWrapper) Output() io.Writer {
- return g.GinkgoT.Output()
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/around_node.go b/vendor/github.com/onsi/ginkgo/v2/internal/around_node.go
deleted file mode 100644
index c965710205..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/internal/around_node.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package internal
-
-import (
- "github.com/onsi/ginkgo/v2/types"
-)
-
-func ComputeAroundNodes(specs Specs) Specs {
- out := Specs{}
- for _, spec := range specs {
- nodes := Nodes{}
- currentNestingLevel := 0
- aroundNodes := types.AroundNodes{}
- nestingLevelIndices := []int{}
- for _, node := range spec.Nodes {
- switch node.NodeType {
- case types.NodeTypeContainer:
- currentNestingLevel = node.NestingLevel + 1
- nestingLevelIndices = append(nestingLevelIndices, len(aroundNodes))
- aroundNodes = aroundNodes.Append(node.AroundNodes...)
- nodes = append(nodes, node)
- default:
- if currentNestingLevel > node.NestingLevel {
- currentNestingLevel = node.NestingLevel
- aroundNodes = aroundNodes[:nestingLevelIndices[currentNestingLevel]]
- }
- node.AroundNodes = types.AroundNodes{}.Append(aroundNodes...).Append(node.AroundNodes...)
- nodes = append(nodes, node)
- }
- }
- spec.Nodes = nodes
- out = append(out, spec)
- }
- return out
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/failer.go b/vendor/github.com/onsi/ginkgo/v2/internal/failer.go
index 8c5de9c160..e9bd9565fc 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/failer.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/failer.go
@@ -32,7 +32,7 @@ func (f *Failer) GetFailure() types.Failure {
return f.failure
}
-func (f *Failer) Panic(location types.CodeLocation, forwardedPanic any) {
+func (f *Failer) Panic(location types.CodeLocation, forwardedPanic interface{}) {
f.lock.Lock()
defer f.lock.Unlock()
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/focus.go b/vendor/github.com/onsi/ginkgo/v2/internal/focus.go
index 498e707dbf..e3da7d14dd 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/focus.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/focus.go
@@ -56,7 +56,7 @@ This function sets the `Skip` property on specs by applying Ginkgo's focus polic
*Note:* specs with pending nodes are Skipped when created by NewSpec.
*/
-func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suiteConfig types.SuiteConfig) (Specs, bool) {
+func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suiteConfig types.SuiteConfig) (Specs, bool) {
focusString := strings.Join(suiteConfig.FocusStrings, "|")
skipString := strings.Join(suiteConfig.SkipStrings, "|")
@@ -84,30 +84,6 @@ func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suit
})
}
- if suiteConfig.SemVerFilter != "" {
- semVerFilter, _ := types.ParseSemVerFilter(suiteConfig.SemVerFilter)
- skipChecks = append(skipChecks, func(spec Spec) bool {
- noRun := false
-
- // non-component-specific constraints
- constraints := UnionOfSemVerConstraints(suiteSemVerConstraints, spec.Nodes.UnionOfSemVerConstraints())
- if len(constraints) != 0 && semVerFilter("", constraints) == false {
- noRun = true
- }
-
- // component-specific constraints
- componentConstraints := UnionOfComponentSemVerConstraints(suiteComponentSemVerConstraints, spec.Nodes.UnionOfComponentSemVerConstraints())
- for component, constraints := range componentConstraints {
- if semVerFilter(component, constraints) == false {
- noRun = true
- break
- }
- }
-
- return noRun
- })
- }
-
if len(suiteConfig.FocusFiles) > 0 {
focusFilters, _ := types.ParseFileFilters(suiteConfig.FocusFiles)
skipChecks = append(skipChecks, func(spec Spec) bool { return !focusFilters.Matches(spec.Nodes.CodeLocations()) })
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/group.go b/vendor/github.com/onsi/ginkgo/v2/internal/group.go
index 5e66113343..02c9fe4fcd 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/group.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/group.go
@@ -110,56 +110,21 @@ func newGroup(suite *Suite) *group {
}
}
-// initialReportForSpec constructs a new SpecReport right before running the spec.
func (g *group) initialReportForSpec(spec Spec) types.SpecReport {
return types.SpecReport{
- ContainerHierarchyTexts: spec.Nodes.WithType(types.NodeTypeContainer).Texts(),
- ContainerHierarchyLocations: spec.Nodes.WithType(types.NodeTypeContainer).CodeLocations(),
- ContainerHierarchyLabels: spec.Nodes.WithType(types.NodeTypeContainer).Labels(),
- ContainerHierarchySemVerConstraints: spec.Nodes.WithType(types.NodeTypeContainer).SemVerConstraints(),
- ContainerHierarchyComponentSemVerConstraints: spec.Nodes.WithType(types.NodeTypeContainer).ComponentSemVerConstraints(),
- LeafNodeLocation: spec.FirstNodeWithType(types.NodeTypeIt).CodeLocation,
- LeafNodeType: types.NodeTypeIt,
- LeafNodeText: spec.FirstNodeWithType(types.NodeTypeIt).Text,
- LeafNodeLabels: []string(spec.FirstNodeWithType(types.NodeTypeIt).Labels),
- LeafNodeSemVerConstraints: []string(spec.FirstNodeWithType(types.NodeTypeIt).SemVerConstraints),
- LeafNodeComponentSemVerConstraints: map[string][]string(spec.FirstNodeWithType(types.NodeTypeIt).ComponentSemVerConstraints),
- ParallelProcess: g.suite.config.ParallelProcess,
- RunningInParallel: g.suite.isRunningInParallel(),
- IsSerial: spec.Nodes.HasNodeMarkedSerial(),
- IsInOrderedContainer: !spec.Nodes.FirstNodeMarkedOrdered().IsZero(),
- MaxFlakeAttempts: spec.Nodes.GetMaxFlakeAttempts(),
- MaxMustPassRepeatedly: spec.Nodes.GetMaxMustPassRepeatedly(),
- SpecPriority: spec.Nodes.GetSpecPriority(),
- }
-}
-
-// constructionNodeReportForTreeNode constructs a new SpecReport right before invoking the body
-// of a container node during construction of the full tree.
-func constructionNodeReportForTreeNode(node *TreeNode) *types.ConstructionNodeReport {
- var report types.ConstructionNodeReport
- // Walk up the tree and set attributes accordingly.
- addNodeToReportForNode(&report, node)
- return &report
-}
-
-// addNodeToReportForNode is conceptually similar to initialReportForSpec and therefore placed here
-// although it doesn't do anything with a group.
-func addNodeToReportForNode(report *types.ConstructionNodeReport, node *TreeNode) {
- if node.Parent != nil {
- // First add the parent node, then the current one.
- addNodeToReportForNode(report, node.Parent)
- }
- report.ContainerHierarchyTexts = append(report.ContainerHierarchyTexts, node.Node.Text)
- report.ContainerHierarchyLocations = append(report.ContainerHierarchyLocations, node.Node.CodeLocation)
- report.ContainerHierarchyLabels = append(report.ContainerHierarchyLabels, node.Node.Labels)
- report.ContainerHierarchySemVerConstraints = append(report.ContainerHierarchySemVerConstraints, node.Node.SemVerConstraints)
- report.ContainerHierarchyComponentSemVerConstraints = append(report.ContainerHierarchyComponentSemVerConstraints, node.Node.ComponentSemVerConstraints)
- if node.Node.MarkedSerial {
- report.IsSerial = true
- }
- if node.Node.MarkedOrdered {
- report.IsInOrderedContainer = true
+ ContainerHierarchyTexts: spec.Nodes.WithType(types.NodeTypeContainer).Texts(),
+ ContainerHierarchyLocations: spec.Nodes.WithType(types.NodeTypeContainer).CodeLocations(),
+ ContainerHierarchyLabels: spec.Nodes.WithType(types.NodeTypeContainer).Labels(),
+ LeafNodeLocation: spec.FirstNodeWithType(types.NodeTypeIt).CodeLocation,
+ LeafNodeType: types.NodeTypeIt,
+ LeafNodeText: spec.FirstNodeWithType(types.NodeTypeIt).Text,
+ LeafNodeLabels: []string(spec.FirstNodeWithType(types.NodeTypeIt).Labels),
+ ParallelProcess: g.suite.config.ParallelProcess,
+ RunningInParallel: g.suite.isRunningInParallel(),
+ IsSerial: spec.Nodes.HasNodeMarkedSerial(),
+ IsInOrderedContainer: !spec.Nodes.FirstNodeMarkedOrdered().IsZero(),
+ MaxFlakeAttempts: spec.Nodes.GetMaxFlakeAttempts(),
+ MaxMustPassRepeatedly: spec.Nodes.GetMaxMustPassRepeatedly(),
}
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go b/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go
index 79bfa87db2..8ed86111f7 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go
@@ -40,7 +40,7 @@ func (ic InterruptCause) String() string {
}
type InterruptStatus struct {
- Channel chan any
+ Channel chan interface{}
Level InterruptLevel
Cause InterruptCause
}
@@ -62,14 +62,14 @@ type InterruptHandlerInterface interface {
}
type InterruptHandler struct {
- c chan any
+ c chan interface{}
lock *sync.Mutex
level InterruptLevel
cause InterruptCause
client parallel_support.Client
- stop chan any
+ stop chan interface{}
signals []os.Signal
- requestAbortCheck chan any
+ requestAbortCheck chan interface{}
}
func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *InterruptHandler {
@@ -77,10 +77,10 @@ func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *
signals = []os.Signal{os.Interrupt, syscall.SIGTERM}
}
handler := &InterruptHandler{
- c: make(chan any),
+ c: make(chan interface{}),
lock: &sync.Mutex{},
- stop: make(chan any),
- requestAbortCheck: make(chan any),
+ stop: make(chan interface{}),
+ requestAbortCheck: make(chan interface{}),
client: client,
signals: signals,
}
@@ -98,9 +98,9 @@ func (handler *InterruptHandler) registerForInterrupts() {
signal.Notify(signalChannel, handler.signals...)
// cross-process abort handling
- var abortChannel chan any
+ var abortChannel chan interface{}
if handler.client != nil {
- abortChannel = make(chan any)
+ abortChannel = make(chan interface{})
go func() {
pollTicker := time.NewTicker(ABORT_POLLING_INTERVAL)
for {
@@ -125,7 +125,7 @@ func (handler *InterruptHandler) registerForInterrupts() {
}()
}
- go func(abortChannel chan any) {
+ go func(abortChannel chan interface{}) {
var interruptCause InterruptCause
for {
select {
@@ -151,7 +151,7 @@ func (handler *InterruptHandler) registerForInterrupts() {
}
if handler.level != oldLevel {
close(handler.c)
- handler.c = make(chan any)
+ handler.c = make(chan interface{})
}
handler.lock.Unlock()
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/node.go b/vendor/github.com/onsi/ginkgo/v2/internal/node.go
index b0c8de8d69..6a15f19ae0 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/node.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/node.go
@@ -4,7 +4,6 @@ import (
"context"
"fmt"
"reflect"
- "slices"
"sort"
"sync"
"time"
@@ -47,25 +46,20 @@ type Node struct {
ReportEachBody func(SpecContext, types.SpecReport)
ReportSuiteBody func(SpecContext, types.Report)
- MarkedFocus bool
- MarkedPending bool
- MarkedSerial bool
- MarkedOrdered bool
- MarkedContinueOnFailure bool
- MarkedOncePerOrdered bool
- FlakeAttempts int
- MustPassRepeatedly int
- Labels Labels
- SemVerConstraints SemVerConstraints
- ComponentSemVerConstraints ComponentSemVerConstraints
- PollProgressAfter time.Duration
- PollProgressInterval time.Duration
- NodeTimeout time.Duration
- SpecTimeout time.Duration
- GracePeriod time.Duration
- AroundNodes types.AroundNodes
- HasExplicitlySetSpecPriority bool
- SpecPriority int
+ MarkedFocus bool
+ MarkedPending bool
+ MarkedSerial bool
+ MarkedOrdered bool
+ MarkedContinueOnFailure bool
+ MarkedOncePerOrdered bool
+ FlakeAttempts int
+ MustPassRepeatedly int
+ Labels Labels
+ PollProgressAfter time.Duration
+ PollProgressInterval time.Duration
+ NodeTimeout time.Duration
+ SpecTimeout time.Duration
+ GracePeriod time.Duration
NodeIDWhereCleanupWasGenerated uint
}
@@ -90,78 +84,35 @@ const SuppressProgressReporting = suppressProgressReporting(true)
type FlakeAttempts uint
type MustPassRepeatedly uint
type Offset uint
-type Done chan<- any // Deprecated Done Channel for asynchronous testing
+type Done chan<- interface{} // Deprecated Done Channel for asynchronous testing
+type Labels []string
type PollProgressInterval time.Duration
type PollProgressAfter time.Duration
type NodeTimeout time.Duration
type SpecTimeout time.Duration
type GracePeriod time.Duration
-type SpecPriority int
-
-type Labels []string
func (l Labels) MatchesLabelFilter(query string) bool {
return types.MustParseLabelFilter(query)(l)
}
-type SemVerConstraints []string
-
-func (svc SemVerConstraints) MatchesSemVerFilter(version string) bool {
- return types.MustParseSemVerFilter(version)("", svc)
-}
-
-type ComponentSemVerConstraints map[string][]string
-
-func (csvc ComponentSemVerConstraints) MatchesSemVerFilter(component, version string) bool {
- for comp, constraints := range csvc {
- if comp != component {
- continue
- }
-
- input := version
- if len(component) > 0 {
- input = fmt.Sprintf("%s=%s", component, version)
- }
- return types.MustParseSemVerFilter(input)(component, constraints)
- }
- return false
-}
-
-func unionOf[S ~[]E, E comparable](slices ...S) S {
- out := S{}
- seen := map[E]bool{}
- for _, slice := range slices {
- for _, item := range slice {
- if !seen[item] {
- seen[item] = true
- out = append(out, item)
+func UnionOfLabels(labels ...Labels) Labels {
+ out := Labels{}
+ seen := map[string]bool{}
+ for _, labelSet := range labels {
+ for _, label := range labelSet {
+ if !seen[label] {
+ seen[label] = true
+ out = append(out, label)
}
}
}
return out
}
-func UnionOfLabels(labels ...Labels) Labels {
- return unionOf(labels...)
-}
-
-func UnionOfSemVerConstraints(semVerConstraints ...SemVerConstraints) SemVerConstraints {
- return unionOf(semVerConstraints...)
-}
-
-func UnionOfComponentSemVerConstraints(componentSemVerConstraintsSlice ...ComponentSemVerConstraints) ComponentSemVerConstraints {
- unionComponentSemVerConstraints := ComponentSemVerConstraints{}
- for _, componentSemVerConstraints := range componentSemVerConstraintsSlice {
- for component, constraints := range componentSemVerConstraints {
- unionComponentSemVerConstraints[component] = unionOf(unionComponentSemVerConstraints[component], constraints)
- }
- }
- return unionComponentSemVerConstraints
-}
-
-func PartitionDecorations(args ...any) ([]any, []any) {
- decorations := []any{}
- remainingArgs := []any{}
+func PartitionDecorations(args ...interface{}) ([]interface{}, []interface{}) {
+ decorations := []interface{}{}
+ remainingArgs := []interface{}{}
for _, arg := range args {
if isDecoration(arg) {
decorations = append(decorations, arg)
@@ -172,7 +123,7 @@ func PartitionDecorations(args ...any) ([]any, []any) {
return decorations, remainingArgs
}
-func isDecoration(arg any) bool {
+func isDecoration(arg interface{}) bool {
switch t := reflect.TypeOf(arg); {
case t == nil:
return false
@@ -200,10 +151,6 @@ func isDecoration(arg any) bool {
return true
case t == reflect.TypeOf(Labels{}):
return true
- case t == reflect.TypeOf(SemVerConstraints{}):
- return true
- case t == reflect.TypeOf(ComponentSemVerConstraints{}):
- return true
case t == reflect.TypeOf(PollProgressInterval(0)):
return true
case t == reflect.TypeOf(PollProgressAfter(0)):
@@ -214,10 +161,6 @@ func isDecoration(arg any) bool {
return true
case t == reflect.TypeOf(GracePeriod(0)):
return true
- case t == reflect.TypeOf(types.AroundNodeDecorator{}):
- return true
- case t == reflect.TypeOf(SpecPriority(0)):
- return true
case t.Kind() == reflect.Slice && isSliceOfDecorations(arg):
return true
default:
@@ -225,7 +168,7 @@ func isDecoration(arg any) bool {
}
}
-func isSliceOfDecorations(slice any) bool {
+func isSliceOfDecorations(slice interface{}) bool {
vSlice := reflect.ValueOf(slice)
if vSlice.Len() == 0 {
return false
@@ -241,20 +184,18 @@ func isSliceOfDecorations(slice any) bool {
var contextType = reflect.TypeOf(new(context.Context)).Elem()
var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
-func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...any) (Node, []error) {
+func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...interface{}) (Node, []error) {
baseOffset := 2
node := Node{
- ID: UniqueNodeID(),
- NodeType: nodeType,
- Text: text,
- Labels: Labels{},
- SemVerConstraints: SemVerConstraints{},
- ComponentSemVerConstraints: ComponentSemVerConstraints{},
- CodeLocation: types.NewCodeLocation(baseOffset),
- NestingLevel: -1,
- PollProgressAfter: -1,
- PollProgressInterval: -1,
- GracePeriod: -1,
+ ID: UniqueNodeID(),
+ NodeType: nodeType,
+ Text: text,
+ Labels: Labels{},
+ CodeLocation: types.NewCodeLocation(baseOffset),
+ NestingLevel: -1,
+ PollProgressAfter: -1,
+ PollProgressInterval: -1,
+ GracePeriod: -1,
}
errors := []error{}
@@ -264,9 +205,9 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
}
}
- args = UnrollInterfaceSlice(args)
+ args = unrollInterfaceSlice(args)
- remainingArgs := []any{}
+ remainingArgs := []interface{}{}
// First get the CodeLocation up-to-date
for _, arg := range args {
switch v := arg.(type) {
@@ -280,10 +221,9 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
}
labelsSeen := map[string]bool{}
- semVerConstraintsSeen := map[string]bool{}
trackedFunctionError := false
args = remainingArgs
- remainingArgs = []any{}
+ remainingArgs = []interface{}{}
// now process the rest of the args
for _, arg := range args {
switch t := reflect.TypeOf(arg); {
@@ -301,9 +241,6 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
}
case t == reflect.TypeOf(Serial):
node.MarkedSerial = bool(arg.(serialType))
- if !labelsSeen["Serial"] {
- node.Labels = append(node.Labels, "Serial")
- }
if !nodeType.Is(types.NodeTypesForContainerAndIt) {
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "Serial"))
}
@@ -359,14 +296,6 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
if nodeType.Is(types.NodeTypeContainer) {
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "GracePeriod"))
}
- case t == reflect.TypeOf(SpecPriority(0)):
- if !nodeType.Is(types.NodeTypesForContainerAndIt) {
- appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "SpecPriority"))
- }
- node.SpecPriority = int(arg.(SpecPriority))
- node.HasExplicitlySetSpecPriority = true
- case t == reflect.TypeOf(types.AroundNodeDecorator{}):
- node.AroundNodes = append(node.AroundNodes, arg.(types.AroundNodeDecorator))
case t == reflect.TypeOf(Labels{}):
if !nodeType.Is(types.NodeTypesForContainerAndIt) {
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "Label"))
@@ -379,48 +308,6 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
appendError(err)
}
}
- case t == reflect.TypeOf(SemVerConstraints{}):
- if !nodeType.Is(types.NodeTypesForContainerAndIt) {
- appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "SemVerConstraint"))
- }
- for _, semVerConstraint := range arg.(SemVerConstraints) {
- if !semVerConstraintsSeen[semVerConstraint] {
- semVerConstraintsSeen[semVerConstraint] = true
- semVerConstraint, err := types.ValidateAndCleanupSemVerConstraint(semVerConstraint, node.CodeLocation)
- node.SemVerConstraints = append(node.SemVerConstraints, semVerConstraint)
- appendError(err)
- }
- }
- case t == reflect.TypeOf(ComponentSemVerConstraints{}):
- if !nodeType.Is(types.NodeTypesForContainerAndIt) {
- appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "ComponentSemVerConstraint"))
- }
- for component, semVerConstraints := range arg.(ComponentSemVerConstraints) {
- // while using ComponentSemVerConstraints, we should not allow empty component names.
- // you should use SemVerConstraints for that.
- hasErr := false
- if len(component) == 0 {
- appendError(types.GinkgoErrors.InvalidEmptyComponentForSemVerConstraint(node.CodeLocation))
- hasErr = true
- }
- for _, semVerConstraint := range semVerConstraints {
- _, err := types.ValidateAndCleanupSemVerConstraint(semVerConstraint, node.CodeLocation)
- if err != nil {
- appendError(err)
- hasErr = true
- }
- }
-
- if !hasErr {
- // merge constraints if the component already exists
- constraints := slices.Clone(semVerConstraints)
- if existingConstraints, exists := node.ComponentSemVerConstraints[component]; exists {
- constraints = UnionOfSemVerConstraints([]string(existingConstraints), constraints)
- }
-
- node.ComponentSemVerConstraints[component] = slices.Clone(constraints)
- }
- }
case t.Kind() == reflect.Func:
if nodeType.Is(types.NodeTypeContainer) {
if node.Body != nil {
@@ -561,7 +448,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
var doneType = reflect.TypeOf(make(Done))
-func extractBodyFunction(deprecationTracker *types.DeprecationTracker, cl types.CodeLocation, arg any) (func(SpecContext), bool) {
+func extractBodyFunction(deprecationTracker *types.DeprecationTracker, cl types.CodeLocation, arg interface{}) (func(SpecContext), bool) {
t := reflect.TypeOf(arg)
if t.NumOut() > 0 || t.NumIn() > 1 {
return nil, false
@@ -587,7 +474,7 @@ func extractBodyFunction(deprecationTracker *types.DeprecationTracker, cl types.
var byteType = reflect.TypeOf([]byte{})
-func extractSynchronizedBeforeSuiteProc1Body(arg any) (func(SpecContext) []byte, bool) {
+func extractSynchronizedBeforeSuiteProc1Body(arg interface{}) (func(SpecContext) []byte, bool) {
t := reflect.TypeOf(arg)
v := reflect.ValueOf(arg)
@@ -615,7 +502,7 @@ func extractSynchronizedBeforeSuiteProc1Body(arg any) (func(SpecContext) []byte,
}, hasContext
}
-func extractSynchronizedBeforeSuiteAllProcsBody(arg any) (func(SpecContext, []byte), bool) {
+func extractSynchronizedBeforeSuiteAllProcsBody(arg interface{}) (func(SpecContext, []byte), bool) {
t := reflect.TypeOf(arg)
v := reflect.ValueOf(arg)
hasContext, hasByte := false, false
@@ -646,11 +533,11 @@ func extractSynchronizedBeforeSuiteAllProcsBody(arg any) (func(SpecContext, []by
var errInterface = reflect.TypeOf((*error)(nil)).Elem()
-func NewCleanupNode(deprecationTracker *types.DeprecationTracker, fail func(string, types.CodeLocation), args ...any) (Node, []error) {
+func NewCleanupNode(deprecationTracker *types.DeprecationTracker, fail func(string, types.CodeLocation), args ...interface{}) (Node, []error) {
decorations, remainingArgs := PartitionDecorations(args...)
baseOffset := 2
cl := types.NewCodeLocation(baseOffset)
- finalArgs := []any{}
+ finalArgs := []interface{}{}
for _, arg := range decorations {
switch t := reflect.TypeOf(arg); {
case t == reflect.TypeOf(Offset(0)):
@@ -709,7 +596,7 @@ func NewCleanupNode(deprecationTracker *types.DeprecationTracker, fail func(stri
})
}
- return NewNode(deprecationTracker, types.NodeTypeCleanupInvalid, "", finalArgs)
+ return NewNode(deprecationTracker, types.NodeTypeCleanupInvalid, "", finalArgs...)
}
func (n Node) IsZero() bool {
@@ -934,60 +821,6 @@ func (n Nodes) UnionOfLabels() []string {
return out
}
-func (n Nodes) SemVerConstraints() [][]string {
- out := make([][]string, len(n))
- for i := range n {
- if n[i].SemVerConstraints == nil {
- out[i] = []string{}
- } else {
- out[i] = []string(n[i].SemVerConstraints)
- }
- }
- return out
-}
-
-func (n Nodes) UnionOfSemVerConstraints() []string {
- out := []string{}
- seen := map[string]bool{}
- for i := range n {
- for _, constraint := range n[i].SemVerConstraints {
- if !seen[constraint] {
- seen[constraint] = true
- out = append(out, constraint)
- }
- }
- }
- return out
-}
-
-func (n Nodes) ComponentSemVerConstraints() []map[string][]string {
- out := make([]map[string][]string, len(n))
- for i := range n {
- if n[i].ComponentSemVerConstraints == nil {
- out[i] = map[string][]string{}
- } else {
- out[i] = map[string][]string(n[i].ComponentSemVerConstraints)
- }
- }
- return out
-}
-
-func (n Nodes) UnionOfComponentSemVerConstraints() map[string][]string {
- out := map[string][]string{}
- seen := map[string]bool{}
- for i := range n {
- for component := range n[i].ComponentSemVerConstraints {
- if !seen[component] {
- seen[component] = true
- out[component] = n[i].ComponentSemVerConstraints[component]
- } else {
- out[component] = UnionOfSemVerConstraints(out[component], n[i].ComponentSemVerConstraints[component])
- }
- }
- }
- return out
-}
-
func (n Nodes) CodeLocations() []types.CodeLocation {
out := make([]types.CodeLocation, len(n))
for i := range n {
@@ -1084,84 +917,19 @@ func (n Nodes) GetMaxMustPassRepeatedly() int {
return maxMustPassRepeatedly
}
-func (n Nodes) GetSpecPriority() int {
- for i := len(n) - 1; i >= 0; i-- {
- if n[i].HasExplicitlySetSpecPriority {
- return n[i].SpecPriority
- }
- }
- return 0
-}
-
-func UnrollInterfaceSlice(args any) []any {
+func unrollInterfaceSlice(args interface{}) []interface{} {
v := reflect.ValueOf(args)
if v.Kind() != reflect.Slice {
- return []any{args}
+ return []interface{}{args}
}
- out := []any{}
+ out := []interface{}{}
for i := 0; i < v.Len(); i++ {
el := reflect.ValueOf(v.Index(i).Interface())
- if el.Kind() == reflect.Slice && el.Type() != reflect.TypeOf(Labels{}) && el.Type() != reflect.TypeOf(SemVerConstraints{}) {
- out = append(out, UnrollInterfaceSlice(el.Interface())...)
+ if el.Kind() == reflect.Slice && el.Type() != reflect.TypeOf(Labels{}) {
+ out = append(out, unrollInterfaceSlice(el.Interface())...)
} else {
out = append(out, v.Index(i).Interface())
}
}
return out
}
-
-type NodeArgsTransformer func(nodeType types.NodeType, offset Offset, text string, args []any) (string, []any, []error)
-
-func AddTreeConstructionNodeArgsTransformer(transformer NodeArgsTransformer) func() {
- id := nodeArgsTransformerCounter
- nodeArgsTransformerCounter++
- nodeArgsTransformers = append(nodeArgsTransformers, registeredNodeArgsTransformer{id, transformer})
- return func() {
- nodeArgsTransformers = slices.DeleteFunc(nodeArgsTransformers, func(transformer registeredNodeArgsTransformer) bool {
- return transformer.id == id
- })
- }
-}
-
-var (
- nodeArgsTransformerCounter int64
- nodeArgsTransformers []registeredNodeArgsTransformer
-)
-
-type registeredNodeArgsTransformer struct {
- id int64
- transformer NodeArgsTransformer
-}
-
-// TransformNewNodeArgs is the helper for DSL functions which handles NodeArgsTransformers.
-//
-// Its return valus are intentionally the same as the internal.NewNode parameters,
-// which makes it possible to chain the invocations:
-//
-// NewNode(transformNewNodeArgs(...))
-func TransformNewNodeArgs(exitIfErrors func([]error), deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...any) (*types.DeprecationTracker, types.NodeType, string, []any) {
- var errs []error
-
- // Most recent first...
- //
- // This intentionally doesn't use slices.Backward because
- // using iterators influences stack unwinding.
- for i := len(nodeArgsTransformers) - 1; i >= 0; i-- {
- transformer := nodeArgsTransformers[i].transformer
- args = UnrollInterfaceSlice(args)
-
- // We do not really need to recompute this on additional loop iterations,
- // but its fast and simpler this way.
- var offset Offset
- for _, arg := range args {
- if o, ok := arg.(Offset); ok {
- offset = o
- }
- }
- offset += 3 // The DSL function, this helper, and the TransformNodeArgs implementation.
-
- text, args, errs = transformer(nodeType, offset, text, args)
- exitIfErrors(errs)
- }
- return deprecationTracker, nodeType, text, args
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/ordering.go b/vendor/github.com/onsi/ginkgo/v2/internal/ordering.go
index da58d54f95..84eea0a59e 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/ordering.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/ordering.go
@@ -125,7 +125,7 @@ func OrderSpecs(specs Specs, suiteConfig types.SuiteConfig) (GroupedSpecIndices,
// pick out a representative spec
representativeSpec := specs[executionGroups[groupID][0]]
- // and grab the node on the spec that will represent which shufflable group this execution group belongs to
+ // and grab the node on the spec that will represent which shufflable group this execution group belongs tu
shufflableGroupingNode := representativeSpec.Nodes.FirstNodeWithType(nodeTypesToShuffle)
//add the execution group to its shufflable group
@@ -138,35 +138,14 @@ func OrderSpecs(specs Specs, suiteConfig types.SuiteConfig) (GroupedSpecIndices,
}
}
- // now, for each shuffleable group, we compute the priority
- shufflableGroupingIDPriorities := map[uint]int{}
- for shufflableGroupingID, groupIDs := range shufflableGroupingIDToGroupIDs {
- // the priority of a shufflable grouping is the max priority of any spec in any execution group in the shufflable grouping
- maxPriority := -1 << 31 // min int
- for _, groupID := range groupIDs {
- for _, specIdx := range executionGroups[groupID] {
- specPriority := specs[specIdx].Nodes.GetSpecPriority()
- maxPriority = max(specPriority, maxPriority)
- }
- }
- shufflableGroupingIDPriorities[shufflableGroupingID] = maxPriority
- }
-
// now we permute the sorted shufflable grouping IDs and build the ordered Groups
- permutation := r.Perm(len(shufflableGroupingIDs))
- shuffledGroupingIds := make([]uint, len(shufflableGroupingIDs))
- for i, j := range permutation {
- shuffledGroupingIds[i] = shufflableGroupingIDs[j]
- }
- // now, we need to stable sort the shuffledGroupingIds by priority (higher priority first)
- sort.SliceStable(shuffledGroupingIds, func(i, j int) bool {
- return shufflableGroupingIDPriorities[shuffledGroupingIds[i]] > shufflableGroupingIDPriorities[shuffledGroupingIds[j]]
- })
-
- // we can now take these prioritized, shuffled, groupings and form the final set of ordered spec groups
orderedGroups := GroupedSpecIndices{}
- for _, id := range shuffledGroupingIds {
- for _, executionGroupID := range shufflableGroupingIDToGroupIDs[id] {
+ permutation := r.Perm(len(shufflableGroupingIDs))
+ for _, j := range permutation {
+ //let's get the execution group IDs for this shufflable group:
+ executionGroupIDsForJ := shufflableGroupingIDToGroupIDs[shufflableGroupingIDs[j]]
+ // and we'll add their associated specindices to the orderedGroups slice:
+ for _, executionGroupID := range executionGroupIDsForJ {
orderedGroups = append(orderedGroups, executionGroups[executionGroupID])
}
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor.go b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor.go
index 5598f15cbb..4a1c094612 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor.go
@@ -69,7 +69,7 @@ type pipePair struct {
writer *os.File
}
-func startPipeFactory(pipeChannel chan pipePair, shutdown chan any) {
+func startPipeFactory(pipeChannel chan pipePair, shutdown chan interface{}) {
for {
//make the next pipe...
pair := pipePair{}
@@ -101,8 +101,8 @@ type genericOutputInterceptor struct {
stderrClone *os.File
pipe pipePair
- shutdown chan any
- emergencyBailout chan any
+ shutdown chan interface{}
+ emergencyBailout chan interface{}
pipeChannel chan pipePair
interceptedContent chan string
@@ -139,7 +139,7 @@ func (interceptor *genericOutputInterceptor) ResumeIntercepting() {
interceptor.intercepting = true
if interceptor.stdoutClone == nil {
interceptor.stdoutClone, interceptor.stderrClone = interceptor.implementation.CreateStdoutStderrClones()
- interceptor.shutdown = make(chan any)
+ interceptor.shutdown = make(chan interface{})
go startPipeFactory(interceptor.pipeChannel, interceptor.shutdown)
}
@@ -147,13 +147,13 @@ func (interceptor *genericOutputInterceptor) ResumeIntercepting() {
// we get the pipe from our pipe factory. it runs in the background so we can request the next pipe while the spec being intercepted is running
interceptor.pipe = <-interceptor.pipeChannel
- interceptor.emergencyBailout = make(chan any)
+ interceptor.emergencyBailout = make(chan interface{})
//Spin up a goroutine to copy data from the pipe into a buffer, this is how we capture any output the user is emitting
go func() {
buffer := &bytes.Buffer{}
destination := io.MultiWriter(buffer, interceptor.forwardTo)
- copyFinished := make(chan any)
+ copyFinished := make(chan interface{})
reader := interceptor.pipe.reader
go func() {
io.Copy(destination, reader)
@@ -224,7 +224,7 @@ func NewOSGlobalReassigningOutputInterceptor() OutputInterceptor {
return &genericOutputInterceptor{
interceptedContent: make(chan string),
pipeChannel: make(chan pipePair),
- shutdown: make(chan any),
+ shutdown: make(chan interface{}),
implementation: &osGlobalReassigningOutputInterceptorImpl{},
}
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go
index e0f1431d51..8a237f4463 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/output_interceptor_unix.go
@@ -13,7 +13,7 @@ func NewOutputInterceptor() OutputInterceptor {
return &genericOutputInterceptor{
interceptedContent: make(chan string),
pipeChannel: make(chan pipePair),
- shutdown: make(chan any),
+ shutdown: make(chan interface{}),
implementation: &dupSyscallOutputInterceptorImpl{},
}
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go
index 4234d802cf..b3cd64292a 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go
@@ -30,7 +30,7 @@ type Server interface {
Close()
Address() string
RegisterAlive(node int, alive func() bool)
- GetSuiteDone() chan any
+ GetSuiteDone() chan interface{}
GetOutputDestination() io.Writer
SetOutputDestination(io.Writer)
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go
index 4aa10ae4f9..6547c7a66e 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go
@@ -34,7 +34,7 @@ func (client *httpClient) Close() error {
return nil
}
-func (client *httpClient) post(path string, data any) error {
+func (client *httpClient) post(path string, data interface{}) error {
var body io.Reader
if data != nil {
encoded, err := json.Marshal(data)
@@ -54,7 +54,7 @@ func (client *httpClient) post(path string, data any) error {
return nil
}
-func (client *httpClient) poll(path string, data any) error {
+func (client *httpClient) poll(path string, data interface{}) error {
for {
resp, err := http.Get(client.serverHost + path)
if err != nil {
@@ -153,7 +153,10 @@ func (client *httpClient) PostAbort() error {
func (client *httpClient) ShouldAbort() bool {
err := client.poll("/abort", nil)
- return err == ErrorGone
+ if err == ErrorGone {
+ return true
+ }
+ return false
}
func (client *httpClient) Write(p []byte) (int, error) {
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go
index 8a1b7a5bbe..d2c71ab1b2 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go
@@ -75,7 +75,7 @@ func (server *httpServer) Address() string {
return "http://" + server.listener.Addr().String()
}
-func (server *httpServer) GetSuiteDone() chan any {
+func (server *httpServer) GetSuiteDone() chan interface{} {
return server.handler.done
}
@@ -96,7 +96,7 @@ func (server *httpServer) RegisterAlive(node int, alive func() bool) {
//
// The server will forward all received messages to Ginkgo reporters registered with `RegisterReporters`
-func (server *httpServer) decode(writer http.ResponseWriter, request *http.Request, object any) bool {
+func (server *httpServer) decode(writer http.ResponseWriter, request *http.Request, object interface{}) bool {
defer request.Body.Close()
if json.NewDecoder(request.Body).Decode(object) != nil {
writer.WriteHeader(http.StatusBadRequest)
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go
index bb4675a02c..59e8e6fd0a 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go
@@ -35,7 +35,7 @@ func (client *rpcClient) Close() error {
return client.client.Close()
}
-func (client *rpcClient) poll(method string, data any) error {
+func (client *rpcClient) poll(method string, data interface{}) error {
for {
err := client.client.Call(method, voidSender, data)
if err == nil {
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_server.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_server.go
index 1574f99ac4..2620fd562d 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_server.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_server.go
@@ -25,7 +25,7 @@ type RPCServer struct {
handler *ServerHandler
}
-// Create a new server, automatically selecting a port
+//Create a new server, automatically selecting a port
func newRPCServer(parallelTotal int, reporter reporters.Reporter) (*RPCServer, error) {
listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
@@ -37,7 +37,7 @@ func newRPCServer(parallelTotal int, reporter reporters.Reporter) (*RPCServer, e
}, nil
}
-// Start the server. You don't need to `go s.Start()`, just `s.Start()`
+//Start the server. You don't need to `go s.Start()`, just `s.Start()`
func (server *RPCServer) Start() {
rpcServer := rpc.NewServer()
rpcServer.RegisterName("Server", server.handler) //register the handler's methods as the server
@@ -48,17 +48,17 @@ func (server *RPCServer) Start() {
go httpServer.Serve(server.listener)
}
-// Stop the server
+//Stop the server
func (server *RPCServer) Close() {
server.listener.Close()
}
-// The address the server can be reached it. Pass this into the `ForwardingReporter`.
+//The address the server can be reached it. Pass this into the `ForwardingReporter`.
func (server *RPCServer) Address() string {
return server.listener.Addr().String()
}
-func (server *RPCServer) GetSuiteDone() chan any {
+func (server *RPCServer) GetSuiteDone() chan interface{} {
return server.handler.done
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go
index ab9e11372c..a6d98793e9 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go
@@ -18,7 +18,7 @@ var voidSender Void
// It handles all the business logic to avoid duplication between the two servers
type ServerHandler struct {
- done chan any
+ done chan interface{}
outputDestination io.Writer
reporter reporters.Reporter
alives []func() bool
@@ -46,7 +46,7 @@ func newServerHandler(parallelTotal int, reporter reporters.Reporter) *ServerHan
parallelTotal: parallelTotal,
outputDestination: os.Stdout,
- done: make(chan any),
+ done: make(chan interface{}),
}
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/progress_report.go b/vendor/github.com/onsi/ginkgo/v2/internal/progress_report.go
index 165cbc4b67..11269cf1f2 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/progress_report.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/progress_report.go
@@ -236,7 +236,7 @@ func extractRunningGoroutines() ([]types.Goroutine, error) {
}
functionCall.Filename = line[:delimiterIdx]
line = strings.Split(line[delimiterIdx+1:], " ")[0]
- lineNumber, err := strconv.ParseInt(line, 10, 32)
+ lineNumber, err := strconv.ParseInt(line, 10, 64)
functionCall.Line = int(lineNumber)
if err != nil {
return nil, types.GinkgoErrors.FailedToParseStackTrace(fmt.Sprintf("Invalid function call line number: %s\n%s", line, err.Error()))
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/report_entry.go b/vendor/github.com/onsi/ginkgo/v2/internal/report_entry.go
index 9c18dc8e58..cc351a39bd 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/report_entry.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/report_entry.go
@@ -8,7 +8,7 @@ import (
type ReportEntry = types.ReportEntry
-func NewReportEntry(name string, cl types.CodeLocation, args ...any) (ReportEntry, error) {
+func NewReportEntry(name string, cl types.CodeLocation, args ...interface{}) (ReportEntry, error) {
out := ReportEntry{
Visibility: types.ReportEntryVisibilityAlways,
Name: name,
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go b/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go
deleted file mode 100644
index 751543ea78..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go
+++ /dev/null
@@ -1,171 +0,0 @@
-package reporters
-
-import (
- "errors"
- "fmt"
- "strings"
- "time"
-
- "github.com/onsi/ginkgo/v2/types"
- "golang.org/x/tools/go/packages"
-)
-
-func ptr[T any](in T) *T {
- return &in
-}
-
-type encoder interface {
- Encode(v any) error
-}
-
-// gojsonEvent matches the format from go internals
-// https://github.com/golang/go/blob/master/src/cmd/internal/test2json/test2json.go#L31-L41
-// https://pkg.go.dev/cmd/test2json
-type gojsonEvent struct {
- Time *time.Time `json:",omitempty"`
- Action GoJSONAction
- Package string `json:",omitempty"`
- Test string `json:",omitempty"`
- Elapsed *float64 `json:",omitempty"`
- Output *string `json:",omitempty"`
- FailedBuild string `json:",omitempty"`
-}
-
-type GoJSONAction string
-
-const (
- // start - the test binary is about to be executed
- GoJSONStart GoJSONAction = "start"
- // run - the test has started running
- GoJSONRun GoJSONAction = "run"
- // pause - the test has been paused
- GoJSONPause GoJSONAction = "pause"
- // cont - the test has continued running
- GoJSONCont GoJSONAction = "cont"
- // pass - the test passed
- GoJSONPass GoJSONAction = "pass"
- // bench - the benchmark printed log output but did not fail
- GoJSONBench GoJSONAction = "bench"
- // fail - the test or benchmark failed
- GoJSONFail GoJSONAction = "fail"
- // output - the test printed output
- GoJSONOutput GoJSONAction = "output"
- // skip - the test was skipped or the package contained no tests
- GoJSONSkip GoJSONAction = "skip"
-)
-
-func goJSONActionFromSpecState(state types.SpecState) GoJSONAction {
- switch state {
- case types.SpecStateInvalid:
- return GoJSONFail
- case types.SpecStatePending:
- return GoJSONSkip
- case types.SpecStateSkipped:
- return GoJSONSkip
- case types.SpecStatePassed:
- return GoJSONPass
- case types.SpecStateFailed:
- return GoJSONFail
- case types.SpecStateAborted:
- return GoJSONFail
- case types.SpecStatePanicked:
- return GoJSONFail
- case types.SpecStateInterrupted:
- return GoJSONFail
- case types.SpecStateTimedout:
- return GoJSONFail
- default:
- panic("unexpected state should not happen")
- }
-}
-
-// gojsonReport wraps types.Report and calcualtes extra fields requires by gojson
-type gojsonReport struct {
- o types.Report
- // Extra calculated fields
- goPkg string
- elapsed float64
-}
-
-func newReport(in types.Report) *gojsonReport {
- return &gojsonReport{
- o: in,
- }
-}
-
-func (r *gojsonReport) Fill() error {
- // NOTE: could the types.Report include the go package name?
- goPkg, err := suitePathToPkg(r.o.SuitePath)
- if err != nil {
- return err
- }
- r.goPkg = goPkg
- r.elapsed = r.o.RunTime.Seconds()
- return nil
-}
-
-// gojsonSpecReport wraps types.SpecReport and calculates extra fields required by gojson
-type gojsonSpecReport struct {
- o types.SpecReport
- // extra calculated fields
- testName string
- elapsed float64
- action GoJSONAction
-}
-
-func newSpecReport(in types.SpecReport) *gojsonSpecReport {
- return &gojsonSpecReport{
- o: in,
- }
-}
-
-func (sr *gojsonSpecReport) Fill() error {
- sr.elapsed = sr.o.RunTime.Seconds()
- sr.testName = createTestName(sr.o)
- sr.action = goJSONActionFromSpecState(sr.o.State)
- return nil
-}
-
-func suitePathToPkg(dir string) (string, error) {
- cfg := &packages.Config{
- Mode: packages.NeedFiles | packages.NeedSyntax,
- }
- pkgs, err := packages.Load(cfg, dir)
- if err != nil {
- return "", err
- }
- if len(pkgs) != 1 {
- return "", errors.New("error")
- }
- return pkgs[0].ID, nil
-}
-
-func createTestName(spec types.SpecReport) string {
- name := fmt.Sprintf("[%s]", spec.LeafNodeType)
- if spec.FullText() != "" {
- name = name + " " + spec.FullText()
- }
- labels := spec.Labels()
- if len(labels) > 0 {
- name = name + " [" + strings.Join(labels, ", ") + "]"
- }
- semVerConstraints := spec.SemVerConstraints()
- if len(semVerConstraints) > 0 {
- name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
- }
- componentSemVerConstraints := spec.ComponentSemVerConstraints()
- if len(componentSemVerConstraints) > 0 {
- name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]"
- }
- name = strings.TrimSpace(name)
- return name
-}
-
-func formatComponentSemVerConstraintsToString(componentSemVerConstraints map[string][]string) string {
- var tmpStr string
- for component, semVerConstraints := range componentSemVerConstraints {
- tmpStr = tmpStr + fmt.Sprintf("%s: %s, ", component, semVerConstraints)
- }
- tmpStr = strings.TrimSuffix(tmpStr, ", ")
- return tmpStr
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson_event_writer.go b/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson_event_writer.go
deleted file mode 100644
index ec5311d069..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson_event_writer.go
+++ /dev/null
@@ -1,111 +0,0 @@
-package reporters
-
-type GoJSONEventWriter struct {
- enc encoder
- specSystemErrFn specSystemExtractFn
- specSystemOutFn specSystemExtractFn
-}
-
-func NewGoJSONEventWriter(enc encoder, errFn specSystemExtractFn, outFn specSystemExtractFn) *GoJSONEventWriter {
- return &GoJSONEventWriter{
- enc: enc,
- specSystemErrFn: errFn,
- specSystemOutFn: outFn,
- }
-}
-
-func (r *GoJSONEventWriter) writeEvent(e *gojsonEvent) error {
- return r.enc.Encode(e)
-}
-
-func (r *GoJSONEventWriter) WriteSuiteStart(report *gojsonReport) error {
- e := &gojsonEvent{
- Time: &report.o.StartTime,
- Action: GoJSONStart,
- Package: report.goPkg,
- Output: nil,
- FailedBuild: "",
- }
- return r.writeEvent(e)
-}
-
-func (r *GoJSONEventWriter) WriteSuiteResult(report *gojsonReport) error {
- var action GoJSONAction
- switch {
- case report.o.PreRunStats.SpecsThatWillRun == 0:
- action = GoJSONSkip
- case report.o.SuiteSucceeded:
- action = GoJSONPass
- default:
- action = GoJSONFail
- }
- e := &gojsonEvent{
- Time: &report.o.EndTime,
- Action: action,
- Package: report.goPkg,
- Output: nil,
- FailedBuild: "",
- Elapsed: ptr(report.elapsed),
- }
- return r.writeEvent(e)
-}
-
-func (r *GoJSONEventWriter) WriteSpecStart(report *gojsonReport, specReport *gojsonSpecReport) error {
- e := &gojsonEvent{
- Time: &specReport.o.StartTime,
- Action: GoJSONRun,
- Test: specReport.testName,
- Package: report.goPkg,
- Output: nil,
- FailedBuild: "",
- }
- return r.writeEvent(e)
-}
-
-func (r *GoJSONEventWriter) WriteSpecOut(report *gojsonReport, specReport *gojsonSpecReport) error {
- events := []*gojsonEvent{}
-
- stdErr := r.specSystemErrFn(specReport.o)
- if stdErr != "" {
- events = append(events, &gojsonEvent{
- Time: &specReport.o.EndTime,
- Action: GoJSONOutput,
- Test: specReport.testName,
- Package: report.goPkg,
- Output: ptr(stdErr),
- FailedBuild: "",
- })
- }
- stdOut := r.specSystemOutFn(specReport.o)
- if stdOut != "" {
- events = append(events, &gojsonEvent{
- Time: &specReport.o.EndTime,
- Action: GoJSONOutput,
- Test: specReport.testName,
- Package: report.goPkg,
- Output: ptr(stdOut),
- FailedBuild: "",
- })
- }
-
- for _, ev := range events {
- err := r.writeEvent(ev)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func (r *GoJSONEventWriter) WriteSpecResult(report *gojsonReport, specReport *gojsonSpecReport) error {
- e := &gojsonEvent{
- Time: &specReport.o.EndTime,
- Action: specReport.action,
- Test: specReport.testName,
- Package: report.goPkg,
- Elapsed: ptr(specReport.elapsed),
- Output: nil,
- FailedBuild: "",
- }
- return r.writeEvent(e)
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson_reporter.go b/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson_reporter.go
deleted file mode 100644
index 633e49b88d..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson_reporter.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package reporters
-
-import (
- "github.com/onsi/ginkgo/v2/types"
-)
-
-type GoJSONReporter struct {
- ev *GoJSONEventWriter
-}
-
-type specSystemExtractFn func (spec types.SpecReport) string
-
-func NewGoJSONReporter(enc encoder, errFn specSystemExtractFn, outFn specSystemExtractFn) *GoJSONReporter {
- return &GoJSONReporter{
- ev: NewGoJSONEventWriter(enc, errFn, outFn),
- }
-}
-
-func (r *GoJSONReporter) Write(originalReport types.Report) error {
- // suite start events
- report := newReport(originalReport)
- err := report.Fill()
- if err != nil {
- return err
- }
- r.ev.WriteSuiteStart(report)
- for _, originalSpecReport := range originalReport.SpecReports {
- specReport := newSpecReport(originalSpecReport)
- err := specReport.Fill()
- if err != nil {
- return err
- }
- if specReport.o.LeafNodeType == types.NodeTypeIt {
- // handle any It leaf node as a spec
- r.ev.WriteSpecStart(report, specReport)
- r.ev.WriteSpecOut(report, specReport)
- r.ev.WriteSpecResult(report, specReport)
- } else {
- // handle any other leaf node as generic output
- r.ev.WriteSpecOut(report, specReport)
- }
- }
- r.ev.WriteSuiteResult(report)
- return nil
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/spec_context.go b/vendor/github.com/onsi/ginkgo/v2/internal/spec_context.go
index 99c9c5f5be..2d2ea2fc35 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/spec_context.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/spec_context.go
@@ -2,7 +2,6 @@ package internal
import (
"context"
- "reflect"
"github.com/onsi/ginkgo/v2/types"
)
@@ -12,7 +11,6 @@ type SpecContext interface {
SpecReport() types.SpecReport
AttachProgressReporter(func() string) func()
- WrappedContext() context.Context
}
type specContext struct {
@@ -47,28 +45,3 @@ func NewSpecContext(suite *Suite) *specContext {
func (sc *specContext) SpecReport() types.SpecReport {
return sc.suite.CurrentSpecReport()
}
-
-func (sc *specContext) WrappedContext() context.Context {
- return sc.Context
-}
-
-/*
-The user is allowed to wrap `SpecContext` in a new context.Context when using AroundNodes. But body functions expect SpecContext.
-We support this by taking their context.Context and returning a SpecContext that wraps it.
-*/
-func wrapContextChain(ctx context.Context) SpecContext {
- if ctx == nil {
- return nil
- }
- if reflect.TypeOf(ctx) == reflect.TypeOf(&specContext{}) {
- return ctx.(*specContext)
- } else if sc, ok := ctx.Value("GINKGO_SPEC_CONTEXT").(*specContext); ok {
- return &specContext{
- Context: ctx,
- ProgressReporterManager: sc.ProgressReporterManager,
- cancel: sc.cancel,
- suite: sc.suite,
- }
- }
- return nil
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/spec_patch.go b/vendor/github.com/onsi/ginkgo/v2/internal/spec_patch.go
new file mode 100644
index 0000000000..2d0bcc914d
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/spec_patch.go
@@ -0,0 +1,22 @@
+package internal
+
+import (
+ "github.com/onsi/ginkgo/v2/types"
+)
+
+func (s Spec) CodeLocations() []types.CodeLocation {
+ return s.Nodes.CodeLocations()
+}
+
+func (s Spec) AppendText(text string) {
+ s.Nodes[len(s.Nodes)-1].Text += text
+}
+
+func (s Spec) Labels() []string {
+ var labels []string
+ for _, n := range s.Nodes {
+ labels = append(labels, n.Labels...)
+ }
+
+ return labels
+}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/suite.go b/vendor/github.com/onsi/ginkgo/v2/internal/suite.go
index 57c1cffe71..12e50b8a95 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/suite.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/suite.go
@@ -1,7 +1,6 @@
package internal
import (
- "context"
"fmt"
"sync"
"time"
@@ -10,6 +9,7 @@ import (
"github.com/onsi/ginkgo/v2/internal/parallel_support"
"github.com/onsi/ginkgo/v2/reporters"
"github.com/onsi/ginkgo/v2/types"
+ "golang.org/x/net/context"
)
type Phase uint
@@ -20,7 +20,7 @@ const (
PhaseRun
)
-const ProgressReporterDeadline = 5 * time.Second
+var PROGRESS_REPORTER_DEADLING = 5 * time.Second
type Suite struct {
tree *TreeNode
@@ -32,7 +32,6 @@ type Suite struct {
suiteNodes Nodes
cleanupNodes Nodes
- aroundNodes types.AroundNodes
failer *Failer
reporter reporters.Reporter
@@ -42,8 +41,6 @@ type Suite struct {
config types.SuiteConfig
deadline time.Time
- currentConstructionNodeReport *types.ConstructionNodeReport
-
skipAll bool
report types.Report
currentSpecReport types.SpecReport
@@ -68,6 +65,8 @@ type Suite struct {
selectiveLock *sync.Mutex
client parallel_support.Client
+
+ annotateFn AnnotateFunc
}
func NewSuite() *Suite {
@@ -90,7 +89,6 @@ func (suite *Suite) Clone() (*Suite, error) {
ProgressReporterManager: NewProgressReporterManager(),
topLevelContainers: suite.topLevelContainers.Clone(),
suiteNodes: suite.suiteNodes.Clone(),
- aroundNodes: suite.aroundNodes.Clone(),
selectiveLock: &sync.Mutex{},
}, nil
}
@@ -108,14 +106,18 @@ func (suite *Suite) BuildTree() error {
return nil
}
-func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suiteAroundNodes types.AroundNodes, suitePath string, failer *Failer, reporter reporters.Reporter, writer WriterInterface, outputInterceptor OutputInterceptor, interruptHandler interrupt_handler.InterruptHandlerInterface, client parallel_support.Client, progressSignalRegistrar ProgressSignalRegistrar, suiteConfig types.SuiteConfig) (bool, bool) {
+func (suite *Suite) Run(description string, suiteLabels Labels, suitePath string, failer *Failer, reporter reporters.Reporter, writer WriterInterface, outputInterceptor OutputInterceptor, interruptHandler interrupt_handler.InterruptHandlerInterface, client parallel_support.Client, progressSignalRegistrar ProgressSignalRegistrar, suiteConfig types.SuiteConfig) (bool, bool) {
if suite.phase != PhaseBuildTree {
panic("cannot run before building the tree = call suite.BuildTree() first")
}
ApplyNestedFocusPolicyToTree(suite.tree)
specs := GenerateSpecsFromTreeRoot(suite.tree)
- specs, hasProgrammaticFocus := ApplyFocusToSpecs(specs, description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteConfig)
- specs = ComputeAroundNodes(specs)
+ if suite.annotateFn != nil {
+ for _, spec := range specs {
+ suite.annotateFn(spec.Text(), spec)
+ }
+ }
+ specs, hasProgrammaticFocus := ApplyFocusToSpecs(specs, description, suiteLabels, suiteConfig)
suite.phase = PhaseRun
suite.client = client
@@ -125,7 +127,6 @@ func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConst
suite.outputInterceptor = outputInterceptor
suite.interruptHandler = interruptHandler
suite.config = suiteConfig
- suite.aroundNodes = suiteAroundNodes
if suite.config.Timeout > 0 {
suite.deadline = time.Now().Add(suite.config.Timeout)
@@ -133,7 +134,7 @@ func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConst
cancelProgressHandler := progressSignalRegistrar(suite.handleProgressSignal)
- success := suite.runSpecs(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suitePath, hasProgrammaticFocus, specs)
+ success := suite.runSpecs(description, suiteLabels, suitePath, hasProgrammaticFocus, specs)
cancelProgressHandler()
@@ -205,17 +206,6 @@ func (suite *Suite) PushNode(node Node) error {
err = types.GinkgoErrors.CaughtPanicDuringABuildPhase(e, node.CodeLocation)
}
}()
-
- // Ensure that code running in the body of the container node
- // has access to information about the current container node(s).
- // The current one (nil in top-level container nodes, non-nil in an
- // embedded container node) gets restored when the node is done.
- oldConstructionNodeReport := suite.currentConstructionNodeReport
- suite.currentConstructionNodeReport = constructionNodeReportForTreeNode(suite.tree)
- defer func() {
- suite.currentConstructionNodeReport = oldConstructionNodeReport
- }()
-
node.Body(nil)
return err
}()
@@ -276,7 +266,6 @@ func (suite *Suite) pushCleanupNode(node Node) error {
node.NodeIDWhereCleanupWasGenerated = suite.currentNode.ID
node.NestingLevel = suite.currentNode.NestingLevel
- node.AroundNodes = types.AroundNodes{}.Append(suite.currentNode.AroundNodes...).Append(node.AroundNodes...)
suite.selectiveLock.Lock()
suite.cleanupNodes = append(suite.cleanupNodes, node)
suite.selectiveLock.Unlock()
@@ -345,16 +334,6 @@ func (suite *Suite) By(text string, callback ...func()) error {
return nil
}
-func (suite *Suite) CurrentConstructionNodeReport() types.ConstructionNodeReport {
- suite.selectiveLock.Lock()
- defer suite.selectiveLock.Unlock()
- report := suite.currentConstructionNodeReport
- if report == nil {
- panic("CurrentConstructionNodeReport may only be called during construction of the spec tree")
- }
- return *report
-}
-
/*
Spec Running methods - used during PhaseRun
*/
@@ -398,7 +377,7 @@ func (suite *Suite) generateProgressReport(fullReport bool) types.ProgressReport
suite.selectiveLock.Lock()
defer suite.selectiveLock.Unlock()
- deadline, cancel := context.WithTimeout(context.Background(), ProgressReporterDeadline)
+ deadline, cancel := context.WithTimeout(context.Background(), PROGRESS_REPORTER_DEADLING)
defer cancel()
var additionalReports []string
if suite.currentSpecContext != nil {
@@ -456,17 +435,15 @@ func (suite *Suite) processCurrentSpecReport() {
}
}
-func (suite *Suite) runSpecs(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suitePath string, hasProgrammaticFocus bool, specs Specs) bool {
+func (suite *Suite) runSpecs(description string, suiteLabels Labels, suitePath string, hasProgrammaticFocus bool, specs Specs) bool {
numSpecsThatWillBeRun := specs.CountWithoutSkip()
suite.report = types.Report{
- SuitePath: suitePath,
- SuiteDescription: description,
- SuiteLabels: suiteLabels,
- SuiteSemVerConstraints: suiteSemVerConstraints,
- SuiteComponentSemVerConstraints: suiteComponentSemVerConstraints,
- SuiteConfig: suite.config,
- SuiteHasProgrammaticFocus: hasProgrammaticFocus,
+ SuitePath: suitePath,
+ SuiteDescription: description,
+ SuiteLabels: suiteLabels,
+ SuiteConfig: suite.config,
+ SuiteHasProgrammaticFocus: hasProgrammaticFocus,
PreRunStats: types.PreRunStats{
TotalSpecs: len(specs),
SpecsThatWillRun: numSpecsThatWillBeRun,
@@ -921,30 +898,7 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ
failureC <- failureFromRun
}()
- aroundNodes := types.AroundNodes{}.Append(suite.aroundNodes...).Append(node.AroundNodes...)
- if len(aroundNodes) > 0 {
- i := 0
- var f func(context.Context)
- f = func(c context.Context) {
- sc := wrapContextChain(c)
- if sc == nil {
- suite.failer.Fail("An AroundNode failed to pass a valid Ginkgo SpecContext in. You must always pass in a context derived from the context passed to you.", aroundNodes[i].CodeLocation)
- return
- }
- i++
- if i < len(aroundNodes) {
- aroundNodes[i].Body(sc, f)
- } else {
- node.Body(sc)
- }
- }
- aroundNodes[0].Body(sc, f)
- if i != len(aroundNodes) {
- suite.failer.Fail("An AroundNode failed to call the passed in function.", aroundNodes[i].CodeLocation)
- }
- } else {
- node.Body(sc)
- }
+ node.Body(sc)
finished = true
}()
@@ -1043,7 +997,7 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ
}
progressReport = progressReport.WithoutOtherGoroutines()
- sc.cancel(fmt.Errorf("%s", interruptStatus.Message()))
+ sc.cancel(fmt.Errorf(interruptStatus.Message()))
if interruptStatus.Level == interrupt_handler.InterruptLevelBailOut {
if interruptStatus.ShouldIncludeProgressReport() {
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/suite_patch.go b/vendor/github.com/onsi/ginkgo/v2/internal/suite_patch.go
new file mode 100644
index 0000000000..29eae02832
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/suite_patch.go
@@ -0,0 +1,71 @@
+package internal
+
+import (
+ "time"
+
+ "github.com/onsi/ginkgo/v2/internal/interrupt_handler"
+ "github.com/onsi/ginkgo/v2/reporters"
+ "github.com/onsi/ginkgo/v2/types"
+)
+
+type AnnotateFunc func(testName string, test types.TestSpec)
+
+func (suite *Suite) SetAnnotateFn(fn AnnotateFunc) {
+ suite.annotateFn = fn
+}
+
+func (suite *Suite) GetReport() types.Report {
+ return suite.report
+}
+
+func (suite *Suite) WalkTests(fn AnnotateFunc) {
+ if suite.phase != PhaseBuildTree {
+ panic("cannot run before building the tree = call suite.BuildTree() first")
+ }
+ ApplyNestedFocusPolicyToTree(suite.tree)
+ specs := GenerateSpecsFromTreeRoot(suite.tree)
+ for _, spec := range specs {
+ fn(spec.Text(), spec)
+ }
+}
+
+func (suite *Suite) InPhaseBuildTree() bool {
+ return suite.phase == PhaseBuildTree
+}
+
+func (suite *Suite) ClearBeforeAndAfterSuiteNodes() {
+ // Don't build the tree multiple times, it results in multiple initing of tests
+ if !suite.InPhaseBuildTree() {
+ suite.BuildTree()
+ }
+ newNodes := Nodes{}
+ for _, node := range suite.suiteNodes {
+ if node.NodeType == types.NodeTypeBeforeSuite || node.NodeType == types.NodeTypeAfterSuite || node.NodeType == types.NodeTypeSynchronizedBeforeSuite || node.NodeType == types.NodeTypeSynchronizedAfterSuite {
+ continue
+ }
+ newNodes = append(newNodes, node)
+ }
+ suite.suiteNodes = newNodes
+}
+
+func (suite *Suite) RunSpec(spec types.TestSpec, suiteLabels Labels, suiteDescription, suitePath string, failer *Failer, writer WriterInterface, suiteConfig types.SuiteConfig, reporterConfig types.ReporterConfig) (bool, bool) {
+ if suite.phase != PhaseBuildTree {
+ panic("cannot run before building the tree = call suite.BuildTree() first")
+ }
+
+ suite.phase = PhaseRun
+ suite.client = nil
+ suite.failer = failer
+ suite.reporter = reporters.NewDefaultReporter(reporterConfig, writer)
+ suite.writer = writer
+ suite.outputInterceptor = NoopOutputInterceptor{}
+ if suite.config.Timeout > 0 {
+ suite.deadline = time.Now().Add(suiteConfig.Timeout)
+ }
+ suite.interruptHandler = interrupt_handler.NewInterruptHandler(nil)
+ suite.config = suiteConfig
+
+ success := suite.runSpecs(suiteDescription, suiteLabels, suitePath, false, []Spec{spec.(Spec)})
+
+ return success, false
+}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go b/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go
index 5704f0fdf9..73e2655656 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go
@@ -1,7 +1,6 @@
package testingtproxy
import (
- "context"
"fmt"
"io"
"os"
@@ -20,18 +19,13 @@ type addReportEntryFunc func(names string, args ...any)
type ginkgoWriterInterface interface {
io.Writer
- Print(a ...any)
- Printf(format string, a ...any)
- Println(a ...any)
+ Print(a ...interface{})
+ Printf(format string, a ...interface{})
+ Println(a ...interface{})
}
type ginkgoRecoverFunc func()
type attachProgressReporterFunc func(func() string) func()
-var formatters = map[bool]formatter.Formatter{
- true: formatter.NewWithNoColorBool(true),
- false: formatter.NewWithNoColorBool(false),
-}
-
func New(writer ginkgoWriterInterface, fail failFunc, skip skipFunc, cleanup cleanupFunc, report reportFunc, addReportEntry addReportEntryFunc, ginkgoRecover ginkgoRecoverFunc, attachProgressReporter attachProgressReporterFunc, randomSeed int64, parallelProcess int, parallelTotal int, noColor bool, offset int) *ginkgoTestingTProxy {
return &ginkgoTestingTProxy{
fail: fail,
@@ -46,7 +40,7 @@ func New(writer ginkgoWriterInterface, fail failFunc, skip skipFunc, cleanup cle
randomSeed: randomSeed,
parallelProcess: parallelProcess,
parallelTotal: parallelTotal,
- f: formatters[noColor], //minimize allocations by reusing formatters
+ f: formatter.NewWithNoColorBool(noColor),
}
}
@@ -86,31 +80,11 @@ func (t *ginkgoTestingTProxy) Setenv(key, value string) {
}
}
-func (t *ginkgoTestingTProxy) Chdir(dir string) {
- currentDir, err := os.Getwd()
- if err != nil {
- t.fail(fmt.Sprintf("Failed to get current directory: %v", err), 1)
- }
-
- t.cleanup(os.Chdir, currentDir, internal.Offset(1))
-
- err = os.Chdir(dir)
- if err != nil {
- t.fail(fmt.Sprintf("Failed to change directory: %v", err), 1)
- }
-}
-
-func (t *ginkgoTestingTProxy) Context() context.Context {
- ctx, cancel := context.WithCancel(context.Background())
- t.cleanup(cancel, internal.Offset(1))
- return ctx
-}
-
-func (t *ginkgoTestingTProxy) Error(args ...any) {
+func (t *ginkgoTestingTProxy) Error(args ...interface{}) {
t.fail(fmt.Sprintln(args...), t.offset)
}
-func (t *ginkgoTestingTProxy) Errorf(format string, args ...any) {
+func (t *ginkgoTestingTProxy) Errorf(format string, args ...interface{}) {
t.fail(fmt.Sprintf(format, args...), t.offset)
}
@@ -126,11 +100,11 @@ func (t *ginkgoTestingTProxy) Failed() bool {
return t.report().Failed()
}
-func (t *ginkgoTestingTProxy) Fatal(args ...any) {
+func (t *ginkgoTestingTProxy) Fatal(args ...interface{}) {
t.fail(fmt.Sprintln(args...), t.offset)
}
-func (t *ginkgoTestingTProxy) Fatalf(format string, args ...any) {
+func (t *ginkgoTestingTProxy) Fatalf(format string, args ...interface{}) {
t.fail(fmt.Sprintf(format, args...), t.offset)
}
@@ -138,11 +112,11 @@ func (t *ginkgoTestingTProxy) Helper() {
types.MarkAsHelper(1)
}
-func (t *ginkgoTestingTProxy) Log(args ...any) {
+func (t *ginkgoTestingTProxy) Log(args ...interface{}) {
fmt.Fprintln(t.writer, args...)
}
-func (t *ginkgoTestingTProxy) Logf(format string, args ...any) {
+func (t *ginkgoTestingTProxy) Logf(format string, args ...interface{}) {
t.Log(fmt.Sprintf(format, args...))
}
@@ -154,7 +128,7 @@ func (t *ginkgoTestingTProxy) Parallel() {
// No-op
}
-func (t *ginkgoTestingTProxy) Skip(args ...any) {
+func (t *ginkgoTestingTProxy) Skip(args ...interface{}) {
t.skip(fmt.Sprintln(args...), t.offset)
}
@@ -162,7 +136,7 @@ func (t *ginkgoTestingTProxy) SkipNow() {
t.skip("skip", t.offset)
}
-func (t *ginkgoTestingTProxy) Skipf(format string, args ...any) {
+func (t *ginkgoTestingTProxy) Skipf(format string, args ...interface{}) {
t.skip(fmt.Sprintf(format, args...), t.offset)
}
@@ -234,9 +208,3 @@ func (t *ginkgoTestingTProxy) ParallelTotal() int {
func (t *ginkgoTestingTProxy) AttachProgressReporter(f func() string) func() {
return t.attachProgressReporter(f)
}
-func (t *ginkgoTestingTProxy) Output() io.Writer {
- return t.writer
-}
-func (t *ginkgoTestingTProxy) Attr(key, value string) {
- t.addReportEntry(key, value, internal.Offset(1), types.ReportEntryVisibilityFailureOrVerbose)
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/writer.go b/vendor/github.com/onsi/ginkgo/v2/internal/writer.go
index 1c4e0534e4..aab42d5fb3 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/writer.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/writer.go
@@ -121,15 +121,15 @@ func (w *Writer) ClearTeeWriters() {
w.teeWriters = []io.Writer{}
}
-func (w *Writer) Print(a ...any) {
+func (w *Writer) Print(a ...interface{}) {
fmt.Fprint(w, a...)
}
-func (w *Writer) Printf(format string, a ...any) {
+func (w *Writer) Printf(format string, a ...interface{}) {
fmt.Fprintf(w, format, a...)
}
-func (w *Writer) Println(a ...any) {
+func (w *Writer) Println(a ...interface{}) {
fmt.Fprintln(w, a...)
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
index ef66b22898..480730486a 100644
--- a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
+++ b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
@@ -72,12 +72,6 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) {
if len(report.SuiteLabels) > 0 {
r.emit(r.f("{{coral}}[%s]{{/}} ", strings.Join(report.SuiteLabels, ", ")))
}
- if len(report.SuiteSemVerConstraints) > 0 {
- r.emit(r.f("{{coral}}[%s]{{/}} ", strings.Join(report.SuiteSemVerConstraints, ", ")))
- }
- if len(report.SuiteComponentSemVerConstraints) > 0 {
- r.emit(r.f("{{coral}}[Components: %s]{{/}} ", formatComponentSemVerConstraintsToString(report.SuiteComponentSemVerConstraints)))
- }
r.emit(r.f("- %d/%d specs ", report.PreRunStats.SpecsThatWillRun, report.PreRunStats.TotalSpecs))
if report.SuiteConfig.ParallelTotal > 1 {
r.emit(r.f("- %d procs ", report.SuiteConfig.ParallelTotal))
@@ -93,20 +87,6 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) {
bannerWidth = len(labels) + 2
}
}
- if len(report.SuiteSemVerConstraints) > 0 {
- semVerConstraints := strings.Join(report.SuiteSemVerConstraints, ", ")
- r.emitBlock(r.f("{{coral}}[%s]{{/}} ", semVerConstraints))
- if len(semVerConstraints)+2 > bannerWidth {
- bannerWidth = len(semVerConstraints) + 2
- }
- }
- if len(report.SuiteComponentSemVerConstraints) > 0 {
- componentSemVerConstraints := formatComponentSemVerConstraintsToString(report.SuiteComponentSemVerConstraints)
- r.emitBlock(r.f("{{coral}}[Components: %s]{{/}} ", componentSemVerConstraints))
- if len(componentSemVerConstraints)+2 > bannerWidth {
- bannerWidth = len(componentSemVerConstraints) + 2
- }
- }
r.emitBlock(strings.Repeat("=", bannerWidth))
out := r.f("Random Seed: {{bold}}%d{{/}}", report.SuiteConfig.RandomSeed)
@@ -391,22 +371,13 @@ func (r *DefaultReporter) emitTimeline(indent uint, report types.SpecReport, tim
cursor := 0
for _, entry := range timeline {
tl := entry.GetTimelineLocation()
-
- end := tl.Offset
- if end > len(gw) {
- end = len(gw)
- }
- if end < cursor {
- end = cursor
- }
- if cursor < end && cursor <= len(gw) && end <= len(gw) {
- r.emit(r.fi(indent, "%s", gw[cursor:end]))
- cursor = end
- } else if cursor < len(gw) && end == len(gw) {
+ if tl.Offset < len(gw) {
+ r.emit(r.fi(indent, "%s", gw[cursor:tl.Offset]))
+ cursor = tl.Offset
+ } else if cursor < len(gw) {
r.emit(r.fi(indent, "%s", gw[cursor:]))
cursor = len(gw)
}
-
switch x := entry.(type) {
case types.Failure:
if isVeryVerbose {
@@ -423,7 +394,7 @@ func (r *DefaultReporter) emitTimeline(indent uint, report types.SpecReport, tim
case types.ReportEntry:
r.emitReportEntry(indent, x)
case types.ProgressReport:
- r.emitProgressReport(indent, false, isVeryVerbose, x)
+ r.emitProgressReport(indent, false, x)
case types.SpecEvent:
if isVeryVerbose || !x.IsOnlyVisibleAtVeryVerbose() || r.conf.ShowNodeEvents {
r.emitSpecEvent(indent, x, isVeryVerbose)
@@ -477,7 +448,7 @@ func (r *DefaultReporter) emitFailure(indent uint, state types.SpecState, failur
if !failure.ProgressReport.IsZero() {
r.emitBlock("\n")
- r.emitProgressReport(indent, false, false, failure.ProgressReport)
+ r.emitProgressReport(indent, false, failure.ProgressReport)
}
if failure.AdditionalFailure != nil && includeAdditionalFailure {
@@ -493,11 +464,11 @@ func (r *DefaultReporter) EmitProgressReport(report types.ProgressReport) {
r.emit(r.fi(1, "{{coral}}Progress Report for Ginkgo Process #{{bold}}%d{{/}}\n", report.ParallelProcess))
}
shouldEmitGW := report.RunningInParallel || r.conf.Verbosity().LT(types.VerbosityLevelVerbose)
- r.emitProgressReport(1, shouldEmitGW, true, report)
+ r.emitProgressReport(1, shouldEmitGW, report)
r.emitDelimiter(1)
}
-func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput, emitGroup bool, report types.ProgressReport) {
+func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput bool, report types.ProgressReport) {
if report.Message != "" {
r.emitBlock(r.fi(indent, report.Message+"\n"))
indent += 1
@@ -533,10 +504,6 @@ func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput
indent -= 1
}
- if r.conf.GithubOutput && emitGroup {
- r.emitBlock(r.fi(indent, "::group::Progress Report"))
- }
-
if emitGinkgoWriterOutput && report.CapturedGinkgoWriterOutput != "" {
r.emit("\n")
r.emitBlock(r.fi(indent, "{{gray}}Begin Captured GinkgoWriter Output >>{{/}}"))
@@ -583,10 +550,6 @@ func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput
r.emit(r.fi(indent, "{{gray}}{{bold}}{{underline}}Other Goroutines{{/}}\n"))
r.emitGoroutines(indent, otherGoroutines...)
}
-
- if r.conf.GithubOutput && emitGroup {
- r.emitBlock(r.fi(indent, "::endgroup::"))
- }
}
func (r *DefaultReporter) EmitReportEntry(entry types.ReportEntry) {
@@ -722,11 +685,11 @@ func (r *DefaultReporter) _emit(s string, block bool, isDelimiter bool) {
}
/* Rendering text */
-func (r *DefaultReporter) f(format string, args ...any) string {
+func (r *DefaultReporter) f(format string, args ...interface{}) string {
return r.formatter.F(format, args...)
}
-func (r *DefaultReporter) fi(indentation uint, format string, args ...any) string {
+func (r *DefaultReporter) fi(indentation uint, format string, args ...interface{}) string {
return r.formatter.Fi(indentation, format, args...)
}
@@ -735,12 +698,8 @@ func (r *DefaultReporter) cycleJoin(elements []string, joiner string) string {
}
func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, veryVerbose bool, usePreciseFailureLocation bool) string {
- texts, locations, labels, semVerConstraints, componentSemVerConstraints := []string{}, []types.CodeLocation{}, [][]string{}, [][]string{}, []map[string][]string{}
- texts = append(texts, report.ContainerHierarchyTexts...)
- locations = append(locations, report.ContainerHierarchyLocations...)
- labels = append(labels, report.ContainerHierarchyLabels...)
- semVerConstraints = append(semVerConstraints, report.ContainerHierarchySemVerConstraints...)
- componentSemVerConstraints = append(componentSemVerConstraints, report.ContainerHierarchyComponentSemVerConstraints...)
+ texts, locations, labels := []string{}, []types.CodeLocation{}, [][]string{}
+ texts, locations, labels = append(texts, report.ContainerHierarchyTexts...), append(locations, report.ContainerHierarchyLocations...), append(labels, report.ContainerHierarchyLabels...)
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
texts = append(texts, r.f("[%s] %s", report.LeafNodeType, report.LeafNodeText))
@@ -748,8 +707,6 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
texts = append(texts, r.f(report.LeafNodeText))
}
labels = append(labels, report.LeafNodeLabels)
- semVerConstraints = append(semVerConstraints, report.LeafNodeSemVerConstraints)
- componentSemVerConstraints = append(componentSemVerConstraints, report.LeafNodeComponentSemVerConstraints)
locations = append(locations, report.LeafNodeLocation)
failureLocation := report.Failure.FailureNodeLocation
@@ -763,8 +720,6 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
texts = append([]string{fmt.Sprintf("TOP-LEVEL [%s]", report.Failure.FailureNodeType)}, texts...)
locations = append([]types.CodeLocation{failureLocation}, locations...)
labels = append([][]string{{}}, labels...)
- semVerConstraints = append([][]string{{}}, semVerConstraints...)
- componentSemVerConstraints = append([]map[string][]string{{}}, componentSemVerConstraints...)
highlightIndex = 0
case types.FailureNodeInContainer:
i := report.Failure.FailureNodeContainerIndex
@@ -792,12 +747,6 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
if len(labels[i]) > 0 {
out += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels[i], ", "))
}
- if len(semVerConstraints[i]) > 0 {
- out += r.f(" {{coral}}[%s]{{/}}", strings.Join(semVerConstraints[i], ", "))
- }
- if len(componentSemVerConstraints[i]) > 0 {
- out += r.f(" {{coral}}[%s]{{/}}", formatComponentSemVerConstraintsToString(componentSemVerConstraints[i]))
- }
out += "\n"
out += r.fi(uint(i), "{{gray}}%s{{/}}\n", locations[i])
}
@@ -821,14 +770,6 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
if len(flattenedLabels) > 0 {
out += r.f(" {{coral}}[%s]{{/}}", strings.Join(flattenedLabels, ", "))
}
- flattenedSemVerConstraints := report.SemVerConstraints()
- if len(flattenedSemVerConstraints) > 0 {
- out += r.f(" {{coral}}[%s]{{/}}", strings.Join(flattenedSemVerConstraints, ", "))
- }
- flattenedComponentSemVerConstraints := report.ComponentSemVerConstraints()
- if len(flattenedComponentSemVerConstraints) > 0 {
- out += r.f(" {{coral}}[%s]{{/}}", formatComponentSemVerConstraintsToString(flattenedComponentSemVerConstraints))
- }
out += "\n"
if usePreciseFailureLocation {
out += r.f("{{gray}}%s{{/}}", failureLocation)
diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/gojson_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/gojson_report.go
deleted file mode 100644
index d02fb7a1ae..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/reporters/gojson_report.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package reporters
-
-import (
- "encoding/json"
- "fmt"
- "os"
- "path"
-
- "github.com/onsi/ginkgo/v2/internal/reporters"
- "github.com/onsi/ginkgo/v2/types"
-)
-
-// GenerateGoTestJSONReport produces a JSON-formatted in the test2json format used by `go test -json`
-func GenerateGoTestJSONReport(report types.Report, destination string) error {
- // walk report and generate test2json-compatible objects
- // JSON-encode the objects into filename
- if err := os.MkdirAll(path.Dir(destination), 0770); err != nil {
- return err
- }
- f, err := os.Create(destination)
- if err != nil {
- return err
- }
- defer f.Close()
- enc := json.NewEncoder(f)
- r := reporters.NewGoJSONReporter(
- enc,
- systemErrForUnstructuredReporters,
- systemOutForUnstructuredReporters,
- )
- return r.Write(report)
-}
-
-// MergeJSONReports produces a single JSON-formatted report at the passed in destination by merging the JSON-formatted reports provided in sources
-// It skips over reports that fail to decode but reports on them via the returned messages []string
-func MergeAndCleanupGoTestJSONReports(sources []string, destination string) ([]string, error) {
- messages := []string{}
- if err := os.MkdirAll(path.Dir(destination), 0770); err != nil {
- return messages, err
- }
- f, err := os.Create(destination)
- if err != nil {
- return messages, err
- }
- defer f.Close()
-
- for _, source := range sources {
- data, err := os.ReadFile(source)
- if err != nil {
- messages = append(messages, fmt.Sprintf("Could not open %s:\n%s", source, err.Error()))
- continue
- }
- _, err = f.Write(data)
- if err != nil {
- messages = append(messages, fmt.Sprintf("Could not write to %s:\n%s", destination, err.Error()))
- continue
- }
- os.Remove(source)
- }
- return messages, nil
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
index d4720ee949..562e0f62ba 100644
--- a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
+++ b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
@@ -13,11 +13,9 @@ package reporters
import (
"encoding/xml"
"fmt"
- "maps"
"os"
"path"
"regexp"
- "slices"
"strings"
"github.com/onsi/ginkgo/v2/config"
@@ -38,12 +36,6 @@ type JunitReportConfig struct {
// Enable OmitSpecLabels to prevent labels from appearing in the spec name
OmitSpecLabels bool
- // Enable OmitSpecSemVerConstraints to prevent semantic version constraints from appearing in the spec name
- OmitSpecSemVerConstraints bool
-
- // Enable OmitSpecComponentSemVerConstraints to prevent component semantic version constraints from appearing in the spec name
- OmitSpecComponentSemVerConstraints bool
-
// Enable OmitLeafNodeType to prevent the spec leaf node type from appearing in the spec name
OmitLeafNodeType bool
@@ -177,12 +169,9 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit
{"SuiteHasProgrammaticFocus", fmt.Sprintf("%t", report.SuiteHasProgrammaticFocus)},
{"SpecialSuiteFailureReason", strings.Join(report.SpecialSuiteFailureReasons, ",")},
{"SuiteLabels", fmt.Sprintf("[%s]", strings.Join(report.SuiteLabels, ","))},
- {"SuiteSemVerConstraints", fmt.Sprintf("[%s]", strings.Join(report.SuiteSemVerConstraints, ","))},
- {"SuiteComponentSemVerConstraints", fmt.Sprintf("[%s]", formatComponentSemVerConstraintsToString(report.SuiteComponentSemVerConstraints))},
{"RandomSeed", fmt.Sprintf("%d", report.SuiteConfig.RandomSeed)},
{"RandomizeAllSpecs", fmt.Sprintf("%t", report.SuiteConfig.RandomizeAllSpecs)},
{"LabelFilter", report.SuiteConfig.LabelFilter},
- {"SemVerFilter", report.SuiteConfig.SemVerFilter},
{"FocusStrings", strings.Join(report.SuiteConfig.FocusStrings, ",")},
{"SkipStrings", strings.Join(report.SuiteConfig.SkipStrings, ",")},
{"FocusFiles", strings.Join(report.SuiteConfig.FocusFiles, ";")},
@@ -218,14 +207,6 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit
owner = matches[1]
}
}
- semVerConstraints := spec.SemVerConstraints()
- if len(semVerConstraints) > 0 && !config.OmitSpecSemVerConstraints {
- name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
- }
- componentSemVerConstraints := spec.ComponentSemVerConstraints()
- if len(componentSemVerConstraints) > 0 && !config.OmitSpecComponentSemVerConstraints {
- name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]"
- }
name = strings.TrimSpace(name)
test := JUnitTestCase{
@@ -397,16 +378,6 @@ func systemOutForUnstructuredReporters(spec types.SpecReport) string {
return spec.CapturedStdOutErr
}
-func formatComponentSemVerConstraintsToString(componentSemVerConstraints map[string][]string) string {
- var tmpStr string
- for _, key := range slices.Sorted(maps.Keys(componentSemVerConstraints)) {
- tmpStr = tmpStr + fmt.Sprintf("%s: %s, ", key, componentSemVerConstraints[key])
- }
-
- tmpStr = strings.TrimSuffix(tmpStr, ", ")
- return tmpStr
-}
-
// Deprecated JUnitReporter (so folks can still compile their suites)
type JUnitReporter struct{}
diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go
index ed3e3a2bb9..e990ad82e1 100644
--- a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go
+++ b/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go
@@ -38,17 +38,9 @@ func GenerateTeamcityReport(report types.Report, dst string) error {
name := report.SuiteDescription
labels := report.SuiteLabels
- semVerConstraints := report.SuiteSemVerConstraints
- componentSemVerConstraints := report.SuiteComponentSemVerConstraints
if len(labels) > 0 {
name = name + " [" + strings.Join(labels, ", ") + "]"
}
- if len(semVerConstraints) > 0 {
- name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
- }
- if len(componentSemVerConstraints) > 0 {
- name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]"
- }
fmt.Fprintf(f, "##teamcity[testSuiteStarted name='%s']\n", tcEscape(name))
for _, spec := range report.SpecReports {
name := fmt.Sprintf("[%s]", spec.LeafNodeType)
@@ -59,14 +51,6 @@ func GenerateTeamcityReport(report types.Report, dst string) error {
if len(labels) > 0 {
name = name + " [" + strings.Join(labels, ", ") + "]"
}
- semVerConstraints := spec.SemVerConstraints()
- if len(semVerConstraints) > 0 {
- name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
- }
- componentSemVerConstraints := spec.ComponentSemVerConstraints()
- if len(componentSemVerConstraints) > 0 {
- name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]"
- }
name = tcEscape(name)
fmt.Fprintf(f, "##teamcity[testStarted name='%s']\n", name)
diff --git a/vendor/github.com/onsi/ginkgo/v2/reporting_dsl.go b/vendor/github.com/onsi/ginkgo/v2/reporting_dsl.go
index 4e86dba84d..aa1a35176a 100644
--- a/vendor/github.com/onsi/ginkgo/v2/reporting_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/reporting_dsl.go
@@ -27,8 +27,6 @@ CurrentSpecReport returns information about the current running spec.
The returned object is a types.SpecReport which includes helper methods
to make extracting information about the spec easier.
-During construction of the test tree the result is empty.
-
You can learn more about SpecReport here: https://pkg.go.dev/github.com/onsi/ginkgo/types#SpecReport
You can learn more about CurrentSpecReport() here: https://onsi.github.io/ginkgo/#getting-a-report-for-the-current-spec
*/
@@ -36,31 +34,6 @@ func CurrentSpecReport() SpecReport {
return global.Suite.CurrentSpecReport()
}
-/*
-ConstructionNodeReport describes the container nodes during construction of
-the spec tree. It provides a subset of the information that is provided
-by SpecReport at runtime.
-
-It is documented here: [types.ConstructionNodeReport]
-*/
-type ConstructionNodeReport = types.ConstructionNodeReport
-
-/*
-CurrentConstructionNodeReport returns information about the current container nodes
-that are leading to the current path in the spec tree.
-The returned object is a types.ConstructionNodeReport which includes helper methods
-to make extracting information about the spec easier.
-
-May only be called during construction of the spec tree. It panics when
-called while tests are running. Use CurrentSpecReport instead in that
-phase.
-
-You can learn more about ConstructionNodeReport here: [types.ConstructionNodeReport]
-*/
-func CurrentTreeConstructionNodeReport() ConstructionNodeReport {
- return global.Suite.CurrentConstructionNodeReport()
-}
-
/*
ReportEntryVisibility governs the visibility of ReportEntries in Ginkgo's console reporter
@@ -87,7 +60,7 @@ AddReportEntry() must be called within a Subject or Setup node - not in a Contai
You can learn more about Report Entries here: https://onsi.github.io/ginkgo/#attaching-data-to-reports
*/
-func AddReportEntry(name string, args ...any) {
+func AddReportEntry(name string, args ...interface{}) {
cl := types.NewCodeLocation(1)
reportEntry, err := internal.NewReportEntry(name, cl, args...)
if err != nil {
@@ -116,10 +89,10 @@ You can learn more about ReportBeforeEach here: https://onsi.github.io/ginkgo/#g
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
*/
func ReportBeforeEach(body any, args ...any) bool {
- combinedArgs := []any{body}
+ combinedArgs := []interface{}{body}
combinedArgs = append(combinedArgs, args...)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeReportBeforeEach, "", combinedArgs...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeEach, "", combinedArgs...))
}
/*
@@ -140,10 +113,10 @@ You can learn more about ReportAfterEach here: https://onsi.github.io/ginkgo/#ge
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
*/
func ReportAfterEach(body any, args ...any) bool {
- combinedArgs := []any{body}
+ combinedArgs := []interface{}{body}
combinedArgs = append(combinedArgs, args...)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeReportAfterEach, "", combinedArgs...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterEach, "", combinedArgs...))
}
/*
@@ -170,9 +143,9 @@ You can learn more about Ginkgo's reporting infrastructure, including generating
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
*/
func ReportBeforeSuite(body any, args ...any) bool {
- combinedArgs := []any{body}
+ combinedArgs := []interface{}{body}
combinedArgs = append(combinedArgs, args...)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeReportBeforeSuite, "", combinedArgs...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeSuite, "", combinedArgs...))
}
/*
@@ -192,7 +165,7 @@ ReportAfterSuite nodes must be created at the top-level (i.e. not nested in a Co
When running in parallel, Ginkgo ensures that only one of the parallel nodes runs the ReportAfterSuite and that it is passed a report that is aggregated across
all parallel nodes
-In addition to using ReportAfterSuite to programmatically generate suite reports, you can also generate JSON, GoJSON, JUnit, and Teamcity formatted reports using the --json-report, --gojson-report, --junit-report, and --teamcity-report ginkgo CLI flags.
+In addition to using ReportAfterSuite to programmatically generate suite reports, you can also generate JSON, JUnit, and Teamcity formatted reports using the --json-report, --junit-report, and --teamcity-report ginkgo CLI flags.
You cannot nest any other Ginkgo nodes within a ReportAfterSuite node's closure.
You can learn more about ReportAfterSuite here: https://onsi.github.io/ginkgo/#generating-reports-programmatically
@@ -201,10 +174,10 @@ You can learn more about Ginkgo's reporting infrastructure, including generating
You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spec-timeouts-and-interruptible-nodes
*/
-func ReportAfterSuite(text string, body any, args ...any) bool {
- combinedArgs := []any{body}
+func ReportAfterSuite(text string, body any, args ...interface{}) bool {
+ combinedArgs := []interface{}{body}
combinedArgs = append(combinedArgs, args...)
- return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeReportAfterSuite, text, combinedArgs...)))
+ return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterSuite, text, combinedArgs...))
}
func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.ReporterConfig) {
@@ -215,12 +188,6 @@ func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.Re
Fail(fmt.Sprintf("Failed to generate JSON report:\n%s", err.Error()))
}
}
- if reporterConfig.GoJSONReport != "" {
- err := reporters.GenerateGoTestJSONReport(report, reporterConfig.GoJSONReport)
- if err != nil {
- Fail(fmt.Sprintf("Failed to generate Go JSON report:\n%s", err.Error()))
- }
- }
if reporterConfig.JUnitReport != "" {
err := reporters.GenerateJUnitReport(report, reporterConfig.JUnitReport)
if err != nil {
@@ -239,9 +206,6 @@ func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.Re
if reporterConfig.JSONReport != "" {
flags = append(flags, "--json-report")
}
- if reporterConfig.GoJSONReport != "" {
- flags = append(flags, "--gojson-report")
- }
if reporterConfig.JUnitReport != "" {
flags = append(flags, "--junit-report")
}
@@ -249,11 +213,9 @@ func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.Re
flags = append(flags, "--teamcity-report")
}
pushNode(internal.NewNode(
- internal.TransformNewNodeArgs(
- exitIfErrors, deprecationTracker, types.NodeTypeReportAfterSuite,
- fmt.Sprintf("Autogenerated ReportAfterSuite for %s", strings.Join(flags, " ")),
- body,
- types.NewCustomCodeLocation("autogenerated by Ginkgo"),
- ),
+ deprecationTracker, types.NodeTypeReportAfterSuite,
+ fmt.Sprintf("Autogenerated ReportAfterSuite for %s", strings.Join(flags, " ")),
+ body,
+ types.NewCustomCodeLocation("autogenerated by Ginkgo"),
))
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/table_dsl.go b/vendor/github.com/onsi/ginkgo/v2/table_dsl.go
index 1031aa8554..c7de7a8be0 100644
--- a/vendor/github.com/onsi/ginkgo/v2/table_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/table_dsl.go
@@ -23,7 +23,7 @@ You can learn more about generating EntryDescriptions here: https://onsi.github.
*/
type EntryDescription string
-func (ed EntryDescription) render(args ...any) string {
+func (ed EntryDescription) render(args ...interface{}) string {
return fmt.Sprintf(string(ed), args...)
}
@@ -44,7 +44,7 @@ For example:
You can learn more about DescribeTable here: https://onsi.github.io/ginkgo/#table-specs
And can explore some Table patterns here: https://onsi.github.io/ginkgo/#table-specs-patterns
*/
-func DescribeTable(description string, args ...any) bool {
+func DescribeTable(description string, args ...interface{}) bool {
GinkgoHelper()
generateTable(description, false, args...)
return true
@@ -53,7 +53,7 @@ func DescribeTable(description string, args ...any) bool {
/*
You can focus a table with `FDescribeTable`. This is equivalent to `FDescribe`.
*/
-func FDescribeTable(description string, args ...any) bool {
+func FDescribeTable(description string, args ...interface{}) bool {
GinkgoHelper()
args = append(args, internal.Focus)
generateTable(description, false, args...)
@@ -63,7 +63,7 @@ func FDescribeTable(description string, args ...any) bool {
/*
You can mark a table as pending with `PDescribeTable`. This is equivalent to `PDescribe`.
*/
-func PDescribeTable(description string, args ...any) bool {
+func PDescribeTable(description string, args ...interface{}) bool {
GinkgoHelper()
args = append(args, internal.Pending)
generateTable(description, false, args...)
@@ -95,7 +95,7 @@ For example:
})
It("should return the expected message", func() {
- body, err := io.ReadAll(resp.Body)
+ body, err := ioutil.ReadAll(resp.Body)
Expect(err).NotTo(HaveOccurred())
Expect(string(body)).To(Equal(message))
})
@@ -109,7 +109,7 @@ Note that you **must** place define an It inside the body function.
You can learn more about DescribeTableSubtree here: https://onsi.github.io/ginkgo/#table-specs
And can explore some Table patterns here: https://onsi.github.io/ginkgo/#table-specs-patterns
*/
-func DescribeTableSubtree(description string, args ...any) bool {
+func DescribeTableSubtree(description string, args ...interface{}) bool {
GinkgoHelper()
generateTable(description, true, args...)
return true
@@ -118,7 +118,7 @@ func DescribeTableSubtree(description string, args ...any) bool {
/*
You can focus a table with `FDescribeTableSubtree`. This is equivalent to `FDescribe`.
*/
-func FDescribeTableSubtree(description string, args ...any) bool {
+func FDescribeTableSubtree(description string, args ...interface{}) bool {
GinkgoHelper()
args = append(args, internal.Focus)
generateTable(description, true, args...)
@@ -128,7 +128,7 @@ func FDescribeTableSubtree(description string, args ...any) bool {
/*
You can mark a table as pending with `PDescribeTableSubtree`. This is equivalent to `PDescribe`.
*/
-func PDescribeTableSubtree(description string, args ...any) bool {
+func PDescribeTableSubtree(description string, args ...interface{}) bool {
GinkgoHelper()
args = append(args, internal.Pending)
generateTable(description, true, args...)
@@ -144,9 +144,9 @@ var XDescribeTableSubtree = PDescribeTableSubtree
TableEntry represents an entry in a table test. You generally use the `Entry` constructor.
*/
type TableEntry struct {
- description any
- decorations []any
- parameters []any
+ description interface{}
+ decorations []interface{}
+ parameters []interface{}
codeLocation types.CodeLocation
}
@@ -162,7 +162,7 @@ If you want to generate interruptible specs simply write a Table function that a
You can learn more about Entry here: https://onsi.github.io/ginkgo/#table-specs
*/
-func Entry(description any, args ...any) TableEntry {
+func Entry(description interface{}, args ...interface{}) TableEntry {
GinkgoHelper()
decorations, parameters := internal.PartitionDecorations(args...)
return TableEntry{description: description, decorations: decorations, parameters: parameters, codeLocation: types.NewCodeLocation(0)}
@@ -171,7 +171,7 @@ func Entry(description any, args ...any) TableEntry {
/*
You can focus a particular entry with FEntry. This is equivalent to FIt.
*/
-func FEntry(description any, args ...any) TableEntry {
+func FEntry(description interface{}, args ...interface{}) TableEntry {
GinkgoHelper()
decorations, parameters := internal.PartitionDecorations(args...)
decorations = append(decorations, internal.Focus)
@@ -181,7 +181,7 @@ func FEntry(description any, args ...any) TableEntry {
/*
You can mark a particular entry as pending with PEntry. This is equivalent to PIt.
*/
-func PEntry(description any, args ...any) TableEntry {
+func PEntry(description interface{}, args ...interface{}) TableEntry {
GinkgoHelper()
decorations, parameters := internal.PartitionDecorations(args...)
decorations = append(decorations, internal.Pending)
@@ -196,17 +196,17 @@ var XEntry = PEntry
var contextType = reflect.TypeOf(new(context.Context)).Elem()
var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
-func generateTable(description string, isSubtree bool, args ...any) {
+func generateTable(description string, isSubtree bool, args ...interface{}) {
GinkgoHelper()
cl := types.NewCodeLocation(0)
- containerNodeArgs := []any{cl}
+ containerNodeArgs := []interface{}{cl}
entries := []TableEntry{}
- var internalBody any
+ var internalBody interface{}
var internalBodyType reflect.Type
- var tableLevelEntryDescription any
- tableLevelEntryDescription = func(args ...any) string {
+ var tableLevelEntryDescription interface{}
+ tableLevelEntryDescription = func(args ...interface{}) string {
out := []string{}
for _, arg := range args {
out = append(out, fmt.Sprint(arg))
@@ -265,7 +265,7 @@ func generateTable(description string, isSubtree bool, args ...any) {
err = types.GinkgoErrors.InvalidEntryDescription(entry.codeLocation)
}
- internalNodeArgs := []any{entry.codeLocation}
+ internalNodeArgs := []interface{}{entry.codeLocation}
internalNodeArgs = append(internalNodeArgs, entry.decorations...)
hasContext := false
@@ -290,7 +290,7 @@ func generateTable(description string, isSubtree bool, args ...any) {
if err != nil {
panic(err)
}
- invokeFunction(internalBody, append([]any{c}, entry.parameters...))
+ invokeFunction(internalBody, append([]interface{}{c}, entry.parameters...))
})
if isSubtree {
exitIfErr(types.GinkgoErrors.ContextsCannotBeUsedInSubtreeTables(cl))
@@ -309,14 +309,14 @@ func generateTable(description string, isSubtree bool, args ...any) {
internalNodeType = types.NodeTypeContainer
}
- pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, internalNodeType, description, internalNodeArgs...)))
+ pushNode(internal.NewNode(deprecationTracker, internalNodeType, description, internalNodeArgs...))
}
})
- pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, description, containerNodeArgs...)))
+ pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, description, containerNodeArgs...))
}
-func invokeFunction(function any, parameters []any) []reflect.Value {
+func invokeFunction(function interface{}, parameters []interface{}) []reflect.Value {
inValues := make([]reflect.Value, len(parameters))
funcType := reflect.TypeOf(function)
@@ -339,7 +339,7 @@ func invokeFunction(function any, parameters []any) []reflect.Value {
return reflect.ValueOf(function).Call(inValues)
}
-func validateParameters(function any, parameters []any, kind string, cl types.CodeLocation, hasContext bool) error {
+func validateParameters(function interface{}, parameters []interface{}, kind string, cl types.CodeLocation, hasContext bool) error {
funcType := reflect.TypeOf(function)
limit := funcType.NumIn()
offset := 0
@@ -377,7 +377,7 @@ func validateParameters(function any, parameters []any, kind string, cl types.Co
return nil
}
-func computeValue(parameter any, t reflect.Type) reflect.Value {
+func computeValue(parameter interface{}, t reflect.Type) reflect.Value {
if parameter == nil {
return reflect.Zero(t)
} else {
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/around_node.go b/vendor/github.com/onsi/ginkgo/v2/types/around_node.go
deleted file mode 100644
index a069e0623d..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/types/around_node.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package types
-
-import (
- "context"
-)
-
-type AroundNodeAllowedFuncs interface {
- ~func(context.Context, func(context.Context)) | ~func(context.Context) context.Context | ~func()
-}
-type AroundNodeFunc func(ctx context.Context, body func(ctx context.Context))
-
-func AroundNode[F AroundNodeAllowedFuncs](f F, cl CodeLocation) AroundNodeDecorator {
- if f == nil {
- panic("BuildAroundNode cannot be called with a nil function.")
- }
- var aroundNodeFunc func(context.Context, func(context.Context))
- switch x := any(f).(type) {
- case func(context.Context, func(context.Context)):
- aroundNodeFunc = x
- case func(context.Context) context.Context:
- aroundNodeFunc = func(ctx context.Context, body func(context.Context)) {
- ctx = x(ctx)
- body(ctx)
- }
- case func():
- aroundNodeFunc = func(ctx context.Context, body func(context.Context)) {
- x()
- body(ctx)
- }
- }
-
- return AroundNodeDecorator{
- Body: aroundNodeFunc,
- CodeLocation: cl,
- }
-}
-
-type AroundNodeDecorator struct {
- Body AroundNodeFunc
- CodeLocation CodeLocation
-}
-
-type AroundNodes []AroundNodeDecorator
-
-func (an AroundNodes) Clone() AroundNodes {
- out := make(AroundNodes, len(an))
- copy(out, an)
- return out
-}
-
-func (an AroundNodes) Append(other ...AroundNodeDecorator) AroundNodes {
- out := make(AroundNodes, len(an)+len(other))
- copy(out, an)
- copy(out[len(an):], other)
- return out
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/config.go b/vendor/github.com/onsi/ginkgo/v2/types/config.go
index f847036046..8c0dfab8c0 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/config.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/config.go
@@ -24,7 +24,6 @@ type SuiteConfig struct {
FocusFiles []string
SkipFiles []string
LabelFilter string
- SemVerFilter string
FailOnPending bool
FailOnEmpty bool
FailFast bool
@@ -96,7 +95,6 @@ type ReporterConfig struct {
ForceNewlines bool
JSONReport string
- GoJSONReport string
JUnitReport string
TeamcityReport string
}
@@ -113,7 +111,7 @@ func (rc ReporterConfig) Verbosity() VerbosityLevel {
}
func (rc ReporterConfig) WillGenerateReport() bool {
- return rc.JSONReport != "" || rc.GoJSONReport != "" || rc.JUnitReport != "" || rc.TeamcityReport != ""
+ return rc.JSONReport != "" || rc.JUnitReport != "" || rc.TeamcityReport != ""
}
func NewDefaultReporterConfig() ReporterConfig {
@@ -161,7 +159,7 @@ func (g CLIConfig) ComputedProcs() int {
n := 1
if g.Parallel {
- n = runtime.GOMAXPROCS(-1)
+ n = runtime.NumCPU()
if n > 4 {
n = n - 1
}
@@ -174,7 +172,7 @@ func (g CLIConfig) ComputedNumCompilers() int {
return g.NumCompilers
}
- return runtime.GOMAXPROCS(-1)
+ return runtime.NumCPU()
}
// Configuration for the Ginkgo CLI capturing available go flags
@@ -233,10 +231,6 @@ func (g GoFlagsConfig) BinaryMustBePreserved() bool {
return g.BlockProfile != "" || g.CPUProfile != "" || g.MemProfile != "" || g.MutexProfile != ""
}
-func (g GoFlagsConfig) NeedsSymbols() bool {
- return g.BinaryMustBePreserved()
-}
-
// Configuration that were deprecated in 2.0
type deprecatedConfig struct {
DebugParallel bool
@@ -263,12 +257,8 @@ var FlagSections = GinkgoFlagSections{
{Key: "filter", Style: "{{cyan}}", Heading: "Filtering Tests"},
{Key: "failure", Style: "{{red}}", Heading: "Failure Handling"},
{Key: "output", Style: "{{magenta}}", Heading: "Controlling Output Formatting"},
- {Key: "code-and-coverage-analysis", Style: "{{orange}}", Heading: "Code and Coverage Analysis",
- Description: "When generating a cover files, please pass a filename {{bold}}not{{/}} a path. To specify a different directory use {{magenta}}--output-dir{{/}}.",
- },
- {Key: "performance-analysis", Style: "{{coral}}", Heading: "Performance Analysis",
- Description: "When generating profile files, please pass filenames {{bold}}not{{/}} a path. Ginkgo will generate a profile file with the given name in the package's directory. To specify a different directory use {{magenta}}--output-dir{{/}}.",
- },
+ {Key: "code-and-coverage-analysis", Style: "{{orange}}", Heading: "Code and Coverage Analysis"},
+ {Key: "performance-analysis", Style: "{{coral}}", Heading: "Performance Analysis"},
{Key: "debug", Style: "{{blue}}", Heading: "Debugging Tests",
Description: "In addition to these flags, Ginkgo supports a few debugging environment variables. To change the parallel server protocol set {{blue}}GINKGO_PARALLEL_PROTOCOL{{/}} to {{bold}}HTTP{{/}}. To avoid pruning callstacks set {{blue}}GINKGO_PRUNE_STACK{{/}} to {{bold}}FALSE{{/}}."},
{Key: "watch", Style: "{{light-yellow}}", Heading: "Controlling Ginkgo Watch"},
@@ -310,8 +300,6 @@ var SuiteConfigFlags = GinkgoFlags{
{KeyPath: "S.LabelFilter", Name: "label-filter", SectionKey: "filter", UsageArgument: "expression",
Usage: "If set, ginkgo will only run specs with labels that match the label-filter. The passed-in expression can include boolean operations (!, &&, ||, ','), groupings via '()', and regular expressions '/regexp/'. e.g. '(cat || dog) && !fruit'"},
- {KeyPath: "S.SemVerFilter", Name: "sem-ver-filter", SectionKey: "filter", UsageArgument: "version",
- Usage: "If set, ginkgo will only run specs with semantic version constraints that are satisfied by the provided version. e.g. '2.1.0'"},
{KeyPath: "S.FocusStrings", Name: "focus", SectionKey: "filter",
Usage: "If set, ginkgo will only run specs that match this regular expression. Can be specified multiple times, values are ORed."},
{KeyPath: "S.SkipStrings", Name: "skip", SectionKey: "filter",
@@ -360,8 +348,6 @@ var ReporterConfigFlags = GinkgoFlags{
{KeyPath: "R.JSONReport", Name: "json-report", UsageArgument: "filename.json", SectionKey: "output",
Usage: "If set, Ginkgo will generate a JSON-formatted test report at the specified location."},
- {KeyPath: "R.GoJSONReport", Name: "gojson-report", UsageArgument: "filename.json", SectionKey: "output",
- Usage: "If set, Ginkgo will generate a Go JSON-formatted test report at the specified location."},
{KeyPath: "R.JUnitReport", Name: "junit-report", UsageArgument: "filename.xml", SectionKey: "output", DeprecatedName: "reportFile", DeprecatedDocLink: "improved-reporting-infrastructure",
Usage: "If set, Ginkgo will generate a conformant junit test report in the specified file."},
{KeyPath: "R.TeamcityReport", Name: "teamcity-report", UsageArgument: "filename", SectionKey: "output",
@@ -379,7 +365,7 @@ var ReporterConfigFlags = GinkgoFlags{
func BuildTestSuiteFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterConfig) (GinkgoFlagSet, error) {
flags := SuiteConfigFlags.CopyAppend(ParallelConfigFlags...).CopyAppend(ReporterConfigFlags...)
flags = flags.WithPrefix("ginkgo")
- bindings := map[string]any{
+ bindings := map[string]interface{}{
"S": suiteConfig,
"R": reporterConfig,
"D": &deprecatedConfig{},
@@ -449,13 +435,6 @@ func VetConfig(flagSet GinkgoFlagSet, suiteConfig SuiteConfig, reporterConfig Re
}
}
- if suiteConfig.SemVerFilter != "" {
- _, err := ParseSemVerFilter(suiteConfig.SemVerFilter)
- if err != nil {
- errors = append(errors, err)
- }
- }
-
switch strings.ToLower(suiteConfig.OutputInterceptorMode) {
case "", "dup", "swap", "none":
default:
@@ -536,7 +515,7 @@ var GoBuildFlags = GinkgoFlags{
{KeyPath: "Go.Race", Name: "race", SectionKey: "code-and-coverage-analysis",
Usage: "enable data race detection. Supported on linux/amd64, linux/ppc64le, linux/arm64, linux/s390x, freebsd/amd64, netbsd/amd64, darwin/amd64, darwin/arm64, and windows/amd64."},
{KeyPath: "Go.Vet", Name: "vet", UsageArgument: "list", SectionKey: "code-and-coverage-analysis",
- Usage: `Configure the invocation of "go vet" during "go test" to use the comma-separated list of vet checks. If list is empty (by explicitly passing --vet=""), "go test" runs "go vet" with a curated list of checks believed to be always worth addressing. If list is "off", "go test" does not run "go vet" at all. Available checks can be found by running 'go doc cmd/vet'`},
+ Usage: `Configure the invocation of "go vet" during "go test" to use the comma-separated list of vet checks. If list is empty, "go test" runs "go vet" with a curated list of checks believed to be always worth addressing. If list is "off", "go test" does not run "go vet" at all. Available checks can be found by running 'go doc cmd/vet'`},
{KeyPath: "Go.Cover", Name: "cover", SectionKey: "code-and-coverage-analysis",
Usage: "Enable coverage analysis. Note that because coverage works by annotating the source code before compilation, compilation and test failures with coverage enabled may report line numbers that don't correspond to the original sources."},
{KeyPath: "Go.CoverMode", Name: "covermode", UsageArgument: "set,count,atomic", SectionKey: "code-and-coverage-analysis",
@@ -586,9 +565,6 @@ var GoBuildFlags = GinkgoFlags{
Usage: "print the name of the temporary work directory and do not delete it when exiting."},
{KeyPath: "Go.X", Name: "x", SectionKey: "go-build",
Usage: "print the commands."},
-}
-
-var GoBuildOFlags = GinkgoFlags{
{KeyPath: "Go.O", Name: "o", SectionKey: "go-build",
Usage: "output binary path (including name)."},
}
@@ -596,7 +572,7 @@ var GoBuildOFlags = GinkgoFlags{
// GoRunFlags provides flags for the Ginkgo CLI run, and watch commands that capture go's run-time flags. These are passed to the compiled test binary by the ginkgo CLI
var GoRunFlags = GinkgoFlags{
{KeyPath: "Go.CoverProfile", Name: "coverprofile", UsageArgument: "file", SectionKey: "code-and-coverage-analysis",
- Usage: `Write a coverage profile to the file after all tests have passed. Sets -cover. Must be passed a filename, not a path. Use output-dir to control the location of the output.`},
+ Usage: `Write a coverage profile to the file after all tests have passed. Sets -cover.`},
{KeyPath: "Go.BlockProfile", Name: "blockprofile", UsageArgument: "file", SectionKey: "performance-analysis",
Usage: `Write a goroutine blocking profile to the specified file when all tests are complete. Preserves test binary.`},
{KeyPath: "Go.BlockProfileRate", Name: "blockprofilerate", UsageArgument: "rate", SectionKey: "performance-analysis",
@@ -624,22 +600,6 @@ func VetAndInitializeCLIAndGoConfig(cliConfig CLIConfig, goFlagsConfig GoFlagsCo
errors = append(errors, GinkgoErrors.BothRepeatAndUntilItFails())
}
- if strings.ContainsRune(goFlagsConfig.CoverProfile, os.PathSeparator) {
- errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--coverprofile", goFlagsConfig.CoverProfile))
- }
- if strings.ContainsRune(goFlagsConfig.CPUProfile, os.PathSeparator) {
- errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--cpuprofile", goFlagsConfig.CPUProfile))
- }
- if strings.ContainsRune(goFlagsConfig.MemProfile, os.PathSeparator) {
- errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--memprofile", goFlagsConfig.MemProfile))
- }
- if strings.ContainsRune(goFlagsConfig.BlockProfile, os.PathSeparator) {
- errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--blockprofile", goFlagsConfig.BlockProfile))
- }
- if strings.ContainsRune(goFlagsConfig.MutexProfile, os.PathSeparator) {
- errors = append(errors, GinkgoErrors.ExpectFilenameNotPath("--mutexprofile", goFlagsConfig.MutexProfile))
- }
-
//initialize the output directory
if cliConfig.OutputDir != "" {
err := os.MkdirAll(cliConfig.OutputDir, 0777)
@@ -660,7 +620,7 @@ func VetAndInitializeCLIAndGoConfig(cliConfig CLIConfig, goFlagsConfig GoFlagsCo
}
// GenerateGoTestCompileArgs is used by the Ginkgo CLI to generate command line arguments to pass to the go test -c command when compiling the test
-func GenerateGoTestCompileArgs(goFlagsConfig GoFlagsConfig, packageToBuild string, pathToInvocationPath string, preserveSymbols bool) ([]string, error) {
+func GenerateGoTestCompileArgs(goFlagsConfig GoFlagsConfig, packageToBuild string, pathToInvocationPath string) ([]string, error) {
// if the user has set the CoverProfile run-time flag make sure to set the build-time cover flag to make sure
// the built test binary can generate a coverprofile
if goFlagsConfig.CoverProfile != "" {
@@ -683,14 +643,10 @@ func GenerateGoTestCompileArgs(goFlagsConfig GoFlagsConfig, packageToBuild strin
goFlagsConfig.CoverPkg = strings.Join(adjustedCoverPkgs, ",")
}
- if !goFlagsConfig.NeedsSymbols() && goFlagsConfig.LDFlags == "" && !preserveSymbols {
- goFlagsConfig.LDFlags = "-w -s"
- }
-
args := []string{"test", "-c", packageToBuild}
goArgs, err := GenerateFlagArgs(
- GoBuildFlags.CopyAppend(GoBuildOFlags...),
- map[string]any{
+ GoBuildFlags,
+ map[string]interface{}{
"Go": &goFlagsConfig,
},
)
@@ -709,7 +665,7 @@ func GenerateGinkgoTestRunArgs(suiteConfig SuiteConfig, reporterConfig ReporterC
flags = flags.CopyAppend(ParallelConfigFlags.WithPrefix("ginkgo")...)
flags = flags.CopyAppend(ReporterConfigFlags.WithPrefix("ginkgo")...)
flags = flags.CopyAppend(GoRunFlags.WithPrefix("test")...)
- bindings := map[string]any{
+ bindings := map[string]interface{}{
"S": &suiteConfig,
"R": &reporterConfig,
"Go": &goFlagsConfig,
@@ -721,7 +677,7 @@ func GenerateGinkgoTestRunArgs(suiteConfig SuiteConfig, reporterConfig ReporterC
// GenerateGoTestRunArgs is used by the Ginkgo CLI to generate command line arguments to pass to the compiled non-Ginkgo test binary
func GenerateGoTestRunArgs(goFlagsConfig GoFlagsConfig) ([]string, error) {
flags := GoRunFlags.WithPrefix("test")
- bindings := map[string]any{
+ bindings := map[string]interface{}{
"Go": &goFlagsConfig,
}
@@ -743,7 +699,7 @@ func BuildRunCommandFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterCo
flags = flags.CopyAppend(GoBuildFlags...)
flags = flags.CopyAppend(GoRunFlags...)
- bindings := map[string]any{
+ bindings := map[string]interface{}{
"S": suiteConfig,
"R": reporterConfig,
"C": cliConfig,
@@ -764,7 +720,7 @@ func BuildWatchCommandFlagSet(suiteConfig *SuiteConfig, reporterConfig *Reporter
flags = flags.CopyAppend(GoBuildFlags...)
flags = flags.CopyAppend(GoRunFlags...)
- bindings := map[string]any{
+ bindings := map[string]interface{}{
"S": suiteConfig,
"R": reporterConfig,
"C": cliConfig,
@@ -779,9 +735,8 @@ func BuildWatchCommandFlagSet(suiteConfig *SuiteConfig, reporterConfig *Reporter
func BuildBuildCommandFlagSet(cliConfig *CLIConfig, goFlagsConfig *GoFlagsConfig) (GinkgoFlagSet, error) {
flags := GinkgoCLISharedFlags
flags = flags.CopyAppend(GoBuildFlags...)
- flags = flags.CopyAppend(GoBuildOFlags...)
- bindings := map[string]any{
+ bindings := map[string]interface{}{
"C": cliConfig,
"Go": goFlagsConfig,
"D": &deprecatedConfig{},
@@ -805,7 +760,7 @@ func BuildBuildCommandFlagSet(cliConfig *CLIConfig, goFlagsConfig *GoFlagsConfig
func BuildLabelsCommandFlagSet(cliConfig *CLIConfig) (GinkgoFlagSet, error) {
flags := GinkgoCLISharedFlags.SubsetWithNames("r", "skip-package")
- bindings := map[string]any{
+ bindings := map[string]interface{}{
"C": cliConfig,
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/deprecated_types.go b/vendor/github.com/onsi/ginkgo/v2/types/deprecated_types.go
index 518989a844..17922304b6 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/deprecated_types.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/deprecated_types.go
@@ -113,7 +113,7 @@ type DeprecatedSpecFailure struct {
type DeprecatedSpecMeasurement struct {
Name string
- Info any
+ Info interface{}
Order int
Results []float64
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/errors.go b/vendor/github.com/onsi/ginkgo/v2/types/errors.go
index 623e54b66e..6bb72d00cc 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/errors.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/errors.go
@@ -88,7 +88,7 @@ body of a {{bold}}Describe{{/}}, {{bold}}Context{{/}}, or {{bold}}When{{/}}.`, n
}
}
-func (g ginkgoErrors) CaughtPanicDuringABuildPhase(caughtPanic any, cl CodeLocation) error {
+func (g ginkgoErrors) CaughtPanicDuringABuildPhase(caughtPanic interface{}, cl CodeLocation) error {
return GinkgoError{
Heading: "Assertion or Panic detected during tree construction",
Message: formatter.F(
@@ -189,7 +189,7 @@ func (g ginkgoErrors) InvalidDeclarationOfFlakeAttemptsAndMustPassRepeatedly(cl
}
}
-func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decorator any) error {
+func (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decorator interface{}) error {
return GinkgoError{
Heading: "Unknown Decorator",
Message: formatter.F(`[%s] node was passed an unknown decorator: '%#v'`, nodeType, decorator),
@@ -345,7 +345,7 @@ func (g ginkgoErrors) PushingCleanupInCleanupNode(cl CodeLocation) error {
}
/* ReportEntry errors */
-func (g ginkgoErrors) TooManyReportEntryValues(cl CodeLocation, arg any) error {
+func (g ginkgoErrors) TooManyReportEntryValues(cl CodeLocation, arg interface{}) error {
return GinkgoError{
Heading: "Too Many ReportEntry Values",
Message: formatter.F(`{{bold}}AddGinkgoReport{{/}} can only be given one value. Got unexpected value: %#v`, arg),
@@ -432,33 +432,6 @@ func (g ginkgoErrors) InvalidEmptyLabel(cl CodeLocation) error {
}
}
-func (g ginkgoErrors) InvalidSemVerConstraint(semVerConstraint, errMsg string, cl CodeLocation) error {
- return GinkgoError{
- Heading: "Invalid SemVerConstraint",
- Message: fmt.Sprintf("'%s' is an invalid SemVerConstraint: %s", semVerConstraint, errMsg),
- CodeLocation: cl,
- DocLink: "spec-semantic-version-filtering",
- }
-}
-
-func (g ginkgoErrors) InvalidEmptySemVerConstraint(cl CodeLocation) error {
- return GinkgoError{
- Heading: "Invalid Empty SemVerConstraint",
- Message: "SemVerConstraint cannot be empty",
- CodeLocation: cl,
- DocLink: "spec-semantic-version-filtering",
- }
-}
-
-func (g ginkgoErrors) InvalidEmptyComponentForSemVerConstraint(cl CodeLocation) error {
- return GinkgoError{
- Heading: "Invalid Empty Component for ComponentSemVerConstraint",
- Message: "ComponentSemVerConstraint requires a non-empty component name",
- CodeLocation: cl,
- DocLink: "spec-semantic-version-filtering",
- }
-}
-
/* Table errors */
func (g ginkgoErrors) MultipleEntryBodyFunctionsForTable(cl CodeLocation) error {
return GinkgoError{
@@ -566,7 +539,7 @@ func (g ginkgoErrors) SynchronizedBeforeSuiteDisappearedOnProc1() error {
/* Configuration errors */
-func (g ginkgoErrors) UnknownTypePassedToRunSpecs(value any) error {
+func (g ginkgoErrors) UnknownTypePassedToRunSpecs(value interface{}) error {
return GinkgoError{
Heading: "Unknown Type passed to RunSpecs",
Message: fmt.Sprintf("RunSpecs() accepts labels, and configuration of type types.SuiteConfig and/or types.ReporterConfig.\n You passed in: %v", value),
@@ -656,20 +629,6 @@ func (g ginkgoErrors) BothRepeatAndUntilItFails() error {
}
}
-func (g ginkgoErrors) ExpectFilenameNotPath(flag string, path string) error {
- return GinkgoError{
- Heading: fmt.Sprintf("%s expects a filename but was given a path: %s", flag, path),
- Message: fmt.Sprintf("%s takes a filename, not a path. Use --output-dir to specify a directory to collect all test outputs.", flag),
- }
-}
-
-func (g ginkgoErrors) FlagAfterPositionalParameter() error {
- return GinkgoError{
- Heading: "Malformed arguments - detected a flag after the package liste",
- Message: "Make sure all flags appear {{bold}}after{{/}} the Ginkgo subcommand and {{bold}}before{{/}} your list of packages (or './...').\n{{gray}}e.g. 'ginkgo run -p my_package' is valid but `ginkgo -p run my_package` is not.\n{{gray}}e.g. 'ginkgo -p -vet=\"\" ./...' is valid but 'ginkgo -p ./... -vet=\"\"' is not{{/}}",
- }
-}
-
/* Stack-Trace parsing errors */
func (g ginkgoErrors) FailedToParseStackTrace(message string) error {
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/flags.go b/vendor/github.com/onsi/ginkgo/v2/types/flags.go
index 8409653f97..de69f3022d 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/flags.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/flags.go
@@ -92,7 +92,7 @@ func (gfs GinkgoFlagSections) Lookup(key string) (GinkgoFlagSection, bool) {
type GinkgoFlagSet struct {
flags GinkgoFlags
- bindings any
+ bindings interface{}
sections GinkgoFlagSections
extraGoFlagsSection GinkgoFlagSection
@@ -101,7 +101,7 @@ type GinkgoFlagSet struct {
}
// Call NewGinkgoFlagSet to create GinkgoFlagSet that creates and binds to it's own *flag.FlagSet
-func NewGinkgoFlagSet(flags GinkgoFlags, bindings any, sections GinkgoFlagSections) (GinkgoFlagSet, error) {
+func NewGinkgoFlagSet(flags GinkgoFlags, bindings interface{}, sections GinkgoFlagSections) (GinkgoFlagSet, error) {
return bindFlagSet(GinkgoFlagSet{
flags: flags,
bindings: bindings,
@@ -110,7 +110,7 @@ func NewGinkgoFlagSet(flags GinkgoFlags, bindings any, sections GinkgoFlagSectio
}
// Call NewGinkgoFlagSet to create GinkgoFlagSet that extends an existing *flag.FlagSet
-func NewAttachedGinkgoFlagSet(flagSet *flag.FlagSet, flags GinkgoFlags, bindings any, sections GinkgoFlagSections, extraGoFlagsSection GinkgoFlagSection) (GinkgoFlagSet, error) {
+func NewAttachedGinkgoFlagSet(flagSet *flag.FlagSet, flags GinkgoFlags, bindings interface{}, sections GinkgoFlagSections, extraGoFlagsSection GinkgoFlagSection) (GinkgoFlagSet, error) {
return bindFlagSet(GinkgoFlagSet{
flags: flags,
bindings: bindings,
@@ -335,7 +335,7 @@ func (f GinkgoFlagSet) substituteUsage() {
fmt.Fprintln(f.flagSet.Output(), f.Usage())
}
-func valueAtKeyPath(root any, keyPath string) (reflect.Value, bool) {
+func valueAtKeyPath(root interface{}, keyPath string) (reflect.Value, bool) {
if len(keyPath) == 0 {
return reflect.Value{}, false
}
@@ -433,7 +433,7 @@ func (ssv stringSliceVar) Set(s string) error {
}
// given a set of GinkgoFlags and bindings, generate flag arguments suitable to be passed to an application with that set of flags configured.
-func GenerateFlagArgs(flags GinkgoFlags, bindings any) ([]string, error) {
+func GenerateFlagArgs(flags GinkgoFlags, bindings interface{}) ([]string, error) {
result := []string{}
for _, flag := range flags {
name := flag.ExportAs
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/label_filter.go b/vendor/github.com/onsi/ginkgo/v2/types/label_filter.go
index 40a909b6d5..7fdc8aa23f 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/label_filter.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/label_filter.go
@@ -343,7 +343,7 @@ func tokenize(input string) func() (*treeNode, error) {
consumeUntil := func(cutset string) (string, int) {
j := i
for ; j < len(runes); j++ {
- if strings.ContainsRune(cutset, runes[j]) {
+ if strings.IndexRune(cutset, runes[j]) >= 0 {
break
}
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go b/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go
index 63f7a9f6da..7b1524b52e 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/report_entry.go
@@ -9,18 +9,18 @@ import (
// ReportEntryValue wraps a report entry's value ensuring it can be encoded and decoded safely into reports
// and across the network connection when running in parallel
type ReportEntryValue struct {
- raw any //unexported to prevent gob from freaking out about unregistered structs
+ raw interface{} //unexported to prevent gob from freaking out about unregistered structs
AsJSON string
Representation string
}
-func WrapEntryValue(value any) ReportEntryValue {
+func WrapEntryValue(value interface{}) ReportEntryValue {
return ReportEntryValue{
raw: value,
}
}
-func (rev ReportEntryValue) GetRawValue() any {
+func (rev ReportEntryValue) GetRawValue() interface{} {
return rev.raw
}
@@ -118,7 +118,7 @@ func (entry ReportEntry) StringRepresentation() string {
// If used from a rehydrated JSON file _or_ in a ReportAfterSuite when running in parallel this will be
// a JSON-decoded {}interface. If you want to reconstitute your original object you can decode the entry.Value.AsJSON
// field yourself.
-func (entry ReportEntry) GetRawValue() any {
+func (entry ReportEntry) GetRawValue() interface{} {
return entry.Value.GetRawValue()
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go b/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go
deleted file mode 100644
index 71778078da..0000000000
--- a/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go
+++ /dev/null
@@ -1,121 +0,0 @@
-package types
-
-import (
- "fmt"
- "strings"
-
- "github.com/Masterminds/semver/v3"
-)
-
-type SemVerFilter func(component string, constraints []string) bool
-
-func MustParseSemVerFilter(input string) SemVerFilter {
- filter, err := ParseSemVerFilter(input)
- if err != nil {
- panic(err)
- }
- return filter
-}
-
-// ParseSemVerFilter parses non-component and component-specific semantic version filter string.
-// The filter string can contain multiple non-component and component-specific versions separated by commas.
-// Each component-specific version is in the format "component=version".
-// If a version is specified without a component, it applies to non-component-specific constraints.
-func ParseSemVerFilter(componentFilterVersions string) (SemVerFilter, error) {
- if componentFilterVersions == "" {
- return func(_ string, _ []string) bool { return true }, nil
- }
-
- result := map[string]*semver.Version{}
- parts := strings.Split(componentFilterVersions, ",")
- for _, part := range parts {
- part = strings.TrimSpace(part)
- if len(part) == 0 {
- continue
- }
- if strings.Contains(part, "=") {
- // validate component-specific version string
- invalidPart, invalidErr := false, fmt.Errorf("invalid component filter version: %s", part)
- subParts := strings.Split(part, "=")
- if len(subParts) != 2 {
- invalidPart = true
- }
- component := strings.TrimSpace(subParts[0])
- versionStr := strings.TrimSpace(subParts[1])
- if len(component) == 0 || len(versionStr) == 0 {
- invalidPart = true
- }
- if invalidPart {
- return nil, invalidErr
- }
-
- // validate semver
- v, err := semver.NewVersion(versionStr)
- if err != nil {
- return nil, fmt.Errorf("invalid component filter version: %s, error: %w", part, err)
- }
- result[component] = v
- } else {
- v, err := semver.NewVersion(part)
- if err != nil {
- return nil, fmt.Errorf("invalid filter version: %s, error: %w", part, err)
- }
- result[""] = v
- }
- }
-
- return func(component string, constraints []string) bool {
- // unconstrained specs always run
- if len(component) == 0 && len(constraints) == 0 {
- return true
- }
-
- // check non-component specific version constraints
- if len(component) == 0 && len(constraints) != 0 {
- v := result[""]
- if v != nil {
- for _, constraintStr := range constraints {
- constraint, err := semver.NewConstraint(constraintStr)
- if err != nil {
- return false
- }
-
- if !constraint.Check(v) {
- return false
- }
- }
- }
- }
-
- // check component-specific version constraints
- if len(component) != 0 && len(constraints) != 0 {
- v := result[component]
- if v != nil {
- for _, constraintStr := range constraints {
- constraint, err := semver.NewConstraint(constraintStr)
- if err != nil {
- return false
- }
-
- if !constraint.Check(v) {
- return false
- }
- }
- }
- }
-
- return true
- }, nil
-}
-
-func ValidateAndCleanupSemVerConstraint(semVerConstraint string, cl CodeLocation) (string, error) {
- if len(semVerConstraint) == 0 {
- return "", GinkgoErrors.InvalidEmptySemVerConstraint(cl)
- }
- _, err := semver.NewConstraint(semVerConstraint)
- if err != nil {
- return "", GinkgoErrors.InvalidSemVerConstraint(semVerConstraint, err.Error(), cl)
- }
-
- return semVerConstraint, nil
-}
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/types.go b/vendor/github.com/onsi/ginkgo/v2/types/types.go
index 2401505120..ddcbec1ba8 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/types.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/types.go
@@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"
"os"
- "slices"
"sort"
"strings"
"time"
@@ -20,61 +19,6 @@ func init() {
}
}
-// ConstructionNodeReport captures information about a Ginkgo spec.
-type ConstructionNodeReport struct {
- // ContainerHierarchyTexts is a slice containing the text strings of
- // all Describe/Context/When containers in this spec's hierarchy.
- ContainerHierarchyTexts []string
-
- // ContainerHierarchyLocations is a slice containing the CodeLocations of
- // all Describe/Context/When containers in this spec's hierarchy.
- ContainerHierarchyLocations []CodeLocation
-
- // ContainerHierarchyLabels is a slice containing the labels of
- // all Describe/Context/When containers in this spec's hierarchy
- ContainerHierarchyLabels [][]string
-
- // ContainerHierarchySemVerConstraints is a slice containing the semVerConstraints of
- // all Describe/Context/When containers in this spec's hierarchy
- ContainerHierarchySemVerConstraints [][]string
-
- // ContainerHierarchyComponentSemVerConstraints is a slice containing the component-specific semVerConstraints of
- // all Describe/Context/When containers in this spec's hierarchy
- ContainerHierarchyComponentSemVerConstraints []map[string][]string
-
- // IsSerial captures whether the any container has the Serial decorator
- IsSerial bool
-
- // IsInOrderedContainer captures whether any container is an Ordered container
- IsInOrderedContainer bool
-}
-
-// FullText returns a concatenation of all the report.ContainerHierarchyTexts and report.LeafNodeText
-func (report ConstructionNodeReport) FullText() string {
- texts := []string{}
- texts = append(texts, report.ContainerHierarchyTexts...)
- texts = slices.DeleteFunc(texts, func(t string) bool {
- return t == ""
- })
- return strings.Join(texts, " ")
-}
-
-// Labels returns a deduped set of all the spec's Labels.
-func (report ConstructionNodeReport) Labels() []string {
- out := []string{}
- seen := map[string]bool{}
- for _, labels := range report.ContainerHierarchyLabels {
- for _, label := range labels {
- if !seen[label] {
- seen[label] = true
- out = append(out, label)
- }
- }
- }
-
- return out
-}
-
// Report captures information about a Ginkgo test run
type Report struct {
//SuitePath captures the absolute path to the test suite
@@ -86,12 +30,6 @@ type Report struct {
//SuiteLabels captures any labels attached to the suite by the DSL's RunSpecs() function
SuiteLabels []string
- //SuiteSemVerConstraints captures any semVerConstraints attached to the suite by the DSL's RunSpecs() function
- SuiteSemVerConstraints []string
-
- //SuiteComponentSemVerConstraints captures any component-specific semVerConstraints attached to the suite by the DSL's RunSpecs() function
- SuiteComponentSemVerConstraints map[string][]string
-
//SuiteSucceeded captures the success or failure status of the test run
//If true, the test run is considered successful.
//If false, the test run is considered unsuccessful
@@ -191,26 +129,13 @@ type SpecReport struct {
// all Describe/Context/When containers in this spec's hierarchy
ContainerHierarchyLabels [][]string
- // ContainerHierarchySemVerConstraints is a slice containing the semVerConstraints of
- // all Describe/Context/When containers in this spec's hierarchy
- ContainerHierarchySemVerConstraints [][]string
-
- // ContainerHierarchyComponentSemVerConstraints is a slice containing the component-specific semVerConstraints of
- // all Describe/Context/When containers in this spec's hierarchy
- ContainerHierarchyComponentSemVerConstraints []map[string][]string
-
- // LeafNodeType, LeafNodeLocation, LeafNodeLabels, LeafNodeSemVerConstraints and LeafNodeText capture the NodeType, CodeLocation, and text
+ // LeafNodeType, LeadNodeLocation, LeafNodeLabels and LeafNodeText capture the NodeType, CodeLocation, and text
// of the Ginkgo node being tested (typically an NodeTypeIt node, though this can also be
// one of the NodeTypesForSuiteLevelNodes node types)
- LeafNodeType NodeType
- LeafNodeLocation CodeLocation
- LeafNodeLabels []string
- LeafNodeSemVerConstraints []string
- LeafNodeComponentSemVerConstraints map[string][]string
- LeafNodeText string
-
- // Captures the Spec Priority
- SpecPriority int
+ LeafNodeType NodeType
+ LeafNodeLocation CodeLocation
+ LeafNodeLabels []string
+ LeafNodeText string
// State captures whether the spec has passed, failed, etc.
State SpecState
@@ -273,54 +198,48 @@ type SpecReport struct {
func (report SpecReport) MarshalJSON() ([]byte, error) {
//All this to avoid emitting an empty Failure struct in the JSON
out := struct {
- ContainerHierarchyTexts []string
- ContainerHierarchyLocations []CodeLocation
- ContainerHierarchyLabels [][]string
- ContainerHierarchySemVerConstraints [][]string
- ContainerHierarchyComponentSemVerConstraints []map[string][]string
- LeafNodeType NodeType
- LeafNodeLocation CodeLocation
- LeafNodeLabels []string
- LeafNodeSemVerConstraints []string
- LeafNodeText string
- State SpecState
- StartTime time.Time
- EndTime time.Time
- RunTime time.Duration
- ParallelProcess int
- Failure *Failure `json:",omitempty"`
- NumAttempts int
- MaxFlakeAttempts int
- MaxMustPassRepeatedly int
- CapturedGinkgoWriterOutput string `json:",omitempty"`
- CapturedStdOutErr string `json:",omitempty"`
- ReportEntries ReportEntries `json:",omitempty"`
- ProgressReports []ProgressReport `json:",omitempty"`
- AdditionalFailures []AdditionalFailure `json:",omitempty"`
- SpecEvents SpecEvents `json:",omitempty"`
+ ContainerHierarchyTexts []string
+ ContainerHierarchyLocations []CodeLocation
+ ContainerHierarchyLabels [][]string
+ LeafNodeType NodeType
+ LeafNodeLocation CodeLocation
+ LeafNodeLabels []string
+ LeafNodeText string
+ State SpecState
+ StartTime time.Time
+ EndTime time.Time
+ RunTime time.Duration
+ ParallelProcess int
+ Failure *Failure `json:",omitempty"`
+ NumAttempts int
+ MaxFlakeAttempts int
+ MaxMustPassRepeatedly int
+ CapturedGinkgoWriterOutput string `json:",omitempty"`
+ CapturedStdOutErr string `json:",omitempty"`
+ ReportEntries ReportEntries `json:",omitempty"`
+ ProgressReports []ProgressReport `json:",omitempty"`
+ AdditionalFailures []AdditionalFailure `json:",omitempty"`
+ SpecEvents SpecEvents `json:",omitempty"`
}{
- ContainerHierarchyTexts: report.ContainerHierarchyTexts,
- ContainerHierarchyLocations: report.ContainerHierarchyLocations,
- ContainerHierarchyLabels: report.ContainerHierarchyLabels,
- ContainerHierarchySemVerConstraints: report.ContainerHierarchySemVerConstraints,
- ContainerHierarchyComponentSemVerConstraints: report.ContainerHierarchyComponentSemVerConstraints,
- LeafNodeType: report.LeafNodeType,
- LeafNodeLocation: report.LeafNodeLocation,
- LeafNodeLabels: report.LeafNodeLabels,
- LeafNodeSemVerConstraints: report.LeafNodeSemVerConstraints,
- LeafNodeText: report.LeafNodeText,
- State: report.State,
- StartTime: report.StartTime,
- EndTime: report.EndTime,
- RunTime: report.RunTime,
- ParallelProcess: report.ParallelProcess,
- Failure: nil,
- ReportEntries: nil,
- NumAttempts: report.NumAttempts,
- MaxFlakeAttempts: report.MaxFlakeAttempts,
- MaxMustPassRepeatedly: report.MaxMustPassRepeatedly,
- CapturedGinkgoWriterOutput: report.CapturedGinkgoWriterOutput,
- CapturedStdOutErr: report.CapturedStdOutErr,
+ ContainerHierarchyTexts: report.ContainerHierarchyTexts,
+ ContainerHierarchyLocations: report.ContainerHierarchyLocations,
+ ContainerHierarchyLabels: report.ContainerHierarchyLabels,
+ LeafNodeType: report.LeafNodeType,
+ LeafNodeLocation: report.LeafNodeLocation,
+ LeafNodeLabels: report.LeafNodeLabels,
+ LeafNodeText: report.LeafNodeText,
+ State: report.State,
+ StartTime: report.StartTime,
+ EndTime: report.EndTime,
+ RunTime: report.RunTime,
+ ParallelProcess: report.ParallelProcess,
+ Failure: nil,
+ ReportEntries: nil,
+ NumAttempts: report.NumAttempts,
+ MaxFlakeAttempts: report.MaxFlakeAttempts,
+ MaxMustPassRepeatedly: report.MaxMustPassRepeatedly,
+ CapturedGinkgoWriterOutput: report.CapturedGinkgoWriterOutput,
+ CapturedStdOutErr: report.CapturedStdOutErr,
}
if !report.Failure.IsZero() {
@@ -368,9 +287,6 @@ func (report SpecReport) FullText() string {
if report.LeafNodeText != "" {
texts = append(texts, report.LeafNodeText)
}
- texts = slices.DeleteFunc(texts, func(t string) bool {
- return t == ""
- })
return strings.Join(texts, " ")
}
@@ -396,56 +312,6 @@ func (report SpecReport) Labels() []string {
return out
}
-// SemVerConstraints returns a deduped set of all the spec's SemVerConstraints.
-func (report SpecReport) SemVerConstraints() []string {
- out := []string{}
- seen := map[string]bool{}
- for _, semVerConstraints := range report.ContainerHierarchySemVerConstraints {
- for _, semVerConstraint := range semVerConstraints {
- if !seen[semVerConstraint] {
- seen[semVerConstraint] = true
- out = append(out, semVerConstraint)
- }
- }
- }
- for _, semVerConstraint := range report.LeafNodeSemVerConstraints {
- if !seen[semVerConstraint] {
- seen[semVerConstraint] = true
- out = append(out, semVerConstraint)
- }
- }
-
- return out
-}
-
-// ComponentSemVerConstraints returns a deduped map of all the spec's component-specific SemVerConstraints.
-func (report SpecReport) ComponentSemVerConstraints() map[string][]string {
- out := map[string][]string{}
- seen := map[string]bool{}
- for _, compSemVerConstraints := range report.ContainerHierarchyComponentSemVerConstraints {
- for component := range compSemVerConstraints {
- if !seen[component] {
- seen[component] = true
- out[component] = compSemVerConstraints[component]
- } else {
- out[component] = append(out[component], compSemVerConstraints[component]...)
- out[component] = slices.Compact(out[component])
- }
- }
- }
- for component := range report.LeafNodeComponentSemVerConstraints {
- if !seen[component] {
- seen[component] = true
- out[component] = report.LeafNodeComponentSemVerConstraints[component]
- } else {
- out[component] = append(out[component], report.LeafNodeComponentSemVerConstraints[component]...)
- out[component] = slices.Compact(out[component])
- }
- }
-
- return out
-}
-
// MatchesLabelFilter returns true if the spec satisfies the passed in label filter query
func (report SpecReport) MatchesLabelFilter(query string) (bool, error) {
filter, err := ParseLabelFilter(query)
@@ -455,30 +321,6 @@ func (report SpecReport) MatchesLabelFilter(query string) (bool, error) {
return filter(report.Labels()), nil
}
-// MatchesSemVerFilter returns true if the spec satisfies the passed in label filter query
-func (report SpecReport) MatchesSemVerFilter(version string) (bool, error) {
- filter, err := ParseSemVerFilter(version)
- if err != nil {
- return false, err
- }
-
- semVerConstraints := report.SemVerConstraints()
- if len(semVerConstraints) != 0 && filter("", report.SemVerConstraints()) == false {
- return false, nil
- }
-
- componentSemVerConstraints := report.ComponentSemVerConstraints()
- if len(componentSemVerConstraints) != 0 {
- for component, constraints := range componentSemVerConstraints {
- if filter(component, constraints) == false {
- return false, nil
- }
- }
- }
-
- return true, nil
-}
-
// FileName() returns the name of the file containing the spec
func (report SpecReport) FileName() string {
return report.LeafNodeLocation.FileName
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/types_patch.go b/vendor/github.com/onsi/ginkgo/v2/types/types_patch.go
new file mode 100644
index 0000000000..02d319bba0
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/v2/types/types_patch.go
@@ -0,0 +1,8 @@
+package types
+
+type TestSpec interface {
+ CodeLocations() []CodeLocation
+ Text() string
+ AppendText(text string)
+ Labels() []string
+}
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go
index 1df09be005..caf3c9f5e7 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.1"
+const VERSION = "2.21.0"
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/LICENSE b/vendor/github.com/openshift-eng/openshift-tests-extension/LICENSE
new file mode 100644
index 0000000000..261eeb9e9f
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmd.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmd.go
new file mode 100644
index 0000000000..2db8cfa6ea
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmd.go
@@ -0,0 +1,23 @@
+package cmd
+
+import (
+ "github.com/spf13/cobra"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdimages"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdinfo"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdlist"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdupdate"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/extension"
+)
+
+func DefaultExtensionCommands(registry *extension.Registry) []*cobra.Command {
+ return []*cobra.Command{
+ cmdrun.NewRunSuiteCommand(registry),
+ cmdrun.NewRunTestCommand(registry),
+ cmdlist.NewListCommand(registry),
+ cmdinfo.NewInfoCommand(registry),
+ cmdupdate.NewUpdateCommand(registry),
+ cmdimages.NewImagesCommand(registry),
+ }
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdimages/cmdimages.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdimages/cmdimages.go
new file mode 100644
index 0000000000..33b458fac2
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdimages/cmdimages.go
@@ -0,0 +1,36 @@
+package cmdimages
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+
+ "github.com/spf13/cobra"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/extension"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/flags"
+)
+
+func NewImagesCommand(registry *extension.Registry) *cobra.Command {
+ componentFlags := flags.NewComponentFlags()
+
+ cmd := &cobra.Command{
+ Use: "images",
+ Short: "List test images",
+ SilenceUsage: true,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ extension := registry.Get(componentFlags.Component)
+ if extension == nil {
+ return fmt.Errorf("couldn't find the component %q", componentFlags.Component)
+ }
+ images, err := json.Marshal(extension.Images)
+ if err != nil {
+ return err
+ }
+ fmt.Fprintf(os.Stdout, "%s\n", images)
+ return nil
+ },
+ }
+ componentFlags.BindFlags(cmd.Flags())
+ return cmd
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdinfo/info.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdinfo/info.go
new file mode 100644
index 0000000000..1d4237876d
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdinfo/info.go
@@ -0,0 +1,38 @@
+package cmdinfo
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+
+ "github.com/spf13/cobra"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/extension"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/flags"
+)
+
+func NewInfoCommand(registry *extension.Registry) *cobra.Command {
+ componentFlags := flags.NewComponentFlags()
+
+ cmd := &cobra.Command{
+ Use: "info",
+ Short: "Display extension metadata",
+ SilenceUsage: true,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ extension := registry.Get(componentFlags.Component)
+ if extension == nil {
+ return fmt.Errorf("couldn't find the component %q", componentFlags.Component)
+ }
+
+ info, err := json.MarshalIndent(extension, "", " ")
+ if err != nil {
+ return err
+ }
+
+ fmt.Fprintf(os.Stdout, "%s\n", string(info))
+ return nil
+ },
+ }
+ componentFlags.BindFlags(cmd.Flags())
+ return cmd
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdlist/list.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdlist/list.go
new file mode 100644
index 0000000000..31a040b7c9
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdlist/list.go
@@ -0,0 +1,133 @@
+package cmdlist
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/spf13/cobra"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/extension"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/flags"
+)
+
+func NewListCommand(registry *extension.Registry) *cobra.Command {
+ opts := struct {
+ componentFlags *flags.ComponentFlags
+ suiteFlags *flags.SuiteFlags
+ outputFlags *flags.OutputFlags
+ environmentalFlags *flags.EnvironmentalFlags
+ }{
+ suiteFlags: flags.NewSuiteFlags(),
+ componentFlags: flags.NewComponentFlags(),
+ outputFlags: flags.NewOutputFlags(),
+ environmentalFlags: flags.NewEnvironmentalFlags(),
+ }
+
+ // Tests
+ listTestsCmd := &cobra.Command{
+ Use: "tests",
+ Short: "List available tests",
+ SilenceUsage: true,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ext := registry.Get(opts.componentFlags.Component)
+ if ext == nil {
+ return fmt.Errorf("component not found: %s", opts.componentFlags.Component)
+ }
+
+ // Find suite, if specified
+ var foundSuite *extension.Suite
+ var err error
+ if opts.suiteFlags.Suite != "" {
+ foundSuite, err = ext.GetSuite(opts.suiteFlags.Suite)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Filter for suite
+ specs := ext.GetSpecs()
+ if foundSuite != nil {
+ specs, err = specs.Filter(foundSuite.Qualifiers)
+ if err != nil {
+ return err
+ }
+ }
+
+ specs, err = specs.FilterByEnvironment(*opts.environmentalFlags)
+ if err != nil {
+ return err
+ }
+
+ data, err := opts.outputFlags.Marshal(specs)
+ if err != nil {
+ return err
+ }
+ fmt.Fprintf(os.Stdout, "%s\n", string(data))
+ return nil
+ },
+ }
+ opts.suiteFlags.BindFlags(listTestsCmd.Flags())
+ opts.componentFlags.BindFlags(listTestsCmd.Flags())
+ opts.environmentalFlags.BindFlags(listTestsCmd.Flags())
+ opts.outputFlags.BindFlags(listTestsCmd.Flags())
+
+ // Suites
+ listSuitesCommand := &cobra.Command{
+ Use: "suites",
+ Short: "List available suites",
+ SilenceUsage: true,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ext := registry.Get(opts.componentFlags.Component)
+ if ext == nil {
+ return fmt.Errorf("component not found: %s", opts.componentFlags.Component)
+ }
+
+ suites := ext.Suites
+
+ data, err := opts.outputFlags.Marshal(suites)
+ if err != nil {
+ return err
+ }
+ fmt.Fprintf(os.Stdout, "%s\n", string(data))
+ return nil
+ },
+ }
+ opts.componentFlags.BindFlags(listSuitesCommand.Flags())
+ opts.outputFlags.BindFlags(listSuitesCommand.Flags())
+
+ // Components
+ listComponentsCmd := &cobra.Command{
+ Use: "components",
+ Short: "List available components",
+ SilenceUsage: true,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ var components []*extension.Component
+ registry.Walk(func(e *extension.Extension) {
+ components = append(components, &e.Component)
+ })
+
+ data, err := opts.outputFlags.Marshal(components)
+ if err != nil {
+ return err
+ }
+ fmt.Fprintf(os.Stdout, "%s\n", string(data))
+ return nil
+ },
+ }
+ opts.outputFlags.BindFlags(listComponentsCmd.Flags())
+
+ var listCmd = &cobra.Command{
+ Use: "list [subcommand]",
+ Short: "List items",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return listTestsCmd.RunE(cmd, args)
+ },
+ }
+ opts.suiteFlags.BindFlags(listCmd.Flags())
+ opts.componentFlags.BindFlags(listCmd.Flags())
+ opts.outputFlags.BindFlags(listCmd.Flags())
+ opts.environmentalFlags.BindFlags(listCmd.Flags())
+ listCmd.AddCommand(listTestsCmd, listComponentsCmd, listSuitesCommand)
+
+ return listCmd
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runsuite.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runsuite.go
new file mode 100644
index 0000000000..a30b05e867
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runsuite.go
@@ -0,0 +1,161 @@
+package cmdrun
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "os"
+ "os/signal"
+ "path/filepath"
+ "syscall"
+ "time"
+
+ "github.com/spf13/cobra"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/extension"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/flags"
+)
+
+func NewRunSuiteCommand(registry *extension.Registry) *cobra.Command {
+ opts := struct {
+ componentFlags *flags.ComponentFlags
+ outputFlags *flags.OutputFlags
+ concurrencyFlags *flags.ConcurrencyFlags
+ junitPath string
+ htmlPath string
+ }{
+ componentFlags: flags.NewComponentFlags(),
+ outputFlags: flags.NewOutputFlags(),
+ concurrencyFlags: flags.NewConcurrencyFlags(),
+ junitPath: "",
+ htmlPath: "",
+ }
+
+ cmd := &cobra.Command{
+ Use: "run-suite NAME",
+ Short: "Run a group of tests by suite. This is more limited than origin, and intended for light local " +
+ "development use. Orchestration parameters, scheduling, isolation, etc are not obeyed, and Ginkgo tests are executed serially.",
+ SilenceUsage: true,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx, cancelCause := context.WithCancelCause(context.Background())
+ defer cancelCause(errors.New("exiting"))
+
+ abortCh := make(chan os.Signal, 2)
+ go func() {
+ <-abortCh
+ fmt.Fprintf(os.Stderr, "Interrupted, terminating tests")
+ cancelCause(errors.New("interrupt received"))
+
+ select {
+ case sig := <-abortCh:
+ fmt.Fprintf(os.Stderr, "Interrupted twice, exiting (%s)", sig)
+ switch sig {
+ case syscall.SIGINT:
+ os.Exit(130)
+ default:
+ os.Exit(130) // if we were interrupted, never return zero.
+ }
+
+ case <-time.After(30 * time.Minute): // allow time for cleanup. If we finish before this, we'll exit
+ fmt.Fprintf(os.Stderr, "Timed out during cleanup, exiting")
+ os.Exit(130) // if we were interrupted, never return zero.
+ }
+ }()
+ signal.Notify(abortCh, syscall.SIGINT, syscall.SIGTERM)
+
+ ext := registry.Get(opts.componentFlags.Component)
+ if ext == nil {
+ return fmt.Errorf("component not found: %s", opts.componentFlags.Component)
+ }
+ if len(args) != 1 {
+ return fmt.Errorf("must specify one suite name")
+ }
+ suite, err := ext.GetSuite(args[0])
+ if err != nil {
+ return fmt.Errorf("couldn't find suite %q: %w", args[0], err)
+ }
+
+ compositeWriter := extensiontests.NewCompositeResultWriter()
+ defer func() {
+ if err = compositeWriter.Flush(); err != nil {
+ fmt.Fprintf(os.Stderr, "failed to write results: %v\n", err)
+ }
+ }()
+
+ // JUnit writer if needed
+ if opts.junitPath != "" {
+ junitWriter, err := extensiontests.NewJUnitResultWriter(opts.junitPath, suite.Name)
+ if err != nil {
+ return fmt.Errorf("couldn't create junit writer: %w", err)
+ }
+ compositeWriter.AddWriter(junitWriter)
+ }
+ // HTML writer if needed
+ if opts.htmlPath != "" {
+ htmlWriter, err := extensiontests.NewHTMLResultWriter(opts.htmlPath, suite.Name)
+ if err != nil {
+ return fmt.Errorf("couldn't create html writer: %w", err)
+ }
+ compositeWriter.AddWriter(htmlWriter)
+ }
+
+ // JSON writer
+ jsonWriter, err := extensiontests.NewJSONResultWriter(os.Stdout,
+ extensiontests.ResultFormat(opts.outputFlags.Output))
+ if err != nil {
+ return err
+ }
+ compositeWriter.AddWriter(jsonWriter)
+
+ specs, err := ext.GetSpecs().Filter(suite.Qualifiers)
+ if err != nil {
+ return fmt.Errorf("couldn't filter specs: %w", err)
+ }
+
+ if suite.TestTimeout != nil {
+ for _, spec := range specs {
+ if spec.Timeout == 0 {
+ spec.Timeout = *suite.TestTimeout
+ }
+ }
+ }
+
+ concurrency := opts.concurrencyFlags.MaxConcurency
+ if suite.Parallelism > 0 {
+ concurrency = min(concurrency, suite.Parallelism)
+ }
+ results, runErr := specs.Run(ctx, compositeWriter, concurrency)
+ if opts.junitPath != "" {
+ // we want to commit the results to disk regardless of the success or failure of the specs
+ if err := writeResults(opts.junitPath, results); err != nil {
+ fmt.Fprintf(os.Stderr, "Failed to write test results to disk: %v\n", err)
+ }
+ }
+ return runErr
+ },
+ }
+ opts.componentFlags.BindFlags(cmd.Flags())
+ opts.outputFlags.BindFlags(cmd.Flags())
+ opts.concurrencyFlags.BindFlags(cmd.Flags())
+ cmd.Flags().StringVarP(&opts.junitPath, "junit-path", "j", opts.junitPath, "write results to junit XML")
+ cmd.Flags().StringVar(&opts.htmlPath, "html-path", opts.htmlPath, "write results to summary HTML")
+
+ return cmd
+}
+
+func writeResults(jUnitPath string, results []*extensiontests.ExtensionTestResult) error {
+ jUnitDir := filepath.Dir(jUnitPath)
+ if err := os.MkdirAll(jUnitDir, 0755); err != nil {
+ return fmt.Errorf("failed to create output directory: %v", err)
+ }
+
+ encodedResults, err := json.MarshalIndent(results, "", " ")
+ if err != nil {
+ return fmt.Errorf("failed to marshal results: %v", err)
+ }
+
+ outputPath := filepath.Join(jUnitDir, fmt.Sprintf("extension_test_result_e2e_%s.json", time.Now().UTC().Format("20060102-150405")))
+ return os.WriteFile(outputPath, encodedResults, 0644)
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runtest.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runtest.go
new file mode 100644
index 0000000000..86e10e02e2
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun/runtest.go
@@ -0,0 +1,120 @@
+package cmdrun
+
+import (
+ "bufio"
+ "context"
+ "errors"
+ "fmt"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+
+ "github.com/spf13/cobra"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/extension"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/flags"
+)
+
+func NewRunTestCommand(registry *extension.Registry) *cobra.Command {
+ opts := struct {
+ componentFlags *flags.ComponentFlags
+ concurrencyFlags *flags.ConcurrencyFlags
+ nameFlags *flags.NamesFlags
+ outputFlags *flags.OutputFlags
+ timeout time.Duration
+ }{
+ componentFlags: flags.NewComponentFlags(),
+ nameFlags: flags.NewNamesFlags(),
+ outputFlags: flags.NewOutputFlags(),
+ concurrencyFlags: flags.NewConcurrencyFlags(),
+ }
+
+ cmd := &cobra.Command{
+ Use: "run-test [-n NAME...] [NAME]",
+ Short: "Runs tests by name",
+ SilenceUsage: true,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx, cancelCause := context.WithCancelCause(context.Background())
+ defer cancelCause(errors.New("exiting"))
+ if opts.timeout > 0 {
+ var cancel context.CancelFunc
+ ctx, cancel = context.WithTimeout(ctx, opts.timeout)
+ defer cancel()
+ }
+
+ abortCh := make(chan os.Signal, 2)
+ go func() {
+ <-abortCh
+ fmt.Fprintf(os.Stderr, "Interrupted, terminating tests")
+ cancelCause(errors.New("interrupt received"))
+
+ select {
+ case sig := <-abortCh:
+ fmt.Fprintf(os.Stderr, "Interrupted twice, exiting (%s)", sig)
+ switch sig {
+ case syscall.SIGINT:
+ os.Exit(130)
+ default:
+ os.Exit(130) // if we were interrupted, never return zero.
+ }
+
+ case <-time.After(30 * time.Minute): // allow time for cleanup. If we finish before this, we'll exit
+ fmt.Fprintf(os.Stderr, "Timed out during cleanup, exiting")
+ os.Exit(130) // if we were interrupted, never return zero.
+ }
+ }()
+ signal.Notify(abortCh, syscall.SIGINT, syscall.SIGTERM)
+
+ ext := registry.Get(opts.componentFlags.Component)
+ if ext == nil {
+ return fmt.Errorf("component not found: %s", opts.componentFlags.Component)
+ }
+ if len(args) > 1 {
+ return fmt.Errorf("use --names to specify more than one test")
+ }
+ opts.nameFlags.Names = append(opts.nameFlags.Names, args...)
+
+ // allow reading tests from an stdin pipe
+ info, err := os.Stdin.Stat()
+ if err != nil {
+ return err
+ }
+ if info.Mode()&os.ModeCharDevice == 0 { // Check if input is from a pipe
+ scanner := bufio.NewScanner(os.Stdin)
+ for scanner.Scan() {
+ opts.nameFlags.Names = append(opts.nameFlags.Names, scanner.Text())
+ }
+ if err := scanner.Err(); err != nil {
+ return fmt.Errorf("error reading from stdin: %v", err)
+ }
+ }
+
+ if len(opts.nameFlags.Names) == 0 {
+ return fmt.Errorf("must specify at least one test")
+ }
+
+ specs, err := ext.FindSpecsByName(opts.nameFlags.Names...)
+ if err != nil {
+ return err
+ }
+
+ w, err := extensiontests.NewJSONResultWriter(os.Stdout, extensiontests.ResultFormat(opts.outputFlags.Output))
+ if err != nil {
+ return err
+ }
+ defer w.Flush()
+
+ _, err = specs.Run(ctx, w, opts.concurrencyFlags.MaxConcurency)
+ return err
+ },
+ }
+ cmd.Flags().DurationVar(&opts.timeout, "timeout", 0, "Maximum duration for the test. When set, the test context will have a deadline, causing blocking operations like PollUntilDone to fail cleanly instead of hanging until the parent kills the process.")
+ opts.componentFlags.BindFlags(cmd.Flags())
+ opts.nameFlags.BindFlags(cmd.Flags())
+ opts.outputFlags.BindFlags(cmd.Flags())
+ opts.concurrencyFlags.BindFlags(cmd.Flags())
+
+ return cmd
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdupdate/update.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdupdate/update.go
new file mode 100644
index 0000000000..5d847308e5
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdupdate/update.go
@@ -0,0 +1,84 @@
+package cmdupdate
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/spf13/cobra"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/extension"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/flags"
+)
+
+const metadataDirectory = ".openshift-tests-extension"
+
+// NewUpdateCommand adds an "update" command used to generate and verify the metadata we keep track of. This should
+// be a black box to end users, i.e. we can add more criteria later they'll consume when revendoring. For now,
+// we prevent a test to be renamed without updating other names, or a test to be deleted.
+func NewUpdateCommand(registry *extension.Registry) *cobra.Command {
+ componentFlags := flags.NewComponentFlags()
+
+ cmd := &cobra.Command{
+ Use: "update",
+ Short: "Update test metadata",
+ SilenceUsage: true,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ext := registry.Get(componentFlags.Component)
+ if ext == nil {
+ return fmt.Errorf("couldn't find the component %q", componentFlags.Component)
+ }
+
+ // Create the metadata directory if it doesn't exist
+ if err := os.MkdirAll(metadataDirectory, 0755); err != nil {
+ return fmt.Errorf("failed to create directory %s: %w", metadataDirectory, err)
+ }
+
+ // Read existing specs
+ metadataPath := filepath.Join(metadataDirectory, fmt.Sprintf("%s.json", strings.ReplaceAll(ext.Component.Identifier(), ":", "_")))
+ var oldSpecs extensiontests.ExtensionTestSpecs
+ source, err := os.Open(metadataPath)
+ if err != nil {
+ if !os.IsNotExist(err) {
+ return fmt.Errorf("failed to open file: %s: %+w", metadataPath, err)
+ }
+ } else {
+ if err := json.NewDecoder(source).Decode(&oldSpecs); err != nil {
+ return fmt.Errorf("failed to decode file: %s: %+w", metadataPath, err)
+ }
+
+ missing, err := ext.FindRemovedTestsWithoutRename(oldSpecs)
+ if err != nil && len(missing) > 0 {
+ fmt.Fprintf(os.Stderr, "Missing Tests:\n")
+ for _, name := range missing {
+ fmt.Fprintf(os.Stdout, " * %s\n", name)
+ }
+ fmt.Fprintf(os.Stderr, "\n")
+
+ return fmt.Errorf("missing tests, if you've renamed tests you must add their names to OriginalName, " +
+ "or mark them obsolete")
+ }
+ }
+
+ // no missing tests, write the results
+ newSpecs := ext.GetSpecs()
+ data, err := json.MarshalIndent(newSpecs, "", " ")
+ if err != nil {
+ return fmt.Errorf("failed to marshal specs to JSON: %w", err)
+ }
+
+ // Write the JSON data to the file
+ if err := os.WriteFile(metadataPath, data, 0644); err != nil {
+ return fmt.Errorf("failed to write file %s: %w", metadataPath, err)
+ }
+
+ fmt.Printf("successfully updated metadata\n")
+ return nil
+ },
+ }
+ componentFlags.BindFlags(cmd.Flags())
+ return cmd
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/dbtime/time.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/dbtime/time.go
new file mode 100644
index 0000000000..b7651ba022
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/dbtime/time.go
@@ -0,0 +1,26 @@
+package dbtime
+
+import "time"
+
+// DBTime is a type suitable for direct importing into databases like BigQuery,
+// formatted like 2006-01-02 15:04:05.000000 UTC.
+type DBTime time.Time
+
+func Ptr(t time.Time) *DBTime {
+ return (*DBTime)(&t)
+}
+
+func (dbt *DBTime) MarshalJSON() ([]byte, error) {
+ formattedTime := time.Time(*dbt).Format(`"2006-01-02 15:04:05.000000 UTC"`)
+ return []byte(formattedTime), nil
+}
+
+func (dbt *DBTime) UnmarshalJSON(b []byte) error {
+ timeStr := string(b[1 : len(b)-1])
+ parsedTime, err := time.Parse("2006-01-02 15:04:05.000000 UTC", timeStr)
+ if err != nil {
+ return err
+ }
+ *dbt = (DBTime)(parsedTime)
+ return nil
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extension.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extension.go
new file mode 100644
index 0000000000..b9fbfb2ece
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extension.go
@@ -0,0 +1,165 @@
+package extension
+
+import (
+ "fmt"
+ "strings"
+
+ et "github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/util/sets"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/version"
+)
+
+func NewExtension(product, kind, name string) *Extension {
+ return &Extension{
+ APIVersion: CurrentExtensionAPIVersion,
+ Source: Source{
+ Commit: version.CommitFromGit,
+ BuildDate: version.BuildDate,
+ GitTreeState: version.GitTreeState,
+ },
+ Component: Component{
+ Product: product,
+ Kind: kind,
+ Name: name,
+ },
+ }
+}
+
+func (e *Extension) GetSuite(name string) (*Suite, error) {
+ var suite *Suite
+
+ for _, s := range e.Suites {
+ if s.Name == name {
+ suite = &s
+ break
+ }
+ }
+
+ if suite == nil {
+ return nil, fmt.Errorf("no such suite: %s", name)
+ }
+
+ return suite, nil
+}
+
+func (e *Extension) GetSpecs() et.ExtensionTestSpecs {
+ return e.specs
+}
+
+func (e *Extension) AddSpecs(specs et.ExtensionTestSpecs) {
+ specs.Walk(func(spec *et.ExtensionTestSpec) {
+ spec.Source = e.Component.Identifier()
+ })
+
+ e.specs = append(e.specs, specs...)
+}
+
+// IgnoreObsoleteTests allows removal of a test.
+func (e *Extension) IgnoreObsoleteTests(testNames ...string) {
+ if e.obsoleteTests == nil {
+ e.obsoleteTests = sets.New[string](testNames...)
+ } else {
+ e.obsoleteTests.Insert(testNames...)
+ }
+}
+
+// FindRemovedTestsWithoutRename compares the current set of test specs against oldSpecs, including consideration of the original name,
+// we return an error. Can be used to detect test renames or removals.
+func (e *Extension) FindRemovedTestsWithoutRename(oldSpecs et.ExtensionTestSpecs) ([]string, error) {
+ currentSpecs := e.GetSpecs()
+ currentMap := make(map[string]bool)
+
+ // Populate current specs into a map for quick lookup by both Name and OriginalName.
+ for _, spec := range currentSpecs {
+ currentMap[spec.Name] = true
+ if spec.OriginalName != "" {
+ currentMap[spec.OriginalName] = true
+ }
+ }
+
+ var removedTests []string
+
+ // Check oldSpecs against current specs.
+ for _, oldSpec := range oldSpecs {
+ // Skip if the test is marked as obsolete.
+ if e.obsoleteTests.Has(oldSpec.Name) {
+ continue
+ }
+
+ // Check if oldSpec is missing in currentSpecs by both Name and OriginalName.
+ if !currentMap[oldSpec.Name] && (oldSpec.OriginalName == "" || !currentMap[oldSpec.OriginalName]) {
+ removedTests = append(removedTests, oldSpec.Name)
+ }
+ }
+
+ // Return error if any removed tests were found.
+ if len(removedTests) > 0 {
+ return removedTests, fmt.Errorf("tests removed without rename: %v", removedTests)
+ }
+
+ return nil, nil
+}
+
+// AddGlobalSuite adds a suite whose qualifiers will apply to all tests,
+// not just this one. Allowing a developer to create a composed suite of
+// tests from many sources.
+func (e *Extension) AddGlobalSuite(suite Suite) *Extension {
+ if e.Suites == nil {
+ e.Suites = []Suite{suite}
+ } else {
+ e.Suites = append(e.Suites, suite)
+ }
+
+ return e
+}
+
+// AddSuite adds a suite whose qualifiers will only apply to tests present
+// in its own extension.
+func (e *Extension) AddSuite(suite Suite) *Extension {
+ expr := fmt.Sprintf("source == %q", e.Component.Identifier())
+ if len(suite.Qualifiers) == 0 {
+ suite.Qualifiers = []string{expr}
+ } else {
+ for i := range suite.Qualifiers {
+ suite.Qualifiers[i] = fmt.Sprintf("(%s) && (%s)",
+ expr, suite.Qualifiers[i])
+ }
+ }
+
+ e.AddGlobalSuite(suite)
+ return e
+}
+
+func (e *Extension) RegisterImage(image Image) *Extension {
+ e.Images = append(e.Images, image)
+ return e
+}
+
+func (e *Extension) FindSpecsByName(names ...string) (et.ExtensionTestSpecs, error) {
+ var specs et.ExtensionTestSpecs
+ var notFound []string
+
+ for _, name := range names {
+ found := false
+ for i := range e.specs {
+ if e.specs[i].Name == name {
+ specs = append(specs, e.specs[i])
+ found = true
+ break
+ }
+ }
+ if !found {
+ notFound = append(notFound, name)
+ }
+ }
+
+ if len(notFound) > 0 {
+ return nil, fmt.Errorf("no such tests: %s", strings.Join(notFound, ", "))
+ }
+
+ return specs, nil
+}
+
+func (e *Component) Identifier() string {
+ return fmt.Sprintf("%s:%s:%s", e.Product, e.Kind, e.Name)
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/environment.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/environment.go
new file mode 100644
index 0000000000..b5116a5359
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/environment.go
@@ -0,0 +1,92 @@
+package extensiontests
+
+import (
+ "fmt"
+ "strings"
+)
+
+func PlatformEquals(platform string) string {
+ return fmt.Sprintf(`platform=="%s"`, platform)
+}
+
+func NetworkEquals(network string) string {
+ return fmt.Sprintf(`network=="%s"`, network)
+}
+
+func NetworkStackEquals(networkStack string) string {
+ return fmt.Sprintf(`networkStack=="%s"`, networkStack)
+}
+
+func UpgradeEquals(upgrade string) string {
+ return fmt.Sprintf(`upgrade=="%s"`, upgrade)
+}
+
+func TopologyEquals(topology string) string {
+ return fmt.Sprintf(`topology=="%s"`, topology)
+}
+
+func ArchitectureEquals(arch string) string {
+ return fmt.Sprintf(`architecture=="%s"`, arch)
+}
+
+func APIGroupEnabled(apiGroup string) string {
+ return fmt.Sprintf(`apiGroups.exists(api, api=="%s")`, apiGroup)
+}
+
+func APIGroupDisabled(apiGroup string) string {
+ return fmt.Sprintf(`!apiGroups.exists(api, api=="%s")`, apiGroup)
+}
+
+func FeatureGateEnabled(featureGate string) string {
+ return fmt.Sprintf(`featureGates.exists(fg, fg=="%s")`, featureGate)
+}
+
+func FeatureGateDisabled(featureGate string) string {
+ return fmt.Sprintf(`!featureGates.exists(fg, fg=="%s")`, featureGate)
+}
+
+func ExternalConnectivityEquals(externalConnectivity string) string {
+ return fmt.Sprintf(`externalConnectivity=="%s"`, externalConnectivity)
+}
+
+func OptionalCapabilitiesIncludeAny(optionalCapability ...string) string {
+ for i := range optionalCapability {
+ optionalCapability[i] = OptionalCapabilityExists(optionalCapability[i])
+ }
+ return fmt.Sprintf("(%s)", fmt.Sprint(strings.Join(optionalCapability, " || ")))
+}
+
+func OptionalCapabilitiesIncludeAll(optionalCapability ...string) string {
+ for i := range optionalCapability {
+ optionalCapability[i] = OptionalCapabilityExists(optionalCapability[i])
+ }
+ return fmt.Sprintf("(%s)", fmt.Sprint(strings.Join(optionalCapability, " && ")))
+}
+
+func OptionalCapabilityExists(optionalCapability string) string {
+ return fmt.Sprintf(`optionalCapabilities.exists(oc, oc=="%s")`, optionalCapability)
+}
+
+func NoOptionalCapabilitiesExist() string {
+ return "size(optionalCapabilities) == 0"
+}
+
+func InstallerEquals(installer string) string {
+ return fmt.Sprintf(`installer=="%s"`, installer)
+}
+
+func VersionEquals(version string) string {
+ return fmt.Sprintf(`version=="%s"`, version)
+}
+
+func FactEquals(key, value string) string {
+ return fmt.Sprintf(`(fact_keys.exists(k, k=="%s") && facts["%s"].matches("%s"))`, key, key, value)
+}
+
+func Or(cel ...string) string {
+ return fmt.Sprintf("(%s)", strings.Join(cel, " || "))
+}
+
+func And(cel ...string) string {
+ return fmt.Sprintf("(%s)", strings.Join(cel, " && "))
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/result.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/result.go
new file mode 100644
index 0000000000..9c03a0a84b
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/result.go
@@ -0,0 +1,125 @@
+package extensiontests
+
+import (
+ "bytes"
+ _ "embed"
+ "encoding/json"
+ "fmt"
+ "strings"
+ "text/template"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/junit"
+)
+
+func (results ExtensionTestResults) Walk(walkFn func(*ExtensionTestResult)) {
+ for i := range results {
+ walkFn(results[i])
+ }
+}
+
+// AddDetails adds additional information to an ExtensionTestResult. Value must marshal to JSON.
+func (result *ExtensionTestResult) AddDetails(name string, value interface{}) {
+ result.Details = append(result.Details, Details{Name: name, Value: value})
+}
+
+func (result ExtensionTestResult) ToJUnit() *junit.TestCase {
+ tc := &junit.TestCase{
+ Name: result.Name,
+ Duration: float64(result.Duration) / 1000.0,
+ }
+ switch result.Result {
+ case ResultFailed:
+ tc.FailureOutput = &junit.FailureOutput{
+ Message: result.Error,
+ Output: result.Error,
+ }
+ case ResultSkipped:
+ messages := []string{}
+ for _, detail := range result.Details {
+ messages = append(messages, fmt.Sprintf("%s: %s", detail.Name, detail.Value))
+ }
+ tc.SkipMessage = &junit.SkipMessage{
+ Message: strings.Join(messages, "\n"),
+ }
+ case ResultPassed:
+ tc.SystemOut = result.Output
+ }
+
+ return tc
+}
+
+func (results ExtensionTestResults) ToJUnit(suiteName string) junit.TestSuite {
+ suite := junit.TestSuite{
+ Name: suiteName,
+ }
+
+ results.Walk(func(result *ExtensionTestResult) {
+ suite.NumTests++
+ switch result.Result {
+ case ResultFailed:
+ suite.NumFailed++
+ case ResultSkipped:
+ suite.NumSkipped++
+ case ResultPassed:
+ // do nothing
+ default:
+ panic(fmt.Sprintf("unknown result type: %s", result.Result))
+ }
+
+ suite.TestCases = append(suite.TestCases, result.ToJUnit())
+ })
+
+ return suite
+}
+
+//go:embed viewer.html
+var viewerHtml []byte
+
+// RenderResultsHTML renders the HTML viewer template with the provided JSON data.
+// The caller is responsible for marshaling their results to JSON. This allows
+// callers with different result struct types to use the same HTML viewer.
+func RenderResultsHTML(jsonData []byte, suiteName string) ([]byte, error) {
+ tmpl, err := template.New("viewer").Parse(string(viewerHtml))
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse template: %w", err)
+ }
+ var out bytes.Buffer
+ if err := tmpl.Execute(&out, struct {
+ Data string
+ SuiteName string
+ }{
+ string(jsonData),
+ suiteName,
+ }); err != nil {
+ return nil, fmt.Errorf("failed to execute template: %w", err)
+ }
+ return out.Bytes(), nil
+}
+
+func (results ExtensionTestResults) ToHTML(suiteName string) ([]byte, error) {
+ encoded, err := json.Marshal(results)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal extension test results: %w", err)
+ }
+ // pare down the output if there's a lot, we want this to load in some reasonable amount of time
+ if len(encoded) > 2<<20 {
+ // n.b. this is wasteful, but we want to mutate our inputs in a safe manner, so the encode/decode/encode
+ // pass is useful as a deep copy
+ var copiedResults ExtensionTestResults
+ if err := json.Unmarshal(encoded, &copiedResults); err != nil {
+ return nil, fmt.Errorf("failed to unmarshal extension test results: %w", err)
+ }
+ copiedResults.Walk(func(result *ExtensionTestResult) {
+ if result.Result == ResultPassed {
+ result.Error = ""
+ result.Output = ""
+ result.Details = nil
+ }
+ })
+ encoded, err = json.Marshal(copiedResults)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal extension test results: %w", err)
+ }
+ }
+ return RenderResultsHTML(encoded, suiteName)
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/result_writer.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/result_writer.go
new file mode 100644
index 0000000000..f9ca434cad
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/result_writer.go
@@ -0,0 +1,213 @@
+package extensiontests
+
+import (
+ "encoding/json"
+ "encoding/xml"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "sync"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/junit"
+)
+
+type ResultWriter interface {
+ Write(result *ExtensionTestResult)
+ Flush() error
+}
+
+type NullResultWriter struct{}
+
+func (NullResultWriter) Write(*ExtensionTestResult) {}
+func (NullResultWriter) Flush() error { return nil }
+
+type CompositeResultWriter struct {
+ writers []ResultWriter
+}
+
+func NewCompositeResultWriter(writers ...ResultWriter) *CompositeResultWriter {
+ return &CompositeResultWriter{
+ writers: writers,
+ }
+}
+
+func (w *CompositeResultWriter) AddWriter(writer ResultWriter) {
+ w.writers = append(w.writers, writer)
+}
+
+func (w *CompositeResultWriter) Write(res *ExtensionTestResult) {
+ for _, writer := range w.writers {
+ writer.Write(res)
+ }
+}
+
+func (w *CompositeResultWriter) Flush() error {
+ var errs []error
+ for _, writer := range w.writers {
+ if err := writer.Flush(); err != nil {
+ errs = append(errs, err)
+ }
+ }
+
+ return errors.Join(errs...)
+}
+
+type JUnitResultWriter struct {
+ lock sync.Mutex
+ testSuite *junit.TestSuite
+ out *os.File
+ suiteName string
+ path string
+ results ExtensionTestResults
+}
+
+func NewJUnitResultWriter(path, suiteName string) (ResultWriter, error) {
+ file, err := os.Create(path)
+ if err != nil {
+ return nil, err
+ }
+
+ return &JUnitResultWriter{
+ testSuite: &junit.TestSuite{
+ Name: suiteName,
+ },
+ out: file,
+ suiteName: suiteName,
+ path: path,
+ }, nil
+}
+
+func (w *JUnitResultWriter) Write(res *ExtensionTestResult) {
+ w.lock.Lock()
+ defer w.lock.Unlock()
+ w.results = append(w.results, res)
+}
+
+func (w *JUnitResultWriter) Flush() error {
+ w.lock.Lock()
+ defer w.lock.Unlock()
+ data, err := xml.MarshalIndent(w.results.ToJUnit(w.suiteName), "", " ")
+ if err != nil {
+ return fmt.Errorf("failed to marshal JUnit XML: %w", err)
+ }
+ if _, err := w.out.Write(data); err != nil {
+ return err
+ }
+ if err := w.out.Close(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+type ResultFormat string
+
+var (
+ JSON ResultFormat = "json"
+ JSONL ResultFormat = "jsonl"
+)
+
+type JSONResultWriter struct {
+ lock sync.Mutex
+ out io.Writer
+ format ResultFormat
+ results ExtensionTestResults
+}
+
+func NewJSONResultWriter(out io.Writer, format ResultFormat) (*JSONResultWriter, error) {
+ switch format {
+ case JSON, JSONL:
+ // do nothing
+ default:
+ return nil, fmt.Errorf("unsupported result format: %s", format)
+ }
+
+ return &JSONResultWriter{
+ out: out,
+ format: format,
+ results: ExtensionTestResults{},
+ }, nil
+}
+
+func (w *JSONResultWriter) Write(result *ExtensionTestResult) {
+ w.lock.Lock()
+ defer w.lock.Unlock()
+ switch w.format {
+ case JSONL:
+ // JSONL gets written to out as we get the items
+ data, err := json.Marshal(result)
+ if err != nil {
+ panic(err)
+ }
+ fmt.Fprintf(w.out, "%s\n", string(data))
+ case JSON:
+ w.results = append(w.results, result)
+ }
+}
+
+func (w *JSONResultWriter) Flush() error {
+ w.lock.Lock()
+ defer w.lock.Unlock()
+ switch w.format {
+ case JSONL:
+ // we already wrote it out
+ case JSON:
+ data, err := json.MarshalIndent(w.results, "", " ")
+ if err != nil {
+ return err
+ }
+ _, err = w.out.Write(data)
+ return err
+ }
+
+ return nil
+}
+
+type HTMLResultWriter struct {
+ lock sync.Mutex
+ testSuite *junit.TestSuite
+ out *os.File
+ suiteName string
+ path string
+ results ExtensionTestResults
+}
+
+func NewHTMLResultWriter(path, suiteName string) (ResultWriter, error) {
+ file, err := os.Create(path)
+ if err != nil {
+ return nil, err
+ }
+
+ return &HTMLResultWriter{
+ testSuite: &junit.TestSuite{
+ Name: suiteName,
+ },
+ out: file,
+ suiteName: suiteName,
+ path: path,
+ }, nil
+}
+
+func (w *HTMLResultWriter) Write(res *ExtensionTestResult) {
+ w.lock.Lock()
+ defer w.lock.Unlock()
+ w.results = append(w.results, res)
+}
+
+func (w *HTMLResultWriter) Flush() error {
+ w.lock.Lock()
+ defer w.lock.Unlock()
+ data, err := w.results.ToHTML(w.suiteName)
+ if err != nil {
+ return fmt.Errorf("failed to create result HTML: %w", err)
+ }
+ if _, err := w.out.Write(data); err != nil {
+ return err
+ }
+ if err := w.out.Close(); err != nil {
+ return err
+ }
+
+ return nil
+}
\ No newline at end of file
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/spec.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/spec.go
new file mode 100644
index 0000000000..e87809c8a2
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/spec.go
@@ -0,0 +1,621 @@
+package extensiontests
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/google/cel-go/cel"
+ "github.com/google/cel-go/checker/decls"
+ "github.com/google/cel-go/common/types"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/dbtime"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/flags"
+)
+
+// Walk iterates over all test specs, and executions the function provided. The test spec can be mutated.
+func (specs ExtensionTestSpecs) Walk(walkFn func(*ExtensionTestSpec)) ExtensionTestSpecs {
+ for i := range specs {
+ walkFn(specs[i])
+ }
+
+ return specs
+}
+
+type SelectFunction func(spec *ExtensionTestSpec) bool
+
+// Select filters the ExtensionTestSpecs to only those that match the provided SelectFunction
+func (specs ExtensionTestSpecs) Select(selectFn SelectFunction) ExtensionTestSpecs {
+ filtered := ExtensionTestSpecs{}
+ for _, spec := range specs {
+ if selectFn(spec) {
+ filtered = append(filtered, spec)
+ }
+ }
+
+ return filtered
+}
+
+// MustSelect filters the ExtensionTestSpecs to only those that match the provided SelectFunction.
+// if no specs are selected, it will throw an error
+func (specs ExtensionTestSpecs) MustSelect(selectFn SelectFunction) (ExtensionTestSpecs, error) {
+ filtered := specs.Select(selectFn)
+ if len(filtered) == 0 {
+ return filtered, fmt.Errorf("no specs selected with specified SelectFunctions")
+ }
+
+ return filtered, nil
+}
+
+// SelectAny filters the ExtensionTestSpecs to only those that match any of the provided SelectFunctions
+func (specs ExtensionTestSpecs) SelectAny(selectFns []SelectFunction) ExtensionTestSpecs {
+ filtered := ExtensionTestSpecs{}
+ for _, spec := range specs {
+ for _, selectFn := range selectFns {
+ if selectFn(spec) {
+ filtered = append(filtered, spec)
+ break
+ }
+ }
+ }
+
+ return filtered
+}
+
+// MustSelectAny filters the ExtensionTestSpecs to only those that match any of the provided SelectFunctions.
+// if no specs are selected, it will throw an error
+func (specs ExtensionTestSpecs) MustSelectAny(selectFns []SelectFunction) (ExtensionTestSpecs, error) {
+ filtered := specs.SelectAny(selectFns)
+ if len(filtered) == 0 {
+ return filtered, fmt.Errorf("no specs selected with specified SelectFunctions")
+ }
+
+ return filtered, nil
+}
+
+// SelectAll filters the ExtensionTestSpecs to only those that match all the provided SelectFunctions
+func (specs ExtensionTestSpecs) SelectAll(selectFns []SelectFunction) ExtensionTestSpecs {
+ filtered := ExtensionTestSpecs{}
+ for _, spec := range specs {
+ anyFalse := false
+ for _, selectFn := range selectFns {
+ if !selectFn(spec) {
+ anyFalse = true
+ break
+ }
+ }
+ if !anyFalse {
+ filtered = append(filtered, spec)
+ }
+ }
+
+ return filtered
+}
+
+// MustSelectAll filters the ExtensionTestSpecs to only those that match all the provided SelectFunctions.
+// if no specs are selected, it will throw an error
+func (specs ExtensionTestSpecs) MustSelectAll(selectFns []SelectFunction) (ExtensionTestSpecs, error) {
+ filtered := specs.SelectAll(selectFns)
+ if len(filtered) == 0 {
+ return filtered, fmt.Errorf("no specs selected with specified SelectFunctions")
+ }
+
+ return filtered, nil
+}
+
+// ModuleTestsOnly ensures that ginkgo tests from vendored sources aren't selected. Unfortunately, making
+// use of kubernetes test helpers results in the entire Ginkgo suite being initialized (ginkgo loves global state),
+// so we need to be careful about which tests we select.
+//
+// A test is excluded if ALL of its code locations with full paths are external (vendored or from external test
+// suites). If at least one code location with a full path is from the local module, the test is included, because
+// local tests may legitimately call helper functions from vendored test frameworks.
+func ModuleTestsOnly() SelectFunction {
+ return func(spec *ExtensionTestSpec) bool {
+ hasLocalCode := false
+
+ for _, cl := range spec.CodeLocations {
+ // Short-form code locations (e.g., "set up framework | framework.go:200") are ignored in this determination.
+ if !strings.Contains(cl, "/") {
+ continue
+ }
+
+ // If this code location is not external (vendored or k8s test), it's local code
+ if !(strings.Contains(cl, "/vendor/") || strings.HasPrefix(cl, "k8s.io/kubernetes")) {
+ hasLocalCode = true
+ break
+ }
+ }
+
+ // Include the test only if it has at least one local code location
+ return hasLocalCode
+ }
+}
+
+// AllTestsIncludingVendored is an alternative to ModuleTestsOnly, which would explicitly opt-in
+// to including vendored tests.
+func AllTestsIncludingVendored() SelectFunction {
+ return func(spec *ExtensionTestSpec) bool {
+ return true
+ }
+}
+
+// NameContains returns a function that selects specs whose name contains the provided string
+func NameContains(name string) SelectFunction {
+ return func(spec *ExtensionTestSpec) bool {
+ return strings.Contains(spec.Name, name)
+ }
+}
+
+// NameContainsAll returns a function that selects specs whose name contains each of the provided contents strings
+func NameContainsAll(contents ...string) SelectFunction {
+ return func(spec *ExtensionTestSpec) bool {
+ for _, content := range contents {
+ if !strings.Contains(spec.Name, content) {
+ return false
+ }
+ }
+ return true
+ }
+}
+
+// HasLabel returns a function that selects specs with the provided label
+func HasLabel(label string) SelectFunction {
+ return func(spec *ExtensionTestSpec) bool {
+ return spec.Labels.Has(label)
+ }
+}
+
+// HasTagWithValue returns a function that selects specs containing a tag with the provided key and value
+func HasTagWithValue(key, value string) SelectFunction {
+ return func(spec *ExtensionTestSpec) bool {
+ return spec.Tags[key] == value
+ }
+}
+
+// WithLifecycle returns a function that selects specs with the provided Lifecycle
+func WithLifecycle(lifecycle Lifecycle) SelectFunction {
+ return func(spec *ExtensionTestSpec) bool {
+ return spec.Lifecycle == lifecycle
+ }
+}
+
+func (specs ExtensionTestSpecs) Names() []string {
+ var names []string
+ for _, spec := range specs {
+ names = append(names, spec.Name)
+ }
+ return names
+}
+
+// Run executes all the specs in parallel, up to maxConcurrent at the same time. Results
+// are written to the given ResultWriter after each spec has completed execution. BeforeEach,
+// BeforeAll, AfterEach, AfterAll hooks are executed when specified. "Each" hooks must be thread
+// safe. Returns an error if any test spec failed, indicating the quantity of failures.
+func (specs ExtensionTestSpecs) Run(ctx context.Context, w ResultWriter, maxConcurrent int) ([]*ExtensionTestResult, error) {
+ queue := make(chan *ExtensionTestSpec)
+ terminalFailures := atomic.Int64{}
+ nonTerminalFailures := atomic.Int64{}
+
+ // Execute beforeAll
+ for _, spec := range specs {
+ for _, beforeAllTask := range spec.beforeAll {
+ beforeAllTask.Run()
+ }
+ }
+
+ // Feed the queue
+ go func() {
+ specs.Walk(func(spec *ExtensionTestSpec) {
+ queue <- spec
+ })
+ close(queue)
+ }()
+
+ // if we have only a single spec to run, we do that differently than running multiple.
+ // multiple specs can run in parallel and do so by exec-ing back into the binary with `run-test` with a single test to execute.
+ // This means that to avoid infinite recursion, when requesting a single test to run
+ // we need to run it in process.
+ runSingleSpec := len(specs) == 1
+
+ // Start consumers
+ var wg sync.WaitGroup
+ resultChan := make(chan *ExtensionTestResult, len(specs))
+ for i := 0; i < maxConcurrent; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for spec := range queue {
+ for _, beforeEachTask := range spec.beforeEach {
+ beforeEachTask.Run(*spec)
+ }
+
+ res := runSpec(ctx, spec, runSingleSpec)
+ if res.Result == ResultFailed {
+ if res.Lifecycle.IsTerminal() {
+ terminalFailures.Add(1)
+ } else {
+ nonTerminalFailures.Add(1)
+ }
+ }
+
+ for _, afterEachTask := range spec.afterEach {
+ afterEachTask.Run(res)
+ }
+
+ // We can't assume the runner will set the name of a test; it may not know it. Even if
+ // it does, we may want to modify it (e.g. k8s-tests for annotations currently).
+ res.Name = spec.Name
+ w.Write(res)
+ resultChan <- res
+ }
+ }()
+ }
+
+ // Wait for all consumers to finish
+ wg.Wait()
+ close(resultChan)
+
+ // Execute afterAll
+ for _, spec := range specs {
+ for _, afterAllTask := range spec.afterAll {
+ afterAllTask.Run()
+ }
+ }
+
+ var results []*ExtensionTestResult
+ for res := range resultChan {
+ results = append(results, res)
+ }
+
+ terminalFailCount := terminalFailures.Load()
+ nonTerminalFailCount := nonTerminalFailures.Load()
+
+ // Non-terminal failures don't cause exit 1, but we still log them
+ if nonTerminalFailCount > 0 {
+ fmt.Fprintf(os.Stderr, "%d informing tests failed (not terminal)\n", nonTerminalFailCount)
+ }
+
+ // Only exit with error if terminal lifecycle tests failed
+ if terminalFailCount > 0 {
+ if nonTerminalFailCount > 0 {
+ return results, fmt.Errorf("%d tests failed (%d informing)", terminalFailCount+nonTerminalFailCount, nonTerminalFailCount)
+ }
+ return results, fmt.Errorf("%d tests failed", terminalFailCount)
+ }
+
+ return results, nil
+}
+
+// AddBeforeAll adds a function to be run once before all tests start executing.
+func (specs ExtensionTestSpecs) AddBeforeAll(fn func()) {
+ task := &OneTimeTask{fn: fn}
+ specs.Walk(func(spec *ExtensionTestSpec) {
+ spec.beforeAll = append(spec.beforeAll, task)
+ })
+}
+
+// AddAfterAll adds a function to be run once after all tests have finished.
+func (specs ExtensionTestSpecs) AddAfterAll(fn func()) {
+ task := &OneTimeTask{fn: fn}
+ specs.Walk(func(spec *ExtensionTestSpec) {
+ spec.afterAll = append(spec.afterAll, task)
+ })
+}
+
+// AddBeforeEach adds a function that runs before each test starts executing. The ExtensionTestSpec is
+// passed in for contextual information, but must not be modified. The provided function must be thread
+// safe.
+func (specs ExtensionTestSpecs) AddBeforeEach(fn func(spec ExtensionTestSpec)) {
+ task := &SpecTask{fn: fn}
+ specs.Walk(func(spec *ExtensionTestSpec) {
+ spec.beforeEach = append(spec.beforeEach, task)
+ })
+}
+
+// AddAfterEach adds a function that runs after each test has finished executing. The ExtensionTestResult
+// can be modified if needed. The provided function must be thread safe.
+func (specs ExtensionTestSpecs) AddAfterEach(fn func(task *ExtensionTestResult)) {
+ task := &TestResultTask{fn: fn}
+ specs.Walk(func(spec *ExtensionTestSpec) {
+ spec.afterEach = append(spec.afterEach, task)
+ })
+}
+
+// MustFilter filters specs using the given celExprs. Each celExpr is OR'd together, if any
+// match the spec is included in the filtered set. If your CEL expression is invalid or filtering
+// otherwise fails, this function panics.
+func (specs ExtensionTestSpecs) MustFilter(celExprs []string) ExtensionTestSpecs {
+ specs, err := specs.Filter(celExprs)
+ if err != nil {
+ panic(fmt.Sprintf("filter did not succeed: %s", err.Error()))
+ }
+
+ return specs
+}
+
+// Filter filters specs using the given celExprs. Each celExpr is OR'd together, if any
+// match the spec is included in the filtered set.
+func (specs ExtensionTestSpecs) Filter(celExprs []string) (ExtensionTestSpecs, error) {
+ var filteredSpecs ExtensionTestSpecs
+
+ // Empty filters returns all
+ if len(celExprs) == 0 {
+ return specs, nil
+ }
+
+ env, err := cel.NewEnv(
+ cel.Declarations(
+ decls.NewVar("source", decls.String),
+ decls.NewVar("name", decls.String),
+ decls.NewVar("originalName", decls.String),
+ decls.NewVar("labels", decls.NewListType(decls.String)),
+ decls.NewVar("codeLocations", decls.NewListType(decls.String)),
+ decls.NewVar("tags", decls.NewMapType(decls.String, decls.String)),
+ ),
+ )
+ if err != nil {
+ return nil, fmt.Errorf("failed to create CEL environment: %w", err)
+ }
+
+ // OR all expressions together
+ for _, spec := range specs {
+ include := false
+ for _, celExpr := range celExprs {
+ prg, err := programForCEL(env, celExpr)
+ if err != nil {
+ return nil, err
+ }
+ out, _, err := prg.Eval(map[string]interface{}{
+ "name": spec.Name,
+ "source": spec.Source,
+ "originalName": spec.OriginalName,
+ "labels": spec.Labels.UnsortedList(),
+ "codeLocations": spec.CodeLocations,
+ "tags": spec.Tags,
+ })
+ if err != nil {
+ return nil, fmt.Errorf("error evaluating CEL expression: %v", err)
+ }
+
+ // If any CEL expression evaluates to true, include the TestSpec
+ if out == types.True {
+ include = true
+ break
+ }
+ }
+ if include {
+ filteredSpecs = append(filteredSpecs, spec)
+ }
+ }
+
+ return filteredSpecs, nil
+}
+
+func programForCEL(env *cel.Env, celExpr string) (cel.Program, error) {
+ // Parse CEL expression
+ ast, iss := env.Parse(celExpr)
+ if iss.Err() != nil {
+ return nil, fmt.Errorf("error parsing CEL expression '%s': %v", celExpr, iss.Err())
+ }
+
+ // Check the AST
+ checked, iss := env.Check(ast)
+ if iss.Err() != nil {
+ return nil, fmt.Errorf("error checking CEL expression '%s': %v", celExpr, iss.Err())
+ }
+
+ // Create a CEL program from the checked AST
+ prg, err := env.Program(checked)
+ if err != nil {
+ return nil, fmt.Errorf("error creating CEL program: %v", err)
+ }
+ return prg, nil
+}
+
+// FilterByEnvironment checks both the Include and Exclude fields of the ExtensionTestSpec to return those specs which match.
+// Tests will be included by default unless they are explicitly excluded. If Include is specified, only those tests matching
+// the CEL expression will be included.
+//
+// See helper functions in extensiontests/environment.go to craft CEL expressions
+func (specs ExtensionTestSpecs) FilterByEnvironment(envFlags flags.EnvironmentalFlags) (ExtensionTestSpecs, error) {
+ var filteredSpecs ExtensionTestSpecs
+ if envFlags.IsEmpty() {
+ return specs, nil
+ }
+
+ env, err := cel.NewEnv(
+ cel.Declarations(
+ decls.NewVar("apiGroups", decls.NewListType(decls.String)),
+ decls.NewVar("architecture", decls.String),
+ decls.NewVar("externalConnectivity", decls.String),
+ decls.NewVar("fact_keys", decls.NewListType(decls.String)),
+ decls.NewVar("facts", decls.NewMapType(decls.String, decls.String)),
+ decls.NewVar("featureGates", decls.NewListType(decls.String)),
+ decls.NewVar("network", decls.String),
+ decls.NewVar("networkStack", decls.String),
+ decls.NewVar("optionalCapabilities", decls.NewListType(decls.String)),
+ decls.NewVar("platform", decls.String),
+ decls.NewVar("topology", decls.String),
+ decls.NewVar("upgrade", decls.String),
+ decls.NewVar("version", decls.String),
+ ),
+ )
+ if err != nil {
+ return nil, fmt.Errorf("failed to create CEL environment: %w", err)
+ }
+ factKeys := make([]string, len(envFlags.Facts))
+ for k := range envFlags.Facts {
+ factKeys = append(factKeys, k)
+ }
+ vars := map[string]interface{}{
+ "apiGroups": envFlags.APIGroups,
+ "architecture": envFlags.Architecture,
+ "externalConnectivity": envFlags.ExternalConnectivity,
+ "fact_keys": factKeys,
+ "facts": envFlags.Facts,
+ "featureGates": envFlags.FeatureGates,
+ "network": envFlags.Network,
+ "networkStack": envFlags.NetworkStack,
+ "optionalCapabilities": envFlags.OptionalCapabilities,
+ "platform": envFlags.Platform,
+ "topology": envFlags.Topology,
+ "upgrade": envFlags.Upgrade,
+ "version": envFlags.Version,
+ }
+
+ for _, spec := range specs {
+ envSel := spec.EnvironmentSelector
+ // If there is no include or exclude CEL, include it implicitly
+ if envSel.IsEmpty() {
+ filteredSpecs = append(filteredSpecs, spec)
+ continue
+ }
+
+ if envSel.Exclude != "" {
+ prg, err := programForCEL(env, envSel.Exclude)
+ if err != nil {
+ return nil, err
+ }
+ out, _, err := prg.Eval(vars)
+ if err != nil {
+ return nil, fmt.Errorf("error evaluating CEL expression: %v", err)
+ }
+ // If it is explicitly excluded, don't check include
+ if out == types.True {
+ continue
+ }
+ }
+
+ if envSel.Include != "" {
+ prg, err := programForCEL(env, envSel.Include)
+ if err != nil {
+ return nil, err
+ }
+ out, _, err := prg.Eval(vars)
+ if err != nil {
+ return nil, fmt.Errorf("error evaluating CEL expression: %v", err)
+ }
+
+ if out == types.True {
+ filteredSpecs = append(filteredSpecs, spec)
+ }
+ } else { // If it hasn't been excluded, and there is no "include" it will be implicitly included
+ filteredSpecs = append(filteredSpecs, spec)
+ }
+
+ }
+
+ return filteredSpecs, nil
+}
+
+// AddLabel adds the labels to each spec.
+func (specs ExtensionTestSpecs) AddLabel(labels ...string) ExtensionTestSpecs {
+ for i := range specs {
+ specs[i].Labels.Insert(labels...)
+ }
+
+ return specs
+}
+
+// RemoveLabel removes the labels from each spec.
+func (specs ExtensionTestSpecs) RemoveLabel(labels ...string) ExtensionTestSpecs {
+ for i := range specs {
+ specs[i].Labels.Delete(labels...)
+ }
+
+ return specs
+}
+
+// SetTag specifies a key/value pair for each spec.
+func (specs ExtensionTestSpecs) SetTag(key, value string) ExtensionTestSpecs {
+ for i := range specs {
+ specs[i].Tags[key] = value
+ }
+
+ return specs
+}
+
+// UnsetTag removes the specified key from each spec.
+func (specs ExtensionTestSpecs) UnsetTag(key string) ExtensionTestSpecs {
+ for i := range specs {
+ delete(specs[i].Tags, key)
+ }
+
+ return specs
+}
+
+// Include adds the specified CEL expression to explicitly include tests by environment to each spec
+func (specs ExtensionTestSpecs) Include(includeCEL string) ExtensionTestSpecs {
+ for _, spec := range specs {
+ spec.Include(includeCEL)
+ }
+ return specs
+}
+
+// Exclude adds the specified CEL expression to explicitly exclude tests by environment to each spec
+func (specs ExtensionTestSpecs) Exclude(excludeCEL string) ExtensionTestSpecs {
+ for _, spec := range specs {
+ spec.Exclude(excludeCEL)
+ }
+ return specs
+}
+
+// Include adds the specified CEL expression to explicitly include tests by environment.
+// If there is already an "include" defined, it will OR the expressions together
+func (spec *ExtensionTestSpec) Include(includeCEL string) *ExtensionTestSpec {
+ existingInclude := spec.EnvironmentSelector.Include
+ if existingInclude != "" {
+ includeCEL = fmt.Sprintf("(%s) || (%s)", existingInclude, includeCEL)
+ }
+
+ spec.EnvironmentSelector.Include = includeCEL
+ return spec
+}
+
+// Exclude adds the specified CEL expression to explicitly exclude tests by environment.
+// If there is already an "exclude" defined, it will OR the expressions together
+func (spec *ExtensionTestSpec) Exclude(excludeCEL string) *ExtensionTestSpec {
+ existingExclude := spec.EnvironmentSelector.Exclude
+ if existingExclude != "" {
+ excludeCEL = fmt.Sprintf("(%s) || (%s)", existingExclude, excludeCEL)
+ }
+
+ spec.EnvironmentSelector.Exclude = excludeCEL
+ return spec
+}
+
+func runSpec(ctx context.Context, spec *ExtensionTestSpec, runSingleSpec bool) *ExtensionTestResult {
+ startTime := time.Now().UTC()
+ var res *ExtensionTestResult
+ if runSingleSpec || spec.RunParallel == nil {
+ res = spec.Run(ctx)
+ } else {
+ res = spec.RunParallel(ctx)
+ }
+ duration := time.Since(startTime)
+ endTime := startTime.Add(duration).UTC()
+ if res == nil {
+ // this shouldn't happen
+ panic(fmt.Sprintf("test produced no result: %s", spec.Name))
+ }
+
+ res.Lifecycle = spec.Lifecycle
+
+ // If the runner doesn't populate this info, we should set it
+ if res.StartTime == nil {
+ res.StartTime = dbtime.Ptr(startTime)
+ }
+ if res.EndTime == nil {
+ res.EndTime = dbtime.Ptr(endTime)
+ }
+ if res.Duration == 0 {
+ res.Duration = duration.Milliseconds()
+ }
+
+ return res
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/task.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/task.go
new file mode 100644
index 0000000000..e808bea87b
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/task.go
@@ -0,0 +1,31 @@
+package extensiontests
+
+import "sync/atomic"
+
+type SpecTask struct {
+ fn func(spec ExtensionTestSpec)
+}
+
+func (t *SpecTask) Run(spec ExtensionTestSpec) {
+ t.fn(spec)
+}
+
+type TestResultTask struct {
+ fn func(result *ExtensionTestResult)
+}
+
+func (t *TestResultTask) Run(result *ExtensionTestResult) {
+ t.fn(result)
+}
+
+type OneTimeTask struct {
+ fn func()
+ executed int32 // Atomic boolean to indicate whether the function has been run
+}
+
+func (t *OneTimeTask) Run() {
+ // Ensure one-time tasks are only run once
+ if atomic.CompareAndSwapInt32(&t.executed, 0, 1) {
+ t.fn()
+ }
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/types.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/types.go
new file mode 100644
index 0000000000..f3edf41a6e
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/types.go
@@ -0,0 +1,124 @@
+package extensiontests
+
+import (
+ "context"
+ "time"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/dbtime"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/util/sets"
+)
+
+type Lifecycle string
+
+var LifecycleInforming Lifecycle = "informing"
+var LifecycleBlocking Lifecycle = "blocking"
+
+// IsTerminal returns true if failures in tests with this lifecycle should cause
+// the test run to exit with a non-zero exit code.
+func (l Lifecycle) IsTerminal() bool {
+ return l != LifecycleInforming
+}
+
+type ExtensionTestSpecs []*ExtensionTestSpec
+
+type ExtensionTestSpec struct {
+ Name string `json:"name"`
+
+ // OriginalName contains the very first name this test was ever known as, used to preserve
+ // history across all names.
+ OriginalName string `json:"originalName,omitempty"`
+
+ // Labels are single string values to apply to the test spec
+ Labels sets.Set[string] `json:"labels"`
+
+ // Tags are key:value pairs
+ Tags map[string]string `json:"tags,omitempty"`
+
+ // Resources gives optional information about what's required to run this test.
+ Resources Resources `json:"resources"`
+
+ // Source is the origin of the test.
+ Source string `json:"source"`
+
+ // CodeLocations are the files where the spec originates from.
+ CodeLocations []string `json:"codeLocations,omitempty"`
+
+ // Lifecycle informs the executor whether the test is informing only, and should not cause the
+ // overall job run to fail, or if it's blocking where a failure of the test is fatal.
+ // Informing lifecycle tests can be used temporarily to gather information about a test's stability.
+ // Tests must not remain informing forever.
+ Lifecycle Lifecycle `json:"lifecycle"`
+
+ // EnvironmentSelector allows for CEL expressions to be used to control test inclusion
+ EnvironmentSelector EnvironmentSelector `json:"environmentSelector,omitempty"`
+
+ // Run invokes a test in-process. It must not call back into `ote-binary run-test` because that will usually
+ // cause an infinite recursion.
+ Run func(ctx context.Context) *ExtensionTestResult `json:"-"`
+
+ // RunParallel invokes a test in parallel with other tests. This is usually done by exec-ing out
+ // to the `ote-binary run-test "test name"` commmand and interpretting the result.
+ RunParallel func(ctx context.Context) *ExtensionTestResult `json:"-"`
+
+ // Timeout is the maximum duration for this test. If set, it overrides the default 90-minute
+ // timeout used by SpawnProcessToRunTest. This is typically populated from Suite.TestTimeout.
+ Timeout time.Duration `json:"-"`
+
+ // Hook functions
+ afterAll []*OneTimeTask
+ beforeAll []*OneTimeTask
+ afterEach []*TestResultTask
+ beforeEach []*SpecTask
+}
+
+type Resources struct {
+ Isolation Isolation `json:"isolation"`
+ Memory string `json:"memory,omitempty"`
+ Duration string `json:"duration,omitempty"`
+ Timeout string `json:"timeout,omitempty"`
+}
+
+type Isolation struct {
+ Mode string `json:"mode,omitempty"`
+ Conflict []string `json:"conflict,omitempty"`
+ Taint []string `json:"taint,omitempty"`
+ Toleration []string `json:"toleration,omitempty"`
+}
+
+type EnvironmentSelector struct {
+ Include string `json:"include,omitempty"`
+ Exclude string `json:"exclude,omitempty"`
+}
+
+func (e EnvironmentSelector) IsEmpty() bool {
+ return e.Include == "" && e.Exclude == ""
+}
+
+type ExtensionTestResults []*ExtensionTestResult
+
+type Result string
+
+var ResultPassed Result = "passed"
+var ResultSkipped Result = "skipped"
+var ResultFailed Result = "failed"
+
+type ExtensionTestResult struct {
+ Name string `json:"name"`
+ Lifecycle Lifecycle `json:"lifecycle"`
+ Duration int64 `json:"duration"`
+ StartTime *dbtime.DBTime `json:"startTime"`
+ EndTime *dbtime.DBTime `json:"endTime"`
+ Result Result `json:"result"`
+ Output string `json:"output"`
+ Error string `json:"error,omitempty"`
+ Details []Details `json:"details,omitempty"`
+}
+
+// Details are human-readable messages to further explain skips, timeouts, etc.
+// It can also be used to provide contemporaneous information about failures
+// that may not be easily returned by must-gather. For larger artifacts (greater than
+// 10KB, write them to $EXTENSION_ARTIFACTS_DIR.
+type Details struct {
+ Name string `json:"name"`
+ Value interface{} `json:"value"`
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/viewer.html b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/viewer.html
new file mode 100644
index 0000000000..2ff236aa32
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests/viewer.html
@@ -0,0 +1,1520 @@
+
+
+
+
+
+ Results for {{ .SuiteName }}
+
+
+
+
+
+
+
+ Results for {{ .SuiteName }}
+
+
No file loaded
+
+
+
+
Load Test Results
+
Drag and drop a JSON test results file here, or click to browse
+
+
+
+
+
+
+
0
+
Total
+
+
+
0
+
Passed
+
+
+
0
+
Failed
+
+
+
0
+
Flaky
+
+
+
0
+
Skipped
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0ms - 0ms
+
+
+
+
+
+
+
+
+ 0ms
+ 0ms
+
+
+
+
+
+ 0 tests
+
+
+
+
+
+
+
+
+
+
+ Page 1 of 1
+
+
+
+
+
+
No tests match your filters
+
Try adjusting your search criteria
+
+
+
+
+
+
+
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/registry.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/registry.go
new file mode 100644
index 0000000000..bbae421df7
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/registry.go
@@ -0,0 +1,39 @@
+package extension
+
+const DefaultExtension = "default"
+
+type Registry struct {
+ extensions map[string]*Extension
+}
+
+func NewRegistry() *Registry {
+ var r Registry
+ return &r
+}
+
+func (r *Registry) Walk(walkFn func(*Extension)) {
+ for k := range r.extensions {
+ if k == DefaultExtension {
+ continue
+ }
+ walkFn(r.extensions[k])
+ }
+}
+
+func (r *Registry) Get(name string) *Extension {
+ return r.extensions[name]
+}
+
+func (r *Registry) Register(extension *Extension) {
+ if r.extensions == nil {
+ r.extensions = make(map[string]*Extension)
+ // first extension is default
+ r.extensions[DefaultExtension] = extension
+ }
+
+ r.extensions[extension.Component.Identifier()] = extension
+}
+
+func (r *Registry) Deregister(name string) {
+ delete(r.extensions, name)
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/types.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/types.go
new file mode 100644
index 0000000000..00d2d9d663
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/extension/types.go
@@ -0,0 +1,94 @@
+package extension
+
+import (
+ "time"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/util/sets"
+)
+
+const CurrentExtensionAPIVersion = "v1.1"
+
+// Extension represents an extension to openshift-tests.
+type Extension struct {
+ APIVersion string `json:"apiVersion"`
+ Source Source `json:"source"`
+ Component Component `json:"component"`
+
+ // Suites that the extension wants to advertise/participate in.
+ Suites []Suite `json:"suites"`
+
+ Images []Image `json:"images"`
+
+ // Private data
+ specs extensiontests.ExtensionTestSpecs
+ obsoleteTests sets.Set[string]
+}
+
+// Source contains the details of the commit and source URL.
+type Source struct {
+ // Commit from which this binary was compiled.
+ Commit string `json:"commit"`
+ // BuildDate ISO8601 string of when the binary was built
+ BuildDate string `json:"build_date"`
+ // GitTreeState lets you know the status of the git tree (clean/dirty)
+ GitTreeState string `json:"git_tree_state"`
+ // SourceURL contains the url of the git repository (if known) that this extension was built from.
+ SourceURL string `json:"source_url,omitempty"`
+}
+
+// Component represents the component the binary acts on.
+type Component struct {
+ // The product this component is part of.
+ Product string `json:"product"`
+ // The type of the component.
+ Kind string `json:"type"`
+ // The name of the component.
+ Name string `json:"name"`
+}
+
+type ClusterStability string
+
+var (
+ // ClusterStabilityStable means that at no point during testing do we expect a component to take downtime and upgrades are not happening.
+ ClusterStabilityStable ClusterStability = "Stable"
+
+ // ClusterStabilityDisruptive means that the suite is expected to induce outages to the cluster.
+ ClusterStabilityDisruptive ClusterStability = "Disruptive"
+
+ // ClusterStabilityUpgrade was previously defined, but was removed by @deads2k. Please contact him if you find a use
+ // case for it and needs to be reintroduced.
+ // ClusterStabilityUpgrade ClusterStability = "Upgrade"
+)
+
+// Suite represents additional suites the extension wants to advertise. Child suites when being executed in the context
+// of a parent will have their count, parallelism, stability, and timeout options superseded by the parent's suite.
+type Suite struct {
+ Name string `json:"name"`
+ Description string `json:"description"`
+
+ // Parents are the parent suites this suite is part of.
+ Parents []string `json:"parents,omitempty"`
+ // Qualifiers are CEL expressions that are OR'd together for test selection that are members of the suite.
+ Qualifiers []string `json:"qualifiers,omitempty"`
+
+ // Count is the default number of times to execute each test in this suite.
+ Count int `json:"count,omitempty"`
+ // Parallelism is the maximum parallelism of this suite.
+ Parallelism int `json:"parallelism,omitempty"`
+ // ClusterStability informs openshift-tests whether this entire test suite is expected to be disruptive or not
+ // to normal cluster operations.
+ ClusterStability ClusterStability `json:"clusterStability,omitempty"`
+ // TestTimeout is the default timeout for tests in this suite.
+ TestTimeout *time.Duration `json:"testTimeout,omitempty"`
+}
+
+type Image struct {
+ Index int `json:"index"`
+ Registry string `json:"registry"`
+ Name string `json:"name"`
+ Version string `json:"version"`
+ // Mapped is the image reference that this image is mirrored to by the image mirror tool.
+ // This field should be populated if the mirrored image reference is predetermined by the test extensions.
+ Mapped *Image `json:"mapped,omitempty"`
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/component.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/component.go
new file mode 100644
index 0000000000..ca9e425c44
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/component.go
@@ -0,0 +1,25 @@
+package flags
+
+import (
+ "github.com/spf13/pflag"
+)
+
+const DefaultExtension = "default"
+
+// ComponentFlags contains information for specifying the component.
+type ComponentFlags struct {
+ Component string
+}
+
+func NewComponentFlags() *ComponentFlags {
+ return &ComponentFlags{
+ Component: DefaultExtension,
+ }
+}
+
+func (f *ComponentFlags) BindFlags(fs *pflag.FlagSet) {
+ fs.StringVar(&f.Component,
+ "component",
+ f.Component,
+ "specify the component to enable")
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/concurrency.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/concurrency.go
new file mode 100644
index 0000000000..2db07c7654
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/concurrency.go
@@ -0,0 +1,23 @@
+package flags
+
+import "github.com/spf13/pflag"
+
+// ConcurrencyFlags contains information for configuring concurrency
+type ConcurrencyFlags struct {
+ MaxConcurency int
+}
+
+func NewConcurrencyFlags() *ConcurrencyFlags {
+ return &ConcurrencyFlags{
+ MaxConcurency: 10,
+ }
+}
+
+func (f *ConcurrencyFlags) BindFlags(fs *pflag.FlagSet) {
+ fs.IntVarP(&f.MaxConcurency,
+ "max-concurrency",
+ "c",
+ f.MaxConcurency,
+ "maximum number of tests to run in parallel",
+ )
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/environment.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/environment.go
new file mode 100644
index 0000000000..af7a0258e2
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/environment.go
@@ -0,0 +1,114 @@
+package flags
+
+import (
+ "reflect"
+
+ "github.com/spf13/pflag"
+)
+
+type EnvironmentalFlags struct {
+ APIGroups []string
+ Architecture string
+ ExternalConnectivity string
+ Facts map[string]string
+ FeatureGates []string
+ Network string
+ NetworkStack string
+ OptionalCapabilities []string
+ Platform string
+ Topology string
+ Upgrade string
+ Version string
+}
+
+func NewEnvironmentalFlags() *EnvironmentalFlags {
+ return &EnvironmentalFlags{}
+}
+
+func (f *EnvironmentalFlags) BindFlags(fs *pflag.FlagSet) {
+ fs.StringArrayVar(&f.APIGroups,
+ "api-group",
+ f.APIGroups,
+ "The API groups supported by this cluster. Since: v1.1")
+ fs.StringVar(&f.Architecture,
+ "architecture",
+ "",
+ "The CPU architecture of the target cluster (\"amd64\", \"arm64\"). Since: v1.0")
+ fs.StringVar(&f.ExternalConnectivity,
+ "external-connectivity",
+ "",
+ "The External Connectivity of the target cluster (\"Disconnected\", \"Direct\", \"Proxied\"). Since: v1.0")
+ fs.StringArrayVar(&f.FeatureGates,
+ "feature-gate",
+ f.FeatureGates,
+ "The feature gates enabled on this cluster. Since: v1.1")
+ fs.StringToStringVar(&f.Facts,
+ "fact",
+ make(map[string]string),
+ "Facts advertised by cluster components. Since: v1.0")
+ fs.StringVar(&f.Network,
+ "network",
+ "",
+ "The network of the target cluster (\"ovn\", \"sdn\"). Since: v1.0")
+ fs.StringVar(&f.NetworkStack,
+ "network-stack",
+ "",
+ "The network stack of the target cluster (\"ipv6\", \"ipv4\", \"dual\"). Since: v1.0")
+ fs.StringSliceVar(&f.OptionalCapabilities,
+ "optional-capability",
+ []string{},
+ "An Optional Capability of the target cluster. Can be passed multiple times. Since: v1.0")
+ fs.StringVar(&f.Platform,
+ "platform",
+ "",
+ "The hardware or cloud platform (\"aws\", \"gcp\", \"metal\", ...). Since: v1.0")
+ fs.StringVar(&f.Topology,
+ "topology",
+ "",
+ "The target cluster topology (\"ha\", \"microshift\", ...). Since: v1.0")
+ fs.StringVar(&f.Upgrade,
+ "upgrade",
+ "",
+ "The upgrade that was performed prior to the test run (\"micro\", \"minor\"). Since: v1.0")
+ fs.StringVar(&f.Version,
+ "version",
+ "",
+ "\"major.minor\" version of target cluster. Since: v1.0")
+}
+
+func (f *EnvironmentalFlags) IsEmpty() bool {
+ v := reflect.ValueOf(*f)
+
+ for i := 0; i < v.NumField(); i++ {
+ field := v.Field(i)
+
+ switch field.Kind() {
+ case reflect.Slice, reflect.Map:
+ if !field.IsNil() && field.Len() > 0 {
+ return false
+ }
+ default:
+ if !reflect.DeepEqual(field.Interface(), reflect.Zero(field.Type()).Interface()) {
+ return false
+ }
+ }
+ }
+
+ return true
+}
+
+// EnvironmentFlagVersions holds the "Since" version metadata for each flag.
+var EnvironmentFlagVersions = map[string]string{
+ "api-group": "v1.1",
+ "architecture": "v1.0",
+ "external-connectivity": "v1.0",
+ "fact": "v1.0",
+ "feature-gate": "v1.1",
+ "network": "v1.0",
+ "network-stack": "v1.0",
+ "optional-capability": "v1.0",
+ "platform": "v1.0",
+ "topology": "v1.0",
+ "upgrade": "v1.0",
+ "version": "v1.0",
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/names.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/names.go
new file mode 100644
index 0000000000..9e58648395
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/names.go
@@ -0,0 +1,24 @@
+package flags
+
+import (
+ "github.com/spf13/pflag"
+)
+
+// NamesFlags contains information for specifying multiple test names.
+type NamesFlags struct {
+ Names []string
+}
+
+func NewNamesFlags() *NamesFlags {
+ return &NamesFlags{
+ Names: []string{},
+ }
+}
+
+func (f *NamesFlags) BindFlags(fs *pflag.FlagSet) {
+ fs.StringArrayVarP(&f.Names,
+ "names",
+ "n",
+ f.Names,
+ "specify test name (can be specified multiple times)")
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/output.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/output.go
new file mode 100644
index 0000000000..af62bbf13b
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/output.go
@@ -0,0 +1,96 @@
+package flags
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "reflect"
+ "strings"
+
+ "github.com/spf13/pflag"
+)
+
+// OutputFlags contains information for specifying multiple test names.
+type OutputFlags struct {
+ Output string
+}
+
+func NewOutputFlags() *OutputFlags {
+ return &OutputFlags{
+ Output: "json",
+ }
+}
+
+func (f *OutputFlags) BindFlags(fs *pflag.FlagSet) {
+ fs.StringVarP(&f.Output,
+ "output",
+ "o",
+ f.Output,
+ "output mode")
+}
+
+func (o *OutputFlags) Marshal(v interface{}) ([]byte, error) {
+ switch o.Output {
+ case "", "json":
+ j, err := json.MarshalIndent(&v, "", " ")
+ if err != nil {
+ return nil, err
+ }
+ return j, nil
+ case "jsonl":
+ // Check if v is a slice or array
+ val := reflect.ValueOf(v)
+ if val.Kind() == reflect.Slice || val.Kind() == reflect.Array {
+ var result []byte
+ for i := 0; i < val.Len(); i++ {
+ item := val.Index(i).Interface()
+ j, err := json.Marshal(item)
+ if err != nil {
+ return nil, err
+ }
+ result = append(result, j...)
+ result = append(result, '\n') // Append newline after each item
+ }
+ return result, nil
+ }
+ return nil, errors.New("jsonl format requires a slice or array")
+ case "names":
+ val := reflect.ValueOf(v)
+ if val.Kind() == reflect.Slice || val.Kind() == reflect.Array {
+ var names []string
+ outerLoop:
+ for i := 0; i < val.Len(); i++ {
+ item := val.Index(i)
+ // Check for Name() or Identifier() methods
+ itemInterface := item.Interface()
+ nameFuncs := []string{"Name", "Identifier"}
+ for _, fn := range nameFuncs {
+ method := reflect.ValueOf(itemInterface).MethodByName(fn)
+ if method.IsValid() && method.Kind() == reflect.Func && method.Type().NumIn() == 0 && method.Type().NumOut() == 1 && method.Type().Out(0).Kind() == reflect.String {
+ name := method.Call(nil)[0].String()
+ names = append(names, name)
+ continue outerLoop
+ }
+ }
+
+ // Dereference pointer if needed
+ if item.Kind() == reflect.Ptr {
+ item = item.Elem()
+ }
+ // Check for struct with Name field
+ if item.Kind() == reflect.Struct {
+ nameField := item.FieldByName("Name")
+ if nameField.IsValid() && nameField.Kind() == reflect.String {
+ names = append(names, nameField.String())
+ }
+ } else {
+ return nil, errors.New("items must have a Name field or a Name() method")
+ }
+ }
+ return []byte(strings.Join(names, "\n")), nil
+ }
+ return nil, errors.New("names format requires an array of structs")
+ default:
+ return nil, fmt.Errorf("invalid output format: %s", o.Output)
+ }
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/suite.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/suite.go
new file mode 100644
index 0000000000..23de832a85
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/flags/suite.go
@@ -0,0 +1,21 @@
+package flags
+
+import (
+ "github.com/spf13/pflag"
+)
+
+// SuiteFlags contains information for specifying the suite.
+type SuiteFlags struct {
+ Suite string
+}
+
+func NewSuiteFlags() *SuiteFlags {
+ return &SuiteFlags{}
+}
+
+func (f *SuiteFlags) BindFlags(fs *pflag.FlagSet) {
+ fs.StringVar(&f.Suite,
+ "suite",
+ f.Suite,
+ "specify the suite to use")
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/logging.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/logging.go
new file mode 100644
index 0000000000..1cf299a7c0
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/logging.go
@@ -0,0 +1,25 @@
+package ginkgo
+
+import (
+ "github.com/go-logr/logr"
+ "github.com/go-logr/logr/funcr"
+ "github.com/onsi/ginkgo/v2"
+)
+
+// this is copied from ginkgo because ginkgo made it internal and then hardcoded an init block
+// using these functions to wire to os.stdout and we want to wire to stderr (or a different buffer) so we can
+// have json output.
+
+func GinkgoLogrFunc(writer ginkgo.GinkgoWriterInterface) logr.Logger {
+ return funcr.New(func(prefix, args string) {
+ if prefix == "" {
+ writer.Printf("%s\n", args)
+ } else {
+ writer.Printf("%s %s\n", prefix, args)
+ }
+ }, funcr.Options{
+ // LogTimestamp adds timestamps to log lines using the format "2006-01-02 15:04:05.000000"
+ // See: https://github.com/go-logr/logr/blob/bb8ea8159175ccb4eddf4ac8704f84e40ac6d9b0/funcr/funcr.go#L211
+ LogTimestamp: true,
+ })
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/parallel.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/parallel.go
new file mode 100644
index 0000000000..94c47eef6b
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/parallel.go
@@ -0,0 +1,131 @@
+package ginkgo
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "os"
+ "os/exec"
+ "syscall"
+ "time"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/dbtime"
+ "github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests"
+)
+
+func SpawnProcessToRunTest(ctx context.Context, testName string, timeout time.Duration) *extensiontests.ExtensionTestResult {
+ // longerCtx is used to backstop the process, but leave termination up to us if possible to allow a double interrupt
+ longerCtx, longerCancel := context.WithTimeout(ctx, timeout+15*time.Minute)
+ defer longerCancel()
+ timeoutCtx, shorterCancel := context.WithTimeout(longerCtx, timeout)
+ defer shorterCancel()
+
+ stdout := &bytes.Buffer{}
+ stderr := &bytes.Buffer{}
+
+ command := exec.CommandContext(longerCtx, os.Args[0], "run-test", "--output=json", fmt.Sprintf("--timeout=%s", timeout), testName)
+ command.Stdout = stdout
+ command.Stderr = stderr
+
+ start := time.Now()
+ err := command.Start()
+ if err != nil {
+ fmt.Fprintf(stderr, "Command Start Error: %v\n", err)
+ return newTestResult(testName, extensiontests.ResultFailed, start, time.Now(), stdout, stderr)
+ }
+
+ go func() {
+ // interrupt after timeout, or exit early if the process finishes first
+ select {
+ case <-time.After(timeout):
+ case <-timeoutCtx.Done():
+ }
+ if command.Process != nil {
+ _ = command.Process.Signal(syscall.SIGINT)
+ }
+ // Canceled means the process exited and the context was cancelled — no need to escalate
+ if timeoutCtx.Err() == context.Canceled {
+ return
+ }
+ // if the process is hung, send SIGABRT after a grace period for a stack dump
+ <-time.After(time.Minute)
+ if command.Process != nil {
+ _ = command.Process.Signal(syscall.SIGABRT)
+ }
+ }()
+
+ result := extensiontests.ResultFailed
+ cmdErr := command.Wait()
+
+ subcommandResult, parseErr := newTestResultFromOutput(stdout)
+ if parseErr == nil {
+ // even if we have a cmdErr, if we were able to parse the result, trust the output
+ return subcommandResult
+ }
+
+ fmt.Fprintf(stderr, "Command Error: %v\n", cmdErr)
+ fmt.Fprintf(stderr, "Deserialization Error: %v\n", parseErr)
+ return newTestResult(testName, result, start, time.Now(), stdout, stderr)
+}
+
+func newTestResultFromOutput(stdout *bytes.Buffer) (*extensiontests.ExtensionTestResult, error) {
+ if len(stdout.Bytes()) == 0 {
+ return nil, errors.New("no output from command")
+ }
+
+ // when the command runs correctly, we get json or json slice output
+ retArray := []extensiontests.ExtensionTestResult{}
+ if arrayItemErr := json.Unmarshal(stdout.Bytes(), &retArray); arrayItemErr == nil {
+ if len(retArray) != 1 {
+ return nil, errors.New("expected 1 result, got %v results")
+ }
+ return &retArray[0], nil
+ }
+
+ // when the command runs correctly, we get json output
+ ret := &extensiontests.ExtensionTestResult{}
+ if singleItemErr := json.Unmarshal(stdout.Bytes(), ret); singleItemErr != nil {
+ return nil, singleItemErr
+ }
+
+ return ret, nil
+}
+
+func newTestResult(name string, result extensiontests.Result, start, end time.Time, stdout, stderr *bytes.Buffer) *extensiontests.ExtensionTestResult {
+ duration := end.Sub(start)
+ dbStart := dbtime.DBTime(start)
+ dbEnd := dbtime.DBTime(end)
+ ret := &extensiontests.ExtensionTestResult{
+ Name: name,
+ Lifecycle: "", // lifecycle is completed one level above this.
+ Duration: int64(duration),
+ StartTime: &dbStart,
+ EndTime: &dbEnd,
+ Result: result,
+ Details: nil,
+ }
+
+ if stdout != nil && stderr != nil {
+ stdoutStr := stdout.String()
+ stderrStr := stderr.String()
+
+ ret.Output = fmt.Sprintf("STDOUT:\n%s\n\nSTDERR:\n%s\n", stdoutStr, stderrStr)
+
+ // try to choose the best summary
+ switch {
+ case len(stderrStr) > 0 && len(stderrStr) < 5000:
+ ret.Error = stderrStr
+ case len(stderrStr) > 0 && len(stderrStr) >= 5000:
+ ret.Error = stderrStr[len(stderrStr)-5000:]
+
+ case len(stdoutStr) > 0 && len(stdoutStr) < 5000:
+ ret.Error = stdoutStr
+ case len(stdoutStr) > 0 && len(stdoutStr) >= 5000:
+ ret.Error = stdoutStr[len(stdoutStr)-5000:]
+ }
+ }
+
+ return ret
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/util.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/util.go
new file mode 100644
index 0000000000..90c5c2bd17
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo/util.go
@@ -0,0 +1,249 @@
+package ginkgo
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/onsi/ginkgo/v2"
+ "github.com/onsi/ginkgo/v2/types"
+ "github.com/onsi/gomega"
+
+ "github.com/openshift-eng/openshift-tests-extension/pkg/util/sets"
+
+ ext "github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests"
+)
+
+func configureGinkgo() (*types.SuiteConfig, *types.ReporterConfig, error) {
+ if !ginkgo.GetSuite().InPhaseBuildTree() {
+ if err := ginkgo.GetSuite().BuildTree(); err != nil {
+ return nil, nil, fmt.Errorf("couldn't build ginkgo tree: %w", err)
+ }
+ }
+
+ // Ginkgo initialization
+ ginkgo.GetSuite().ClearBeforeAndAfterSuiteNodes()
+ suiteConfig, reporterConfig := ginkgo.GinkgoConfiguration()
+ suiteConfig.RandomizeAllSpecs = true
+ suiteConfig.Timeout = 24 * time.Hour
+ reporterConfig.NoColor = true
+ reporterConfig.Verbose = true
+ ginkgo.SetReporterConfig(reporterConfig)
+
+ // Write output to Stderr
+ ginkgo.GinkgoWriter = ginkgo.NewWriter(os.Stderr)
+ ginkgo.GinkgoLogr = GinkgoLogrFunc(ginkgo.GinkgoWriter)
+
+ gomega.RegisterFailHandler(ginkgo.Fail)
+
+ return &suiteConfig, &reporterConfig, nil
+}
+
+// BuildExtensionTestSpecsFromOpenShiftGinkgoSuite generates OTE specs for Gingko tests. While OTE isn't limited to
+// calling ginkgo tests, anything that implements the ExtensionTestSpec interface can be used, it's the most common
+// course of action. The typical use case is to omit selectFns, but if provided, these will filter the returned list
+// of specs, applied in the order provided.
+func BuildExtensionTestSpecsFromOpenShiftGinkgoSuite(selectFns ...ext.SelectFunction) (ext.ExtensionTestSpecs, error) {
+ var specs ext.ExtensionTestSpecs
+ var enforceSerialExecutionForGinkgo sync.Mutex // in-process parallelization for ginkgo is impossible so far
+
+ if _, _, err := configureGinkgo(); err != nil {
+ return nil, err
+ }
+
+ cwd, err := os.Getwd()
+ if err != nil {
+ return nil, fmt.Errorf("couldn't get current working directory: %w", err)
+ }
+
+ ginkgo.GetSuite().WalkTests(func(name string, spec types.TestSpec) {
+ var codeLocations []string
+ for _, cl := range spec.CodeLocations() {
+ codeLocations = append(codeLocations, cl.String())
+ }
+
+ testCase := &ext.ExtensionTestSpec{
+ Name: spec.Text(),
+ Labels: sets.New[string](spec.Labels()...),
+ CodeLocations: codeLocations,
+ Lifecycle: GetLifecycle(spec.Labels()),
+ Run: func(ctx context.Context) *ext.ExtensionTestResult {
+ enforceSerialExecutionForGinkgo.Lock()
+ defer enforceSerialExecutionForGinkgo.Unlock()
+
+ suiteConfig, reporterConfig, _ := configureGinkgo()
+
+ result := &ext.ExtensionTestResult{
+ Name: spec.Text(),
+ }
+
+ ginkgo.GetSuite().RunSpec(spec, ginkgo.Labels{}, "", cwd, ginkgo.GetFailer(), ginkgo.GetWriter(), *suiteConfig,
+ *reporterConfig)
+ summary := findSpecReport(ginkgo.GetSuite().GetReport().SpecReports)
+
+ result.Output = summary.CapturedGinkgoWriterOutput
+ result.Error = summary.CapturedStdOutErr
+
+ switch summary.State {
+ case types.SpecStatePassed:
+ result.Result = ext.ResultPassed
+ case types.SpecStateSkipped, types.SpecStatePending:
+ result.Result = ext.ResultSkipped
+ if len(summary.Failure.Message) > 0 {
+ result.Output = fmt.Sprintf(
+ "%s\n skip [%s:%d]: %s\n",
+ result.Output,
+ lastFilenameSegment(summary.Failure.Location.FileName),
+ summary.Failure.Location.LineNumber,
+ summary.Failure.Message,
+ )
+ } else if len(summary.Failure.ForwardedPanic) > 0 {
+ result.Output = fmt.Sprintf(
+ "%s\n skip [%s:%d]: %s\n",
+ result.Output,
+ lastFilenameSegment(summary.Failure.Location.FileName),
+ summary.Failure.Location.LineNumber,
+ summary.Failure.ForwardedPanic,
+ )
+ }
+ case types.SpecStateFailed, types.SpecStatePanicked, types.SpecStateInterrupted, types.SpecStateAborted:
+ result.Result = ext.ResultFailed
+ var errors []string
+ if len(summary.Failure.ForwardedPanic) > 0 {
+ if len(summary.Failure.Location.FullStackTrace) > 0 {
+ errors = append(errors, fmt.Sprintf("\n%s\n", summary.Failure.Location.FullStackTrace))
+ }
+ errors = append(errors, fmt.Sprintf("fail [%s:%d]: Test Panicked: %s", lastFilenameSegment(summary.Failure.Location.FileName), summary.Failure.Location.LineNumber, summary.Failure.ForwardedPanic))
+ }
+ errors = append(errors, fmt.Sprintf("fail [%s:%d]: %s", lastFilenameSegment(summary.Failure.Location.FileName), summary.Failure.Location.LineNumber, summary.Failure.Message))
+ result.Error = strings.Join(errors, "\n")
+ case types.SpecStateTimedout:
+ result.Result = ext.ResultFailed
+ var errors []string
+ for _, additionalFailure := range summary.AdditionalFailures {
+ collectAdditionalFailures(&errors, " ", additionalFailure.Failure)
+ }
+ if summary.Failure.AdditionalFailure != nil {
+ collectAdditionalFailures(&errors, " ", summary.Failure.AdditionalFailure.Failure)
+ }
+ errors = append(errors, fmt.Sprintf("fail [%s:%d]: %s", lastFilenameSegment(summary.Failure.Location.FileName), summary.Failure.Location.LineNumber, summary.Failure.Message))
+ result.Error = strings.Join(errors, "\n")
+ case types.SpecStateInvalid:
+ result.Result = ext.ResultFailed
+ result.Error = fmt.Sprintf("test produced no spec report; this is a bug in the test framework: %#v", summary)
+ default:
+ result.Result = ext.ResultFailed
+ result.Error = fmt.Sprintf("test produced unknown outcome: %#v", summary)
+ }
+
+ return result
+ },
+ }
+ testCase.RunParallel = func(ctx context.Context) *ext.ExtensionTestResult {
+ timeout := 90 * time.Minute
+ if testCase.Timeout > 0 {
+ timeout = testCase.Timeout
+ }
+ return SpawnProcessToRunTest(ctx, name, timeout)
+ }
+ specs = append(specs, testCase)
+ })
+
+ // Default select function is to exclude vendored specs. When relying on Kubernetes test framework for its helpers,
+ // it also unfortunately ends up importing *all* Gingko specs. This is unsafe: it would potentially override the
+ // kube specs already present in origin. The best course of action is enforce this behavior on everyone. If for
+ // some reason, you must include vendored specs, you can opt-in directly by supplying your own SelectFunctions or using
+ // AllTestsIncludedVendored().
+ if len(selectFns) == 0 {
+ selectFns = []ext.SelectFunction{ext.ModuleTestsOnly()}
+ }
+
+ for _, selectFn := range selectFns {
+ specs = specs.Select(selectFn)
+ }
+
+ return specs, nil
+}
+
+func Informing() ginkgo.Labels {
+ return ginkgo.Label(fmt.Sprintf("Lifecycle:%s", ext.LifecycleInforming))
+}
+
+func Slow() ginkgo.Labels {
+ return ginkgo.Label("SLOW")
+}
+
+func Blocking() ginkgo.Labels {
+ return ginkgo.Label(fmt.Sprintf("Lifecycle:%s", ext.LifecycleBlocking))
+}
+
+func GetLifecycle(labels ginkgo.Labels) ext.Lifecycle {
+ for _, label := range labels {
+ res := strings.Split(label, ":")
+ if len(res) != 2 || !strings.EqualFold(res[0], "lifecycle") {
+ continue
+ }
+ return MustLifecycle(res[1]) // this panics if unsupported lifecycle is used
+ }
+
+ return ext.LifecycleBlocking
+}
+
+func MustLifecycle(l string) ext.Lifecycle {
+ switch ext.Lifecycle(l) {
+ case ext.LifecycleInforming, ext.LifecycleBlocking:
+ return ext.Lifecycle(l)
+ default:
+ panic(fmt.Sprintf("unknown test lifecycle: %s", l))
+ }
+}
+
+func lastFilenameSegment(filename string) string {
+ if parts := strings.Split(filename, "/vendor/"); len(parts) > 1 {
+ return parts[len(parts)-1]
+ }
+ if parts := strings.Split(filename, "/src/"); len(parts) > 1 {
+ return parts[len(parts)-1]
+ }
+ return filename
+}
+
+// findSpecReport selects the best matching spec report from the list of reports
+// produced by RunSpec. It first looks for a report that was actually attempted
+// (NumAttempts > 0), which covers passed/failed/panicked specs. If none is found
+// (as happens with Pending or Skipped specs where Ginkgo never enters the
+// execution loop), it falls back to the last report in the list.
+func findSpecReport(reports types.SpecReports) types.SpecReport {
+ var summary types.SpecReport
+ for _, report := range reports {
+ if report.NumAttempts > 0 {
+ summary = report
+ }
+ }
+ // Pending/Skipped specs have NumAttempts==0; fall back to the last report
+ if summary.State == types.SpecStateInvalid && len(reports) > 0 {
+ summary = reports[len(reports)-1]
+ }
+ return summary
+}
+
+func collectAdditionalFailures(errors *[]string, suffix string, failure types.Failure) {
+ if failure.IsZero() {
+ return
+ }
+
+ if len(failure.ForwardedPanic) > 0 {
+ if len(failure.Location.FullStackTrace) > 0 {
+ *errors = append(*errors, fmt.Sprintf("\n%s\n", failure.Location.FullStackTrace))
+ }
+ *errors = append(*errors, fmt.Sprintf("fail [%s:%d]: Test Panicked: %s%s", lastFilenameSegment(failure.Location.FileName), failure.Location.LineNumber, failure.ForwardedPanic, suffix))
+ }
+ *errors = append(*errors, fmt.Sprintf("fail [%s:%d] %s%s", lastFilenameSegment(failure.Location.FileName), failure.Location.LineNumber, failure.Message, suffix))
+
+ if failure.AdditionalFailure != nil {
+ collectAdditionalFailures(errors, " ", failure.AdditionalFailure.Failure)
+ }
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/junit/types.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/junit/types.go
new file mode 100644
index 0000000000..0309fbd514
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/junit/types.go
@@ -0,0 +1,104 @@
+package junit
+
+import (
+ "encoding/xml"
+)
+
+// The below types are directly marshalled into XML. The types correspond to jUnit
+// XML schema, but do not contain all valid fields. For instance, the class name
+// field for test cases is omitted, as this concept does not directly apply to Go.
+// For XML specifications see http://help.catchsoftware.com/display/ET/JUnit+Format
+// or view the XSD included in this package as 'junit.xsd'
+
+// TestSuites represents a flat collection of jUnit test suites.
+type TestSuites struct {
+ XMLName xml.Name `xml:"testsuites"`
+
+ // Suites are the jUnit test suites held in this collection
+ Suites []*TestSuite `xml:"testsuite"`
+}
+
+// TestSuite represents a single jUnit test suite, potentially holding child suites.
+type TestSuite struct {
+ XMLName xml.Name `xml:"testsuite"`
+
+ // Name is the name of the test suite
+ Name string `xml:"name,attr"`
+
+ // NumTests records the number of tests in the TestSuite
+ NumTests uint `xml:"tests,attr"`
+
+ // NumSkipped records the number of skipped tests in the suite
+ NumSkipped uint `xml:"skipped,attr"`
+
+ // NumFailed records the number of failed tests in the suite
+ NumFailed uint `xml:"failures,attr"`
+
+ // Duration is the time taken in seconds to run all tests in the suite
+ Duration float64 `xml:"time,attr"`
+
+ // Properties holds other properties of the test suite as a mapping of name to value
+ Properties []*TestSuiteProperty `xml:"properties,omitempty"`
+
+ // TestCases are the test cases contained in the test suite
+ TestCases []*TestCase `xml:"testcases"`
+
+ // Children holds nested test suites
+ Children []*TestSuite `xml:"testsuites"` //nolint
+}
+
+// TestSuiteProperty contains a mapping of a property name to a value
+type TestSuiteProperty struct {
+ XMLName xml.Name `xml:"properties"`
+
+ Name string `xml:"name,attr"`
+ Value string `xml:"value,attr"`
+}
+
+// TestCase represents a jUnit test case
+type TestCase struct {
+ XMLName xml.Name `xml:"testcase"`
+
+ // Name is the name of the test case
+ Name string `xml:"name,attr"`
+
+ // Classname is an attribute set by the package type and is required
+ Classname string `xml:"classname,attr,omitempty"`
+
+ // Duration is the time taken in seconds to run the test
+ Duration float64 `xml:"time,attr"`
+
+ // SkipMessage holds the reason why the test was skipped
+ SkipMessage *SkipMessage `xml:"skipped"`
+
+ // FailureOutput holds the output from a failing test
+ FailureOutput *FailureOutput `xml:"failure"`
+
+ // SystemOut is output written to stdout during the execution of this test case
+ SystemOut string `xml:"system-out,omitempty"`
+
+ // SystemErr is output written to stderr during the execution of this test case
+ SystemErr string `xml:"system-err,omitempty"`
+}
+
+// SkipMessage holds a message explaining why a test was skipped
+type SkipMessage struct {
+ XMLName xml.Name `xml:"skipped"`
+
+ // Message explains why the test was skipped
+ Message string `xml:"message,attr,omitempty"`
+}
+
+// FailureOutput holds the output from a failing test
+type FailureOutput struct {
+ XMLName xml.Name `xml:"failure"`
+
+ // Message holds the failure message from the test
+ Message string `xml:"message,attr"`
+
+ // Output holds verbose failure output from the test
+ Output string `xml:",chardata"`
+}
+
+// TestResult is the result of a test case
+type TestResult string
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/LICENSE b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/LICENSE
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/README.md b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/README.md
new file mode 100644
index 0000000000..1a5def7723
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/README.md
@@ -0,0 +1,3 @@
+This package is copy/pasted from [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery/tree/master/pkg/util/sets)
+to avoid a circular dependency with `openshift/kubernetes` as it requires OTE and, without having done this,
+OTE would require `kubernetes/kubernetes`.
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/byte.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/byte.go
new file mode 100644
index 0000000000..4d7a17c3af
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/byte.go
@@ -0,0 +1,137 @@
+/*
+Copyright 2022 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package sets
+
+// Byte is a set of bytes, implemented via map[byte]struct{} for minimal memory consumption.
+//
+// Deprecated: use generic Set instead.
+// new ways:
+// s1 := Set[byte]{}
+// s2 := New[byte]()
+type Byte map[byte]Empty
+
+// NewByte creates a Byte from a list of values.
+func NewByte(items ...byte) Byte {
+ return Byte(New[byte](items...))
+}
+
+// ByteKeySet creates a Byte from a keys of a map[byte](? extends interface{}).
+// If the value passed in is not actually a map, this will panic.
+func ByteKeySet[T any](theMap map[byte]T) Byte {
+ return Byte(KeySet(theMap))
+}
+
+// Insert adds items to the set.
+func (s Byte) Insert(items ...byte) Byte {
+ return Byte(cast(s).Insert(items...))
+}
+
+// Delete removes all items from the set.
+func (s Byte) Delete(items ...byte) Byte {
+ return Byte(cast(s).Delete(items...))
+}
+
+// Has returns true if and only if item is contained in the set.
+func (s Byte) Has(item byte) bool {
+ return cast(s).Has(item)
+}
+
+// HasAll returns true if and only if all items are contained in the set.
+func (s Byte) HasAll(items ...byte) bool {
+ return cast(s).HasAll(items...)
+}
+
+// HasAny returns true if any items are contained in the set.
+func (s Byte) HasAny(items ...byte) bool {
+ return cast(s).HasAny(items...)
+}
+
+// Clone returns a new set which is a copy of the current set.
+func (s Byte) Clone() Byte {
+ return Byte(cast(s).Clone())
+}
+
+// Difference returns a set of objects that are not in s2.
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.Difference(s2) = {a3}
+// s2.Difference(s1) = {a4, a5}
+func (s1 Byte) Difference(s2 Byte) Byte {
+ return Byte(cast(s1).Difference(cast(s2)))
+}
+
+// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection.
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.SymmetricDifference(s2) = {a3, a4, a5}
+// s2.SymmetricDifference(s1) = {a3, a4, a5}
+func (s1 Byte) SymmetricDifference(s2 Byte) Byte {
+ return Byte(cast(s1).SymmetricDifference(cast(s2)))
+}
+
+// Union returns a new set which includes items in either s1 or s2.
+// For example:
+// s1 = {a1, a2}
+// s2 = {a3, a4}
+// s1.Union(s2) = {a1, a2, a3, a4}
+// s2.Union(s1) = {a1, a2, a3, a4}
+func (s1 Byte) Union(s2 Byte) Byte {
+ return Byte(cast(s1).Union(cast(s2)))
+}
+
+// Intersection returns a new set which includes the item in BOTH s1 and s2
+// For example:
+// s1 = {a1, a2}
+// s2 = {a2, a3}
+// s1.Intersection(s2) = {a2}
+func (s1 Byte) Intersection(s2 Byte) Byte {
+ return Byte(cast(s1).Intersection(cast(s2)))
+}
+
+// IsSuperset returns true if and only if s1 is a superset of s2.
+func (s1 Byte) IsSuperset(s2 Byte) bool {
+ return cast(s1).IsSuperset(cast(s2))
+}
+
+// Equal returns true if and only if s1 is equal (as a set) to s2.
+// Two sets are equal if their membership is identical.
+// (In practice, this means same elements, order doesn't matter)
+func (s1 Byte) Equal(s2 Byte) bool {
+ return cast(s1).Equal(cast(s2))
+}
+
+// List returns the contents as a sorted byte slice.
+func (s Byte) List() []byte {
+ return List(cast(s))
+}
+
+// UnsortedList returns the slice with contents in random order.
+func (s Byte) UnsortedList() []byte {
+ return cast(s).UnsortedList()
+}
+
+// PopAny returns a single element from the set.
+func (s Byte) PopAny() (byte, bool) {
+ return cast(s).PopAny()
+}
+
+// Len returns the size of the set.
+func (s Byte) Len() int {
+ return len(s)
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/doc.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/doc.go
new file mode 100644
index 0000000000..997f5e0330
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/doc.go
@@ -0,0 +1,19 @@
+/*
+Copyright 2022 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package sets has generic set and specified sets. Generic set will
+// replace specified ones over time. And specific ones are deprecated.
+package sets // import "github.com/openshift-eng/openshift-tests-extension/pkg/util/sets"
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/empty.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/empty.go
new file mode 100644
index 0000000000..fbb1df06d9
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/empty.go
@@ -0,0 +1,21 @@
+/*
+Copyright 2022 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package sets
+
+// Empty is public since it is used by some internal API objects for conversions between external
+// string arrays and internal sets, and conversion logic requires public types today.
+type Empty struct{}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/int.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/int.go
new file mode 100644
index 0000000000..5876fc9deb
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/int.go
@@ -0,0 +1,137 @@
+/*
+Copyright 2022 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package sets
+
+// Int is a set of ints, implemented via map[int]struct{} for minimal memory consumption.
+//
+// Deprecated: use generic Set instead.
+// new ways:
+// s1 := Set[int]{}
+// s2 := New[int]()
+type Int map[int]Empty
+
+// NewInt creates a Int from a list of values.
+func NewInt(items ...int) Int {
+ return Int(New[int](items...))
+}
+
+// IntKeySet creates a Int from a keys of a map[int](? extends interface{}).
+// If the value passed in is not actually a map, this will panic.
+func IntKeySet[T any](theMap map[int]T) Int {
+ return Int(KeySet(theMap))
+}
+
+// Insert adds items to the set.
+func (s Int) Insert(items ...int) Int {
+ return Int(cast(s).Insert(items...))
+}
+
+// Delete removes all items from the set.
+func (s Int) Delete(items ...int) Int {
+ return Int(cast(s).Delete(items...))
+}
+
+// Has returns true if and only if item is contained in the set.
+func (s Int) Has(item int) bool {
+ return cast(s).Has(item)
+}
+
+// HasAll returns true if and only if all items are contained in the set.
+func (s Int) HasAll(items ...int) bool {
+ return cast(s).HasAll(items...)
+}
+
+// HasAny returns true if any items are contained in the set.
+func (s Int) HasAny(items ...int) bool {
+ return cast(s).HasAny(items...)
+}
+
+// Clone returns a new set which is a copy of the current set.
+func (s Int) Clone() Int {
+ return Int(cast(s).Clone())
+}
+
+// Difference returns a set of objects that are not in s2.
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.Difference(s2) = {a3}
+// s2.Difference(s1) = {a4, a5}
+func (s1 Int) Difference(s2 Int) Int {
+ return Int(cast(s1).Difference(cast(s2)))
+}
+
+// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection.
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.SymmetricDifference(s2) = {a3, a4, a5}
+// s2.SymmetricDifference(s1) = {a3, a4, a5}
+func (s1 Int) SymmetricDifference(s2 Int) Int {
+ return Int(cast(s1).SymmetricDifference(cast(s2)))
+}
+
+// Union returns a new set which includes items in either s1 or s2.
+// For example:
+// s1 = {a1, a2}
+// s2 = {a3, a4}
+// s1.Union(s2) = {a1, a2, a3, a4}
+// s2.Union(s1) = {a1, a2, a3, a4}
+func (s1 Int) Union(s2 Int) Int {
+ return Int(cast(s1).Union(cast(s2)))
+}
+
+// Intersection returns a new set which includes the item in BOTH s1 and s2
+// For example:
+// s1 = {a1, a2}
+// s2 = {a2, a3}
+// s1.Intersection(s2) = {a2}
+func (s1 Int) Intersection(s2 Int) Int {
+ return Int(cast(s1).Intersection(cast(s2)))
+}
+
+// IsSuperset returns true if and only if s1 is a superset of s2.
+func (s1 Int) IsSuperset(s2 Int) bool {
+ return cast(s1).IsSuperset(cast(s2))
+}
+
+// Equal returns true if and only if s1 is equal (as a set) to s2.
+// Two sets are equal if their membership is identical.
+// (In practice, this means same elements, order doesn't matter)
+func (s1 Int) Equal(s2 Int) bool {
+ return cast(s1).Equal(cast(s2))
+}
+
+// List returns the contents as a sorted int slice.
+func (s Int) List() []int {
+ return List(cast(s))
+}
+
+// UnsortedList returns the slice with contents in random order.
+func (s Int) UnsortedList() []int {
+ return cast(s).UnsortedList()
+}
+
+// PopAny returns a single element from the set.
+func (s Int) PopAny() (int, bool) {
+ return cast(s).PopAny()
+}
+
+// Len returns the size of the set.
+func (s Int) Len() int {
+ return len(s)
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/int32.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/int32.go
new file mode 100644
index 0000000000..2c640c5d0f
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/int32.go
@@ -0,0 +1,137 @@
+/*
+Copyright 2022 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package sets
+
+// Int32 is a set of int32s, implemented via map[int32]struct{} for minimal memory consumption.
+//
+// Deprecated: use generic Set instead.
+// new ways:
+// s1 := Set[int32]{}
+// s2 := New[int32]()
+type Int32 map[int32]Empty
+
+// NewInt32 creates a Int32 from a list of values.
+func NewInt32(items ...int32) Int32 {
+ return Int32(New[int32](items...))
+}
+
+// Int32KeySet creates a Int32 from a keys of a map[int32](? extends interface{}).
+// If the value passed in is not actually a map, this will panic.
+func Int32KeySet[T any](theMap map[int32]T) Int32 {
+ return Int32(KeySet(theMap))
+}
+
+// Insert adds items to the set.
+func (s Int32) Insert(items ...int32) Int32 {
+ return Int32(cast(s).Insert(items...))
+}
+
+// Delete removes all items from the set.
+func (s Int32) Delete(items ...int32) Int32 {
+ return Int32(cast(s).Delete(items...))
+}
+
+// Has returns true if and only if item is contained in the set.
+func (s Int32) Has(item int32) bool {
+ return cast(s).Has(item)
+}
+
+// HasAll returns true if and only if all items are contained in the set.
+func (s Int32) HasAll(items ...int32) bool {
+ return cast(s).HasAll(items...)
+}
+
+// HasAny returns true if any items are contained in the set.
+func (s Int32) HasAny(items ...int32) bool {
+ return cast(s).HasAny(items...)
+}
+
+// Clone returns a new set which is a copy of the current set.
+func (s Int32) Clone() Int32 {
+ return Int32(cast(s).Clone())
+}
+
+// Difference returns a set of objects that are not in s2.
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.Difference(s2) = {a3}
+// s2.Difference(s1) = {a4, a5}
+func (s1 Int32) Difference(s2 Int32) Int32 {
+ return Int32(cast(s1).Difference(cast(s2)))
+}
+
+// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection.
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.SymmetricDifference(s2) = {a3, a4, a5}
+// s2.SymmetricDifference(s1) = {a3, a4, a5}
+func (s1 Int32) SymmetricDifference(s2 Int32) Int32 {
+ return Int32(cast(s1).SymmetricDifference(cast(s2)))
+}
+
+// Union returns a new set which includes items in either s1 or s2.
+// For example:
+// s1 = {a1, a2}
+// s2 = {a3, a4}
+// s1.Union(s2) = {a1, a2, a3, a4}
+// s2.Union(s1) = {a1, a2, a3, a4}
+func (s1 Int32) Union(s2 Int32) Int32 {
+ return Int32(cast(s1).Union(cast(s2)))
+}
+
+// Intersection returns a new set which includes the item in BOTH s1 and s2
+// For example:
+// s1 = {a1, a2}
+// s2 = {a2, a3}
+// s1.Intersection(s2) = {a2}
+func (s1 Int32) Intersection(s2 Int32) Int32 {
+ return Int32(cast(s1).Intersection(cast(s2)))
+}
+
+// IsSuperset returns true if and only if s1 is a superset of s2.
+func (s1 Int32) IsSuperset(s2 Int32) bool {
+ return cast(s1).IsSuperset(cast(s2))
+}
+
+// Equal returns true if and only if s1 is equal (as a set) to s2.
+// Two sets are equal if their membership is identical.
+// (In practice, this means same elements, order doesn't matter)
+func (s1 Int32) Equal(s2 Int32) bool {
+ return cast(s1).Equal(cast(s2))
+}
+
+// List returns the contents as a sorted int32 slice.
+func (s Int32) List() []int32 {
+ return List(cast(s))
+}
+
+// UnsortedList returns the slice with contents in random order.
+func (s Int32) UnsortedList() []int32 {
+ return cast(s).UnsortedList()
+}
+
+// PopAny returns a single element from the set.
+func (s Int32) PopAny() (int32, bool) {
+ return cast(s).PopAny()
+}
+
+// Len returns the size of the set.
+func (s Int32) Len() int {
+ return len(s)
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/int64.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/int64.go
new file mode 100644
index 0000000000..bf3eb3ffa2
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/int64.go
@@ -0,0 +1,137 @@
+/*
+Copyright 2022 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package sets
+
+// Int64 is a set of int64s, implemented via map[int64]struct{} for minimal memory consumption.
+//
+// Deprecated: use generic Set instead.
+// new ways:
+// s1 := Set[int64]{}
+// s2 := New[int64]()
+type Int64 map[int64]Empty
+
+// NewInt64 creates a Int64 from a list of values.
+func NewInt64(items ...int64) Int64 {
+ return Int64(New[int64](items...))
+}
+
+// Int64KeySet creates a Int64 from a keys of a map[int64](? extends interface{}).
+// If the value passed in is not actually a map, this will panic.
+func Int64KeySet[T any](theMap map[int64]T) Int64 {
+ return Int64(KeySet(theMap))
+}
+
+// Insert adds items to the set.
+func (s Int64) Insert(items ...int64) Int64 {
+ return Int64(cast(s).Insert(items...))
+}
+
+// Delete removes all items from the set.
+func (s Int64) Delete(items ...int64) Int64 {
+ return Int64(cast(s).Delete(items...))
+}
+
+// Has returns true if and only if item is contained in the set.
+func (s Int64) Has(item int64) bool {
+ return cast(s).Has(item)
+}
+
+// HasAll returns true if and only if all items are contained in the set.
+func (s Int64) HasAll(items ...int64) bool {
+ return cast(s).HasAll(items...)
+}
+
+// HasAny returns true if any items are contained in the set.
+func (s Int64) HasAny(items ...int64) bool {
+ return cast(s).HasAny(items...)
+}
+
+// Clone returns a new set which is a copy of the current set.
+func (s Int64) Clone() Int64 {
+ return Int64(cast(s).Clone())
+}
+
+// Difference returns a set of objects that are not in s2.
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.Difference(s2) = {a3}
+// s2.Difference(s1) = {a4, a5}
+func (s1 Int64) Difference(s2 Int64) Int64 {
+ return Int64(cast(s1).Difference(cast(s2)))
+}
+
+// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection.
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.SymmetricDifference(s2) = {a3, a4, a5}
+// s2.SymmetricDifference(s1) = {a3, a4, a5}
+func (s1 Int64) SymmetricDifference(s2 Int64) Int64 {
+ return Int64(cast(s1).SymmetricDifference(cast(s2)))
+}
+
+// Union returns a new set which includes items in either s1 or s2.
+// For example:
+// s1 = {a1, a2}
+// s2 = {a3, a4}
+// s1.Union(s2) = {a1, a2, a3, a4}
+// s2.Union(s1) = {a1, a2, a3, a4}
+func (s1 Int64) Union(s2 Int64) Int64 {
+ return Int64(cast(s1).Union(cast(s2)))
+}
+
+// Intersection returns a new set which includes the item in BOTH s1 and s2
+// For example:
+// s1 = {a1, a2}
+// s2 = {a2, a3}
+// s1.Intersection(s2) = {a2}
+func (s1 Int64) Intersection(s2 Int64) Int64 {
+ return Int64(cast(s1).Intersection(cast(s2)))
+}
+
+// IsSuperset returns true if and only if s1 is a superset of s2.
+func (s1 Int64) IsSuperset(s2 Int64) bool {
+ return cast(s1).IsSuperset(cast(s2))
+}
+
+// Equal returns true if and only if s1 is equal (as a set) to s2.
+// Two sets are equal if their membership is identical.
+// (In practice, this means same elements, order doesn't matter)
+func (s1 Int64) Equal(s2 Int64) bool {
+ return cast(s1).Equal(cast(s2))
+}
+
+// List returns the contents as a sorted int64 slice.
+func (s Int64) List() []int64 {
+ return List(cast(s))
+}
+
+// UnsortedList returns the slice with contents in random order.
+func (s Int64) UnsortedList() []int64 {
+ return cast(s).UnsortedList()
+}
+
+// PopAny returns a single element from the set.
+func (s Int64) PopAny() (int64, bool) {
+ return cast(s).PopAny()
+}
+
+// Len returns the size of the set.
+func (s Int64) Len() int {
+ return len(s)
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/set.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/set.go
new file mode 100644
index 0000000000..cd961c8c59
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/set.go
@@ -0,0 +1,236 @@
+/*
+Copyright 2022 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package sets
+
+import (
+ "cmp"
+ "sort"
+)
+
+// Set is a set of the same type elements, implemented via map[comparable]struct{} for minimal memory consumption.
+type Set[T comparable] map[T]Empty
+
+// cast transforms specified set to generic Set[T].
+func cast[T comparable](s map[T]Empty) Set[T] { return s }
+
+// New creates a Set from a list of values.
+// NOTE: type param must be explicitly instantiated if given items are empty.
+func New[T comparable](items ...T) Set[T] {
+ ss := make(Set[T], len(items))
+ ss.Insert(items...)
+ return ss
+}
+
+// KeySet creates a Set from a keys of a map[comparable](? extends interface{}).
+// If the value passed in is not actually a map, this will panic.
+func KeySet[T comparable, V any](theMap map[T]V) Set[T] {
+ ret := make(Set[T], len(theMap))
+ for keyValue := range theMap {
+ ret.Insert(keyValue)
+ }
+ return ret
+}
+
+// Insert adds items to the set.
+func (s Set[T]) Insert(items ...T) Set[T] {
+ for _, item := range items {
+ s[item] = Empty{}
+ }
+ return s
+}
+
+func Insert[T comparable](set Set[T], items ...T) Set[T] {
+ return set.Insert(items...)
+}
+
+// Delete removes all items from the set.
+func (s Set[T]) Delete(items ...T) Set[T] {
+ for _, item := range items {
+ delete(s, item)
+ }
+ return s
+}
+
+// Clear empties the set.
+// It is preferable to replace the set with a newly constructed set,
+// but not all callers can do that (when there are other references to the map).
+func (s Set[T]) Clear() Set[T] {
+ clear(s)
+ return s
+}
+
+// Has returns true if and only if item is contained in the set.
+func (s Set[T]) Has(item T) bool {
+ _, contained := s[item]
+ return contained
+}
+
+// HasAll returns true if and only if all items are contained in the set.
+func (s Set[T]) HasAll(items ...T) bool {
+ for _, item := range items {
+ if !s.Has(item) {
+ return false
+ }
+ }
+ return true
+}
+
+// HasAny returns true if any items are contained in the set.
+func (s Set[T]) HasAny(items ...T) bool {
+ for _, item := range items {
+ if s.Has(item) {
+ return true
+ }
+ }
+ return false
+}
+
+// Clone returns a new set which is a copy of the current set.
+func (s Set[T]) Clone() Set[T] {
+ result := make(Set[T], len(s))
+ for key := range s {
+ result.Insert(key)
+ }
+ return result
+}
+
+// Difference returns a set of objects that are not in s2.
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.Difference(s2) = {a3}
+// s2.Difference(s1) = {a4, a5}
+func (s1 Set[T]) Difference(s2 Set[T]) Set[T] {
+ result := New[T]()
+ for key := range s1 {
+ if !s2.Has(key) {
+ result.Insert(key)
+ }
+ }
+ return result
+}
+
+// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection.
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.SymmetricDifference(s2) = {a3, a4, a5}
+// s2.SymmetricDifference(s1) = {a3, a4, a5}
+func (s1 Set[T]) SymmetricDifference(s2 Set[T]) Set[T] {
+ return s1.Difference(s2).Union(s2.Difference(s1))
+}
+
+// Union returns a new set which includes items in either s1 or s2.
+// For example:
+// s1 = {a1, a2}
+// s2 = {a3, a4}
+// s1.Union(s2) = {a1, a2, a3, a4}
+// s2.Union(s1) = {a1, a2, a3, a4}
+func (s1 Set[T]) Union(s2 Set[T]) Set[T] {
+ result := s1.Clone()
+ for key := range s2 {
+ result.Insert(key)
+ }
+ return result
+}
+
+// Intersection returns a new set which includes the item in BOTH s1 and s2
+// For example:
+// s1 = {a1, a2}
+// s2 = {a2, a3}
+// s1.Intersection(s2) = {a2}
+func (s1 Set[T]) Intersection(s2 Set[T]) Set[T] {
+ var walk, other Set[T]
+ result := New[T]()
+ if s1.Len() < s2.Len() {
+ walk = s1
+ other = s2
+ } else {
+ walk = s2
+ other = s1
+ }
+ for key := range walk {
+ if other.Has(key) {
+ result.Insert(key)
+ }
+ }
+ return result
+}
+
+// IsSuperset returns true if and only if s1 is a superset of s2.
+func (s1 Set[T]) IsSuperset(s2 Set[T]) bool {
+ for item := range s2 {
+ if !s1.Has(item) {
+ return false
+ }
+ }
+ return true
+}
+
+// Equal returns true if and only if s1 is equal (as a set) to s2.
+// Two sets are equal if their membership is identical.
+// (In practice, this means same elements, order doesn't matter)
+func (s1 Set[T]) Equal(s2 Set[T]) bool {
+ return len(s1) == len(s2) && s1.IsSuperset(s2)
+}
+
+type sortableSliceOfGeneric[T cmp.Ordered] []T
+
+func (g sortableSliceOfGeneric[T]) Len() int { return len(g) }
+func (g sortableSliceOfGeneric[T]) Less(i, j int) bool { return less[T](g[i], g[j]) }
+func (g sortableSliceOfGeneric[T]) Swap(i, j int) { g[i], g[j] = g[j], g[i] }
+
+// List returns the contents as a sorted T slice.
+//
+// This is a separate function and not a method because not all types supported
+// by Generic are ordered and only those can be sorted.
+func List[T cmp.Ordered](s Set[T]) []T {
+ res := make(sortableSliceOfGeneric[T], 0, len(s))
+ for key := range s {
+ res = append(res, key)
+ }
+ sort.Sort(res)
+ return res
+}
+
+// UnsortedList returns the slice with contents in random order.
+func (s Set[T]) UnsortedList() []T {
+ res := make([]T, 0, len(s))
+ for key := range s {
+ res = append(res, key)
+ }
+ return res
+}
+
+// PopAny returns a single element from the set.
+func (s Set[T]) PopAny() (T, bool) {
+ for key := range s {
+ s.Delete(key)
+ return key, true
+ }
+ var zeroValue T
+ return zeroValue, false
+}
+
+// Len returns the size of the set.
+func (s Set[T]) Len() int {
+ return len(s)
+}
+
+func less[T cmp.Ordered](lhs, rhs T) bool {
+ return lhs < rhs
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/string.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/string.go
new file mode 100644
index 0000000000..1dab6d13cc
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/util/sets/string.go
@@ -0,0 +1,137 @@
+/*
+Copyright 2022 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package sets
+
+// String is a set of strings, implemented via map[string]struct{} for minimal memory consumption.
+//
+// Deprecated: use generic Set instead.
+// new ways:
+// s1 := Set[string]{}
+// s2 := New[string]()
+type String map[string]Empty
+
+// NewString creates a String from a list of values.
+func NewString(items ...string) String {
+ return String(New[string](items...))
+}
+
+// StringKeySet creates a String from a keys of a map[string](? extends interface{}).
+// If the value passed in is not actually a map, this will panic.
+func StringKeySet[T any](theMap map[string]T) String {
+ return String(KeySet(theMap))
+}
+
+// Insert adds items to the set.
+func (s String) Insert(items ...string) String {
+ return String(cast(s).Insert(items...))
+}
+
+// Delete removes all items from the set.
+func (s String) Delete(items ...string) String {
+ return String(cast(s).Delete(items...))
+}
+
+// Has returns true if and only if item is contained in the set.
+func (s String) Has(item string) bool {
+ return cast(s).Has(item)
+}
+
+// HasAll returns true if and only if all items are contained in the set.
+func (s String) HasAll(items ...string) bool {
+ return cast(s).HasAll(items...)
+}
+
+// HasAny returns true if any items are contained in the set.
+func (s String) HasAny(items ...string) bool {
+ return cast(s).HasAny(items...)
+}
+
+// Clone returns a new set which is a copy of the current set.
+func (s String) Clone() String {
+ return String(cast(s).Clone())
+}
+
+// Difference returns a set of objects that are not in s2.
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.Difference(s2) = {a3}
+// s2.Difference(s1) = {a4, a5}
+func (s1 String) Difference(s2 String) String {
+ return String(cast(s1).Difference(cast(s2)))
+}
+
+// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection.
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.SymmetricDifference(s2) = {a3, a4, a5}
+// s2.SymmetricDifference(s1) = {a3, a4, a5}
+func (s1 String) SymmetricDifference(s2 String) String {
+ return String(cast(s1).SymmetricDifference(cast(s2)))
+}
+
+// Union returns a new set which includes items in either s1 or s2.
+// For example:
+// s1 = {a1, a2}
+// s2 = {a3, a4}
+// s1.Union(s2) = {a1, a2, a3, a4}
+// s2.Union(s1) = {a1, a2, a3, a4}
+func (s1 String) Union(s2 String) String {
+ return String(cast(s1).Union(cast(s2)))
+}
+
+// Intersection returns a new set which includes the item in BOTH s1 and s2
+// For example:
+// s1 = {a1, a2}
+// s2 = {a2, a3}
+// s1.Intersection(s2) = {a2}
+func (s1 String) Intersection(s2 String) String {
+ return String(cast(s1).Intersection(cast(s2)))
+}
+
+// IsSuperset returns true if and only if s1 is a superset of s2.
+func (s1 String) IsSuperset(s2 String) bool {
+ return cast(s1).IsSuperset(cast(s2))
+}
+
+// Equal returns true if and only if s1 is equal (as a set) to s2.
+// Two sets are equal if their membership is identical.
+// (In practice, this means same elements, order doesn't matter)
+func (s1 String) Equal(s2 String) bool {
+ return cast(s1).Equal(cast(s2))
+}
+
+// List returns the contents as a sorted string slice.
+func (s String) List() []string {
+ return List(cast(s))
+}
+
+// UnsortedList returns the slice with contents in random order.
+func (s String) UnsortedList() []string {
+ return cast(s).UnsortedList()
+}
+
+// PopAny returns a single element from the set.
+func (s String) PopAny() (string, bool) {
+ return cast(s).PopAny()
+}
+
+// Len returns the size of the set.
+func (s String) Len() int {
+ return len(s)
+}
diff --git a/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/version/version.go b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/version/version.go
new file mode 100644
index 0000000000..7d6a3309b3
--- /dev/null
+++ b/vendor/github.com/openshift-eng/openshift-tests-extension/pkg/version/version.go
@@ -0,0 +1,11 @@
+package version
+
+var (
+ // CommitFromGit is a constant representing the source version that
+ // generated this build. It should be set during build via -ldflags.
+ CommitFromGit string
+ // BuildDate in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ')
+ BuildDate string
+ // GitTreeState has the state of git tree, either "clean" or "dirty"
+ GitTreeState string
+)
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 36f75b5f4a..a6d861e247 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1093,13 +1093,12 @@ github.com/nunnatsa/ginkgolinter/version
# github.com/oklog/ulid v1.3.1
## explicit
github.com/oklog/ulid
-# github.com/onsi/ginkgo/v2 v2.28.1
-## explicit; go 1.24.0
+# github.com/onsi/ginkgo/v2 v2.28.1 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20241205171354-8006f302fd12
+## explicit; go 1.22.0
github.com/onsi/ginkgo/v2
github.com/onsi/ginkgo/v2/config
github.com/onsi/ginkgo/v2/formatter
github.com/onsi/ginkgo/v2/ginkgo
-github.com/onsi/ginkgo/v2/ginkgo/automaxprocs
github.com/onsi/ginkgo/v2/ginkgo/build
github.com/onsi/ginkgo/v2/ginkgo/command
github.com/onsi/ginkgo/v2/ginkgo/generators
@@ -1113,7 +1112,6 @@ github.com/onsi/ginkgo/v2/internal
github.com/onsi/ginkgo/v2/internal/global
github.com/onsi/ginkgo/v2/internal/interrupt_handler
github.com/onsi/ginkgo/v2/internal/parallel_support
-github.com/onsi/ginkgo/v2/internal/reporters
github.com/onsi/ginkgo/v2/internal/testingtproxy
github.com/onsi/ginkgo/v2/reporters
github.com/onsi/ginkgo/v2/types
@@ -1133,6 +1131,22 @@ github.com/onsi/gomega/types
# github.com/opencontainers/go-digest v1.0.0
## explicit; go 1.13
github.com/opencontainers/go-digest
+# github.com/openshift-eng/openshift-tests-extension v0.0.0-20260612102633-2fd5b2fa4221
+## explicit; go 1.23.0
+github.com/openshift-eng/openshift-tests-extension/pkg/cmd
+github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdimages
+github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdinfo
+github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdlist
+github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdrun
+github.com/openshift-eng/openshift-tests-extension/pkg/cmd/cmdupdate
+github.com/openshift-eng/openshift-tests-extension/pkg/dbtime
+github.com/openshift-eng/openshift-tests-extension/pkg/extension
+github.com/openshift-eng/openshift-tests-extension/pkg/extension/extensiontests
+github.com/openshift-eng/openshift-tests-extension/pkg/flags
+github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo
+github.com/openshift-eng/openshift-tests-extension/pkg/junit
+github.com/openshift-eng/openshift-tests-extension/pkg/util/sets
+github.com/openshift-eng/openshift-tests-extension/pkg/version
# github.com/openshift/api v0.0.0-20260416105050-3c6b218b8a80
## explicit; go 1.25.0
github.com/openshift/api
@@ -1269,6 +1283,8 @@ github.com/openshift/cluster-api-provider-baremetal/pkg/apis/baremetal/v1alpha1
github.com/openshift/cluster-autoscaler-operator/pkg/apis/autoscaling/v1
# github.com/openshift/cluster-capi-operator v0.0.0-20260425200736-89a8af46df2a
## explicit; go 1.25.3
+# github.com/openshift/cluster-capi-operator/e2e v0.0.0-00010101000000-000000000000 => ./e2e
+## explicit; go 1.25.3
# github.com/openshift/cluster-capi-operator/manifests-gen v0.0.0-00010101000000-000000000000 => ./manifests-gen
## explicit; go 1.25.0
# github.com/openshift/controller-runtime-common v0.0.0-20260428152732-64ee174f5e2e
@@ -3346,3 +3362,4 @@ sigs.k8s.io/yaml/goyaml.v2
# k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.35.3
# k8s.io/sample-controller => k8s.io/sample-controller v0.35.3
# github.com/metal3-io/baremetal-operator => github.com/metal3-io/baremetal-operator v0.5.1
+# github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20241205171354-8006f302fd12