chore(deps): bump github.com/onsi/ginkgo/v2 from 2.26.0 to 2.27.2

Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.26.0 to 2.27.2.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.26.0...v2.27.2)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.27.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2025-11-06 06:03:05 +00:00
committed by GitHub
parent 62f4548d67
commit ddea215337
40 changed files with 480 additions and 706 deletions

3
go.mod
View File

@@ -61,7 +61,7 @@ require (
github.com/nats-io/nats.go v1.46.1
github.com/olekukonko/tablewriter v1.1.0
github.com/onsi/ginkgo v1.16.5
github.com/onsi/ginkgo/v2 v2.26.0
github.com/onsi/ginkgo/v2 v2.27.2
github.com/onsi/gomega v1.38.2
github.com/open-policy-agent/opa v1.6.0
github.com/orcaman/concurrent-map v1.0.0
@@ -326,7 +326,6 @@ require (
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect
go.opentelemetry.io/otel/metric v1.38.0 // indirect
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect

12
go.sum
View File

@@ -273,8 +273,8 @@ github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BN
github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
github.com/gkampitakis/go-snaps v0.5.14 h1:3fAqdB6BCPKHDMHAKRwtPUwYexKtGrNuw8HX/T/4neo=
github.com/gkampitakis/go-snaps v0.5.14/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=
github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE=
github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
github.com/go-acme/lego/v4 v4.25.2 h1:+D1Q+VnZrD+WJdlkgUEGHFFTcDrwGlE7q24IFtMmHDI=
@@ -702,8 +702,8 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.26.0 h1:1J4Wut1IlYZNEAWIV3ALrT9NfiaGW2cDCJQSFQMs/gE=
github.com/onsi/ginkgo/v2 v2.26.0/go.mod h1:qhEywmzWTBUY88kfO0BRvX4py7scov9yR+Az2oavUzw=
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.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
@@ -746,8 +746,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/cachecontrol v0.2.0 h1:vBXSNuE5MYP9IJ5kjsdo8uq+w41jSPgvba2DEnkRx9k=
github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/alertmanager v0.28.1 h1:BK5pCoAtaKg01BYRUJhEDV1tqJMEtYBGzPw8QdvnnvA=
github.com/prometheus/alertmanager v0.28.1/go.mod h1:0StpPUDDHi1VXeM7p2yYfeZgLVi/PPlt39vo9LQUHxM=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -968,8 +966,6 @@ go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42s
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=

View File

@@ -1,3 +1,40 @@
## 2.27.2
### Fixes
- inline automaxprocs to simplify dependencies; this will be removed when Go 1.26 comes out [a69113a]
### Maintenance
- Fix syntax errors and typo [a99c6e0]
- Fix paragraph position error [f993df5]
## 2.27.1
### Fixes
- Fix Ginkgo Reporter slice-bounds panic [606c1cb]
- Bug Fix: Add GinkoTBWrapper.Attr() and GinkoTBWrapper.Output() [a6463b3]
## 2.27.0
### Features
#### Transforming Nodes during Tree Construction
This release adds support for `NodeArgsTransformer`s that can be registered with `AddTreeConstructionNodeArgsTransformer`.
These are called during the tree construction phase as nodes are constructed and can modify the node strings and decorators. This enables frameworks built on top of Ginkgo to modify Ginkgo nodes and enforce conventions.
Learn more [here](https://onsi.github.io/ginkgo/#advanced-transforming-node-arguments-during-tree-construction).
#### Spec Prioritization
A new `SpecPriority(int)` decorator has been added. Ginkgo will honor priority when ordering specs, ensuring that higher priority specs start running before lower priority specs
Learn more [here](https://onsi.github.io/ginkgo/#prioritizing-specs).
### Maintenance
- Bump rexml from 3.4.0 to 3.4.2 in /docs (#1595) [1333dae]
- Bump github.com/gkampitakis/go-snaps from 0.5.14 to 0.5.15 (#1600) [17ae63e]
## 2.26.0
### Features

View File

@@ -501,6 +501,38 @@ func pushNode(node internal.Node, errors []error) bool {
return true
}
// NodeArgsTransformer is a hook which is called by the test construction DSL methods
// before creating the new node. If it returns any error, the test suite
// prints those errors and exits. The text and arguments can be modified,
// which includes directly changing the args slice that is passed in.
// Arguments have been flattened already, i.e. none of the entries in args is another []any.
// The result may be nested.
//
// The node type is provided for information and remains the same.
//
// The offset is valid for calling NewLocation directly in the
// implementation of TransformNodeArgs to find the location where
// the Ginkgo DSL function is called. An additional offset supplied
// by the caller via args is already included.
//
// A NodeArgsTransformer can be registered with AddTreeConstructionNodeArgsTransformer.
type NodeArgsTransformer func(nodeType types.NodeType, offset Offset, text string, args []any) (string, []any, []error)
// AddTreeConstructionNodeArgsTransformer registers a NodeArgsTransformer.
// Only nodes which get created after registering a NodeArgsTransformer
// are transformed by it. The returned function can be called to
// unregister the transformer.
//
// Both may only be called during the construction phase.
//
// If there is more than one registered transformer, then the most
// recently added ones get called first.
func AddTreeConstructionNodeArgsTransformer(transformer NodeArgsTransformer) func() {
// This conversion could be avoided with a type alias, but type aliases make
// developer documentation less useful.
return internal.AddTreeConstructionNodeArgsTransformer(internal.NodeArgsTransformer(transformer))
}
/*
Describe nodes are Container nodes that allow you to organize your specs. A Describe node's closure can contain any number of
Setup nodes (e.g. BeforeEach, AfterEach, JustBeforeEach), and Subject nodes (i.e. It).
@@ -512,7 +544,7 @@ You can learn more at https://onsi.github.io/ginkgo/#organizing-specs-with-conta
In addition, container nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference
*/
func Describe(text string, args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, text, args...)))
}
/*
@@ -520,7 +552,7 @@ FDescribe focuses specs within the Describe block.
*/
func FDescribe(text string, args ...any) bool {
args = append(args, internal.Focus)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, text, args...)))
}
/*
@@ -528,7 +560,7 @@ PDescribe marks specs within the Describe block as pending.
*/
func PDescribe(text string, args ...any) bool {
args = append(args, internal.Pending)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, text, args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, text, args...)))
}
/*
@@ -541,21 +573,21 @@ var XDescribe = PDescribe
/* Context is an alias for Describe - it generates the exact same kind of Container node */
var Context, FContext, PContext, XContext = Describe, FDescribe, PDescribe, XDescribe
/* When is an alias for Describe - it generates the exact same kind of Container node */
/* When is an alias for Describe - it generates the exact same kind of Container node with "when " as prefix for the text. */
func When(text string, args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, "when "+text, args...)))
}
/* When is an alias for Describe - it generates the exact same kind of Container node */
/* When is an alias for Describe - it generates the exact same kind of Container node with "when " as prefix for the text. */
func FWhen(text string, args ...any) bool {
args = append(args, internal.Focus)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, "when "+text, args...)))
}
/* When is an alias for Describe - it generates the exact same kind of Container node */
func PWhen(text string, args ...any) bool {
args = append(args, internal.Pending)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, "when "+text, args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, "when "+text, args...)))
}
var XWhen = PWhen
@@ -571,7 +603,7 @@ You can learn more at https://onsi.github.io/ginkgo/#spec-subjects-it
In addition, subject nodes can be decorated with a variety of decorators. You can learn more here: https://onsi.github.io/ginkgo/#decorator-reference
*/
func It(text string, args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeIt, text, args...)))
}
/*
@@ -579,7 +611,7 @@ FIt allows you to focus an individual It.
*/
func FIt(text string, args ...any) bool {
args = append(args, internal.Focus)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeIt, text, args...)))
}
/*
@@ -587,7 +619,7 @@ PIt allows you to mark an individual It as pending.
*/
func PIt(text string, args ...any) bool {
args = append(args, internal.Pending)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, text, args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeIt, text, args...)))
}
/*
@@ -634,7 +666,7 @@ You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-
func BeforeSuite(body any, args ...any) bool {
combinedArgs := []any{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeSuite, "", combinedArgs...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeBeforeSuite, "", combinedArgs...)))
}
/*
@@ -653,7 +685,7 @@ You can learn more here: https://onsi.github.io/ginkgo/#suite-setup-and-cleanup-
func AfterSuite(body any, args ...any) bool {
combinedArgs := []any{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterSuite, "", combinedArgs...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeAfterSuite, "", combinedArgs...)))
}
/*
@@ -691,7 +723,7 @@ func SynchronizedBeforeSuite(process1Body any, allProcessBody any, args ...any)
combinedArgs := []any{process1Body, allProcessBody}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeSynchronizedBeforeSuite, "", combinedArgs...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeSynchronizedBeforeSuite, "", combinedArgs...)))
}
/*
@@ -711,7 +743,7 @@ func SynchronizedAfterSuite(allProcessBody any, process1Body any, args ...any) b
combinedArgs := []any{allProcessBody, process1Body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeSynchronizedAfterSuite, "", combinedArgs...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeSynchronizedAfterSuite, "", combinedArgs...)))
}
/*
@@ -724,7 +756,7 @@ You cannot nest any other Ginkgo nodes within a BeforeEach node's closure.
You can learn more here: https://onsi.github.io/ginkgo/#extracting-common-setup-beforeeach
*/
func BeforeEach(args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeEach, "", args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeBeforeEach, "", args...)))
}
/*
@@ -737,7 +769,7 @@ You cannot nest any other Ginkgo nodes within a JustBeforeEach node's closure.
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-creation-and-configuration-justbeforeeach
*/
func JustBeforeEach(args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeJustBeforeEach, "", args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeJustBeforeEach, "", args...)))
}
/*
@@ -752,7 +784,7 @@ You cannot nest any other Ginkgo nodes within an AfterEach node's closure.
You can learn more here: https://onsi.github.io/ginkgo/#spec-cleanup-aftereach-and-defercleanup
*/
func AfterEach(args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterEach, "", args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeAfterEach, "", args...)))
}
/*
@@ -764,7 +796,7 @@ You cannot nest any other Ginkgo nodes within a JustAfterEach node's closure.
You can learn more and see some examples here: https://onsi.github.io/ginkgo/#separating-diagnostics-collection-and-teardown-justaftereach
*/
func JustAfterEach(args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeJustAfterEach, "", args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeJustAfterEach, "", args...)))
}
/*
@@ -779,7 +811,7 @@ You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#o
And you can learn more about BeforeAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
*/
func BeforeAll(args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeBeforeAll, "", args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeBeforeAll, "", args...)))
}
/*
@@ -796,7 +828,7 @@ You can learn more about Ordered Containers at: https://onsi.github.io/ginkgo/#o
And you can learn more about AfterAll at: https://onsi.github.io/ginkgo/#setup-in-ordered-containers-beforeall-and-afterall
*/
func AfterAll(args ...any) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeAfterAll, "", args...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeAfterAll, "", args...)))
}
/*

View File

@@ -154,6 +154,13 @@ Nodes that do not finish within a GracePeriod will be leaked and Ginkgo will pro
*/
type GracePeriod = internal.GracePeriod
/*
SpecPriority allows you to assign a priority to a spec or container.
Specs with higher priority will be scheduled to run before specs with lower priority. The default priority is 0 and negative priorities are allowed.
*/
type SpecPriority = internal.SpecPriority
/*
SuppressProgressReporting is a decorator that allows you to disable progress reporting of a particular node. This is useful if `ginkgo -v -progress` is generating too much noise; particularly
if you have a `ReportAfterEach` node that is running for every skipped spec and is generating lots of progress reports.

View File

@@ -4,5 +4,5 @@
package main
import (
_ "go.uber.org/automaxprocs"
_ "github.com/onsi/ginkgo/v2/ginkgo/automaxprocs"
)

View File

@@ -0,0 +1,3 @@
This entire directory is a lightly modified clone of https://github.com/uber-go/automaxprocs
It will be removed when Go 1.26 ships and we no longer need to support Go 1.24 (which does not correctly autodetect maxprocs in containers).

View File

@@ -0,0 +1,71 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// Package maxprocs lets Go programs easily configure runtime.GOMAXPROCS to
// match the configured Linux CPU quota. Unlike the top-level automaxprocs
// package, it lets the caller configure logging and handle errors.
package automaxprocs
import (
"os"
"runtime"
)
func init() {
Set()
}
const _maxProcsKey = "GOMAXPROCS"
type config struct {
procs func(int, func(v float64) int) (int, CPUQuotaStatus, error)
minGOMAXPROCS int
roundQuotaFunc func(v float64) int
}
// Set GOMAXPROCS to match the Linux container CPU quota (if any), returning
// any error encountered and an undo function.
//
// Set is a no-op on non-Linux systems and in Linux environments without a
// configured CPU quota.
func Set() error {
cfg := &config{
procs: CPUQuotaToGOMAXPROCS,
roundQuotaFunc: DefaultRoundFunc,
minGOMAXPROCS: 1,
}
// Honor the GOMAXPROCS environment variable if present. Otherwise, amend
// `runtime.GOMAXPROCS()` with the current process' CPU quota if the OS is
// Linux, and guarantee a minimum value of 1. The minimum guaranteed value
// can be overridden using `maxprocs.Min()`.
if _, exists := os.LookupEnv(_maxProcsKey); exists {
return nil
}
maxProcs, status, err := cfg.procs(cfg.minGOMAXPROCS, cfg.roundQuotaFunc)
if err != nil {
return err
}
if status == CPUQuotaUndefined {
return nil
}
runtime.GOMAXPROCS(maxProcs)
return nil
}

View File

@@ -21,7 +21,7 @@
//go:build linux
// +build linux
package cgroups
package automaxprocs
import (
"bufio"

View File

@@ -21,7 +21,7 @@
//go:build linux
// +build linux
package cgroups
package automaxprocs
const (
// _cgroupFSType is the Linux CGroup file system type used in

View File

@@ -21,7 +21,7 @@
//go:build linux
// +build linux
package cgroups
package automaxprocs
import (
"bufio"

View File

@@ -21,12 +21,10 @@
//go:build linux
// +build linux
package runtime
package automaxprocs
import (
"errors"
cg "go.uber.org/automaxprocs/internal/cgroups"
)
// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
@@ -58,8 +56,8 @@ type queryer interface {
}
var (
_newCgroups2 = cg.NewCGroups2ForCurrentProcess
_newCgroups = cg.NewCGroupsForCurrentProcess
_newCgroups2 = NewCGroups2ForCurrentProcess
_newCgroups = NewCGroupsForCurrentProcess
_newQueryer = newQueryer
)
@@ -68,7 +66,7 @@ func newQueryer() (queryer, error) {
if err == nil {
return cgroups, nil
}
if errors.Is(err, cg.ErrNotV2) {
if errors.Is(err, ErrNotV2) {
return _newCgroups()
}
return nil, err

View File

@@ -21,7 +21,7 @@
//go:build !linux
// +build !linux
package runtime
package automaxprocs
// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
// to a valid GOMAXPROCS value. This is Linux-specific and not supported in the

View File

@@ -21,7 +21,7 @@
//go:build linux
// +build linux
package cgroups
package automaxprocs
import "fmt"

View File

@@ -21,7 +21,7 @@
//go:build linux
// +build linux
package cgroups
package automaxprocs
import (
"bufio"

View File

@@ -18,7 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package runtime
package automaxprocs
import "math"

View File

@@ -21,7 +21,7 @@
//go:build linux
// +build linux
package cgroups
package automaxprocs
import (
"bufio"

View File

@@ -190,3 +190,9 @@ func (g *GinkgoTBWrapper) Skipped() bool {
func (g *GinkgoTBWrapper) TempDir() string {
return g.GinkgoT.TempDir()
}
func (g *GinkgoTBWrapper) Attr(key, value string) {
g.GinkgoT.Attr(key, value)
}
func (g *GinkgoTBWrapper) Output() io.Writer {
return g.GinkgoT.Output()
}

View File

@@ -110,6 +110,7 @@ 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(),
@@ -127,6 +128,35 @@ func (g *group) initialReportForSpec(spec Spec) types.SpecReport {
IsInOrderedContainer: !spec.Nodes.FirstNodeMarkedOrdered().IsZero(),
MaxFlakeAttempts: spec.Nodes.GetMaxFlakeAttempts(),
MaxMustPassRepeatedly: spec.Nodes.GetMaxMustPassRepeatedly(),
SpecPriority: spec.Nodes.GetSpecPriority(),
}
}
// constructionNodeReportForTreeNode constructs a new SpecReport right before invoking the body
// of a container node during construction of the full tree.
func constructionNodeReportForTreeNode(node *TreeNode) *types.ConstructionNodeReport {
var report types.ConstructionNodeReport
// Walk up the tree and set attributes accordingly.
addNodeToReportForNode(&report, node)
return &report
}
// addNodeToReportForNode is conceptually similar to initialReportForSpec and therefore placed here
// although it doesn't do anything with a group.
func addNodeToReportForNode(report *types.ConstructionNodeReport, node *TreeNode) {
if node.Parent != nil {
// First add the parent node, then the current one.
addNodeToReportForNode(report, node.Parent)
}
report.ContainerHierarchyTexts = append(report.ContainerHierarchyTexts, node.Node.Text)
report.ContainerHierarchyLocations = append(report.ContainerHierarchyLocations, node.Node.CodeLocation)
report.ContainerHierarchyLabels = append(report.ContainerHierarchyLabels, node.Node.Labels)
report.ContainerHierarchySemVerConstraints = append(report.ContainerHierarchySemVerConstraints, node.Node.SemVerConstraints)
if node.Node.MarkedSerial {
report.IsSerial = true
}
if node.Node.MarkedOrdered {
report.IsInOrderedContainer = true
}
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"reflect"
"slices"
"sort"
"sync"
"time"
@@ -46,22 +47,24 @@ type Node struct {
ReportEachBody func(SpecContext, types.SpecReport)
ReportSuiteBody func(SpecContext, types.Report)
MarkedFocus bool
MarkedPending bool
MarkedSerial bool
MarkedOrdered bool
MarkedContinueOnFailure bool
MarkedOncePerOrdered bool
FlakeAttempts int
MustPassRepeatedly int
Labels Labels
SemVerConstraints SemVerConstraints
PollProgressAfter time.Duration
PollProgressInterval time.Duration
NodeTimeout time.Duration
SpecTimeout time.Duration
GracePeriod time.Duration
AroundNodes types.AroundNodes
MarkedFocus bool
MarkedPending bool
MarkedSerial bool
MarkedOrdered bool
MarkedContinueOnFailure bool
MarkedOncePerOrdered bool
FlakeAttempts int
MustPassRepeatedly int
Labels Labels
SemVerConstraints SemVerConstraints
PollProgressAfter time.Duration
PollProgressInterval time.Duration
NodeTimeout time.Duration
SpecTimeout time.Duration
GracePeriod time.Duration
AroundNodes types.AroundNodes
HasExplicitlySetSpecPriority bool
SpecPriority int
NodeIDWhereCleanupWasGenerated uint
}
@@ -92,6 +95,7 @@ type PollProgressAfter time.Duration
type NodeTimeout time.Duration
type SpecTimeout time.Duration
type GracePeriod time.Duration
type SpecPriority int
type Labels []string
@@ -182,6 +186,8 @@ func isDecoration(arg any) bool {
return true
case t == reflect.TypeOf(types.AroundNodeDecorator{}):
return true
case t == reflect.TypeOf(SpecPriority(0)):
return true
case t.Kind() == reflect.Slice && isSliceOfDecorations(arg):
return true
default:
@@ -227,7 +233,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
}
}
args = unrollInterfaceSlice(args)
args = UnrollInterfaceSlice(args)
remainingArgs := []any{}
// First get the CodeLocation up-to-date
@@ -322,6 +328,12 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
if nodeType.Is(types.NodeTypeContainer) {
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "GracePeriod"))
}
case t == reflect.TypeOf(SpecPriority(0)):
if !nodeType.Is(types.NodeTypesForContainerAndIt) {
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "SpecPriority"))
}
node.SpecPriority = int(arg.(SpecPriority))
node.HasExplicitlySetSpecPriority = true
case t == reflect.TypeOf(types.AroundNodeDecorator{}):
node.AroundNodes = append(node.AroundNodes, arg.(types.AroundNodeDecorator))
case t == reflect.TypeOf(Labels{}):
@@ -636,7 +648,7 @@ func NewCleanupNode(deprecationTracker *types.DeprecationTracker, fail func(stri
})
}
return NewNode(deprecationTracker, types.NodeTypeCleanupInvalid, "", finalArgs...)
return NewNode(deprecationTracker, types.NodeTypeCleanupInvalid, "", finalArgs)
}
func (n Node) IsZero() bool {
@@ -983,7 +995,16 @@ func (n Nodes) GetMaxMustPassRepeatedly() int {
return maxMustPassRepeatedly
}
func unrollInterfaceSlice(args any) []any {
func (n Nodes) GetSpecPriority() int {
for i := len(n) - 1; i >= 0; i-- {
if n[i].HasExplicitlySetSpecPriority {
return n[i].SpecPriority
}
}
return 0
}
func UnrollInterfaceSlice(args any) []any {
v := reflect.ValueOf(args)
if v.Kind() != reflect.Slice {
return []any{args}
@@ -992,10 +1013,66 @@ func unrollInterfaceSlice(args any) []any {
for i := 0; i < v.Len(); i++ {
el := reflect.ValueOf(v.Index(i).Interface())
if el.Kind() == reflect.Slice && el.Type() != reflect.TypeOf(Labels{}) && el.Type() != reflect.TypeOf(SemVerConstraints{}) {
out = append(out, unrollInterfaceSlice(el.Interface())...)
out = append(out, UnrollInterfaceSlice(el.Interface())...)
} else {
out = append(out, v.Index(i).Interface())
}
}
return out
}
type NodeArgsTransformer func(nodeType types.NodeType, offset Offset, text string, args []any) (string, []any, []error)
func AddTreeConstructionNodeArgsTransformer(transformer NodeArgsTransformer) func() {
id := nodeArgsTransformerCounter
nodeArgsTransformerCounter++
nodeArgsTransformers = append(nodeArgsTransformers, registeredNodeArgsTransformer{id, transformer})
return func() {
nodeArgsTransformers = slices.DeleteFunc(nodeArgsTransformers, func(transformer registeredNodeArgsTransformer) bool {
return transformer.id == id
})
}
}
var (
nodeArgsTransformerCounter int64
nodeArgsTransformers []registeredNodeArgsTransformer
)
type registeredNodeArgsTransformer struct {
id int64
transformer NodeArgsTransformer
}
// TransformNewNodeArgs is the helper for DSL functions which handles NodeArgsTransformers.
//
// Its return valus are intentionally the same as the internal.NewNode parameters,
// which makes it possible to chain the invocations:
//
// NewNode(transformNewNodeArgs(...))
func TransformNewNodeArgs(exitIfErrors func([]error), deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...any) (*types.DeprecationTracker, types.NodeType, string, []any) {
var errs []error
// Most recent first...
//
// This intentionally doesn't use slices.Backward because
// using iterators influences stack unwinding.
for i := len(nodeArgsTransformers) - 1; i >= 0; i-- {
transformer := nodeArgsTransformers[i].transformer
args = UnrollInterfaceSlice(args)
// We do not really need to recompute this on additional loop iterations,
// but its fast and simpler this way.
var offset Offset
for _, arg := range args {
if o, ok := arg.(Offset); ok {
offset = o
}
}
offset += 3 // The DSL function, this helper, and the TransformNodeArgs implementation.
text, args, errs = transformer(nodeType, offset, text, args)
exitIfErrors(errs)
}
return deprecationTracker, nodeType, text, args
}

View File

@@ -125,7 +125,7 @@ func OrderSpecs(specs Specs, suiteConfig types.SuiteConfig) (GroupedSpecIndices,
// pick out a representative spec
representativeSpec := specs[executionGroups[groupID][0]]
// and grab the node on the spec that will represent which shufflable group this execution group belongs tu
// and grab the node on the spec that will represent which shufflable group this execution group belongs to
shufflableGroupingNode := representativeSpec.Nodes.FirstNodeWithType(nodeTypesToShuffle)
//add the execution group to its shufflable group
@@ -138,14 +138,35 @@ func OrderSpecs(specs Specs, suiteConfig types.SuiteConfig) (GroupedSpecIndices,
}
}
// now, for each shuffleable group, we compute the priority
shufflableGroupingIDPriorities := map[uint]int{}
for shufflableGroupingID, groupIDs := range shufflableGroupingIDToGroupIDs {
// the priority of a shufflable grouping is the max priority of any spec in any execution group in the shufflable grouping
maxPriority := -1 << 31 // min int
for _, groupID := range groupIDs {
for _, specIdx := range executionGroups[groupID] {
specPriority := specs[specIdx].Nodes.GetSpecPriority()
maxPriority = max(specPriority, maxPriority)
}
}
shufflableGroupingIDPriorities[shufflableGroupingID] = maxPriority
}
// now we permute the sorted shufflable grouping IDs and build the ordered Groups
orderedGroups := GroupedSpecIndices{}
permutation := r.Perm(len(shufflableGroupingIDs))
for _, j := range permutation {
//let's get the execution group IDs for this shufflable group:
executionGroupIDsForJ := shufflableGroupingIDToGroupIDs[shufflableGroupingIDs[j]]
// and we'll add their associated specindices to the orderedGroups slice:
for _, executionGroupID := range executionGroupIDsForJ {
shuffledGroupingIds := make([]uint, len(shufflableGroupingIDs))
for i, j := range permutation {
shuffledGroupingIds[i] = shufflableGroupingIDs[j]
}
// now, we need to stable sort the shuffledGroupingIds by priority (higher priority first)
sort.SliceStable(shuffledGroupingIds, func(i, j int) bool {
return shufflableGroupingIDPriorities[shuffledGroupingIds[i]] > shufflableGroupingIDPriorities[shuffledGroupingIds[j]]
})
// we can now take these prioritized, shuffled, groupings and form the final set of ordered spec groups
orderedGroups := GroupedSpecIndices{}
for _, id := range shuffledGroupingIds {
for _, executionGroupID := range shufflableGroupingIDToGroupIDs[id] {
orderedGroups = append(orderedGroups, executionGroups[executionGroupID])
}
}

View File

@@ -42,6 +42,8 @@ type Suite struct {
config types.SuiteConfig
deadline time.Time
currentConstructionNodeReport *types.ConstructionNodeReport
skipAll bool
report types.Report
currentSpecReport types.SpecReport
@@ -203,6 +205,14 @@ func (suite *Suite) PushNode(node Node) error {
err = types.GinkgoErrors.CaughtPanicDuringABuildPhase(e, node.CodeLocation)
}
}()
// Ensure that code running in the body of the container node
// has access to information about the current container node(s).
suite.currentConstructionNodeReport = constructionNodeReportForTreeNode(suite.tree)
defer func() {
suite.currentConstructionNodeReport = nil
}()
node.Body(nil)
return err
}()
@@ -332,6 +342,16 @@ func (suite *Suite) By(text string, callback ...func()) error {
return nil
}
func (suite *Suite) CurrentConstructionNodeReport() types.ConstructionNodeReport {
suite.selectiveLock.Lock()
defer suite.selectiveLock.Unlock()
report := suite.currentConstructionNodeReport
if report == nil {
panic("CurrentConstructionNodeReport may only be called during construction of the spec tree")
}
return *report
}
/*
Spec Running methods - used during PhaseRun
*/

View File

@@ -381,13 +381,22 @@ func (r *DefaultReporter) emitTimeline(indent uint, report types.SpecReport, tim
cursor := 0
for _, entry := range timeline {
tl := entry.GetTimelineLocation()
if tl.Offset < len(gw) {
r.emit(r.fi(indent, "%s", gw[cursor:tl.Offset]))
cursor = tl.Offset
} else if cursor < len(gw) {
end := tl.Offset
if end > len(gw) {
end = len(gw)
}
if end < cursor {
end = cursor
}
if cursor < end && cursor <= len(gw) && end <= len(gw) {
r.emit(r.fi(indent, "%s", gw[cursor:end]))
cursor = end
} else if cursor < len(gw) && end == len(gw) {
r.emit(r.fi(indent, "%s", gw[cursor:]))
cursor = len(gw)
}
switch x := entry.(type) {
case types.Failure:
if isVeryVerbose {
@@ -404,7 +413,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, false, x)
r.emitProgressReport(indent, false, isVeryVerbose, x)
case types.SpecEvent:
if isVeryVerbose || !x.IsOnlyVisibleAtVeryVerbose() || r.conf.ShowNodeEvents {
r.emitSpecEvent(indent, x, isVeryVerbose)

View File

@@ -27,6 +27,8 @@ CurrentSpecReport returns information about the current running spec.
The returned object is a types.SpecReport which includes helper methods
to make extracting information about the spec easier.
During construction of the test tree the result is empty.
You can learn more about SpecReport here: https://pkg.go.dev/github.com/onsi/ginkgo/types#SpecReport
You can learn more about CurrentSpecReport() here: https://onsi.github.io/ginkgo/#getting-a-report-for-the-current-spec
*/
@@ -34,6 +36,31 @@ func CurrentSpecReport() SpecReport {
return global.Suite.CurrentSpecReport()
}
/*
ConstructionNodeReport describes the container nodes during construction of
the spec tree. It provides a subset of the information that is provided
by SpecReport at runtime.
It is documented here: [types.ConstructionNodeReport]
*/
type ConstructionNodeReport = types.ConstructionNodeReport
/*
CurrentConstructionNodeReport returns information about the current container nodes
that are leading to the current path in the spec tree.
The returned object is a types.ConstructionNodeReport which includes helper methods
to make extracting information about the spec easier.
May only be called during construction of the spec tree. It panics when
called while tests are running. Use CurrentSpecReport instead in that
phase.
You can learn more about ConstructionNodeReport here: [types.ConstructionNodeReport]
*/
func CurrentTreeConstructionNodeReport() ConstructionNodeReport {
return global.Suite.CurrentConstructionNodeReport()
}
/*
ReportEntryVisibility governs the visibility of ReportEntries in Ginkgo's console reporter
@@ -92,7 +119,7 @@ func ReportBeforeEach(body any, args ...any) bool {
combinedArgs := []any{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeEach, "", combinedArgs...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeReportBeforeEach, "", combinedArgs...)))
}
/*
@@ -116,7 +143,7 @@ func ReportAfterEach(body any, args ...any) bool {
combinedArgs := []any{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterEach, "", combinedArgs...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeReportAfterEach, "", combinedArgs...)))
}
/*
@@ -145,7 +172,7 @@ You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spe
func ReportBeforeSuite(body any, args ...any) bool {
combinedArgs := []any{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeSuite, "", combinedArgs...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeReportBeforeSuite, "", combinedArgs...)))
}
/*
@@ -177,7 +204,7 @@ You can learn about interruptible nodes here: https://onsi.github.io/ginkgo/#spe
func ReportAfterSuite(text string, body any, args ...any) bool {
combinedArgs := []any{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterSuite, text, combinedArgs...))
return pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeReportAfterSuite, text, combinedArgs...)))
}
func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.ReporterConfig) {
@@ -222,9 +249,11 @@ func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.Re
flags = append(flags, "--teamcity-report")
}
pushNode(internal.NewNode(
deprecationTracker, types.NodeTypeReportAfterSuite,
fmt.Sprintf("Autogenerated ReportAfterSuite for %s", strings.Join(flags, " ")),
body,
types.NewCustomCodeLocation("autogenerated by Ginkgo"),
internal.TransformNewNodeArgs(
exitIfErrors, deprecationTracker, types.NodeTypeReportAfterSuite,
fmt.Sprintf("Autogenerated ReportAfterSuite for %s", strings.Join(flags, " ")),
body,
types.NewCustomCodeLocation("autogenerated by Ginkgo"),
),
))
}

View File

@@ -309,11 +309,11 @@ func generateTable(description string, isSubtree bool, args ...any) {
internalNodeType = types.NodeTypeContainer
}
pushNode(internal.NewNode(deprecationTracker, internalNodeType, description, internalNodeArgs...))
pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, internalNodeType, description, internalNodeArgs...)))
}
})
pushNode(internal.NewNode(deprecationTracker, types.NodeTypeContainer, description, containerNodeArgs...))
pushNode(internal.NewNode(internal.TransformNewNodeArgs(exitIfErrors, deprecationTracker, types.NodeTypeContainer, description, containerNodeArgs...)))
}
func invokeFunction(function any, parameters []any) []reflect.Value {

View File

@@ -20,6 +20,57 @@ func init() {
}
}
// ConstructionNodeReport captures information about a Ginkgo spec.
type ConstructionNodeReport struct {
// ContainerHierarchyTexts is a slice containing the text strings of
// all Describe/Context/When containers in this spec's hierarchy.
ContainerHierarchyTexts []string
// ContainerHierarchyLocations is a slice containing the CodeLocations of
// all Describe/Context/When containers in this spec's hierarchy.
ContainerHierarchyLocations []CodeLocation
// ContainerHierarchyLabels is a slice containing the labels of
// all Describe/Context/When containers in this spec's hierarchy
ContainerHierarchyLabels [][]string
// ContainerHierarchySemVerConstraints is a slice containing the semVerConstraints of
// all Describe/Context/When containers in this spec's hierarchy
ContainerHierarchySemVerConstraints [][]string
// IsSerial captures whether the any container has the Serial decorator
IsSerial bool
// IsInOrderedContainer captures whether any container is an Ordered container
IsInOrderedContainer bool
}
// FullText returns a concatenation of all the report.ContainerHierarchyTexts and report.LeafNodeText
func (report ConstructionNodeReport) FullText() string {
texts := []string{}
texts = append(texts, report.ContainerHierarchyTexts...)
texts = slices.DeleteFunc(texts, func(t string) bool {
return t == ""
})
return strings.Join(texts, " ")
}
// Labels returns a deduped set of all the spec's Labels.
func (report ConstructionNodeReport) Labels() []string {
out := []string{}
seen := map[string]bool{}
for _, labels := range report.ContainerHierarchyLabels {
for _, label := range labels {
if !seen[label] {
seen[label] = true
out = append(out, label)
}
}
}
return out
}
// Report captures information about a Ginkgo test run
type Report struct {
//SuitePath captures the absolute path to the test suite
@@ -146,6 +197,9 @@ type SpecReport struct {
LeafNodeSemVerConstraints []string
LeafNodeText string
// Captures the Spec Priority
SpecPriority int
// State captures whether the spec has passed, failed, etc.
State SpecState

View File

@@ -1,3 +1,3 @@
package types
const VERSION = "2.26.0"
const VERSION = "2.27.2"

View File

@@ -1,14 +0,0 @@
coverage:
range: 80..100
round: down
precision: 2
status:
project: # measuring the overall project coverage
default: # context, you can create multiple ones with custom titles
enabled: yes # must be yes|true to enable this status
target: 90% # specify the target coverage for each commit status
# option: "auto" (must increase from parent commit or pull request base)
# option: "X%" a static target percentage to hit
if_not_found: success # if parent is not found report status as success, error, or failure
if_ci_failed: error # if ci fails report status as success, error, or failure

View File

@@ -1,33 +0,0 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
vendor
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof
*.pprof
*.out
*.log
coverage.txt
/bin
cover.out
cover.html

View File

@@ -1,52 +0,0 @@
# Changelog
## v1.6.0 (2024-07-24)
- Add RoundQuotaFunc option that allows configuration of rounding
behavior for floating point CPU quota.
## v1.5.3 (2023-07-19)
- Fix mountinfo parsing when super options have fields with spaces.
- Fix division by zero while parsing cgroups.
## v1.5.2 (2023-03-16)
- Support child control cgroups
- Fix file descriptor leak
- Update dependencies
## v1.5.1 (2022-04-06)
- Fix cgroups v2 mountpoint detection.
## v1.5.0 (2022-04-05)
- Add support for cgroups v2.
Thanks to @emadolsky for their contribution to this release.
## v1.4.0 (2021-02-01)
- Support colons in cgroup names.
- Remove linters from runtime dependencies.
## v1.3.0 (2020-01-23)
- Migrate to Go modules.
## v1.2.0 (2018-02-22)
- Fixed quota clamping to always round down rather than up; Rather than
guaranteeing constant throttling at saturation, instead assume that the
fractional CPU was added as a hedge for factors outside of Go's scheduler.
## v1.1.0 (2017-11-10)
- Log the new value of `GOMAXPROCS` rather than the current value.
- Make logs more explicit about whether `GOMAXPROCS` was modified or not.
- Allow customization of the minimum `GOMAXPROCS`, and modify default from 2 to 1.
## v1.0.0 (2017-08-09)
- Initial release.

View File

@@ -1,75 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age,
body size, disability, ethnicity, gender identity and expression, level of
experience, nationality, personal appearance, race, religion, or sexual
identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an
appointed representative at an online or offline event. Representation of a
project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at oss-conduct@uber.com. The project
team will review and investigate all complaints, and will respond in a way
that it deems appropriate to the circumstances. The project team is obligated
to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.4, available at
[http://contributor-covenant.org/version/1/4][version].
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -1,81 +0,0 @@
# Contributing
We'd love your help improving this package!
If you'd like to add new exported APIs, please [open an issue][open-issue]
describing your proposal &mdash; discussing API changes ahead of time makes
pull request review much smoother. In your issue, pull request, and any other
communications, please remember to treat your fellow contributors with
respect! We take our [code of conduct](CODE_OF_CONDUCT.md) seriously.
Note that you'll need to sign [Uber's Contributor License Agreement][cla]
before we can accept any of your contributions. If necessary, a bot will remind
you to accept the CLA when you open your pull request.
## Setup
[Fork][fork], then clone the repository:
```
mkdir -p $GOPATH/src/go.uber.org
cd $GOPATH/src/go.uber.org
git clone git@github.com:your_github_username/automaxprocs.git
cd automaxprocs
git remote add upstream https://github.com/uber-go/automaxprocs.git
git fetch upstream
```
Install the test dependencies:
```
make dependencies
```
Make sure that the tests and the linters pass:
```
make test
make lint
```
If you're not using the minor version of Go specified in the Makefile's
`LINTABLE_MINOR_VERSIONS` variable, `make lint` doesn't do anything. This is
fine, but it means that you'll only discover lint failures after you open your
pull request.
## Making Changes
Start by creating a new branch for your changes:
```
cd $GOPATH/src/go.uber.org/automaxprocs
git checkout master
git fetch upstream
git rebase upstream/master
git checkout -b cool_new_feature
```
Make your changes, then ensure that `make lint` and `make test` still pass. If
you're satisfied with your changes, push them to your fork.
```
git push origin cool_new_feature
```
Then use the GitHub UI to open a pull request.
At this point, you're waiting on us to review your changes. We *try* to respond
to issues and pull requests within a few business days, and we may suggest some
improvements or alternatives. Once your changes are approved, one of the
project maintainers will merge them.
We're much more likely to approve your changes if you:
* Add tests for new functionality.
* Write a [good commit message][commit-message].
* Maintain backward compatibility.
[fork]: https://github.com/uber-go/automaxprocs/fork
[open-issue]: https://github.com/uber-go/automaxprocs/issues/new
[cla]: https://cla-assistant.io/uber-go/automaxprocs
[commit-message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html

View File

@@ -1,19 +0,0 @@
Copyright (c) 2017 Uber Technologies, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,46 +0,0 @@
export GOBIN ?= $(shell pwd)/bin
GO_FILES := $(shell \
find . '(' -path '*/.*' -o -path './vendor' ')' -prune \
-o -name '*.go' -print | cut -b3-)
GOLINT = $(GOBIN)/golint
STATICCHECK = $(GOBIN)/staticcheck
.PHONY: build
build:
go build ./...
.PHONY: install
install:
go mod download
.PHONY: test
test:
go test -race ./...
.PHONY: cover
cover:
go test -coverprofile=cover.out -covermode=atomic -coverpkg=./... ./...
go tool cover -html=cover.out -o cover.html
$(GOLINT): tools/go.mod
cd tools && go install golang.org/x/lint/golint
$(STATICCHECK): tools/go.mod
cd tools && go install honnef.co/go/tools/cmd/staticcheck@2023.1.2
.PHONY: lint
lint: $(GOLINT) $(STATICCHECK)
@rm -rf lint.log
@echo "Checking gofmt"
@gofmt -d -s $(GO_FILES) 2>&1 | tee lint.log
@echo "Checking go vet"
@go vet ./... 2>&1 | tee -a lint.log
@echo "Checking golint"
@$(GOLINT) ./... | tee -a lint.log
@echo "Checking staticcheck"
@$(STATICCHECK) ./... 2>&1 | tee -a lint.log
@echo "Checking for license headers..."
@./.build/check_license.sh | tee -a lint.log
@[ ! -s lint.log ]

View File

@@ -1,71 +0,0 @@
# automaxprocs [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]
Automatically set `GOMAXPROCS` to match Linux container CPU quota.
## Installation
`go get -u go.uber.org/automaxprocs`
## Quick Start
```go
import _ "go.uber.org/automaxprocs"
func main() {
// Your application logic here.
}
```
# Performance
Data measured from Uber's internal load balancer. We ran the load balancer with 200% CPU quota (i.e., 2 cores):
| GOMAXPROCS | RPS | P50 (ms) | P99.9 (ms) |
| ------------------ | --------- | -------- | ---------- |
| 1 | 28,893.18 | 1.46 | 19.70 |
| 2 (equal to quota) | 44,715.07 | 0.84 | 26.38 |
| 3 | 44,212.93 | 0.66 | 30.07 |
| 4 | 41,071.15 | 0.57 | 42.94 |
| 8 | 33,111.69 | 0.43 | 64.32 |
| Default (24) | 22,191.40 | 0.45 | 76.19 |
When `GOMAXPROCS` is increased above the CPU quota, we see P50 decrease slightly, but see significant increases to P99. We also see that the total RPS handled also decreases.
When `GOMAXPROCS` is higher than the CPU quota allocated, we also saw significant throttling:
```
$ cat /sys/fs/cgroup/cpu,cpuacct/system.slice/[...]/cpu.stat
nr_periods 42227334
nr_throttled 131923
throttled_time 88613212216618
```
Once `GOMAXPROCS` was reduced to match the CPU quota, we saw no CPU throttling.
## Development Status: Stable
All APIs are finalized, and no breaking changes will be made in the 1.x series
of releases. Users of semver-aware dependency management systems should pin
automaxprocs to `^1`.
## Contributing
We encourage and support an active, healthy community of contributors &mdash;
including you! Details are in the [contribution guide](CONTRIBUTING.md) and
the [code of conduct](CODE_OF_CONDUCT.md). The automaxprocs maintainers keep
an eye on issues and pull requests, but you can also report any negative
conduct to oss-conduct@uber.com. That email list is a private, safe space;
even the automaxprocs maintainers don't have access, so don't hesitate to hold
us to a high standard.
<hr>
Released under the [MIT License](LICENSE).
[doc-img]: https://godoc.org/go.uber.org/automaxprocs?status.svg
[doc]: https://godoc.org/go.uber.org/automaxprocs
[ci-img]: https://github.com/uber-go/automaxprocs/actions/workflows/go.yml/badge.svg
[ci]: https://github.com/uber-go/automaxprocs/actions/workflows/go.yml
[cov-img]: https://codecov.io/gh/uber-go/automaxprocs/branch/master/graph/badge.svg
[cov]: https://codecov.io/gh/uber-go/automaxprocs

View File

@@ -1,33 +0,0 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// Package automaxprocs automatically sets GOMAXPROCS to match the Linux
// container CPU quota, if any.
package automaxprocs // import "go.uber.org/automaxprocs"
import (
"log"
"go.uber.org/automaxprocs/maxprocs"
)
func init() {
maxprocs.Set(maxprocs.Logger(log.Printf))
}

View File

@@ -1,23 +0,0 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// Package cgroups provides utilities to access Linux control group (CGroups)
// parameters (CPU quota, for example) for a given process.
package cgroups

View File

@@ -1,139 +0,0 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// Package maxprocs lets Go programs easily configure runtime.GOMAXPROCS to
// match the configured Linux CPU quota. Unlike the top-level automaxprocs
// package, it lets the caller configure logging and handle errors.
package maxprocs // import "go.uber.org/automaxprocs/maxprocs"
import (
"os"
"runtime"
iruntime "go.uber.org/automaxprocs/internal/runtime"
)
const _maxProcsKey = "GOMAXPROCS"
func currentMaxProcs() int {
return runtime.GOMAXPROCS(0)
}
type config struct {
printf func(string, ...interface{})
procs func(int, func(v float64) int) (int, iruntime.CPUQuotaStatus, error)
minGOMAXPROCS int
roundQuotaFunc func(v float64) int
}
func (c *config) log(fmt string, args ...interface{}) {
if c.printf != nil {
c.printf(fmt, args...)
}
}
// An Option alters the behavior of Set.
type Option interface {
apply(*config)
}
// Logger uses the supplied printf implementation for log output. By default,
// Set doesn't log anything.
func Logger(printf func(string, ...interface{})) Option {
return optionFunc(func(cfg *config) {
cfg.printf = printf
})
}
// Min sets the minimum GOMAXPROCS value that will be used.
// Any value below 1 is ignored.
func Min(n int) Option {
return optionFunc(func(cfg *config) {
if n >= 1 {
cfg.minGOMAXPROCS = n
}
})
}
// RoundQuotaFunc sets the function that will be used to covert the CPU quota from float to int.
func RoundQuotaFunc(rf func(v float64) int) Option {
return optionFunc(func(cfg *config) {
cfg.roundQuotaFunc = rf
})
}
type optionFunc func(*config)
func (of optionFunc) apply(cfg *config) { of(cfg) }
// Set GOMAXPROCS to match the Linux container CPU quota (if any), returning
// any error encountered and an undo function.
//
// Set is a no-op on non-Linux systems and in Linux environments without a
// configured CPU quota.
func Set(opts ...Option) (func(), error) {
cfg := &config{
procs: iruntime.CPUQuotaToGOMAXPROCS,
roundQuotaFunc: iruntime.DefaultRoundFunc,
minGOMAXPROCS: 1,
}
for _, o := range opts {
o.apply(cfg)
}
undoNoop := func() {
cfg.log("maxprocs: No GOMAXPROCS change to reset")
}
// Honor the GOMAXPROCS environment variable if present. Otherwise, amend
// `runtime.GOMAXPROCS()` with the current process' CPU quota if the OS is
// Linux, and guarantee a minimum value of 1. The minimum guaranteed value
// can be overridden using `maxprocs.Min()`.
if max, exists := os.LookupEnv(_maxProcsKey); exists {
cfg.log("maxprocs: Honoring GOMAXPROCS=%q as set in environment", max)
return undoNoop, nil
}
maxProcs, status, err := cfg.procs(cfg.minGOMAXPROCS, cfg.roundQuotaFunc)
if err != nil {
return undoNoop, err
}
if status == iruntime.CPUQuotaUndefined {
cfg.log("maxprocs: Leaving GOMAXPROCS=%v: CPU quota undefined", currentMaxProcs())
return undoNoop, nil
}
prev := currentMaxProcs()
undo := func() {
cfg.log("maxprocs: Resetting GOMAXPROCS to %v", prev)
runtime.GOMAXPROCS(prev)
}
switch status {
case iruntime.CPUQuotaMinUsed:
cfg.log("maxprocs: Updating GOMAXPROCS=%v: using minimum allowed GOMAXPROCS", maxProcs)
case iruntime.CPUQuotaUsed:
cfg.log("maxprocs: Updating GOMAXPROCS=%v: determined from CPU quota", maxProcs)
}
runtime.GOMAXPROCS(maxProcs)
return undo, nil
}

View File

@@ -1,24 +0,0 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
package maxprocs
// Version is the current package version.
const Version = "1.6.0"

9
vendor/modules.txt vendored
View File

@@ -1107,12 +1107,13 @@ github.com/onsi/ginkgo/reporters/stenographer
github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable
github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty
github.com/onsi/ginkgo/types
# github.com/onsi/ginkgo/v2 v2.26.0
# github.com/onsi/ginkgo/v2 v2.27.2
## explicit; go 1.23.0
github.com/onsi/ginkgo/v2
github.com/onsi/ginkgo/v2/config
github.com/onsi/ginkgo/v2/formatter
github.com/onsi/ginkgo/v2/ginkgo
github.com/onsi/ginkgo/v2/ginkgo/automaxprocs
github.com/onsi/ginkgo/v2/ginkgo/build
github.com/onsi/ginkgo/v2/ginkgo/command
github.com/onsi/ginkgo/v2/ginkgo/generators
@@ -2134,12 +2135,6 @@ go.opentelemetry.io/proto/otlp/collector/trace/v1
go.opentelemetry.io/proto/otlp/common/v1
go.opentelemetry.io/proto/otlp/resource/v1
go.opentelemetry.io/proto/otlp/trace/v1
# go.uber.org/automaxprocs v1.6.0
## explicit; go 1.20
go.uber.org/automaxprocs
go.uber.org/automaxprocs/internal/cgroups
go.uber.org/automaxprocs/internal/runtime
go.uber.org/automaxprocs/maxprocs
# go.uber.org/multierr v1.11.0
## explicit; go 1.19
go.uber.org/multierr