diff --git a/go.mod b/go.mod index 3f32274d..816b93dc 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,12 @@ module code.cloudfoundry.org/tps -go 1.25 +go 1.25.1 require ( code.cloudfoundry.org/bbs v0.0.0-20251029140956-4e01df8b0ac1 code.cloudfoundry.org/clock v1.70.0 code.cloudfoundry.org/debugserver v0.96.0 - code.cloudfoundry.org/diego-logging-client v0.105.0 + code.cloudfoundry.org/diego-logging-client v0.106.0 code.cloudfoundry.org/lager/v3 v3.69.0 code.cloudfoundry.org/localip v0.71.0 code.cloudfoundry.org/locket v0.0.0-20251028190928-8f3817b47d6f @@ -14,17 +14,17 @@ require ( code.cloudfoundry.org/workpool v0.0.0-20250911194158-1489753f182e github.com/cloudfoundry/dropsonde v1.1.0 github.com/lib/pq v1.12.3 - github.com/onsi/ginkgo/v2 v2.28.3 - github.com/onsi/gomega v1.40.0 + github.com/onsi/ginkgo/v2 v2.29.0 + github.com/onsi/gomega v1.41.0 github.com/tedsuo/ifrit v0.0.0-20260418191334-846868129986 ) require ( code.cloudfoundry.org/cfhttp/v2 v2.0.1-0.20210513172332-4c5ee488a657 // indirect code.cloudfoundry.org/durationjson v0.0.0-20200131001738-04c274cd71ed // indirect - code.cloudfoundry.org/go-diodes v0.0.0-20260504113438-abdf05667e78 // indirect + code.cloudfoundry.org/go-diodes v0.0.0-20260518082450-53acbbed6d0f // indirect code.cloudfoundry.org/go-loggregator/v9 v9.2.1 // indirect - code.cloudfoundry.org/tlsconfig v0.53.0 // indirect + code.cloudfoundry.org/tlsconfig v0.54.0 // indirect filippo.io/edwards25519 v1.2.0 // indirect github.com/Masterminds/semver/v3 v3.5.0 // indirect github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f // indirect @@ -45,7 +45,7 @@ require ( github.com/square/certstrap v1.3.0 // indirect github.com/tedsuo/rata v1.0.0 // indirect github.com/vito/go-sse v1.0.0 // indirect - go.step.sm/crypto v0.77.9 // indirect + go.step.sm/crypto v0.79.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.51.0 // indirect golang.org/x/mod v0.36.0 // indirect @@ -54,7 +54,7 @@ require ( golang.org/x/sys v0.44.0 // indirect golang.org/x/text v0.37.0 // indirect golang.org/x/tools v0.45.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 // indirect - google.golang.org/grpc v1.81.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260518230821-037a81a441c8 // indirect + google.golang.org/grpc v1.81.1 // indirect google.golang.org/protobuf v1.36.11 // indirect ) diff --git a/go.sum b/go.sum index cf6d9239..523e3ff6 100644 --- a/go.sum +++ b/go.sum @@ -600,12 +600,12 @@ code.cloudfoundry.org/clock v1.70.0 h1:uG04cx3v0ztdmtcGSVmYfHUdG596A5V5Slt37xwJG code.cloudfoundry.org/clock v1.70.0/go.mod h1:h5C2CUJ0PsVnVeEe9c7eNmDdAbxjywHZHZx9dc2Gwnw= code.cloudfoundry.org/debugserver v0.96.0 h1:0rgM1ezM3f5D8UyTS7BQK7sHo9QBMpgxFNEJGjM7YFw= code.cloudfoundry.org/debugserver v0.96.0/go.mod h1:gizNqj1amysfzRiU97DmbdfhAI6V5IP7sK+w9sEFM1o= -code.cloudfoundry.org/diego-logging-client v0.105.0 h1:kZM7mHLMfVple4bDiUG2hOYjhq4BeGSfZMxm/FwaCgE= -code.cloudfoundry.org/diego-logging-client v0.105.0/go.mod h1:eesOddpMpOiV+JR1r9N+u2UK+fDup5J5q96S2l9E/J4= +code.cloudfoundry.org/diego-logging-client v0.106.0 h1:Ono2/BO8kna6abDWkQyfpAzUPCC3BR/syWQYzKczh/4= +code.cloudfoundry.org/diego-logging-client v0.106.0/go.mod h1:E2LnBrNB0jwpY0+gSXgXN0bgnqFn84spPAqUdWIVYMI= code.cloudfoundry.org/durationjson v0.0.0-20200131001738-04c274cd71ed h1:hSvlHcyx91CyefH4h8og5Xrz2gK0KSRbqPcvRXXwho8= code.cloudfoundry.org/durationjson v0.0.0-20200131001738-04c274cd71ed/go.mod h1:uR0bLsCAMy6IeJVZDs/pD+jKZ2+hBt2hKnX4DzLQs5A= -code.cloudfoundry.org/go-diodes v0.0.0-20260504113438-abdf05667e78 h1:5bGjlbR/P1omITVWptbn11zZAVOZg2JiYkQzfol/7qM= -code.cloudfoundry.org/go-diodes v0.0.0-20260504113438-abdf05667e78/go.mod h1:h9KGzD7HrNJeTn9wD8V+C4dy9a6KMj5MT3AEqD1wp3Y= +code.cloudfoundry.org/go-diodes v0.0.0-20260518082450-53acbbed6d0f h1:64yICzxRPmSlKiwWc8EK7Ion6zQzbfLE8VVnOvAyRHM= +code.cloudfoundry.org/go-diodes v0.0.0-20260518082450-53acbbed6d0f/go.mod h1:CBNKjs+CBCb9Q83t8vxzqctA/wa5bonUXh1WQDFxZaY= code.cloudfoundry.org/go-loggregator/v9 v9.2.1 h1:S6Lgg5UJbhh2bt2TGQxs6R00CF8PrUA3GFPYDxy56Fk= code.cloudfoundry.org/go-loggregator/v9 v9.2.1/go.mod h1:FTFFruqGeOhVCDFvyLgl8EV8YW63NNwRzLhxJcporu8= code.cloudfoundry.org/lager/v3 v3.69.0 h1:NXaYN5tL89ezjUM9JuF5xAfKMhvuSfvJYxushp3nwYY= @@ -616,8 +616,8 @@ code.cloudfoundry.org/locket v0.0.0-20251028190928-8f3817b47d6f h1:QQJJHVATi00MC code.cloudfoundry.org/locket v0.0.0-20251028190928-8f3817b47d6f/go.mod h1:AwHLRkdXtttLXNB8RHgLfErJ2kKafH62AR2OClhy6xI= code.cloudfoundry.org/runtimeschema v0.0.0-20240514235758-31be7684c5bf h1:sTpfHaU+tgDeRO/fRnyr91gvf1FaJk3ZNiJHiHq4nko= code.cloudfoundry.org/runtimeschema v0.0.0-20240514235758-31be7684c5bf/go.mod h1:Cbw66uMLAXkeK8ZpcTUIJ9nhXNxaN742q1xS/ONrWiQ= -code.cloudfoundry.org/tlsconfig v0.53.0 h1:ajprkio3g4V+C0AUJt3rXkkA0il+3sQZ9dJMRQ/e7Ug= -code.cloudfoundry.org/tlsconfig v0.53.0/go.mod h1:DMYiC50mOZC38kVQChNoHvLveqD+xohYJgfO9yusAFk= +code.cloudfoundry.org/tlsconfig v0.54.0 h1:TPQG255F1Y1J3e5Q08qd5N9n9d9nxOt6dwwVQwrUDd0= +code.cloudfoundry.org/tlsconfig v0.54.0/go.mod h1:BsXySJAnDqzQh2TX281OO0nMsq+TZCqcInDuLVtqR24= code.cloudfoundry.org/workpool v0.0.0-20250911194158-1489753f182e h1:NsULHptleEmqtoC8j6A8J636L9APnGn8YC0c7vocLww= code.cloudfoundry.org/workpool v0.0.0-20250911194158-1489753f182e/go.mod h1:O9HdfntfyDvYRH9nh03XdpnGMbjyZVi8nb2Kh+6hDho= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -927,8 +927,8 @@ github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxm github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= -github.com/onsi/ginkgo/v2 v2.28.3 h1:4JvMdwtFU0imd8fHx25OJXoDMRexnf8v5NHKYSTTji4= -github.com/onsi/ginkgo/v2 v2.28.3/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44= +github.com/onsi/ginkgo/v2 v2.29.0 h1:rfh+ZFjgJhYWRoIqVf3Uwx/W20yLrcrE2h2GmYVRaag= +github.com/onsi/ginkgo/v2 v2.29.0/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -945,8 +945,8 @@ github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfad github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= -github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc= -github.com/onsi/gomega v1.40.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A= +github.com/onsi/gomega v1.41.0 h1:OwKp4pXNgVxf6sCplzYo794OFNuoL2q2SBMU5NSWOjA= +github.com/onsi/gomega v1.41.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A= github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= @@ -1039,8 +1039,8 @@ go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLh go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.step.sm/crypto v0.77.9 h1:gC/z6/XBlLpq9suHQxbcDS32QSGggpisIZVJr65LDJk= -go.step.sm/crypto v0.77.9/go.mod h1:/5BzDlwYA7C1q6h9OIv0+oR8lbQvK+rTGeBmLLl7hIo= +go.step.sm/crypto v0.79.0 h1:vy6i3ezAV5JokPALXWGNVcjiESjbpJgIT65t/WkhGFM= +go.step.sm/crypto v0.79.0/go.mod h1:hblLC8VVW3SnV7DE88jpdVgJHPYabIlNMMXkrbAZoUs= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -1637,8 +1637,8 @@ google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOl google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 h1:seT2EwLWM78plQ7wcDfuWBc/4FAEAXDDiaSol4ku4qo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260518230821-037a81a441c8 h1:bC5uhsFn4cascckU5rg/YLCaC+KjOn2wP+88VWCcfng= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260518230821-037a81a441c8/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1681,8 +1681,8 @@ google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5v google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= -google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw= -google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= +google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ= +google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/examples v0.0.0-20230512210959-5dcfb37c0b43/go.mod h1:irORyHPQXotoshbRTZVFvPDcfTfFHL23efQeop+H45M= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/vendor/github.com/onsi/ginkgo/v2/.gitignore b/vendor/github.com/onsi/ginkgo/v2/.gitignore index 6faaaf31..c9f05462 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 d382b064..224e8db5 100644 --- a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md +++ b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.29.0 + +`GinkgoHelperGo` makes it easier to write test helpers that need to run in goroutines. Specifically, it makes managing the failure state and capturing failure panics correctly straightforward. + +`ginkgo outline` now includes entries defined in `DescribeTableSubtree` + ## 2.28.3 ### Maintenance diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go index 5d8d00bb..c380bbf2 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 e99d557d..206043f1 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go @@ -54,6 +54,7 @@ func FromASTFile(fset *token.FileSet, src *ast.File) (*outline, error) { // Node is not a Ginkgo spec or container, so it was not pushed onto the stack, continue return true } + expandSubtree(lastVisitedGinkgoNode) stack = stack[0 : len(stack)-1] return true }) @@ -128,3 +129,29 @@ func (o *outline) StringIndent(width int) string { return b.String() } + +// expandSubtree restructures a DescribeTableSubtree node so that each Entry +// child gets a copy of the subtree's spec nodes as its children. This mirrors +// the runtime behavior where each Entry generates a container with the specs +// defined in the DescribeTableSubtree body. +func expandSubtree(gn *ginkgoNode) { + if !strings.Contains(gn.Name, "DescribeTableSubtree") { + return + } + subNodes, entries := splitSubtreeSubnodes(gn.Nodes) + gn.Nodes = entries + for _, entry := range entries { + entry.Nodes = subNodes + } +} + +// splitSubtreeSubnodes splits the child nodes of a DescribeTableSubtree into +// spec/container nodes (defined in the body) and Entry nodes. +func splitSubtreeSubnodes(nodes []*ginkgoNode) ([]*ginkgoNode, []*ginkgoNode) { + for i, node := range nodes { + if strings.Contains(node.Name, "Entry") { + return nodes[:i], nodes[i:] + } + } + return nodes, nil +} diff --git a/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go b/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go new file mode 100644 index 00000000..9d04cc84 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go @@ -0,0 +1,143 @@ +package ginkgo + +import ( + "github.com/onsi/ginkgo/v2/internal/global" + ginkgotypes "github.com/onsi/ginkgo/v2/types" +) + +// GinkgoHelperGo synchronously calls the specified “helper” function in a new +// go routine and with a “defer GinkgoRecover()” already in place, passing the +// function a “helper Fail”. GinkgoHelperGo is typically called from custom test +// helpers that in turn need to synchronously execute caller-supplied custom +// test code in a new Go routine while waiting for this new Go routine to +// terminate (either successfully or failing). +// +// GinkgoHelperGo hides the non-trivial details of correctly unblocking the +// caller's waiting go routine as well as reporting the correct call sites, +// depending on whether the test helper failed, or the caller-supplied function +// had its assertions failing or panicked. +// +// Let's take the following example of a test helper named “EnsureSprockets” +// that runs a set of caller-supplied assertions synchronously on a new Go +// routine and waits for the outcome before returning to the caller of the test +// helper. This is just using Ginkgo: +// +// func EnsureSprockets(sprockets int, assertions func()) { +// GinkgoHelper() +// GinkgoHelperGo(func(helperFail func(string, ...int)) { +// if sprockets == 0 { +// helperFail("sprockets must not be zero") +// } +// assertions() +// }) +// } +// +// And now for an example that additionally uses Gomega assertions. +// +// func EnsureSprockets(sprockets int, assertions func()) { +// GinkgoHelper() +// GinkgoHelperGo(func(helperFail func(string, ...int)) { +// g := gomega.NewGomega(helperFail) +// g.Expect(sprockets).Not(BeZero()) +// assertions() +// }) +// } +// +// The called helper function should make any custom helper-related assertions +// using the passed “helper Fail”. Gomega users will want to create a new Gomega +// wired into this helper Fail. It is expected for the helper function at some +// point to call into a user-supplied function that might contain its own +// assertions. In the example above, that would be the function passed as +// assertions. +// +// Any failing assertion using the helper Gomega in the helper function will be +// reported as a fail at the call site of GinkgoHelperGo. Preferably, only +// custom test helpers call GinkgoHelperGo and thus mark themselves as +// [GinkgoHelper] also: in this case, the fail will be shown at the call site of +// the custom test helper. +// +// Any other failing assertions inside the caller-supplied custom test code and +// thus inside the helper function will instead be reported at the location of +// the failed assertion. +// +// If the caller-supplied custom test code panics, GinkgoHelperGo will fail at +// its call site, or at the call site of the custom test helper if it uses +// GinkgoHelper, reporting the usual stack trace for the panic, as a plain +// GinkgoRecover would also do. +// +// Important: the Gomega passed to the called function must only be used in +// assertions belonging to the test helper, but not any user test code called +// from the test helper. Thus, do not pass the Gomega passed to the helper +// function further on to any user test code functions. +func GinkgoHelperGo(fn func(fail func(message string, callerSkip ...int))) { + // userPanicked signals that the called user code panicked, such as due to a + // failed Gomega assertion. + type userPanicked struct{} + + // helperPanicked signals that some helper code assertion panicked in the + // separate Go routine and we are expected to Fail the current test with that + // reason, but on the caller's Go routine. + type helperPanicked string + + GinkgoHelper() + + // possible types of values sent over the result channel: + // - nil (untyped): no problem at all, proceed. + // - helperPanicked: the message with which to (re)fail in the caller's + // go routine. + // - userPanicked: indication to (also) fail on the caller's go routine; + // the message doesn't matter as the user code fail takes precedence. + ch := make(chan any) + + go func() { + isHelperPanic := false + helperFail := func(message string, callerSkip ...int) { + isHelperPanic = true + Fail(message, callerSkip...) + } + // Please note that we cannot simply recover a helper panic before + // GinkgoRecover kicks in as then GinkgoRecover would always report the + // stack trace only from the place of rethrown panic ... and that's + // pretty useless, because it would just consist of the panic rethrow. + defer func() { + // We need to unblock and immediately fail the waiting caller's + // go routine either for a reason, or just "because" when + // GinkgoRecover has already failed the current test on the + // separate go routine. + if global.Failer.GetState() != ginkgotypes.SpecStatePassed { + if isHelperPanic { + _, failure := global.Failer.Drain() + ch <- helperPanicked(failure.Message) + } else { + // keep the panic failure already recorded by GinkgoRecover. + ch <- userPanicked{} + } + } + close(ch) // causes a nil in case there were no panics anywhere. + }() + // Nota bene: GinkgoRecover always eats any user panic and channel the + // panic value into Ginkgo's Failer.Panic(). We can peek at the last + // failure recorded, which should be nil if GinkgoRecover didn't swallow + // a user code panic. The "problem" with GinkgoRecover is that it turns + // any panic value into a string message, so we loose any specific + // typing. + defer GinkgoRecover() + + fn(helperFail) + }() + + // Did we run into trouble? + switch v := (<-ch).(type) { + case userPanicked: + // The message actually is irrelevant, as it comes only second to + // the already registered user panic message. We just need Fail to + // panic on the caller's go routine in order to unblock the test. + Fail("fn panicked", 1) + case helperPanicked: + // Report the failure on the new go routine instead on the caller's go + // routine. + Fail(string(v), 1) + default: + // It's all fine! + } +} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go index 4479578f..003604bd 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/version.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.28.3" +const VERSION = "2.29.0" diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md index 9c94d0e6..5f9966fb 100644 --- a/vendor/github.com/onsi/gomega/CHANGELOG.md +++ b/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -1,3 +1,13 @@ +## 1.41.0 + +### Features + +Add `BeASlice` and `BeAnArray` matchers + +### Fixes + +Object formatting now detects pointer cycles to avoid runaway formatting output. + ## 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). diff --git a/vendor/github.com/onsi/gomega/format/format.go b/vendor/github.com/onsi/gomega/format/format.go index 6c23ba33..d56f9a47 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, true)) + return fmt.Sprintf("%s<%s>: %s%s", indent, formatType(value), commonRepresentation, formatValue(value, indentation, true, map[uintptr]struct{}{})) } /* @@ -306,7 +306,7 @@ func formatType(v reflect.Value) string { } } -func formatValue(value reflect.Value, indentation uint, isTopLevel bool) string { +func formatValue(value reflect.Value, indentation uint, isTopLevel bool, visited map[uintptr]struct{}) string { if indentation > MaxDepth { return "..." } @@ -367,23 +367,28 @@ func formatValue(value reflect.Value, indentation uint, isTopLevel bool) string case reflect.Func: return fmt.Sprintf("0x%x", value.Pointer()) case reflect.Ptr: - return formatValue(value.Elem(), indentation, isTopLevel) + ptr := value.Pointer() + if _, ok := visited[ptr]; ok { + return fmt.Sprintf("0x%x (cyclic reference)", ptr) + } + visited[ptr] = struct{}{} + return formatValue(value.Elem(), indentation, isTopLevel, visited) case reflect.Slice: - return truncateLongStrings(formatSlice(value, indentation)) + return truncateLongStrings(formatSlice(value, indentation, visited)) case reflect.String: return truncateLongStrings(formatString(value.String(), indentation, isTopLevel)) case reflect.Array: - return truncateLongStrings(formatSlice(value, indentation)) + return truncateLongStrings(formatSlice(value, indentation, visited)) case reflect.Map: - return truncateLongStrings(formatMap(value, indentation)) + return truncateLongStrings(formatMap(value, indentation, visited)) case reflect.Struct: if value.Type() == timeType && value.CanInterface() { t, _ := value.Interface().(time.Time) return t.Format(time.RFC3339Nano) } - return truncateLongStrings(formatStruct(value, indentation)) + return truncateLongStrings(formatStruct(value, indentation, visited)) case reflect.Interface: - return formatInterface(value, indentation) + return formatInterface(value, indentation, visited) default: if value.CanInterface() { return truncateLongStrings(fmt.Sprintf("%#v", value.Interface())) @@ -414,7 +419,7 @@ func formatString(object any, indentation uint, isTopLevel bool) string { } } -func formatSlice(v reflect.Value, indentation uint) string { +func formatSlice(v reflect.Value, indentation uint, visited map[uintptr]struct{}) string { if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 && isPrintableString(string(v.Bytes())) { return formatString(v.Bytes(), indentation, false) } @@ -423,7 +428,7 @@ func formatSlice(v reflect.Value, indentation uint) string { result := make([]string, l) longest := 0 for i := range l { - result[i] = formatValue(v.Index(i), indentation+1, false) + result[i] = formatValue(v.Index(i), indentation+1, false, visited) if len(result[i]) > longest { longest = len(result[i]) } @@ -436,14 +441,14 @@ func formatSlice(v reflect.Value, indentation uint) string { return fmt.Sprintf("[%s]", strings.Join(result, ", ")) } -func formatMap(v reflect.Value, indentation uint) string { +func formatMap(v reflect.Value, indentation uint, visited map[uintptr]struct{}) string { l := v.Len() result := make([]string, l) longest := 0 for i, key := range v.MapKeys() { value := v.MapIndex(key) - result[i] = fmt.Sprintf("%s: %s", formatValue(key, indentation+1, false), formatValue(value, indentation+1, false)) + result[i] = fmt.Sprintf("%s: %s", formatValue(key, indentation+1, false, visited), formatValue(value, indentation+1, false, visited)) if len(result[i]) > longest { longest = len(result[i]) } @@ -456,7 +461,7 @@ func formatMap(v reflect.Value, indentation uint) string { return fmt.Sprintf("{%s}", strings.Join(result, ", ")) } -func formatStruct(v reflect.Value, indentation uint) string { +func formatStruct(v reflect.Value, indentation uint, visited map[uintptr]struct{}) string { t := v.Type() l := v.NumField() @@ -465,7 +470,7 @@ func formatStruct(v reflect.Value, indentation uint) string { for i := range l { structField := t.Field(i) fieldEntry := v.Field(i) - representation := fmt.Sprintf("%s: %s", structField.Name, formatValue(fieldEntry, indentation+1, false)) + representation := fmt.Sprintf("%s: %s", structField.Name, formatValue(fieldEntry, indentation+1, false, visited)) result = append(result, representation) if len(representation) > longest { longest = len(representation) @@ -478,8 +483,8 @@ func formatStruct(v reflect.Value, indentation uint) string { return fmt.Sprintf("{%s}", strings.Join(result, ", ")) } -func formatInterface(v reflect.Value, indentation uint) string { - return fmt.Sprintf("<%s>%s", formatType(v.Elem()), formatValue(v.Elem(), indentation, false)) +func formatInterface(v reflect.Value, indentation uint, visited map[uintptr]struct{}) string { + return fmt.Sprintf("<%s>%s", formatType(v.Elem()), formatValue(v.Elem(), indentation, false, visited)) } 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 af1341bd..df16ede1 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.40.0" +const GOMEGA_VERSION = "1.41.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 16ca8f46..bf572260 100644 --- a/vendor/github.com/onsi/gomega/matchers.go +++ b/vendor/github.com/onsi/gomega/matchers.go @@ -621,6 +621,18 @@ func BeADirectory() types.GomegaMatcher { return &matchers.BeADirectoryMatcher{} } +// BeASlice succeeds if actual is a value of slice type. +// This is useful when actual has type any (interface{}) and you want to assert it is a slice. +func BeASlice() types.GomegaMatcher { + return &matchers.BeASliceMatcher{} +} + +// BeAnArray succeeds if actual is a value of array type. +// This is useful when actual has type any (interface{}) and you want to assert it is an array. +func BeAnArray() types.GomegaMatcher { + return &matchers.BeAnArrayMatcher{} +} + // HaveHTTPStatus succeeds if the Status or StatusCode field of an HTTP response matches. // Actual must be either a *http.Response or *httptest.ResponseRecorder. // Expected must be either an int or a string. diff --git a/vendor/github.com/onsi/gomega/matchers/be_a_slice_matcher.go b/vendor/github.com/onsi/gomega/matchers/be_a_slice_matcher.go new file mode 100644 index 00000000..4fcad512 --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/be_a_slice_matcher.go @@ -0,0 +1,28 @@ +// untested sections: 1 + +package matchers + +import ( + "fmt" + "reflect" + + "github.com/onsi/gomega/format" +) + +type BeASliceMatcher struct { +} + +func (matcher *BeASliceMatcher) Match(actual any) (success bool, err error) { + if actual == nil { + return false, fmt.Errorf("BeASlice matcher expects a value, got nil") + } + return reflect.TypeOf(actual).Kind() == reflect.Slice, nil +} + +func (matcher *BeASliceMatcher) FailureMessage(actual any) (message string) { + return format.Message(actual, "to be a slice") +} + +func (matcher *BeASliceMatcher) NegatedFailureMessage(actual any) (message string) { + return format.Message(actual, "not to be a slice") +} diff --git a/vendor/github.com/onsi/gomega/matchers/be_an_array_matcher.go b/vendor/github.com/onsi/gomega/matchers/be_an_array_matcher.go new file mode 100644 index 00000000..573aa819 --- /dev/null +++ b/vendor/github.com/onsi/gomega/matchers/be_an_array_matcher.go @@ -0,0 +1,28 @@ +// untested sections: 1 + +package matchers + +import ( + "fmt" + "reflect" + + "github.com/onsi/gomega/format" +) + +type BeAnArrayMatcher struct { +} + +func (matcher *BeAnArrayMatcher) Match(actual any) (success bool, err error) { + if actual == nil { + return false, fmt.Errorf("BeAnArray matcher expects a value, got nil") + } + return reflect.TypeOf(actual).Kind() == reflect.Array, nil +} + +func (matcher *BeAnArrayMatcher) FailureMessage(actual any) (message string) { + return format.Message(actual, "to be an array") +} + +func (matcher *BeAnArrayMatcher) NegatedFailureMessage(actual any) (message string) { + return format.Message(actual, "not to be an array") +} diff --git a/vendor/github.com/onsi/gomega/types/types.go b/vendor/github.com/onsi/gomega/types/types.go index 685a46f3..e444451a 100644 --- a/vendor/github.com/onsi/gomega/types/types.go +++ b/vendor/github.com/onsi/gomega/types/types.go @@ -66,6 +66,12 @@ func MatchMayChangeInTheFuture(matcher GomegaMatcher, value any) bool { // AsyncAssertions are returned by Eventually and Consistently and enable matchers to be polled repeatedly to ensure // they are eventually satisfied +// +// The optional optionalDescription argument allows you to annotate the assertion with additional information. +// It is passed as the second argument and can be a format string followed by arguments, or a func() string. +// The description is included in failure messages to provide context. +// +// For details on annotating assertions, see: https://onsi.github.io/gomega/#annotating-assertions type AsyncAssertion interface { Should(matcher GomegaMatcher, optionalDescription ...any) bool ShouldNot(matcher GomegaMatcher, optionalDescription ...any) bool @@ -86,6 +92,12 @@ type AsyncAssertion interface { } // Assertions are returned by Ω and Expect and enable assertions against Gomega matchers +// +// The optional optionalDescription argument allows you to annotate the assertion with additional information. +// It is passed as the second argument and can be a format string followed by arguments, or a func() string. +// The description is included in failure messages to provide context. +// +// For details on annotating assertions, see: https://onsi.github.io/gomega/#annotating-assertions type Assertion interface { Should(matcher GomegaMatcher, optionalDescription ...any) bool ShouldNot(matcher GomegaMatcher, optionalDescription ...any) bool diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 7ac723c1..3ccfe515 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.81.0" +const Version = "1.81.1" diff --git a/vendor/modules.txt b/vendor/modules.txt index 2d7e44fd..71705dd7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -18,14 +18,14 @@ code.cloudfoundry.org/clock # code.cloudfoundry.org/debugserver v0.96.0 ## explicit; go 1.25.0 code.cloudfoundry.org/debugserver -# code.cloudfoundry.org/diego-logging-client v0.105.0 -## explicit; go 1.25.0 +# code.cloudfoundry.org/diego-logging-client v0.106.0 +## explicit; go 1.25.1 code.cloudfoundry.org/diego-logging-client code.cloudfoundry.org/diego-logging-client/testhelpers # code.cloudfoundry.org/durationjson v0.0.0-20200131001738-04c274cd71ed ## explicit code.cloudfoundry.org/durationjson -# code.cloudfoundry.org/go-diodes v0.0.0-20260504113438-abdf05667e78 +# code.cloudfoundry.org/go-diodes v0.0.0-20260518082450-53acbbed6d0f ## explicit; go 1.25.0 code.cloudfoundry.org/go-diodes # code.cloudfoundry.org/go-loggregator/v9 v9.2.1 @@ -53,8 +53,8 @@ code.cloudfoundry.org/locket/models # code.cloudfoundry.org/runtimeschema v0.0.0-20240514235758-31be7684c5bf ## explicit; go 1.20 code.cloudfoundry.org/runtimeschema/cc_messages -# code.cloudfoundry.org/tlsconfig v0.53.0 -## explicit; go 1.25.0 +# code.cloudfoundry.org/tlsconfig v0.54.0 +## explicit; go 1.25.1 code.cloudfoundry.org/tlsconfig # code.cloudfoundry.org/workpool v0.0.0-20250911194158-1489753f182e ## explicit @@ -140,7 +140,7 @@ github.com/mailru/easyjson/jwriter # github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d ## explicit github.com/nu7hatch/gouuid -# github.com/onsi/ginkgo/v2 v2.28.3 +# github.com/onsi/ginkgo/v2 v2.29.0 ## explicit; go 1.25.0 github.com/onsi/ginkgo/v2 github.com/onsi/ginkgo/v2/config @@ -164,7 +164,7 @@ 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.40.0 +# github.com/onsi/gomega v1.41.0 ## explicit; go 1.24.0 github.com/onsi/gomega github.com/onsi/gomega/format @@ -203,8 +203,8 @@ github.com/tedsuo/rata # github.com/vito/go-sse v1.0.0 ## explicit; go 1.12 github.com/vito/go-sse/sse -# go.step.sm/crypto v0.77.9 -## explicit; go 1.25.0 +# go.step.sm/crypto v0.79.0 +## explicit; go 1.25.1 go.step.sm/crypto/fingerprint go.step.sm/crypto/internal/bcrypt_pbkdf go.step.sm/crypto/internal/emoji @@ -299,10 +299,10 @@ golang.org/x/tools/internal/stdlib golang.org/x/tools/internal/typeparams golang.org/x/tools/internal/typesinternal golang.org/x/tools/internal/versions -# google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 +# google.golang.org/genproto/googleapis/rpc v0.0.0-20260518230821-037a81a441c8 ## explicit; go 1.25.0 google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.81.0 +# google.golang.org/grpc v1.81.1 ## explicit; go 1.25.0 google.golang.org/grpc google.golang.org/grpc/attributes