diff --git a/go.mod b/go.mod
index f7d044e43..b2250df24 100644
--- a/go.mod
+++ b/go.mod
@@ -19,8 +19,8 @@ require (
github.com/googleapis/gax-go/v2 v2.14.2
github.com/hashicorp/go-version v1.6.0
github.com/lib/pq v1.10.9
- github.com/onsi/ginkgo/v2 v2.27.2
- github.com/onsi/gomega v1.38.2
+ github.com/onsi/ginkgo/v2 v2.32.0
+ github.com/onsi/gomega v1.40.0
github.com/openshift/api v0.0.0-20231204192004-bfea29e5e6c4
github.com/openshift/cloud-credential-operator v0.0.0-20240510165258-af5662f1dbe2
github.com/pkg/errors v0.9.1
@@ -78,7 +78,7 @@ require (
github.com/google/cel-go v0.26.0 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
- github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
+ github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
@@ -113,14 +113,14 @@ require (
go.yaml.in/yaml/v2 v2.4.3 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
- golang.org/x/mod v0.34.0 // indirect
+ golang.org/x/mod v0.35.0 // indirect
golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.43.0 // indirect
golang.org/x/term v0.42.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/time v0.11.0 // indirect
- golang.org/x/tools v0.43.0 // indirect
+ golang.org/x/tools v0.44.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
diff --git a/go.sum b/go.sum
index 4b5b3b6ac..6657d86c0 100644
--- a/go.sum
+++ b/go.sum
@@ -116,8 +116,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
-github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
+github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 h1:EwtI+Al+DeppwYX2oXJCETMO23COyaKGP6fHVpkpWpg=
+github.com/google/pprof v0.0.0-20260402051712-545e8a4df936/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.14.2 h1:eBLnkZ9635krYIPD+ag1USrOAI0Nr0QYF3+/3GqO0k0=
@@ -169,10 +169,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
-github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
-github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
-github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
-github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
+github.com/onsi/ginkgo/v2 v2.32.0 h1:Hw7s2pVrQo/8Yz5N77qdnpHaoc+c6cC9WIV1Jce+J6E=
+github.com/onsi/ginkgo/v2 v2.32.0/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44=
+github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc=
+github.com/onsi/gomega v1.40.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A=
github.com/openshift/api v0.0.0-20231204192004-bfea29e5e6c4 h1:5RyeLvTSZEn/fDQA6e6+qIvFPssWjreY8pbwfg4/EEQ=
github.com/openshift/api v0.0.0-20231204192004-bfea29e5e6c4/go.mod h1:qNtV0315F+f8ld52TLtPvrfivZpdimOzTi3kn9IVbtU=
github.com/openshift/cloud-credential-operator v0.0.0-20240510165258-af5662f1dbe2 h1:AihhvRMLti3ueqRKsbGxD9H5HgCuxX03GQO9ATAv95I=
@@ -266,8 +266,8 @@ golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
-golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
+golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
+golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -299,8 +299,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
-golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
+golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
+golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/vendor/github.com/google/pprof/profile/merge.go b/vendor/github.com/google/pprof/profile/merge.go
index ba4d74640..8a51690be 100644
--- a/vendor/github.com/google/pprof/profile/merge.go
+++ b/vendor/github.com/google/pprof/profile/merge.go
@@ -17,6 +17,7 @@ package profile
import (
"encoding/binary"
"fmt"
+ "slices"
"sort"
"strconv"
"strings"
@@ -78,12 +79,10 @@ func Merge(srcs []*Profile) (*Profile, error) {
}
}
- for _, s := range p.Sample {
- if isZeroSample(s) {
- // If there are any zero samples, re-merge the profile to GC
- // them.
- return Merge([]*Profile{p})
- }
+ if slices.ContainsFunc(p.Sample, isZeroSample) {
+ // If there are any zero samples, re-merge the profile to GC
+ // them.
+ return Merge([]*Profile{p})
}
return p, nil
diff --git a/vendor/github.com/google/pprof/profile/profile.go b/vendor/github.com/google/pprof/profile/profile.go
index f47a24390..18df65a8d 100644
--- a/vendor/github.com/google/pprof/profile/profile.go
+++ b/vendor/github.com/google/pprof/profile/profile.go
@@ -24,6 +24,7 @@ import (
"math"
"path/filepath"
"regexp"
+ "slices"
"sort"
"strings"
"sync"
@@ -277,7 +278,7 @@ func (p *Profile) massageMappings() {
// Use heuristics to identify main binary and move it to the top of the list of mappings
for i, m := range p.Mapping {
- file := strings.TrimSpace(strings.Replace(m.File, "(deleted)", "", -1))
+ file := strings.TrimSpace(strings.ReplaceAll(m.File, "(deleted)", ""))
if len(file) == 0 {
continue
}
@@ -734,12 +735,7 @@ func (p *Profile) RemoveLabel(key string) {
// HasLabel returns true if a sample has a label with indicated key and value.
func (s *Sample) HasLabel(key, value string) bool {
- for _, v := range s.Label[key] {
- if v == value {
- return true
- }
- }
- return false
+ return slices.Contains(s.Label[key], value)
}
// SetNumLabel sets the specified key to the specified value for all samples in the
@@ -852,7 +848,17 @@ func (p *Profile) HasFileLines() bool {
// "[vdso]", "[vsyscall]" and some others, see the code.
func (m *Mapping) Unsymbolizable() bool {
name := filepath.Base(m.File)
- return strings.HasPrefix(name, "[") || strings.HasPrefix(name, "linux-vdso") || strings.HasPrefix(m.File, "/dev/dri/") || m.File == "//anon"
+ switch {
+ case strings.HasPrefix(name, "["):
+ case strings.HasPrefix(name, "linux-vdso"):
+ case strings.HasPrefix(m.File, "/dev/dri/"):
+ case m.File == "//anon":
+ case m.File == "":
+ case strings.HasPrefix(m.File, "/memfd:"):
+ default:
+ return false
+ }
+ return true
}
// Copy makes a fully independent copy of a profile.
diff --git a/vendor/github.com/google/pprof/profile/proto.go b/vendor/github.com/google/pprof/profile/proto.go
index a15696ba1..31bf6bca6 100644
--- a/vendor/github.com/google/pprof/profile/proto.go
+++ b/vendor/github.com/google/pprof/profile/proto.go
@@ -36,6 +36,7 @@ package profile
import (
"errors"
"fmt"
+ "slices"
)
type buffer struct {
@@ -187,6 +188,16 @@ func le32(p []byte) uint32 {
return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24
}
+func peekNumVarints(data []byte) (numVarints int) {
+ for ; len(data) > 0; numVarints++ {
+ var err error
+ if _, data, err = decodeVarint(data); err != nil {
+ break
+ }
+ }
+ return numVarints
+}
+
func decodeVarint(data []byte) (uint64, []byte, error) {
var u uint64
for i := 0; ; i++ {
@@ -286,6 +297,9 @@ func decodeInt64(b *buffer, x *int64) error {
func decodeInt64s(b *buffer, x *[]int64) error {
if b.typ == 2 {
// Packed encoding
+ dataLen := peekNumVarints(b.data)
+ *x = slices.Grow(*x, dataLen)
+
data := b.data
for len(data) > 0 {
var u uint64
@@ -316,8 +330,11 @@ func decodeUint64(b *buffer, x *uint64) error {
func decodeUint64s(b *buffer, x *[]uint64) error {
if b.typ == 2 {
- data := b.data
// Packed encoding
+ dataLen := peekNumVarints(b.data)
+ *x = slices.Grow(*x, dataLen)
+
+ data := b.data
for len(data) > 0 {
var u uint64
var err error
diff --git a/vendor/github.com/google/pprof/profile/prune.go b/vendor/github.com/google/pprof/profile/prune.go
index b2f9fd546..7bba31e8c 100644
--- a/vendor/github.com/google/pprof/profile/prune.go
+++ b/vendor/github.com/google/pprof/profile/prune.go
@@ -19,6 +19,7 @@ package profile
import (
"fmt"
"regexp"
+ "slices"
"strings"
)
@@ -40,13 +41,7 @@ func simplifyFunc(f string) string {
// Account for unsimplified names -- try to remove the argument list by trimming
// starting from the first '(', but skipping reserved names that have '('.
for _, ind := range bracketRx.FindAllStringSubmatchIndex(funcName, -1) {
- foundReserved := false
- for _, res := range reservedNames {
- if funcName[ind[0]:ind[1]] == res {
- foundReserved = true
- break
- }
- }
+ foundReserved := slices.Contains(reservedNames, funcName[ind[0]:ind[1]])
if !foundReserved {
funcName = funcName[:ind[0]]
break
diff --git a/vendor/github.com/onsi/ginkgo/v2/.gitignore b/vendor/github.com/onsi/ginkgo/v2/.gitignore
index 6faaaf315..c9f054620 100644
--- a/vendor/github.com/onsi/ginkgo/v2/.gitignore
+++ b/vendor/github.com/onsi/ginkgo/v2/.gitignore
@@ -1,6 +1,7 @@
.DS_Store
TODO
tmp/**/*
+integration/tmp_*/
*.coverprofile
.vscode
.idea/
diff --git a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
index 092179411..10e608564 100644
--- a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
+++ b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
@@ -1,3 +1,86 @@
+## 2.32.0
+
+`-fd` generate RSpec-style documentation output. Thank @woodie !
+--sleep-on-failure pauses a failed spec before teardown. Thanks @qinqon !
+
+## 2.31.0
+
+Add a bunch of Claude Skills via the marketplace:
+
+```
+/plugin marketplace add onsi/ginkgo
+/plugin install ginkgo@ginkgo
+```
+
+## 2.30.0
+
+### Features
+Ginkgo now allows `extentions/global.Reset` to support running multiple suites from within a single process. This may take some massaging on your part (see [1672](https://github.com/onsi/ginkgo/issues/1672)) but can dramatically speed up codebases with O(hundreds) of test suites.
+
+Thanks @lawrencejones !
+
+### Fixes
+
+- Fix nested --github-output group for progress report nested inside timeline [4f62d7a]
+
+## 2.29.0
+
+`GinkgoHelperGo` makes it easier to write test helpers that need to run in goroutines. Specifically, it makes managing the failure state and capturing failure panics correctly straightforward.
+
+`ginkgo outline` now includes entries defined in `DescribeTableSubtree`
+
+## 2.28.3
+
+### Maintenance
+Bump all dependencies
+
+## 2.28.2
+
+- Add ArtifactDir() to support Go 1.26 testing.TB interface [f3a36b6]
+- Implement shell completion [94151c8]
+- Add asan CLI option mirroring msan implementation [4d21dbb]
+- Bump uri from 1.0.3 to 1.0.4 in /docs (#1630) [c102161]
+- fix aspect ratio [9619647]
+- update logos [5779304]
+
+## 2.28.1
+
+Update all dependencies. This auto-updated the required version of Go to 1.24, consistent with the fact that Go 1.23 has been out of support for almost six months.
+
+## 2.28.0
+
+Ginkgo's SemVer filter now supports filtering multiple components by SemVer version:
+
+```go
+It("should work in a specific version range (1.0.0, 2.0.0) and third-party dependency redis in [8.0.0, ~)", SemVerConstraint(">= 3.2.0"), ComponentSemVerConstraint("redis", ">= 8.0.0") func() {
+ // This test will only run when version is between 1.0.0 (exclusive) and 2.0.0 (exclusive) and redis version is >= 8.0.0
+})
+```
+
+can be filtered in or out with an invocation like:
+
+```bash
+ginkgo --sem-ver-filter="2.1.1, redis=8.2.0"
+```
+
+Huge thanks to @Icarus9913 for working on this!
+
+## 2.27.5
+
+### Fixes
+Don't make a new formatter for each GinkgoT(); that's just silly and uses precious memory
+
+## 2.27.4
+
+### Fixes
+- CurrentTreeConstructionNodeReport: fix for nested container nodes [59bc751]
+
+## 2.27.3
+
+### Fixes
+report exit result in case of failure [1c9f356]
+fix data race [ece19c8]
+
## 2.27.2
### Fixes
diff --git a/vendor/github.com/onsi/ginkgo/v2/README.md b/vendor/github.com/onsi/ginkgo/v2/README.md
index 7b7ab9e39..ad5e45f67 100644
--- a/vendor/github.com/onsi/ginkgo/v2/README.md
+++ b/vendor/github.com/onsi/ginkgo/v2/README.md
@@ -106,6 +106,19 @@ And that's just Ginkgo! [Gomega](https://onsi.github.io/gomega/) brings a rich,
Happy Testing!
+## Using Ginkgo with Claude Code
+
+Ginkgo ships a set of [Claude Code](https://claude.com/claude-code) skills as a plugin, with this repo doubling as the marketplace, so an agent writing specs in *your* project has Ginkgo's idioms, decorators, and gotchas on hand. From inside Claude Code:
+
+```
+/plugin marketplace add onsi/ginkgo
+/plugin install ginkgo@ginkgo
+```
+
+(or non-interactively: `claude plugin marketplace add onsi/ginkgo` then `claude plugin install ginkgo@ginkgo`)
+
+This installs a family of `ginkgo:*` skills that activate automatically while you write and run specs. Start with `ginkgo:overview`; see the [plugin README](plugins/ginkgo/README.md) for the full list.
+
## License
Ginkgo is MIT-Licensed
@@ -119,7 +132,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md)
Sponsors commit to a [sponsorship](https://github.com/sponsors/onsi) for a year. If you're an organization that makes use of Ginkgo please consider becoming a sponsor!
Browser testing via
-
-
+
+
diff --git a/vendor/github.com/onsi/ginkgo/v2/core_dsl.go b/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
index 7e165e473..fb5761c1f 100644
--- a/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
@@ -20,6 +20,7 @@ import (
"io"
"os"
"path/filepath"
+ "slices"
"strings"
"github.com/go-logr/logr"
@@ -38,7 +39,6 @@ var flagSet types.GinkgoFlagSet
var deprecationTracker = types.NewDeprecationTracker()
var suiteConfig = types.NewDefaultSuiteConfig()
var reporterConfig = types.NewDefaultReporterConfig()
-var suiteDidRun = false
var outputInterceptor internal.OutputInterceptor
var client parallel_support.Client
@@ -258,17 +258,17 @@ 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 {
- if suiteDidRun {
+ if global.SuiteDidRun {
exitIfErr(types.GinkgoErrors.RerunningSuite())
}
- suiteDidRun = true
+ global.SuiteDidRun = true
err := global.PushClone()
if err != nil {
exitIfErr(err)
}
defer global.PopClone()
- suiteLabels, suiteSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
+ suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
var reporter reporters.Reporter
if suiteConfig.ParallelTotal == 1 {
@@ -311,7 +311,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, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
+ passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
outputInterceptor.Shutdown()
flagSet.ValidateDeprecations(deprecationTracker)
@@ -330,9 +330,10 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
return passed
}
-func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.AroundNodes) {
+func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, ComponentSemVerConstraints, types.AroundNodes) {
suiteLabels := Labels{}
suiteSemVerConstraints := SemVerConstraints{}
+ suiteComponentSemVerConstraints := ComponentSemVerConstraints{}
aroundNodes := types.AroundNodes{}
configErrors := []error{}
for _, arg := range args {
@@ -345,6 +346,11 @@ func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.Aro
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:
@@ -355,14 +361,14 @@ func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.Aro
configErrors = types.VetConfig(flagSet, suiteConfig, reporterConfig)
if len(configErrors) > 0 {
- fmt.Fprintf(formatter.ColorableStdErr, formatter.F("{{red}}Ginkgo detected configuration issues:{{/}}\n"))
+ fmt.Fprint(formatter.ColorableStdErr, formatter.F("{{red}}Ginkgo detected configuration issues:{{/}}\n"))
for _, err := range configErrors {
- fmt.Fprintf(formatter.ColorableStdErr, err.Error())
+ fmt.Fprint(formatter.ColorableStdErr, err.Error())
}
os.Exit(1)
}
- return suiteLabels, suiteSemVerConstraints, aroundNodes
+ return suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, aroundNodes
}
func getwd() (string, error) {
@@ -385,7 +391,7 @@ func PreviewSpecs(description string, args ...any) Report {
}
defer global.PopClone()
- suiteLabels, suiteSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
+ suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
priorDryRun, priorParallelTotal, priorParallelProcess := suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess
suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess = true, 1, 1
defer func() {
@@ -403,7 +409,7 @@ func PreviewSpecs(description string, args ...any) Report {
suitePath, err = filepath.Abs(suitePath)
exitIfErr(err)
- global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
+ global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
return global.Suite.GetPreviewReport()
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go b/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go
index e331d7cf8..ce1d71cec 100644
--- a/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go
@@ -117,6 +117,27 @@ You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-fi
*/
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.
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 79b83a3af..a30a2ecc9 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go
@@ -22,11 +22,11 @@ type Command struct {
func (c Command) Run(args []string, additionalArgs []string) {
args, err := c.Flags.Parse(args)
if err != nil {
- AbortWithUsage(err.Error())
+ AbortWithUsage("%s", err.Error())
}
for _, arg := range args {
if len(arg) > 1 && strings.HasPrefix(arg, "-") {
- AbortWith(types.GinkgoErrors.FlagAfterPositionalParameter().Error())
+ AbortWith("%s", types.GinkgoErrors.FlagAfterPositionalParameter().Error())
}
}
c.Command(args, additionalArgs)
@@ -49,6 +49,6 @@ func (c Command) EmitUsage(writer io.Writer) {
}
flagUsage := c.Flags.Usage()
if flagUsage != "" {
- fmt.Fprintf(writer, formatter.F(flagUsage))
+ fmt.Fprint(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 c3f6d3a11..53114904c 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go
@@ -1,9 +1,13 @@
package command
import (
+ "bufio"
"fmt"
"io"
+ "maps"
"os"
+ "path/filepath"
+ "slices"
"strings"
"github.com/onsi/ginkgo/v2/formatter"
@@ -158,6 +162,166 @@ func (p Program) handleHelpRequestsAndExit(writer io.Writer, args []string) {
}
}
+type completionOptions = struct {
+ Complete bool
+ Install bool
+}
+
+func (p *Program) BuildCompletionCommand() Command {
+ opts := completionOptions{}
+ flags, err := types.NewGinkgoFlagSet(
+ types.GinkgoFlags{
+ {Name: "complete", KeyPath: "Complete", Usage: "Generate completion for arguments after --"},
+ {Name: "install", KeyPath: "Install", Usage: "Install shell completion script into $XDG_DATA_HOME, ~/.local/share"},
+ },
+ &opts,
+ types.GinkgoFlagSections{},
+ )
+ if err != nil {
+ panic(err)
+ }
+ return Command{
+ Name: "completion",
+ Usage: "ginkgo completion [-- ]",
+ Flags: flags,
+ ShortDoc: "Generate shell completion",
+ Documentation: `To use install completion script for your shell (bash, fish, zsh).
+Or load completion code by: {{bold}}source <(ginkgo completion ){{/}}.`,
+ Command: func(args []string, completeArgs []string) {
+ p.handleCompletionAndExit(args, completeArgs, opts)
+ },
+ }
+}
+
+func (p Program) generateShellCompletionScript(shell string) (scriptPath string, script string) {
+ switch shell {
+ case "bash":
+ scriptPath = fmt.Sprintf("bash-completion/completions/%s", p.Name)
+ script = fmt.Sprintf(`__%s_complete_bash() {
+ mapfile -t COMPREPLY < <("${COMP_WORDS[0]}" completion --complete bash -- "${COMP_WORDS[@]:1:COMP_CWORD}")
+}
+complete -o bashdefault -o default -F __%[1]s_complete_bash %[1]s
+`, p.Name)
+
+ case "fish":
+ scriptPath = fmt.Sprintf("fish/vendor_completions.d/%s.fish", p.Name)
+ script = fmt.Sprintf(`function __fish_%[1]s_complete
+ set -l args (commandline -opc) (commandline -ct)
+ set -e args[1]
+ %[1]s completion --complete fish -- $args
+end
+complete -c %[1]s -a "(__fish_%[1]s_complete)"
+`, p.Name)
+
+ case "zsh":
+ scriptPath = fmt.Sprintf("zsh/site-functions/_%s", p.Name)
+ script = fmt.Sprintf(`#compdef %[1]s
+_%[1]s() {
+ local -a completions
+ completions=(${(f)"$("${words[1]}" completion --complete zsh -- "${words[@]:1:$((CURRENT-1))}")"})
+ if (( ${#completions[@]} )); then
+ _describe 'completions' completions
+ else
+ _default
+ fi
+}
+compdef _%[1]s %[1]s
+if [ "$funcstack[1]" = "_%[1]s" ]; then
+ _%[1]s
+fi
+`, p.Name)
+
+ case "":
+ AbortWithUsage("Shell is not specified")
+ default:
+ AbortWith("Shell %q is not supported yet. Choose: bash, fish, zsh", shell)
+ }
+
+ return scriptPath, script
+}
+
+func (p Program) handleCompletionAndExit(args, completeArgs []string, opts completionOptions) {
+ writer := p.OutWriter
+ if writer == nil {
+ writer = os.Stdout
+ }
+ buffer := bufio.NewWriter(writer)
+ defer buffer.Flush()
+
+ var shell string
+ if len(args) > 0 {
+ shell = args[0]
+ }
+
+ if !opts.Complete {
+ scriptPath, script := p.generateShellCompletionScript(shell)
+ if opts.Install {
+ dataHomeDir := os.Getenv("XDG_DATA_HOME")
+ if dataHomeDir == "" {
+ userHomeDir, err := os.UserHomeDir()
+ AbortIfError("Failed to find home", err)
+ dataHomeDir = filepath.Join(userHomeDir, ".local/share")
+ }
+ scriptPath = filepath.Join(dataHomeDir, scriptPath)
+ fmt.Fprintf(buffer, "Installing completion script: %v\n", scriptPath)
+ err := os.WriteFile(scriptPath, []byte(script), 0644)
+ AbortIfError("Failed to install completion script", err)
+ } else {
+ buffer.Write([]byte(script))
+ }
+ Abort(AbortDetails{})
+ }
+
+ var lastArg string
+ var result map[string]string
+ if len(completeArgs) > 0 {
+ lastArg = completeArgs[len(completeArgs)-1]
+ }
+
+ if delim := slices.Index(completeArgs, "--"); delim >= 0 && delim != len(completeArgs)-1 {
+ // No completion for pass-through arguments after "--"
+ } else if len(lastArg) > 0 && lastArg[0] == '-' {
+ // Complete flags
+ cmd := &p.DefaultCommand
+ for i := range p.Commands {
+ if p.Commands[i].Name == completeArgs[0] {
+ cmd = &p.Commands[i]
+ break
+ }
+ }
+ result = cmd.Flags.Completion(lastArg)
+ } else if len(completeArgs) <= 1 {
+ // Complete commands
+ result = make(map[string]string, len(p.Commands)+1)
+ for _, cmd := range append(p.Commands, p.DefaultCommand) {
+ if strings.HasPrefix(cmd.Name, lastArg) {
+ result[cmd.Name] = cmd.Usage
+ }
+ }
+ }
+
+ width := 0
+ for suggest := range result {
+ width = max(width, len(suggest))
+ }
+
+ for _, suggest := range slices.Sorted(maps.Keys(result)) {
+ usage := result[suggest]
+ switch {
+ case shell == "bash" && usage != "" && len(result) > 1:
+ fmt.Fprintf(buffer, "%*s (%s)\n", -width-2, suggest, usage)
+ case shell == "fish":
+ fmt.Fprintf(buffer, "%s\t%s\n", suggest, usage)
+ case shell == "zsh":
+ fmt.Fprintf(buffer, "%s:%s\n", suggest, usage)
+ default:
+ fmt.Fprintln(buffer, suggest)
+ }
+ }
+
+ Abort(AbortDetails{})
+}
+
func (p Program) EmitUsage(writer io.Writer) {
fmt.Fprintln(writer, formatter.F(p.Heading))
fmt.Fprintln(writer, formatter.F("{{gray}}%s{{/}}", strings.Repeat("-", len(p.Heading))))
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 30d8096cd..68830d9ae 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go
@@ -9,6 +9,7 @@ import (
"path/filepath"
"regexp"
"strings"
+ "sync/atomic"
"syscall"
"time"
@@ -159,12 +160,15 @@ 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{}
@@ -224,16 +228,20 @@ 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 cmd.ProcessState == nil || !cmd.ProcessState.Exited() })
+ server.RegisterAlive(proc, func() bool { return !exited.Load() })
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)
}()
}
@@ -242,6 +250,7 @@ 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
@@ -259,8 +268,10 @@ 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.Fprintf(formatter.ColorableStdErr, formatter.F("{{bold}}Output from proc %d:{{/}}\n", proc))
+ fmt.Fprint(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 419589b48..596c210cf 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go
@@ -41,6 +41,7 @@ func main() {
{Name: "nodot", Deprecation: types.Deprecations.Nodot()},
},
}
+ program.Commands = append(program.Commands, program.BuildCompletionCommand())
program.RunAndExit(os.Args)
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go
index 5d8d00bb1..c380bbf21 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go
@@ -163,17 +163,17 @@ func ginkgoNodeFromCallExpr(fset *token.FileSet, ce *ast.CallExpr, ginkgoPackage
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
n.Labels = labelFromCallExpr(ce)
return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
- case "Context", "Describe", "When", "DescribeTable":
+ case "Context", "Describe", "When", "DescribeTable", "DescribeTableSubtree":
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
n.Labels = labelFromCallExpr(ce)
n.Pending = pendingFromCallExpr(ce)
return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
- case "FContext", "FDescribe", "FWhen", "FDescribeTable":
+ case "FContext", "FDescribe", "FWhen", "FDescribeTable", "FDescribeTableSubtree":
n.Focused = true
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
n.Labels = labelFromCallExpr(ce)
return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
- case "PContext", "PDescribe", "PWhen", "XContext", "XDescribe", "XWhen", "PDescribeTable", "XDescribeTable":
+ case "PContext", "PDescribe", "PWhen", "XContext", "XDescribe", "XWhen", "PDescribeTable", "XDescribeTable", "PDescribeTableSubtree", "XDescribeTableSubtree":
n.Pending = true
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
n.Labels = labelFromCallExpr(ce)
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go
index e99d557d1..206043f1d 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go
@@ -54,6 +54,7 @@ func FromASTFile(fset *token.FileSet, src *ast.File) (*outline, error) {
// Node is not a Ginkgo spec or container, so it was not pushed onto the stack, continue
return true
}
+ expandSubtree(lastVisitedGinkgoNode)
stack = stack[0 : len(stack)-1]
return true
})
@@ -128,3 +129,29 @@ func (o *outline) StringIndent(width int) string {
return b.String()
}
+
+// expandSubtree restructures a DescribeTableSubtree node so that each Entry
+// child gets a copy of the subtree's spec nodes as its children. This mirrors
+// the runtime behavior where each Entry generates a container with the specs
+// defined in the DescribeTableSubtree body.
+func expandSubtree(gn *ginkgoNode) {
+ if !strings.Contains(gn.Name, "DescribeTableSubtree") {
+ return
+ }
+ subNodes, entries := splitSubtreeSubnodes(gn.Nodes)
+ gn.Nodes = entries
+ for _, entry := range entries {
+ entry.Nodes = subNodes
+ }
+}
+
+// splitSubtreeSubnodes splits the child nodes of a DescribeTableSubtree into
+// spec/container nodes (defined in the body) and Entry nodes.
+func splitSubtreeSubnodes(nodes []*ginkgoNode) ([]*ginkgoNode, []*ginkgoNode) {
+ for i, node := range nodes {
+ if strings.Contains(node.Name, "Entry") {
+ return nodes[:i], nodes[i:]
+ }
+ }
+ return nodes, nil
+}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go
index 03875b979..7b6c2cc22 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,12 +33,16 @@ 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-tests",
+ DocLink: "running-specs",
Command: func(args []string, additionalArgs []string) {
var errors []error
cliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig)
command.AbortIfErrors("Ginkgo detected configuration issues:", errors)
+ if types.ReconcileFdOutputConfiguration(reporterConfig, &suiteConfig, &cliConfig) {
+ fmt.Println("--fd is incompatible with parallel runs (-p/-procs) and -randomize-all; ignoring those flags and running specs in series, in declaration order.")
+ }
+
runner := &SpecRunner{
cliConfig: cliConfig,
goFlagsConfig: goFlagsConfig,
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 fe1ca3051..c60d7115f 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
@@ -37,6 +37,10 @@ func BuildWatchCommand() command.Command {
cliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig)
command.AbortIfErrors("Ginkgo detected configuration issues:", errors)
+ if types.ReconcileFdOutputConfiguration(reporterConfig, &suiteConfig, &cliConfig) {
+ fmt.Println("--fd is incompatible with parallel runs (-p/-procs) and -randomize-all; ignoring those flags and running specs in series, in declaration order.")
+ }
+
watcher := &SpecWatcher{
cliConfig: cliConfig,
goFlagsConfig: goFlagsConfig,
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 40d1e1ab5..db3e24847 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go
@@ -72,6 +72,7 @@ type GinkgoTInterface interface {
TempDir() string
Attr(key, value string)
Output() io.Writer
+ ArtifactDir() string
}
/*
@@ -196,3 +197,6 @@ func (g *GinkgoTBWrapper) Attr(key, value string) {
func (g *GinkgoTBWrapper) Output() io.Writer {
return g.GinkgoT.Output()
}
+func (g *GinkgoTBWrapper) ArtifactDir() string {
+ return g.GinkgoT.ArtifactDir()
+}
diff --git a/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go b/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go
new file mode 100644
index 000000000..9d04cc845
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go
@@ -0,0 +1,143 @@
+package ginkgo
+
+import (
+ "github.com/onsi/ginkgo/v2/internal/global"
+ ginkgotypes "github.com/onsi/ginkgo/v2/types"
+)
+
+// GinkgoHelperGo synchronously calls the specified “helper” function in a new
+// go routine and with a “defer GinkgoRecover()” already in place, passing the
+// function a “helper Fail”. GinkgoHelperGo is typically called from custom test
+// helpers that in turn need to synchronously execute caller-supplied custom
+// test code in a new Go routine while waiting for this new Go routine to
+// terminate (either successfully or failing).
+//
+// GinkgoHelperGo hides the non-trivial details of correctly unblocking the
+// caller's waiting go routine as well as reporting the correct call sites,
+// depending on whether the test helper failed, or the caller-supplied function
+// had its assertions failing or panicked.
+//
+// Let's take the following example of a test helper named “EnsureSprockets”
+// that runs a set of caller-supplied assertions synchronously on a new Go
+// routine and waits for the outcome before returning to the caller of the test
+// helper. This is just using Ginkgo:
+//
+// func EnsureSprockets(sprockets int, assertions func()) {
+// GinkgoHelper()
+// GinkgoHelperGo(func(helperFail func(string, ...int)) {
+// if sprockets == 0 {
+// helperFail("sprockets must not be zero")
+// }
+// assertions()
+// })
+// }
+//
+// And now for an example that additionally uses Gomega assertions.
+//
+// func EnsureSprockets(sprockets int, assertions func()) {
+// GinkgoHelper()
+// GinkgoHelperGo(func(helperFail func(string, ...int)) {
+// g := gomega.NewGomega(helperFail)
+// g.Expect(sprockets).Not(BeZero())
+// assertions()
+// })
+// }
+//
+// The called helper function should make any custom helper-related assertions
+// using the passed “helper Fail”. Gomega users will want to create a new Gomega
+// wired into this helper Fail. It is expected for the helper function at some
+// point to call into a user-supplied function that might contain its own
+// assertions. In the example above, that would be the function passed as
+// assertions.
+//
+// Any failing assertion using the helper Gomega in the helper function will be
+// reported as a fail at the call site of GinkgoHelperGo. Preferably, only
+// custom test helpers call GinkgoHelperGo and thus mark themselves as
+// [GinkgoHelper] also: in this case, the fail will be shown at the call site of
+// the custom test helper.
+//
+// Any other failing assertions inside the caller-supplied custom test code and
+// thus inside the helper function will instead be reported at the location of
+// the failed assertion.
+//
+// If the caller-supplied custom test code panics, GinkgoHelperGo will fail at
+// its call site, or at the call site of the custom test helper if it uses
+// GinkgoHelper, reporting the usual stack trace for the panic, as a plain
+// GinkgoRecover would also do.
+//
+// Important: the Gomega passed to the called function must only be used in
+// assertions belonging to the test helper, but not any user test code called
+// from the test helper. Thus, do not pass the Gomega passed to the helper
+// function further on to any user test code functions.
+func GinkgoHelperGo(fn func(fail func(message string, callerSkip ...int))) {
+ // userPanicked signals that the called user code panicked, such as due to a
+ // failed Gomega assertion.
+ type userPanicked struct{}
+
+ // helperPanicked signals that some helper code assertion panicked in the
+ // separate Go routine and we are expected to Fail the current test with that
+ // reason, but on the caller's Go routine.
+ type helperPanicked string
+
+ GinkgoHelper()
+
+ // possible types of values sent over the result channel:
+ // - nil (untyped): no problem at all, proceed.
+ // - helperPanicked: the message with which to (re)fail in the caller's
+ // go routine.
+ // - userPanicked: indication to (also) fail on the caller's go routine;
+ // the message doesn't matter as the user code fail takes precedence.
+ ch := make(chan any)
+
+ go func() {
+ isHelperPanic := false
+ helperFail := func(message string, callerSkip ...int) {
+ isHelperPanic = true
+ Fail(message, callerSkip...)
+ }
+ // Please note that we cannot simply recover a helper panic before
+ // GinkgoRecover kicks in as then GinkgoRecover would always report the
+ // stack trace only from the place of rethrown panic ... and that's
+ // pretty useless, because it would just consist of the panic rethrow.
+ defer func() {
+ // We need to unblock and immediately fail the waiting caller's
+ // go routine either for a reason, or just "because" when
+ // GinkgoRecover has already failed the current test on the
+ // separate go routine.
+ if global.Failer.GetState() != ginkgotypes.SpecStatePassed {
+ if isHelperPanic {
+ _, failure := global.Failer.Drain()
+ ch <- helperPanicked(failure.Message)
+ } else {
+ // keep the panic failure already recorded by GinkgoRecover.
+ ch <- userPanicked{}
+ }
+ }
+ close(ch) // causes a nil in case there were no panics anywhere.
+ }()
+ // Nota bene: GinkgoRecover always eats any user panic and channel the
+ // panic value into Ginkgo's Failer.Panic(). We can peek at the last
+ // failure recorded, which should be nil if GinkgoRecover didn't swallow
+ // a user code panic. The "problem" with GinkgoRecover is that it turns
+ // any panic value into a string message, so we loose any specific
+ // typing.
+ defer GinkgoRecover()
+
+ fn(helperFail)
+ }()
+
+ // Did we run into trouble?
+ switch v := (<-ch).(type) {
+ case userPanicked:
+ // The message actually is irrelevant, as it comes only second to
+ // the already registered user panic message. We just need Fail to
+ // panic on the caller's go routine in order to unblock the test.
+ Fail("fn panicked", 1)
+ case helperPanicked:
+ // Report the failure on the new go routine instead on the caller's go
+ // routine.
+ Fail(string(v), 1)
+ default:
+ // It's all fine!
+ }
+}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/focus.go b/vendor/github.com/onsi/ginkgo/v2/internal/focus.go
index a39daf5a6..498e707db 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, suiteConfig types.SuiteConfig) (Specs, bool) {
+func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suiteConfig types.SuiteConfig) (Specs, bool) {
focusString := strings.Join(suiteConfig.FocusStrings, "|")
skipString := strings.Join(suiteConfig.SkipStrings, "|")
@@ -87,7 +87,24 @@ func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suit
if suiteConfig.SemVerFilter != "" {
semVerFilter, _ := types.ParseSemVerFilter(suiteConfig.SemVerFilter)
skipChecks = append(skipChecks, func(spec Spec) bool {
- return !semVerFilter(UnionOfSemVerConstraints(suiteSemVerConstraints, spec.Nodes.UnionOfSemVerConstraints()))
+ 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
})
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/global/init.go b/vendor/github.com/onsi/ginkgo/v2/internal/global/init.go
index 464e3c97f..14d2552b7 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/global/init.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/global/init.go
@@ -8,6 +8,12 @@ var Suite *internal.Suite
var Failer *internal.Failer
var backupSuite *internal.Suite
+// SuiteDidRun tracks whether RunSpecs has already been invoked for the current global
+// suite. It lives here (rather than in package ginkgo) so that InitializeGlobals can
+// clear it, allowing extensions/globals.Reset to support running multiple suites
+// sequentially in a single process.
+var SuiteDidRun bool
+
func init() {
InitializeGlobals()
}
@@ -15,6 +21,7 @@ func init() {
func InitializeGlobals() {
Failer = internal.NewFailer()
Suite = internal.NewSuite()
+ SuiteDidRun = false
}
func PushClone() error {
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/group.go b/vendor/github.com/onsi/ginkgo/v2/internal/group.go
index cc794903e..5e6611334 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/group.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/group.go
@@ -113,22 +113,24 @@ 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(),
- 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),
- 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(),
+ 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(),
}
}
@@ -152,6 +154,7 @@ func addNodeToReportForNode(report *types.ConstructionNodeReport, node *TreeNode
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
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/node.go b/vendor/github.com/onsi/ginkgo/v2/internal/node.go
index 2bccec2db..b0c8de8d6 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/node.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/node.go
@@ -57,6 +57,7 @@ type Node struct {
MustPassRepeatedly int
Labels Labels
SemVerConstraints SemVerConstraints
+ ComponentSemVerConstraints ComponentSemVerConstraints
PollProgressAfter time.Duration
PollProgressInterval time.Duration
NodeTimeout time.Duration
@@ -106,7 +107,24 @@ func (l Labels) MatchesLabelFilter(query string) bool {
type SemVerConstraints []string
func (svc SemVerConstraints) MatchesSemVerFilter(version string) bool {
- return types.MustParseSemVerFilter(version)(svc)
+ 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 {
@@ -131,6 +149,16 @@ func UnionOfSemVerConstraints(semVerConstraints ...SemVerConstraints) SemVerCons
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{}
@@ -174,6 +202,8 @@ func isDecoration(arg any) bool {
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,16 +244,17 @@ var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...any) (Node, []error) {
baseOffset := 2
node := Node{
- ID: UniqueNodeID(),
- NodeType: nodeType,
- Text: text,
- Labels: Labels{},
- SemVerConstraints: SemVerConstraints{},
- CodeLocation: types.NewCodeLocation(baseOffset),
- NestingLevel: -1,
- PollProgressAfter: -1,
- PollProgressInterval: -1,
- GracePeriod: -1,
+ ID: UniqueNodeID(),
+ NodeType: nodeType,
+ Text: text,
+ Labels: Labels{},
+ SemVerConstraints: SemVerConstraints{},
+ ComponentSemVerConstraints: ComponentSemVerConstraints{},
+ CodeLocation: types.NewCodeLocation(baseOffset),
+ NestingLevel: -1,
+ PollProgressAfter: -1,
+ PollProgressInterval: -1,
+ GracePeriod: -1,
}
errors := []error{}
@@ -360,6 +391,36 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
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 {
@@ -899,6 +960,34 @@ func (n Nodes) UnionOfSemVerConstraints() []string {
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 {
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go b/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go
index 8b7a9ceab..751543ea7 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go
@@ -83,7 +83,7 @@ func goJSONActionFromSpecState(state types.SpecState) GoJSONAction {
type gojsonReport struct {
o types.Report
// Extra calculated fields
- goPkg string
+ goPkg string
elapsed float64
}
@@ -109,8 +109,8 @@ type gojsonSpecReport struct {
o types.SpecReport
// extra calculated fields
testName string
- elapsed float64
- action GoJSONAction
+ elapsed float64
+ action GoJSONAction
}
func newSpecReport(in types.SpecReport) *gojsonSpecReport {
@@ -141,18 +141,31 @@ func suitePathToPkg(dir string) (string, error) {
}
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, ", ") + "]"
- }
- name = strings.TrimSpace(name)
- return name
+ 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/suite.go b/vendor/github.com/onsi/ginkgo/v2/internal/suite.go
index ef76cd099..6c879855e 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/suite.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/suite.go
@@ -108,13 +108,13 @@ func (suite *Suite) BuildTree() error {
return nil
}
-func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, 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, 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) {
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, suiteConfig)
+ specs, hasProgrammaticFocus := ApplyFocusToSpecs(specs, description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteConfig)
specs = ComputeAroundNodes(specs)
suite.phase = PhaseRun
@@ -133,7 +133,7 @@ func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConst
cancelProgressHandler := progressSignalRegistrar(suite.handleProgressSignal)
- success := suite.runSpecs(description, suiteLabels, suiteSemVerConstraints, suitePath, hasProgrammaticFocus, specs)
+ success := suite.runSpecs(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suitePath, hasProgrammaticFocus, specs)
cancelProgressHandler()
@@ -208,9 +208,12 @@ func (suite *Suite) PushNode(node Node) error {
// 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 = nil
+ suite.currentConstructionNodeReport = oldConstructionNodeReport
}()
node.Body(nil)
@@ -453,16 +456,17 @@ func (suite *Suite) processCurrentSpecReport() {
}
}
-func (suite *Suite) runSpecs(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suitePath string, hasProgrammaticFocus bool, specs Specs) bool {
+func (suite *Suite) runSpecs(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suitePath string, hasProgrammaticFocus bool, specs Specs) bool {
numSpecsThatWillBeRun := specs.CountWithoutSkip()
suite.report = types.Report{
- SuitePath: suitePath,
- SuiteDescription: description,
- SuiteLabels: suiteLabels,
- SuiteSemVerConstraints: suiteSemVerConstraints,
- SuiteConfig: suite.config,
- SuiteHasProgrammaticFocus: hasProgrammaticFocus,
+ SuitePath: suitePath,
+ SuiteDescription: description,
+ SuiteLabels: suiteLabels,
+ SuiteSemVerConstraints: suiteSemVerConstraints,
+ SuiteComponentSemVerConstraints: suiteComponentSemVerConstraints,
+ SuiteConfig: suite.config,
+ SuiteHasProgrammaticFocus: hasProgrammaticFocus,
PreRunStats: types.PreRunStats{
TotalSpecs: len(specs),
SpecsThatWillRun: numSpecsThatWillBeRun,
@@ -992,6 +996,7 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ
} else {
failure.Message, failure.Location, failure.ForwardedPanic, failure.TimelineLocation = failureFromRun.Message, failureFromRun.Location, failureFromRun.ForwardedPanic, failureFromRun.TimelineLocation
suite.reporter.EmitFailure(outcomeFromRun, failure)
+ suite.pauseOnFailureIfRequested(node)
return outcomeFromRun, failure
}
case <-gracePeriodChannel:
@@ -1039,7 +1044,7 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ
}
progressReport = progressReport.WithoutOtherGoroutines()
- sc.cancel(fmt.Errorf(interruptStatus.Message()))
+ sc.cancel(fmt.Errorf("%s", interruptStatus.Message()))
if interruptStatus.Level == interrupt_handler.InterruptLevelBailOut {
if interruptStatus.ShouldIncludeProgressReport() {
@@ -1075,6 +1080,42 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ
}
}
+// pauseOnFailureIfRequested pauses the suite at the moment a failure is identified,
+// when the user has set --sleep-on-failure. This hooks directly into runNode's failure
+// path so the pause happens immediately at the point of failure - before any teardown
+// or cleanup runs - leaving the system live for inspection.
+//
+// We only pause for failures in setup and subject nodes (It, Before*, BeforeSuite...),
+// i.e. nodes that run before teardown. Pausing on a failure in a teardown/cleanup or
+// reporting node would be pointless (the system is already being torn down) and could
+// interfere with interrupt handling, so those are skipped.
+//
+// The pause is interruptible: pressing ^C (or any interrupt) ends the pause early and
+// the suite proceeds to run cleanup as usual. It is a no-op if the feature is disabled.
+func (suite *Suite) pauseOnFailureIfRequested(node Node) {
+ if suite.config.SleepOnFailure <= 0 {
+ return
+ }
+ // only pause before teardown - skip teardown/cleanup/reporting nodes
+ if node.NodeType.Is(types.NodeTypesAllowedDuringCleanupInterrupt | types.NodeTypesAllowedDuringReportInterrupt) {
+ return
+ }
+
+ duration := suite.config.SleepOnFailure
+ report := suite.generateProgressReport(false)
+ report.Message = fmt.Sprintf("{{bold}}{{orange}}Paused on failure for up to %s.{{/}}\nThe spec failed and Ginkgo has paused before running any teardown so you can inspect the live system.\nPress {{bold}}^C{{/}} to end the pause and proceed to cleanup.", duration)
+ suite.emitProgressReport(report)
+
+ timer := time.NewTimer(duration)
+ defer timer.Stop()
+ // wait for the pause to elapse, or for the user to interrupt - in which case we end
+ // the pause early and let runNode return so cleanup can proceed
+ select {
+ case <-timer.C:
+ case <-suite.interruptHandler.Status().Channel:
+ }
+}
+
// TODO: search for usages and consider if reporter.EmitFailure() is necessary
func (suite *Suite) failureForLeafNodeWithMessage(node Node, message string) types.Failure {
return types.Failure{
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 9806e315a..e6fbaee41 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
@@ -27,6 +27,11 @@ type ginkgoWriterInterface 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,
@@ -41,7 +46,7 @@ func New(writer ginkgoWriterInterface, fail failFunc, skip skipFunc, cleanup cle
randomSeed: randomSeed,
parallelProcess: parallelProcess,
parallelTotal: parallelTotal,
- f: formatter.NewWithNoColorBool(noColor),
+ f: formatters[noColor], //minimize allocations by reusing formatters
}
}
@@ -176,6 +181,15 @@ func (t *ginkgoTestingTProxy) TempDir() string {
return tmpDir
}
+func (t *ginkgoTestingTProxy) ArtifactDir() string {
+ artifactDir, err := os.MkdirTemp("", "ginkgo")
+ if err != nil {
+ t.fail(fmt.Sprintf("Failed to create artifact directory: %v", err), 1)
+ return ""
+ }
+ return artifactDir
+}
+
// FullGinkgoTInterface
func (t *ginkgoTestingTProxy) AddReportEntryVisibilityAlways(name string, args ...any) {
finalArgs := []any{internal.Offset(1), types.ReportEntryVisibilityAlways}
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 026d9cf9b..f3e15a913 100644
--- a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
+++ b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
@@ -31,6 +31,7 @@ type DefaultReporter struct {
specDenoter string
retryDenoter string
formatter formatter.Formatter
+ fdHierarchy []string
runningInParallel bool
lock *sync.Mutex
@@ -75,10 +76,15 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) {
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))
}
+ } else if r.conf.FdOutput {
+ return
} else {
banner := r.f("Running Suite: %s - %s", report.SuiteDescription, report.SuitePath)
r.emitBlock(banner)
@@ -97,6 +103,13 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) {
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)
@@ -114,7 +127,7 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) {
func (r *DefaultReporter) SuiteDidEnd(report types.Report) {
failures := report.SpecReports.WithState(types.SpecStateFailureStates)
- if len(failures) > 0 {
+ if !r.conf.FdOutput && len(failures) > 0 {
r.emitBlock("\n")
if len(failures) > 1 {
r.emitBlock(r.f("{{red}}{{bold}}Summarizing %d Failures:{{/}}", len(failures)))
@@ -217,6 +230,10 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) {
return
}
+ if r.conf.FdOutput {
+ r.didRunFd(report)
+ return
+ }
header := r.specDenoter
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
header = fmt.Sprintf("[%s]", report.LeafNodeType)
@@ -348,6 +365,51 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) {
r.emitDelimiter(0)
}
+func (r *DefaultReporter) didRunFd(report types.SpecReport) {
+ r.lock.Lock()
+ defer r.lock.Unlock()
+
+ if !report.LeafNodeType.Is(types.NodeTypeIt) {
+ return
+ }
+
+ hierarchy := report.ContainerHierarchyTexts
+
+ // blank line when top-level container changes
+ if len(r.fdHierarchy) > 0 &&
+ (len(hierarchy) == 0 || hierarchy[0] != r.fdHierarchy[0]) {
+ fmt.Fprintln(r.writer)
+ }
+
+ // emit newly-diverged container lines
+ divergeAt := 0
+ for divergeAt < len(r.fdHierarchy) && divergeAt < len(hierarchy) &&
+ r.fdHierarchy[divergeAt] == hierarchy[divergeAt] {
+ divergeAt++
+ }
+ for i := divergeAt; i < len(hierarchy); i++ {
+ fmt.Fprintf(r.writer, "%s%s\n", strings.Repeat(" ", i), hierarchy[i])
+ }
+
+ // leaf label
+ depth := len(hierarchy)
+ indent := strings.Repeat(" ", depth)
+ label := report.LeafNodeText
+
+ switch report.State {
+ case types.SpecStateFailed, types.SpecStatePanicked:
+ label = fmt.Sprintf("%s (FAILED)", label)
+ case types.SpecStatePending:
+ label = fmt.Sprintf("%s (PENDING)", label)
+ case types.SpecStateSkipped:
+ label = fmt.Sprintf("%s (SKIPPED)", label)
+ }
+
+ color := r.highlightColorForState(report.State)
+ fmt.Fprintf(r.writer, "%s%s\n", indent, r.f(color+"%s{{/}}", label))
+ r.fdHierarchy = hierarchy
+}
+
func (r *DefaultReporter) highlightColorForState(state types.SpecState) string {
switch state {
case types.SpecStatePassed:
@@ -413,7 +475,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, isVeryVerbose, false, x)
case types.SpecEvent:
if isVeryVerbose || !x.IsOnlyVisibleAtVeryVerbose() || r.conf.ShowNodeEvents {
r.emitSpecEvent(indent, x, isVeryVerbose)
@@ -523,6 +585,7 @@ func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput
indent -= 1
}
+ // Emit only top-level groups because github logging cannot handle nested groups correctly.
if r.conf.GithubOutput && emitGroup {
r.emitBlock(r.fi(indent, "::group::Progress Report"))
}
@@ -725,8 +788,12 @@ 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 := []string{}, []types.CodeLocation{}, [][]string{}, [][]string{}
- texts, locations, labels, semVerConstraints = append(texts, report.ContainerHierarchyTexts...), append(locations, report.ContainerHierarchyLocations...), append(labels, report.ContainerHierarchyLabels...), append(semVerConstraints, report.ContainerHierarchySemVerConstraints...)
+ 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...)
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
texts = append(texts, r.f("[%s] %s", report.LeafNodeType, report.LeafNodeText))
@@ -735,6 +802,7 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
}
labels = append(labels, report.LeafNodeLabels)
semVerConstraints = append(semVerConstraints, report.LeafNodeSemVerConstraints)
+ componentSemVerConstraints = append(componentSemVerConstraints, report.LeafNodeComponentSemVerConstraints)
locations = append(locations, report.LeafNodeLocation)
failureLocation := report.Failure.FailureNodeLocation
@@ -749,6 +817,7 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
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
@@ -779,6 +848,9 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
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])
}
@@ -806,6 +878,10 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
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/junit_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
index 828f893fb..d4720ee94 100644
--- a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
+++ b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
@@ -13,9 +13,11 @@ package reporters
import (
"encoding/xml"
"fmt"
+ "maps"
"os"
"path"
"regexp"
+ "slices"
"strings"
"github.com/onsi/ginkgo/v2/config"
@@ -39,6 +41,9 @@ type JunitReportConfig struct {
// 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
@@ -173,6 +178,7 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit
{"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},
@@ -216,6 +222,10 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit
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{
@@ -387,6 +397,16 @@ 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 55e1d1f4f..ed3e3a2bb 100644
--- a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go
+++ b/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go
@@ -39,12 +39,16 @@ 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,6 +63,10 @@ func GenerateTeamcityReport(report types.Report, dst string) error {
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/types/config.go b/vendor/github.com/onsi/ginkgo/v2/types/config.go
index f84703604..854fec6a3 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/config.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/config.go
@@ -38,6 +38,7 @@ type SuiteConfig struct {
OutputInterceptorMode string
SourceRoots []string
GracePeriod time.Duration
+ SleepOnFailure time.Duration
ParallelProcess int
ParallelTotal int
@@ -94,6 +95,7 @@ type ReporterConfig struct {
GithubOutput bool
SilenceSkips bool
ForceNewlines bool
+ FdOutput bool
JSONReport string
GoJSONReport string
@@ -215,6 +217,7 @@ type GoFlagsConfig struct {
N bool
ModFile string
ModCacheRW bool
+ ASan bool
MSan bool
PkgDir string
Tags string
@@ -292,6 +295,8 @@ var SuiteConfigFlags = GinkgoFlags{
Usage: "Make up to this many attempts to run each spec. If any of the attempts succeed, the suite will not be failed."},
{KeyPath: "S.FailOnEmpty", Name: "fail-on-empty", SectionKey: "failure",
Usage: "If set, ginkgo will mark the test suite as failed if no specs are run."},
+ {KeyPath: "S.SleepOnFailure", Name: "sleep-on-failure", SectionKey: "failure", UsageDefaultValue: "0 - disabled",
+ Usage: "If set, ginkgo will pause for this duration after a spec fails - before its teardown (AfterEach/JustAfterEach/DeferCleanup) runs - so you can inspect the live system. Press ^C to end the pause early and proceed to cleanup. Serial only: cannot be combined with -p/--procs."},
{KeyPath: "S.DryRun", Name: "dry-run", SectionKey: "debug", DeprecatedName: "dryRun", DeprecatedDocLink: "changed-command-line-flags",
Usage: "If set, ginkgo will walk the test hierarchy without actually running anything. Best paired with -v."},
@@ -357,7 +362,8 @@ var ReporterConfigFlags = GinkgoFlags{
Usage: "If set, default reporter will not print out skipped tests."},
{KeyPath: "R.ForceNewlines", Name: "force-newlines", SectionKey: "output",
Usage: "If set, default reporter will ensure a newline appears after each test."},
-
+ {KeyPath: "R.FdOutput", Name: "fd", SectionKey: "output",
+ Usage: "If set, emits RSpec-style 'format documentation' output instead of Ginkgo's default output. --fd is exclusive: it overrides -p/-procs and -randomize-all, forcing specs to run serially in declaration order, since fd's hierarchical output can't be rendered sensibly when specs are parallelized or randomized."},
{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",
@@ -428,6 +434,14 @@ func VetConfig(flagSet GinkgoFlagSet, suiteConfig SuiteConfig, reporterConfig Re
errors = append(errors, GinkgoErrors.GracePeriodCannotBeZero())
}
+ if suiteConfig.SleepOnFailure < 0 {
+ errors = append(errors, GinkgoErrors.InvalidSleepOnFailureConfiguration())
+ }
+
+ if suiteConfig.SleepOnFailure > 0 && suiteConfig.ParallelTotal > 1 {
+ errors = append(errors, GinkgoErrors.SleepOnFailureInParallelConfiguration())
+ }
+
if len(suiteConfig.FocusFiles) > 0 {
_, err := ParseFileFilters(suiteConfig.FocusFiles)
if err != nil {
@@ -475,6 +489,30 @@ func VetConfig(flagSet GinkgoFlagSet, suiteConfig SuiteConfig, reporterConfig Re
return errors
}
+// ReconcileFdOutputConfiguration forces serial, in-order execution when --fd is combined with
+// -p, -procs (>1), or -randomize-all. fd's RSpec-style hierarchical output assumes specs run
+// one at a time, in declaration order -- parallelism and randomization both break that assumption
+// and produce fragmented, hard-to-read output. Rather than refusing to run, Ginkgo ignores those
+// flags and runs in series instead. suiteConfig and cliConfig are mutated in place; the return
+// value is true if anything was overridden, so callers can let the user know what was ignored.
+func ReconcileFdOutputConfiguration(reporterConfig ReporterConfig, suiteConfig *SuiteConfig, cliConfig *CLIConfig) bool {
+ if !reporterConfig.FdOutput {
+ return false
+ }
+
+ changed := false
+ if cliConfig.ComputedProcs() > 1 {
+ cliConfig.Procs = 1
+ cliConfig.Parallel = false
+ changed = true
+ }
+ if suiteConfig.RandomizeAllSpecs {
+ suiteConfig.RandomizeAllSpecs = false
+ changed = true
+ }
+ return changed
+}
+
// GinkgoCLISharedFlags provides flags shared by the Ginkgo CLI's build, watch, and run commands
var GinkgoCLISharedFlags = GinkgoFlags{
{KeyPath: "C.Recurse", Name: "r", SectionKey: "multiple-suites",
@@ -570,6 +608,8 @@ var GoBuildFlags = GinkgoFlags{
Usage: "leave newly-created directories in the module cache read-write instead of making them read-only."},
{KeyPath: "Go.ModFile", Name: "modfile", UsageArgument: "file", SectionKey: "go-build",
Usage: `in module aware mode, read (and possibly write) an alternate go.mod file instead of the one in the module root directory. A file named go.mod must still be present in order to determine the module root directory, but it is not accessed. When -modfile is specified, an alternate go.sum file is also used: its path is derived from the -modfile flag by trimming the ".mod" extension and appending ".sum".`},
+ {KeyPath: "Go.ASan", Name: "asan", SectionKey: "go-build",
+ Usage: "enable interoperation with address sanitizer."},
{KeyPath: "Go.MSan", Name: "msan", SectionKey: "go-build",
Usage: "enable interoperation with memory sanitizer. Supported only on linux/amd64, linux/arm64 and only with Clang/LLVM as the host C compiler. On linux/arm64, pie build mode will be used."},
{KeyPath: "Go.N", Name: "n", SectionKey: "go-build",
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/errors.go b/vendor/github.com/onsi/ginkgo/v2/types/errors.go
index 59313238c..636070c12 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/errors.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/errors.go
@@ -450,6 +450,15 @@ func (g ginkgoErrors) InvalidEmptySemVerConstraint(cl CodeLocation) error {
}
}
+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{
@@ -612,6 +621,21 @@ func (g ginkgoErrors) GracePeriodCannotBeZero() error {
}
}
+func (g ginkgoErrors) InvalidSleepOnFailureConfiguration() error {
+ return GinkgoError{
+ Heading: "Ginkgo requires a non-negative --sleep-on-failure.",
+ Message: "Please set --sleep-on-failure to a positive duration (e.g. 5m), or 0 to disable it.",
+ }
+}
+
+func (g ginkgoErrors) SleepOnFailureInParallelConfiguration() error {
+ return GinkgoError{
+ Heading: "Ginkgo only supports --sleep-on-failure in serial mode.",
+ Message: "--sleep-on-failure pauses a failed spec on a live system for inspection, which only makes sense when the suite runs serially. Please run again without -p or --procs, or unset --sleep-on-failure.",
+ DocLink: "spec-timeouts-and-interruptible-nodes",
+ }
+}
+
func (g ginkgoErrors) ConflictingVerbosityConfiguration() error {
return GinkgoError{
Heading: "Conflicting reporter verbosity settings.",
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/flags.go b/vendor/github.com/onsi/ginkgo/v2/types/flags.go
index 8409653f9..eb04c3e78 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/flags.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/flags.go
@@ -212,6 +212,24 @@ func (f GinkgoFlagSet) IsZero() bool {
return f.flagSet == nil
}
+func (f GinkgoFlagSet) Completion(arg string) map[string]string {
+ if f.IsZero() {
+ return nil
+ }
+ prefix := strings.TrimLeft(arg, "-")
+ dash := arg[:len(arg)-len(prefix)]
+ if len(dash) < 1 || len(dash) > 3 {
+ return nil
+ }
+ result := make(map[string]string, len(f.flags))
+ for _, flag := range f.flags {
+ if flag.Name != "" && strings.HasPrefix(flag.Name, prefix) {
+ result[dash+flag.Name] = flag.Usage
+ }
+ }
+ return result
+}
+
func (f GinkgoFlagSet) WasSet(name string) bool {
found := false
f.flagSet.Visit(func(f *flag.Flag) {
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go b/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go
index 3fc2ed144..71778078d 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go
@@ -2,11 +2,12 @@ package types
import (
"fmt"
+ "strings"
"github.com/Masterminds/semver/v3"
)
-type SemVerFilter func([]string) bool
+type SemVerFilter func(component string, constraints []string) bool
func MustParseSemVerFilter(input string) SemVerFilter {
filter, err := ParseSemVerFilter(input)
@@ -16,30 +17,90 @@ func MustParseSemVerFilter(input string) SemVerFilter {
return filter
}
-func ParseSemVerFilter(filterVersion string) (SemVerFilter, error) {
- if filterVersion == "" {
- return func(_ []string) bool { return true }, nil
+// 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
}
- targetVersion, err := semver.NewVersion(filterVersion)
- if err != nil {
- return nil, fmt.Errorf("invalid filter version: %w", err)
+ 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(constraints []string) bool {
+ return func(component string, constraints []string) bool {
// unconstrained specs always run
- if len(constraints) == 0 {
+ if len(component) == 0 && len(constraints) == 0 {
return true
}
- for _, constraintStr := range constraints {
- constraint, err := semver.NewConstraint(constraintStr)
- if err != nil {
- return false
+ // 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(targetVersion) {
- return false
+ if !constraint.Check(v) {
+ return false
+ }
+ }
}
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/types.go b/vendor/github.com/onsi/ginkgo/v2/types/types.go
index 9981a0dd6..240150512 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/types.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/types.go
@@ -38,6 +38,10 @@ type ConstructionNodeReport struct {
// 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
@@ -85,6 +89,9 @@ type Report struct {
//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
@@ -188,14 +195,19 @@ type SpecReport struct {
// 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
// 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
- LeafNodeText string
+ LeafNodeType NodeType
+ LeafNodeLocation CodeLocation
+ LeafNodeLabels []string
+ LeafNodeSemVerConstraints []string
+ LeafNodeComponentSemVerConstraints map[string][]string
+ LeafNodeText string
// Captures the Spec Priority
SpecPriority int
@@ -261,52 +273,54 @@ 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
- 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
+ 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: report.ContainerHierarchyTexts,
- ContainerHierarchyLocations: report.ContainerHierarchyLocations,
- ContainerHierarchyLabels: report.ContainerHierarchyLabels,
- ContainerHierarchySemVerConstraints: report.ContainerHierarchySemVerConstraints,
- 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,
+ 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,
}
if !report.Failure.IsZero() {
@@ -404,6 +418,34 @@ func (report SpecReport) SemVerConstraints() []string {
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)
@@ -419,7 +461,22 @@ func (report SpecReport) MatchesSemVerFilter(version string) (bool, error) {
if err != nil {
return false, err
}
- return filter(report.SemVerConstraints()), nil
+
+ 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
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go
index b9c1ea985..dc28324c1 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.27.2"
+const VERSION = "2.32.0"
diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md
index b7d7309f3..9c94d0e6c 100644
--- a/vendor/github.com/onsi/gomega/CHANGELOG.md
+++ b/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -1,3 +1,26 @@
+## 1.40.0
+
+We're adopting a new release strategy to minimize dependency bloat in projects that consume Gomega. It is a limitation of the go mod toolchain that _test_ subdependencies of your project's direct dependencies get pulled in as *indirect* dependencies. In the case of Gomega, this ends up pulling in all of Ginkgo into your `go.mod` even if you are only using Gomega (Gomega uses Ginkgo for its own tests).
+
+Going forward, releases will strip out all tests, tidy up the `go.mod` and then push this stripped down version to a new `master-lite` branch. These stripped-down versions will receive the `vx.y.z` git tag and will be picked up by the go toolchain.
+
+Please open an issue if this new release process causes unexpected changes for your projects.
+
+## 1.39.1
+
+Update all dependencies. This auto-updated the required version of Go to 1.24, consistent with the fact that Go 1.23 has been out of support for almost six months.
+
+## 1.39.0
+
+### Features
+
+Add `MatchErrorStrictly` which only passes if `errors.Is(actual, expected)` returns true. `MatchError`, by contrast, will fallback to string comparison.
+
+## 1.38.3
+
+### Fixes
+make string formatitng more consistent for users who use format.Object directly
+
## 1.38.2
- roll back to go 1.23.0 [c404969]
diff --git a/vendor/github.com/onsi/gomega/format/format.go b/vendor/github.com/onsi/gomega/format/format.go
index 96f04b210..6c23ba338 100644
--- a/vendor/github.com/onsi/gomega/format/format.go
+++ b/vendor/github.com/onsi/gomega/format/format.go
@@ -262,7 +262,7 @@ func Object(object any, indentation uint) string {
if err, ok := object.(error); ok && !isNilValue(value) { // isNilValue check needed here to avoid nil deref due to boxed nil
commonRepresentation += "\n" + IndentString(err.Error(), indentation) + "\n" + indent
}
- return fmt.Sprintf("%s<%s>: %s%s", indent, formatType(value), commonRepresentation, formatValue(value, indentation))
+ return fmt.Sprintf("%s<%s>: %s%s", indent, formatType(value), commonRepresentation, formatValue(value, indentation, true))
}
/*
@@ -306,7 +306,7 @@ func formatType(v reflect.Value) string {
}
}
-func formatValue(value reflect.Value, indentation uint) string {
+func formatValue(value reflect.Value, indentation uint, isTopLevel bool) string {
if indentation > MaxDepth {
return "..."
}
@@ -367,11 +367,11 @@ func formatValue(value reflect.Value, indentation uint) string {
case reflect.Func:
return fmt.Sprintf("0x%x", value.Pointer())
case reflect.Ptr:
- return formatValue(value.Elem(), indentation)
+ return formatValue(value.Elem(), indentation, isTopLevel)
case reflect.Slice:
return truncateLongStrings(formatSlice(value, indentation))
case reflect.String:
- return truncateLongStrings(formatString(value.String(), indentation))
+ return truncateLongStrings(formatString(value.String(), indentation, isTopLevel))
case reflect.Array:
return truncateLongStrings(formatSlice(value, indentation))
case reflect.Map:
@@ -392,8 +392,8 @@ func formatValue(value reflect.Value, indentation uint) string {
}
}
-func formatString(object any, indentation uint) string {
- if indentation == 1 {
+func formatString(object any, indentation uint, isTopLevel bool) string {
+ if isTopLevel {
s := fmt.Sprintf("%s", object)
components := strings.Split(s, "\n")
result := ""
@@ -416,14 +416,14 @@ func formatString(object any, indentation uint) string {
func formatSlice(v reflect.Value, indentation uint) string {
if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 && isPrintableString(string(v.Bytes())) {
- return formatString(v.Bytes(), indentation)
+ return formatString(v.Bytes(), indentation, false)
}
l := v.Len()
result := make([]string, l)
longest := 0
- for i := 0; i < l; i++ {
- result[i] = formatValue(v.Index(i), indentation+1)
+ for i := range l {
+ result[i] = formatValue(v.Index(i), indentation+1, false)
if len(result[i]) > longest {
longest = len(result[i])
}
@@ -443,7 +443,7 @@ func formatMap(v reflect.Value, indentation uint) string {
longest := 0
for i, key := range v.MapKeys() {
value := v.MapIndex(key)
- result[i] = fmt.Sprintf("%s: %s", formatValue(key, indentation+1), formatValue(value, indentation+1))
+ result[i] = fmt.Sprintf("%s: %s", formatValue(key, indentation+1, false), formatValue(value, indentation+1, false))
if len(result[i]) > longest {
longest = len(result[i])
}
@@ -462,10 +462,10 @@ func formatStruct(v reflect.Value, indentation uint) string {
l := v.NumField()
result := []string{}
longest := 0
- for i := 0; i < l; i++ {
+ for i := range l {
structField := t.Field(i)
fieldEntry := v.Field(i)
- representation := fmt.Sprintf("%s: %s", structField.Name, formatValue(fieldEntry, indentation+1))
+ representation := fmt.Sprintf("%s: %s", structField.Name, formatValue(fieldEntry, indentation+1, false))
result = append(result, representation)
if len(representation) > longest {
longest = len(representation)
@@ -479,7 +479,7 @@ func formatStruct(v reflect.Value, indentation uint) string {
}
func formatInterface(v reflect.Value, indentation uint) string {
- return fmt.Sprintf("<%s>%s", formatType(v.Elem()), formatValue(v.Elem(), indentation))
+ return fmt.Sprintf("<%s>%s", formatType(v.Elem()), formatValue(v.Elem(), indentation, false))
}
func isNilValue(a reflect.Value) bool {
diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go
index fdba34ee9..af1341bdb 100644
--- a/vendor/github.com/onsi/gomega/gomega_dsl.go
+++ b/vendor/github.com/onsi/gomega/gomega_dsl.go
@@ -22,7 +22,7 @@ import (
"github.com/onsi/gomega/types"
)
-const GOMEGA_VERSION = "1.38.2"
+const GOMEGA_VERSION = "1.40.0"
const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler.
If you're using Ginkgo then you probably forgot to put your assertion in an It().
diff --git a/vendor/github.com/onsi/gomega/matchers.go b/vendor/github.com/onsi/gomega/matchers.go
index 10b6693fd..16ca8f46d 100644
--- a/vendor/github.com/onsi/gomega/matchers.go
+++ b/vendor/github.com/onsi/gomega/matchers.go
@@ -146,6 +146,24 @@ func MatchError(expected any, functionErrorDescription ...any) types.GomegaMatch
}
}
+// MatchErrorStrictly succeeds iff actual is a non-nil error that matches the passed in
+// expected error according to errors.Is(actual, expected).
+//
+// This behavior differs from MatchError where
+//
+// Expect(errors.New("some error")).To(MatchError(errors.New("some error")))
+//
+// succeeds, but errors.Is would return false so:
+//
+// Expect(errors.New("some error")).To(MatchErrorStrictly(errors.New("some error")))
+//
+// fails.
+func MatchErrorStrictly(expected error) types.GomegaMatcher {
+ return &matchers.MatchErrorStrictlyMatcher{
+ Expected: expected,
+ }
+}
+
// BeClosed succeeds if actual is a closed channel.
// It is an error to pass a non-channel to BeClosed, it is also an error to pass nil
//
@@ -515,8 +533,8 @@ func HaveExistingField(field string) types.GomegaMatcher {
// and even interface values.
//
// actual := 42
-// Expect(actual).To(HaveValue(42))
-// Expect(&actual).To(HaveValue(42))
+// Expect(actual).To(HaveValue(Equal(42)))
+// Expect(&actual).To(HaveValue(Equal(42)))
func HaveValue(matcher types.GomegaMatcher) types.GomegaMatcher {
return &matchers.HaveValueMatcher{
Matcher: matcher,
diff --git a/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go b/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go
index 9e16dcf5d..16630c18e 100644
--- a/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go
+++ b/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go
@@ -39,7 +39,7 @@ func (matcher *HaveKeyMatcher) Match(actual any) (success bool, err error) {
}
keys := reflect.ValueOf(actual).MapKeys()
- for i := 0; i < len(keys); i++ {
+ for i := range keys {
success, err := keyMatcher.Match(keys[i].Interface())
if err != nil {
return false, fmt.Errorf("HaveKey's key matcher failed with:\n%s%s", format.Indent, err.Error())
diff --git a/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go b/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go
index 1c53f1e56..0cd708153 100644
--- a/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go
+++ b/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go
@@ -52,7 +52,7 @@ func (matcher *HaveKeyWithValueMatcher) Match(actual any) (success bool, err err
}
keys := reflect.ValueOf(actual).MapKeys()
- for i := 0; i < len(keys); i++ {
+ for i := range keys {
success, err := keyMatcher.Match(keys[i].Interface())
if err != nil {
return false, fmt.Errorf("HaveKeyWithValue's key matcher failed with:\n%s%s", format.Indent, err.Error())
diff --git a/vendor/github.com/onsi/gomega/matchers/match_error_strictly_matcher.go b/vendor/github.com/onsi/gomega/matchers/match_error_strictly_matcher.go
new file mode 100644
index 000000000..63969b266
--- /dev/null
+++ b/vendor/github.com/onsi/gomega/matchers/match_error_strictly_matcher.go
@@ -0,0 +1,39 @@
+package matchers
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/onsi/gomega/format"
+)
+
+type MatchErrorStrictlyMatcher struct {
+ Expected error
+}
+
+func (matcher *MatchErrorStrictlyMatcher) Match(actual any) (success bool, err error) {
+
+ if isNil(matcher.Expected) {
+ return false, fmt.Errorf("Expected error is nil, use \"ToNot(HaveOccurred())\" to explicitly check for nil errors")
+ }
+
+ if isNil(actual) {
+ return false, fmt.Errorf("Expected an error, got nil")
+ }
+
+ if !isError(actual) {
+ return false, fmt.Errorf("Expected an error. Got:\n%s", format.Object(actual, 1))
+ }
+
+ actualErr := actual.(error)
+
+ return errors.Is(actualErr, matcher.Expected), nil
+}
+
+func (matcher *MatchErrorStrictlyMatcher) FailureMessage(actual any) (message string) {
+ return format.Message(actual, "to match error", matcher.Expected)
+}
+
+func (matcher *MatchErrorStrictlyMatcher) NegatedFailureMessage(actual any) (message string) {
+ return format.Message(actual, "not to match error", matcher.Expected)
+}
diff --git a/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go b/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go
index 8c38411b2..72edba20f 100644
--- a/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go
+++ b/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go
@@ -1,6 +1,9 @@
package edge
-import . "github.com/onsi/gomega/matchers/support/goraph/node"
+import (
+ . "github.com/onsi/gomega/matchers/support/goraph/node"
+ "slices"
+)
type Edge struct {
Node1 int
@@ -20,13 +23,7 @@ func (ec EdgeSet) Free(node Node) bool {
}
func (ec EdgeSet) Contains(edge Edge) bool {
- for _, e := range ec {
- if e == edge {
- return true
- }
- }
-
- return false
+ return slices.Contains(ec, edge)
}
func (ec EdgeSet) FindByNodes(node1, node2 Node) (Edge, bool) {
diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
index 56723d1f8..77aad553d 100644
--- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
+++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
@@ -524,7 +524,7 @@ func (f *finder) find(T types.Type, path []byte) []byte {
for i := 0; i < T.NumMethods(); i++ {
m := T.Method(i)
if f.seenMethods[m] {
- return nil
+ continue // break cycles (see TestIssue70418)
}
path2 := appendOpArg(path, opMethod, i)
if m == f.obj {
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader.go
similarity index 88%
rename from vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go
rename to vendor/golang.org/x/tools/internal/gcimporter/ureader.go
index 2e0d80585..3db62b890 100644
--- a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go
+++ b/vendor/golang.org/x/tools/internal/gcimporter/ureader.go
@@ -35,6 +35,10 @@ type pkgReader struct {
// laterFns holds functions that need to be invoked at the end of
// import reading.
+ //
+ // TODO(mdempsky): Is it safe to have a single "later" slice or do
+ // we need to have multiple passes? See comments on CL 386002 and
+ // go.dev/issue/52104.
laterFns []func()
// laterFors is used in case of 'type A B' to ensure that B is processed before A.
laterFors map[types.Type]int
@@ -158,12 +162,11 @@ type reader struct {
// A readerDict holds the state for type parameters that parameterize
// the current unified IR element.
type readerDict struct {
- // bounds is a slice of typeInfos corresponding to the underlying
- // bounds of the element's type parameters.
- bounds []typeInfo
+ rtbounds []typeInfo // contains constraint types for each parameter in rtparams
+ rtparams []*types.TypeParam // contains receiver type parameters for an element
- // tparams is a slice of the constructed TypeParams for the element.
- tparams []*types.TypeParam
+ tbounds []typeInfo // contains constraint types for each parameter in tparams
+ tparams []*types.TypeParam // contains type parameters for an element
// derived is a slice of types derived from tparams, which may be
// instantiated while reading the current element.
@@ -353,7 +356,11 @@ func (r *reader) doTyp() (res types.Type) {
return name.Type()
case pkgbits.TypeTypeParam:
- return r.dict.tparams[r.Len()]
+ n := r.Len()
+ if n < len(r.dict.rtbounds) {
+ return r.dict.rtparams[n]
+ }
+ return r.dict.tparams[n-len(r.dict.rtbounds)]
case pkgbits.TypeArray:
len := int64(r.Uint64())
@@ -534,7 +541,7 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
pos := r.pos()
var tparams []*types.TypeParam
if r.Version().Has(pkgbits.AliasTypeParamNames) {
- tparams = r.typeParamNames()
+ tparams = r.typeParamNames(false)
}
typ := r.typ()
declare(aliases.New(pos, objPkg, objName, typ, tparams))
@@ -547,8 +554,15 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
case pkgbits.ObjFunc:
pos := r.pos()
- tparams := r.typeParamNames()
- sig := r.signature(nil, nil, tparams)
+ var rtparams []*types.TypeParam
+ var recv *types.Var
+ if r.Version().Has(pkgbits.GenericMethods) && r.Bool() {
+ r.selector()
+ rtparams = r.typeParamNames(true)
+ recv = r.param()
+ }
+ tparams := r.typeParamNames(false)
+ sig := r.signature(recv, rtparams, tparams)
declare(types.NewFunc(pos, objPkg, objName, sig))
case pkgbits.ObjType:
@@ -558,7 +572,7 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
named := types.NewNamed(obj, nil, nil)
declare(obj)
- named.SetTypeParams(r.typeParamNames())
+ named.SetTypeParams(r.typeParamNames(false))
setUnderlying := func(underlying types.Type) {
// If the underlying type is an interface, we need to
@@ -638,9 +652,20 @@ func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
errorf("unexpected object with %v implicit type parameter(s)", implicits)
}
- dict.bounds = make([]typeInfo, r.Len())
- for i := range dict.bounds {
- dict.bounds[i] = r.typInfo()
+ nreceivers := 0
+ if r.Version().Has(pkgbits.GenericMethods) && r.Bool() {
+ nreceivers = r.Len()
+ }
+ nexplicits := r.Len()
+
+ dict.rtbounds = make([]typeInfo, nreceivers)
+ for i := range dict.rtbounds {
+ dict.rtbounds[i] = r.typInfo()
+ }
+
+ dict.tbounds = make([]typeInfo, nexplicits)
+ for i := range dict.tbounds {
+ dict.tbounds[i] = r.typInfo()
}
dict.derived = make([]derivedInfo, r.Len())
@@ -659,15 +684,24 @@ func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
return &dict
}
-func (r *reader) typeParamNames() []*types.TypeParam {
+func (r *reader) typeParamNames(isGenMeth bool) []*types.TypeParam {
r.Sync(pkgbits.SyncTypeParamNames)
- // Note: This code assumes it only processes objects without
- // implement type parameters. This is currently fine, because
- // reader is only used to read in exported declarations, which are
- // always package scoped.
+ // Note: This code assumes there are no implicit type parameters.
+ // This is fine since it only reads exported declarations, which
+ // never have implicits.
- if len(r.dict.bounds) == 0 {
+ var in []typeInfo
+ var out *[]*types.TypeParam
+ if isGenMeth {
+ in = r.dict.rtbounds
+ out = &r.dict.rtparams
+ } else {
+ in = r.dict.tbounds
+ out = &r.dict.tparams
+ }
+
+ if len(in) == 0 {
return nil
}
@@ -676,40 +710,34 @@ func (r *reader) typeParamNames() []*types.TypeParam {
// create all the TypeNames and TypeParams, then we construct and
// set the bound type.
- r.dict.tparams = make([]*types.TypeParam, len(r.dict.bounds))
- for i := range r.dict.bounds {
+ // We have to save tparams outside of the closure, because typeParamNames
+ // can be called multiple times with the same dictionary instance.
+ tparams := make([]*types.TypeParam, len(in))
+ *out = tparams
+
+ for i := range in {
pos := r.pos()
pkg, name := r.localIdent()
tname := types.NewTypeName(pos, pkg, name, nil)
- r.dict.tparams[i] = types.NewTypeParam(tname, nil)
+ tparams[i] = types.NewTypeParam(tname, nil)
}
- typs := make([]types.Type, len(r.dict.bounds))
- for i, bound := range r.dict.bounds {
- typs[i] = r.p.typIdx(bound, r.dict)
+ // The reader dictionary will continue mutating before we have time
+ // to call delayed functions; make a local copy of the constraints.
+ types := make([]types.Type, len(in))
+ for i, info := range in {
+ types[i] = r.p.typIdx(info, r.dict)
}
- // TODO(mdempsky): This is subtle, elaborate further.
- //
- // We have to save tparams outside of the closure, because
- // typeParamNames() can be called multiple times with the same
- // dictionary instance.
- //
- // Also, this needs to happen later to make sure SetUnderlying has
- // been called.
- //
- // TODO(mdempsky): Is it safe to have a single "later" slice or do
- // we need to have multiple passes? See comments on CL 386002 and
- // go.dev/issue/52104.
- tparams := r.dict.tparams
+ // This needs to happen later to make sure SetUnderlying has been called.
r.p.later(func() {
- for i, typ := range typs {
+ for i, typ := range types {
tparams[i].SetConstraint(typ)
}
})
- return r.dict.tparams
+ return tparams
}
func (r *reader) method() *types.Func {
@@ -717,7 +745,7 @@ func (r *reader) method() *types.Func {
pos := r.pos()
pkg, name := r.selector()
- rparams := r.typeParamNames()
+ rparams := r.typeParamNames(false)
sig := r.signature(r.param(), rparams, nil)
_ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go.
diff --git a/vendor/golang.org/x/tools/internal/gocommand/version.go b/vendor/golang.org/x/tools/internal/gocommand/version.go
index 446c5846a..cce290c41 100644
--- a/vendor/golang.org/x/tools/internal/gocommand/version.go
+++ b/vendor/golang.org/x/tools/internal/gocommand/version.go
@@ -26,6 +26,9 @@ func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) {
inv.BuildFlags = nil // This is not a build command.
inv.ModFlag = ""
inv.ModFile = ""
+ // Set GO111MODULE=off so that we are immune to errors in go.{work,mod}.
+ // Unfortunately, this breaks the Go 1.21+ toolchain directive and
+ // may affect the set of ReleaseTags; see #68495.
inv.Env = append(inv.Env[:len(inv.Env):len(inv.Env)], "GO111MODULE=off")
stdoutBytes, err := r.Run(ctx, inv)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/version.go b/vendor/golang.org/x/tools/internal/pkgbits/version.go
index 53af9df22..0db965274 100644
--- a/vendor/golang.org/x/tools/internal/pkgbits/version.go
+++ b/vendor/golang.org/x/tools/internal/pkgbits/version.go
@@ -28,6 +28,15 @@ const (
// - remove derived info "needed" bool
V2
+ // V3: introduces a more compact format for composite literal element lists
+ // - negative lengths indicate that (some) elements may have keys
+ // - positive lengths indicate that no element has a key
+ // - a negative struct field index indicates an embedded field
+ V3
+
+ // V4: encodes generic methods as standalone function objects
+ V4
+
numVersions = iota
)
@@ -61,6 +70,12 @@ const (
// whether a type was a derived type.
DerivedInfoNeeded
+ // Composite literals use a more compact format for element lists.
+ CompactCompLiterals
+
+ // Generic methods may appear as standalone function objects.
+ GenericMethods
+
numFields = iota
)
@@ -68,6 +83,8 @@ const (
var introduced = [numFields]Version{
Flags: V1,
AliasTypeParamNames: V2,
+ CompactCompLiterals: V3,
+ GenericMethods: V4,
}
// removed is the version a field was removed in or 0 for fields
diff --git a/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/vendor/golang.org/x/tools/internal/typeparams/coretype.go
index 27a2b1792..2e05de464 100644
--- a/vendor/golang.org/x/tools/internal/typeparams/coretype.go
+++ b/vendor/golang.org/x/tools/internal/typeparams/coretype.go
@@ -11,7 +11,9 @@ import (
// CoreType returns the core type of T or nil if T does not have a core type.
//
-// See https://go.dev/ref/spec#Core_types for the definition of a core type.
+// As of Go1.25, the notion of a core type has been removed from the language spec.
+// See https://go.dev/blog/coretypes for more details.
+// TODO(mkalil): We should eventually consider removing all uses of CoreType.
func CoreType(T types.Type) types.Type {
U := T.Underlying()
if _, ok := U.(*types.Interface); !ok {
@@ -34,7 +36,7 @@ func CoreType(T types.Type) types.Type {
}
if identical == len(terms) {
- // https://go.dev/ref/spec#Core_types
+ // From the deprecated core types spec:
// "There is a single type U which is the underlying type of all types in the type set of T"
return U
}
@@ -42,7 +44,7 @@ func CoreType(T types.Type) types.Type {
if !ok {
return nil // no core type as identical < len(terms) and U is not a channel.
}
- // https://go.dev/ref/spec#Core_types
+ // From the deprecated core types spec:
// "the type chan E if T contains only bidirectional channels, or the type chan<- E or
// <-chan E depending on the direction of the directional channels present."
for chans := identical; chans < len(terms); chans++ {
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go
index 7112318fc..6582cc81f 100644
--- a/vendor/golang.org/x/tools/internal/typesinternal/types.go
+++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go
@@ -194,3 +194,51 @@ func Imports(pkg *types.Package, path string) bool {
}
return false
}
+
+// ObjectKind returns a description of the object's kind.
+//
+// from objectKind in go/types
+func ObjectKind(obj types.Object) string {
+ switch obj := obj.(type) {
+ case *types.PkgName:
+ return "package name"
+ case *types.Const:
+ return "constant"
+ case *types.TypeName:
+ if obj.IsAlias() {
+ return "type alias"
+ } else if _, ok := obj.Type().(*types.TypeParam); ok {
+ return "type parameter"
+ } else {
+ return "defined type"
+ }
+ case *types.Var:
+ switch obj.Kind() {
+ case PackageVar:
+ return "package-level variable"
+ case LocalVar:
+ return "local variable"
+ case RecvVar:
+ return "receiver"
+ case ParamVar:
+ return "parameter"
+ case ResultVar:
+ return "result variable"
+ case FieldVar:
+ return "struct field"
+ }
+ case *types.Func:
+ if obj.Signature().Recv() != nil {
+ return "method"
+ } else {
+ return "function"
+ }
+ case *types.Label:
+ return "label"
+ case *types.Builtin:
+ return "built-in function"
+ case *types.Nil:
+ return "untyped nil"
+ }
+ return "unknown symbol"
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/features.go b/vendor/golang.org/x/tools/internal/versions/features.go
index cdd36c388..360a5b552 100644
--- a/vendor/golang.org/x/tools/internal/versions/features.go
+++ b/vendor/golang.org/x/tools/internal/versions/features.go
@@ -19,6 +19,7 @@ const (
Go1_24 = "go1.24"
Go1_25 = "go1.25"
Go1_26 = "go1.26"
+ Go1_27 = "go1.27"
)
// Future is an invalid unknown Go version sometime in the future.
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c7bcb65bf..e59291a16 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -259,8 +259,8 @@ github.com/google/go-cmp/cmp/internal/diff
github.com/google/go-cmp/cmp/internal/flags
github.com/google/go-cmp/cmp/internal/function
github.com/google/go-cmp/cmp/internal/value
-# github.com/google/pprof v0.0.0-20250403155104-27863c87afa6
-## explicit; go 1.23
+# github.com/google/pprof v0.0.0-20260402051712-545e8a4df936
+## explicit; go 1.24.0
github.com/google/pprof/profile
# github.com/google/uuid v1.6.0
## explicit
@@ -315,8 +315,8 @@ github.com/munnerz/goautoneg
# github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
## explicit
github.com/mxk/go-flowrate/flowrate
-# github.com/onsi/ginkgo/v2 v2.27.2
-## explicit; go 1.23.0
+# github.com/onsi/ginkgo/v2 v2.32.0
+## explicit; go 1.25.0
github.com/onsi/ginkgo/v2
github.com/onsi/ginkgo/v2/config
github.com/onsi/ginkgo/v2/formatter
@@ -339,8 +339,8 @@ 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
-# github.com/onsi/gomega v1.38.2
-## explicit; go 1.23.0
+# github.com/onsi/gomega v1.40.0
+## explicit; go 1.24.0
github.com/onsi/gomega
github.com/onsi/gomega/format
github.com/onsi/gomega/internal
@@ -508,7 +508,7 @@ go.yaml.in/yaml/v3
## explicit; go 1.20
golang.org/x/exp/constraints
golang.org/x/exp/slices
-# golang.org/x/mod v0.34.0
+# golang.org/x/mod v0.35.0
## explicit; go 1.25.0
golang.org/x/mod/semver
# golang.org/x/net v0.53.0
@@ -579,7 +579,7 @@ golang.org/x/text/unicode/norm
# golang.org/x/time v0.11.0
## explicit; go 1.23.0
golang.org/x/time/rate
-# golang.org/x/tools v0.43.0
+# golang.org/x/tools v0.44.0
## explicit; go 1.25.0
golang.org/x/tools/cover
golang.org/x/tools/go/ast/edge