mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-28 05:39:57 +00:00
TUN-8006: Update quic-go to latest upstream
This commit is contained in:
61
vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go
generated
vendored
61
vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go
generated
vendored
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -50,6 +51,37 @@ func NewWithNoColorBool(noColor bool) Formatter {
|
||||
}
|
||||
|
||||
func New(colorMode ColorMode) Formatter {
|
||||
colorAliases := map[string]int{
|
||||
"black": 0,
|
||||
"red": 1,
|
||||
"green": 2,
|
||||
"yellow": 3,
|
||||
"blue": 4,
|
||||
"magenta": 5,
|
||||
"cyan": 6,
|
||||
"white": 7,
|
||||
}
|
||||
for colorAlias, n := range colorAliases {
|
||||
colorAliases[fmt.Sprintf("bright-%s", colorAlias)] = n + 8
|
||||
}
|
||||
|
||||
getColor := func(color, defaultEscapeCode string) string {
|
||||
color = strings.ToUpper(strings.ReplaceAll(color, "-", "_"))
|
||||
envVar := fmt.Sprintf("GINKGO_CLI_COLOR_%s", color)
|
||||
envVarColor := os.Getenv(envVar)
|
||||
if envVarColor == "" {
|
||||
return defaultEscapeCode
|
||||
}
|
||||
if colorCode, ok := colorAliases[envVarColor]; ok {
|
||||
return fmt.Sprintf("\x1b[38;5;%dm", colorCode)
|
||||
}
|
||||
colorCode, err := strconv.Atoi(envVarColor)
|
||||
if err != nil || colorCode < 0 || colorCode > 255 {
|
||||
return defaultEscapeCode
|
||||
}
|
||||
return fmt.Sprintf("\x1b[38;5;%dm", colorCode)
|
||||
}
|
||||
|
||||
f := Formatter{
|
||||
ColorMode: colorMode,
|
||||
colors: map[string]string{
|
||||
@@ -57,18 +89,18 @@ func New(colorMode ColorMode) Formatter {
|
||||
"bold": "\x1b[1m",
|
||||
"underline": "\x1b[4m",
|
||||
|
||||
"red": "\x1b[38;5;9m",
|
||||
"orange": "\x1b[38;5;214m",
|
||||
"coral": "\x1b[38;5;204m",
|
||||
"magenta": "\x1b[38;5;13m",
|
||||
"green": "\x1b[38;5;10m",
|
||||
"dark-green": "\x1b[38;5;28m",
|
||||
"yellow": "\x1b[38;5;11m",
|
||||
"light-yellow": "\x1b[38;5;228m",
|
||||
"cyan": "\x1b[38;5;14m",
|
||||
"gray": "\x1b[38;5;243m",
|
||||
"light-gray": "\x1b[38;5;246m",
|
||||
"blue": "\x1b[38;5;12m",
|
||||
"red": getColor("red", "\x1b[38;5;9m"),
|
||||
"orange": getColor("orange", "\x1b[38;5;214m"),
|
||||
"coral": getColor("coral", "\x1b[38;5;204m"),
|
||||
"magenta": getColor("magenta", "\x1b[38;5;13m"),
|
||||
"green": getColor("green", "\x1b[38;5;10m"),
|
||||
"dark-green": getColor("dark-green", "\x1b[38;5;28m"),
|
||||
"yellow": getColor("yellow", "\x1b[38;5;11m"),
|
||||
"light-yellow": getColor("light-yellow", "\x1b[38;5;228m"),
|
||||
"cyan": getColor("cyan", "\x1b[38;5;14m"),
|
||||
"gray": getColor("gray", "\x1b[38;5;243m"),
|
||||
"light-gray": getColor("light-gray", "\x1b[38;5;246m"),
|
||||
"blue": getColor("blue", "\x1b[38;5;12m"),
|
||||
},
|
||||
}
|
||||
colors := []string{}
|
||||
@@ -88,7 +120,10 @@ func (f Formatter) Fi(indentation uint, format string, args ...interface{}) stri
|
||||
}
|
||||
|
||||
func (f Formatter) Fiw(indentation uint, maxWidth uint, format string, args ...interface{}) string {
|
||||
out := fmt.Sprintf(f.style(format), args...)
|
||||
out := f.style(format)
|
||||
if len(args) > 0 {
|
||||
out = fmt.Sprintf(out, args...)
|
||||
}
|
||||
|
||||
if indentation == 0 && maxWidth == 0 {
|
||||
return out
|
||||
|
24
vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/bootstrap_command.go
generated
vendored
24
vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/bootstrap_command.go
generated
vendored
@@ -2,6 +2,7 @@ package generators
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"text/template"
|
||||
@@ -25,6 +26,9 @@ func BuildBootstrapCommand() command.Command {
|
||||
{Name: "template", KeyPath: "CustomTemplate",
|
||||
UsageArgument: "template-file",
|
||||
Usage: "If specified, generate will use the contents of the file passed as the bootstrap template"},
|
||||
{Name: "template-data", KeyPath: "CustomTemplateData",
|
||||
UsageArgument: "template-data-file",
|
||||
Usage: "If specified, generate will use the contents of the file passed as data to be rendered in the bootstrap template"},
|
||||
},
|
||||
&conf,
|
||||
types.GinkgoFlagSections{},
|
||||
@@ -57,6 +61,7 @@ type bootstrapData struct {
|
||||
GomegaImport string
|
||||
GinkgoPackage string
|
||||
GomegaPackage string
|
||||
CustomData map[string]any
|
||||
}
|
||||
|
||||
func generateBootstrap(conf GeneratorsConfig) {
|
||||
@@ -95,17 +100,32 @@ func generateBootstrap(conf GeneratorsConfig) {
|
||||
tpl, err := os.ReadFile(conf.CustomTemplate)
|
||||
command.AbortIfError("Failed to read custom bootstrap file:", err)
|
||||
templateText = string(tpl)
|
||||
if conf.CustomTemplateData != "" {
|
||||
var tplCustomDataMap map[string]any
|
||||
tplCustomData, err := os.ReadFile(conf.CustomTemplateData)
|
||||
command.AbortIfError("Failed to read custom boostrap data file:", err)
|
||||
if !json.Valid([]byte(tplCustomData)) {
|
||||
command.AbortWith("Invalid JSON object in custom data file.")
|
||||
}
|
||||
//create map from the custom template data
|
||||
json.Unmarshal(tplCustomData, &tplCustomDataMap)
|
||||
data.CustomData = tplCustomDataMap
|
||||
}
|
||||
} else if conf.Agouti {
|
||||
templateText = agoutiBootstrapText
|
||||
} else {
|
||||
templateText = bootstrapText
|
||||
}
|
||||
|
||||
bootstrapTemplate, err := template.New("bootstrap").Funcs(sprig.TxtFuncMap()).Parse(templateText)
|
||||
//Setting the option to explicitly fail if template is rendered trying to access missing key
|
||||
bootstrapTemplate, err := template.New("bootstrap").Funcs(sprig.TxtFuncMap()).Option("missingkey=error").Parse(templateText)
|
||||
command.AbortIfError("Failed to parse bootstrap template:", err)
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
bootstrapTemplate.Execute(buf, data)
|
||||
//Being explicit about failing sooner during template rendering
|
||||
//when accessing custom data rather than during the go fmt command
|
||||
err = bootstrapTemplate.Execute(buf, data)
|
||||
command.AbortIfError("Failed to render bootstrap template:", err)
|
||||
|
||||
buf.WriteTo(f)
|
||||
|
||||
|
24
vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generate_command.go
generated
vendored
24
vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generate_command.go
generated
vendored
@@ -2,6 +2,7 @@ package generators
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -28,6 +29,9 @@ func BuildGenerateCommand() command.Command {
|
||||
{Name: "template", KeyPath: "CustomTemplate",
|
||||
UsageArgument: "template-file",
|
||||
Usage: "If specified, generate will use the contents of the file passed as the test file template"},
|
||||
{Name: "template-data", KeyPath: "CustomTemplateData",
|
||||
UsageArgument: "template-data-file",
|
||||
Usage: "If specified, generate will use the contents of the file passed as data to be rendered in the test file template"},
|
||||
},
|
||||
&conf,
|
||||
types.GinkgoFlagSections{},
|
||||
@@ -64,6 +68,7 @@ type specData struct {
|
||||
GomegaImport string
|
||||
GinkgoPackage string
|
||||
GomegaPackage string
|
||||
CustomData map[string]any
|
||||
}
|
||||
|
||||
func generateTestFiles(conf GeneratorsConfig, args []string) {
|
||||
@@ -122,16 +127,31 @@ func generateTestFileForSubject(subject string, conf GeneratorsConfig) {
|
||||
tpl, err := os.ReadFile(conf.CustomTemplate)
|
||||
command.AbortIfError("Failed to read custom template file:", err)
|
||||
templateText = string(tpl)
|
||||
if conf.CustomTemplateData != "" {
|
||||
var tplCustomDataMap map[string]any
|
||||
tplCustomData, err := os.ReadFile(conf.CustomTemplateData)
|
||||
command.AbortIfError("Failed to read custom template data file:", err)
|
||||
if !json.Valid([]byte(tplCustomData)) {
|
||||
command.AbortWith("Invalid JSON object in custom data file.")
|
||||
}
|
||||
//create map from the custom template data
|
||||
json.Unmarshal(tplCustomData, &tplCustomDataMap)
|
||||
data.CustomData = tplCustomDataMap
|
||||
}
|
||||
} else if conf.Agouti {
|
||||
templateText = agoutiSpecText
|
||||
} else {
|
||||
templateText = specText
|
||||
}
|
||||
|
||||
specTemplate, err := template.New("spec").Funcs(sprig.TxtFuncMap()).Parse(templateText)
|
||||
//Setting the option to explicitly fail if template is rendered trying to access missing key
|
||||
specTemplate, err := template.New("spec").Funcs(sprig.TxtFuncMap()).Option("missingkey=error").Parse(templateText)
|
||||
command.AbortIfError("Failed to read parse test template:", err)
|
||||
|
||||
specTemplate.Execute(f, data)
|
||||
//Being explicit about failing sooner during template rendering
|
||||
//when accessing custom data rather than during the go fmt command
|
||||
err = specTemplate.Execute(f, data)
|
||||
command.AbortIfError("Failed to render bootstrap template:", err)
|
||||
internal.GoFmt(targetFile)
|
||||
}
|
||||
|
||||
|
1
vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generators_common.go
generated
vendored
1
vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generators_common.go
generated
vendored
@@ -13,6 +13,7 @@ import (
|
||||
type GeneratorsConfig struct {
|
||||
Agouti, NoDot, Internal bool
|
||||
CustomTemplate string
|
||||
CustomTemplateData string
|
||||
}
|
||||
|
||||
func getPackageAndFormattedName() (string, string, string) {
|
||||
|
11
vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/compile.go
generated
vendored
11
vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/compile.go
generated
vendored
@@ -25,7 +25,16 @@ func CompileSuite(suite TestSuite, goFlagsConfig types.GoFlagsConfig) TestSuite
|
||||
return suite
|
||||
}
|
||||
|
||||
args, err := types.GenerateGoTestCompileArgs(goFlagsConfig, path, "./")
|
||||
ginkgoInvocationPath, _ := os.Getwd()
|
||||
ginkgoInvocationPath, _ = filepath.Abs(ginkgoInvocationPath)
|
||||
packagePath := suite.AbsPath()
|
||||
pathToInvocationPath, err := filepath.Rel(packagePath, ginkgoInvocationPath)
|
||||
if err != nil {
|
||||
suite.State = TestSuiteStateFailedToCompile
|
||||
suite.CompilationError = fmt.Errorf("Failed to get relative path from package to the current working directory:\n%s", err.Error())
|
||||
return suite
|
||||
}
|
||||
args, err := types.GenerateGoTestCompileArgs(goFlagsConfig, path, "./", pathToInvocationPath)
|
||||
if err != nil {
|
||||
suite.State = TestSuiteStateFailedToCompile
|
||||
suite.CompilationError = fmt.Errorf("Failed to generate go test compile flags:\n%s", err.Error())
|
||||
|
7
vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go
generated
vendored
7
vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go
generated
vendored
@@ -6,6 +6,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"syscall"
|
||||
@@ -63,6 +64,12 @@ func checkForNoTestsWarning(buf *bytes.Buffer) bool {
|
||||
}
|
||||
|
||||
func runGoTest(suite TestSuite, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig) TestSuite {
|
||||
// As we run the go test from the suite directory, make sure the cover profile is absolute
|
||||
// and placed into the expected output directory when one is configured.
|
||||
if goFlagsConfig.Cover && !filepath.IsAbs(goFlagsConfig.CoverProfile) {
|
||||
goFlagsConfig.CoverProfile = AbsPathForGeneratedAsset(goFlagsConfig.CoverProfile, suite, cliConfig, 0)
|
||||
}
|
||||
|
||||
args, err := types.GenerateGoTestRunArgs(goFlagsConfig)
|
||||
command.AbortIfError("Failed to generate test run arguments", err)
|
||||
cmd, buf := buildAndStartCommand(suite, args, true)
|
||||
|
90
vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go
generated
vendored
90
vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package outline
|
||||
|
||||
import (
|
||||
"github.com/onsi/ginkgo/v2/types"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"strconv"
|
||||
@@ -25,9 +26,10 @@ type ginkgoMetadata struct {
|
||||
// End is the position of first character immediately after the spec or container block
|
||||
End int `json:"end"`
|
||||
|
||||
Spec bool `json:"spec"`
|
||||
Focused bool `json:"focused"`
|
||||
Pending bool `json:"pending"`
|
||||
Spec bool `json:"spec"`
|
||||
Focused bool `json:"focused"`
|
||||
Pending bool `json:"pending"`
|
||||
Labels []string `json:"labels"`
|
||||
}
|
||||
|
||||
// ginkgoNode is used to construct the outline as a tree
|
||||
@@ -145,27 +147,35 @@ func ginkgoNodeFromCallExpr(fset *token.FileSet, ce *ast.CallExpr, ginkgoPackage
|
||||
case "It", "Specify", "Entry":
|
||||
n.Spec = true
|
||||
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
|
||||
n.Labels = labelFromCallExpr(ce)
|
||||
n.Pending = pendingFromCallExpr(ce)
|
||||
return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
|
||||
case "FIt", "FSpecify", "FEntry":
|
||||
n.Spec = true
|
||||
n.Focused = true
|
||||
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
|
||||
n.Labels = labelFromCallExpr(ce)
|
||||
return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
|
||||
case "PIt", "PSpecify", "XIt", "XSpecify", "PEntry", "XEntry":
|
||||
n.Spec = true
|
||||
n.Pending = true
|
||||
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
|
||||
n.Labels = labelFromCallExpr(ce)
|
||||
return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
|
||||
case "Context", "Describe", "When", "DescribeTable":
|
||||
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
|
||||
n.Labels = labelFromCallExpr(ce)
|
||||
n.Pending = pendingFromCallExpr(ce)
|
||||
return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
|
||||
case "FContext", "FDescribe", "FWhen", "FDescribeTable":
|
||||
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":
|
||||
n.Pending = true
|
||||
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
|
||||
n.Labels = labelFromCallExpr(ce)
|
||||
return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
|
||||
case "By":
|
||||
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
|
||||
@@ -216,3 +226,77 @@ func textFromCallExpr(ce *ast.CallExpr) (string, bool) {
|
||||
return text.Value, true
|
||||
}
|
||||
}
|
||||
|
||||
func labelFromCallExpr(ce *ast.CallExpr) []string {
|
||||
|
||||
labels := []string{}
|
||||
if len(ce.Args) < 2 {
|
||||
return labels
|
||||
}
|
||||
|
||||
for _, arg := range ce.Args[1:] {
|
||||
switch expr := arg.(type) {
|
||||
case *ast.CallExpr:
|
||||
id, ok := expr.Fun.(*ast.Ident)
|
||||
if !ok {
|
||||
// to skip over cases where the expr.Fun. is actually *ast.SelectorExpr
|
||||
continue
|
||||
}
|
||||
if id.Name == "Label" {
|
||||
ls := extractLabels(expr)
|
||||
for _, label := range ls {
|
||||
labels = append(labels, label)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return labels
|
||||
}
|
||||
|
||||
func extractLabels(expr *ast.CallExpr) []string {
|
||||
out := []string{}
|
||||
for _, arg := range expr.Args {
|
||||
switch expr := arg.(type) {
|
||||
case *ast.BasicLit:
|
||||
if expr.Kind == token.STRING {
|
||||
unquoted, err := strconv.Unquote(expr.Value)
|
||||
if err != nil {
|
||||
unquoted = expr.Value
|
||||
}
|
||||
validated, err := types.ValidateAndCleanupLabel(unquoted, types.CodeLocation{})
|
||||
if err == nil {
|
||||
out = append(out, validated)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func pendingFromCallExpr(ce *ast.CallExpr) bool {
|
||||
|
||||
pending := false
|
||||
if len(ce.Args) < 2 {
|
||||
return pending
|
||||
}
|
||||
|
||||
for _, arg := range ce.Args[1:] {
|
||||
switch expr := arg.(type) {
|
||||
case *ast.CallExpr:
|
||||
id, ok := expr.Fun.(*ast.Ident)
|
||||
if !ok {
|
||||
// to skip over cases where the expr.Fun. is actually *ast.SelectorExpr
|
||||
continue
|
||||
}
|
||||
if id.Name == "Pending" {
|
||||
pending = true
|
||||
}
|
||||
case *ast.Ident:
|
||||
if expr.Name == "Pending" {
|
||||
pending = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return pending
|
||||
}
|
||||
|
11
vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go
generated
vendored
11
vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go
generated
vendored
@@ -85,12 +85,19 @@ func (o *outline) String() string {
|
||||
// one 'width' of spaces for every level of nesting.
|
||||
func (o *outline) StringIndent(width int) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("Name,Text,Start,End,Spec,Focused,Pending\n")
|
||||
b.WriteString("Name,Text,Start,End,Spec,Focused,Pending,Labels\n")
|
||||
|
||||
currentIndent := 0
|
||||
pre := func(n *ginkgoNode) {
|
||||
b.WriteString(fmt.Sprintf("%*s", currentIndent, ""))
|
||||
b.WriteString(fmt.Sprintf("%s,%s,%d,%d,%t,%t,%t\n", n.Name, n.Text, n.Start, n.End, n.Spec, n.Focused, n.Pending))
|
||||
var labels string
|
||||
if len(n.Labels) == 1 {
|
||||
labels = n.Labels[0]
|
||||
} else {
|
||||
labels = strings.Join(n.Labels, ", ")
|
||||
}
|
||||
//enclosing labels in a double quoted comma separate listed so that when inmported into a CSV app the Labels column has comma separate strings
|
||||
b.WriteString(fmt.Sprintf("%s,%s,%d,%d,%t,%t,%t,\"%s\"\n", n.Name, n.Text, n.Start, n.End, n.Spec, n.Focused, n.Pending, labels))
|
||||
currentIndent += width
|
||||
}
|
||||
post := func(n *ginkgoNode) {
|
||||
|
47
vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go
generated
vendored
47
vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go
generated
vendored
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/onsi/ginkgo/v2/internal/parallel_support"
|
||||
)
|
||||
|
||||
const ABORT_POLLING_INTERVAL = 500 * time.Millisecond
|
||||
var ABORT_POLLING_INTERVAL = 500 * time.Millisecond
|
||||
|
||||
type InterruptCause uint
|
||||
|
||||
@@ -62,13 +62,14 @@ type InterruptHandlerInterface interface {
|
||||
}
|
||||
|
||||
type InterruptHandler struct {
|
||||
c chan interface{}
|
||||
lock *sync.Mutex
|
||||
level InterruptLevel
|
||||
cause InterruptCause
|
||||
client parallel_support.Client
|
||||
stop chan interface{}
|
||||
signals []os.Signal
|
||||
c chan interface{}
|
||||
lock *sync.Mutex
|
||||
level InterruptLevel
|
||||
cause InterruptCause
|
||||
client parallel_support.Client
|
||||
stop chan interface{}
|
||||
signals []os.Signal
|
||||
requestAbortCheck chan interface{}
|
||||
}
|
||||
|
||||
func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *InterruptHandler {
|
||||
@@ -76,11 +77,12 @@ func NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *
|
||||
signals = []os.Signal{os.Interrupt, syscall.SIGTERM}
|
||||
}
|
||||
handler := &InterruptHandler{
|
||||
c: make(chan interface{}),
|
||||
lock: &sync.Mutex{},
|
||||
stop: make(chan interface{}),
|
||||
client: client,
|
||||
signals: signals,
|
||||
c: make(chan interface{}),
|
||||
lock: &sync.Mutex{},
|
||||
stop: make(chan interface{}),
|
||||
requestAbortCheck: make(chan interface{}),
|
||||
client: client,
|
||||
signals: signals,
|
||||
}
|
||||
handler.registerForInterrupts()
|
||||
return handler
|
||||
@@ -109,6 +111,12 @@ func (handler *InterruptHandler) registerForInterrupts() {
|
||||
pollTicker.Stop()
|
||||
return
|
||||
}
|
||||
case <-handler.requestAbortCheck:
|
||||
if handler.client.ShouldAbort() {
|
||||
close(abortChannel)
|
||||
pollTicker.Stop()
|
||||
return
|
||||
}
|
||||
case <-handler.stop:
|
||||
pollTicker.Stop()
|
||||
return
|
||||
@@ -152,11 +160,18 @@ func (handler *InterruptHandler) registerForInterrupts() {
|
||||
|
||||
func (handler *InterruptHandler) Status() InterruptStatus {
|
||||
handler.lock.Lock()
|
||||
defer handler.lock.Unlock()
|
||||
|
||||
return InterruptStatus{
|
||||
status := InterruptStatus{
|
||||
Level: handler.level,
|
||||
Channel: handler.c,
|
||||
Cause: handler.cause,
|
||||
}
|
||||
handler.lock.Unlock()
|
||||
|
||||
if handler.client != nil && handler.client.ShouldAbort() && !status.Interrupted() {
|
||||
close(handler.requestAbortCheck)
|
||||
<-status.Channel
|
||||
return handler.Status()
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
|
2
vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go
generated
vendored
2
vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go
generated
vendored
@@ -42,6 +42,8 @@ type Client interface {
|
||||
PostSuiteWillBegin(report types.Report) error
|
||||
PostDidRun(report types.SpecReport) error
|
||||
PostSuiteDidEnd(report types.Report) error
|
||||
PostReportBeforeSuiteCompleted(state types.SpecState) error
|
||||
BlockUntilReportBeforeSuiteCompleted() (types.SpecState, error)
|
||||
PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error
|
||||
BlockUntilSynchronizedBeforeSuiteData() (types.SpecState, []byte, error)
|
||||
BlockUntilNonprimaryProcsHaveFinished() error
|
||||
|
13
vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go
generated
vendored
13
vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go
generated
vendored
@@ -98,6 +98,19 @@ func (client *httpClient) PostEmitProgressReport(report types.ProgressReport) er
|
||||
return client.post("/progress-report", report)
|
||||
}
|
||||
|
||||
func (client *httpClient) PostReportBeforeSuiteCompleted(state types.SpecState) error {
|
||||
return client.post("/report-before-suite-completed", state)
|
||||
}
|
||||
|
||||
func (client *httpClient) BlockUntilReportBeforeSuiteCompleted() (types.SpecState, error) {
|
||||
var state types.SpecState
|
||||
err := client.poll("/report-before-suite-state", &state)
|
||||
if err == ErrorGone {
|
||||
return types.SpecStateFailed, nil
|
||||
}
|
||||
return state, err
|
||||
}
|
||||
|
||||
func (client *httpClient) PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error {
|
||||
beforeSuiteState := BeforeSuiteState{
|
||||
State: state,
|
||||
|
29
vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go
generated
vendored
29
vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go
generated
vendored
@@ -26,7 +26,7 @@ type httpServer struct {
|
||||
handler *ServerHandler
|
||||
}
|
||||
|
||||
//Create a new server, automatically selecting a port
|
||||
// Create a new server, automatically selecting a port
|
||||
func newHttpServer(parallelTotal int, reporter reporters.Reporter) (*httpServer, error) {
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
@@ -38,7 +38,7 @@ func newHttpServer(parallelTotal int, reporter reporters.Reporter) (*httpServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
//Start the server. You don't need to `go s.Start()`, just `s.Start()`
|
||||
// Start the server. You don't need to `go s.Start()`, just `s.Start()`
|
||||
func (server *httpServer) Start() {
|
||||
httpServer := &http.Server{}
|
||||
mux := http.NewServeMux()
|
||||
@@ -52,6 +52,8 @@ func (server *httpServer) Start() {
|
||||
mux.HandleFunc("/progress-report", server.emitProgressReport)
|
||||
|
||||
//synchronization endpoints
|
||||
mux.HandleFunc("/report-before-suite-completed", server.handleReportBeforeSuiteCompleted)
|
||||
mux.HandleFunc("/report-before-suite-state", server.handleReportBeforeSuiteState)
|
||||
mux.HandleFunc("/before-suite-completed", server.handleBeforeSuiteCompleted)
|
||||
mux.HandleFunc("/before-suite-state", server.handleBeforeSuiteState)
|
||||
mux.HandleFunc("/have-nonprimary-procs-finished", server.handleHaveNonprimaryProcsFinished)
|
||||
@@ -63,12 +65,12 @@ func (server *httpServer) Start() {
|
||||
go httpServer.Serve(server.listener)
|
||||
}
|
||||
|
||||
//Stop the server
|
||||
// Stop the server
|
||||
func (server *httpServer) Close() {
|
||||
server.listener.Close()
|
||||
}
|
||||
|
||||
//The address the server can be reached it. Pass this into the `ForwardingReporter`.
|
||||
// The address the server can be reached it. Pass this into the `ForwardingReporter`.
|
||||
func (server *httpServer) Address() string {
|
||||
return "http://" + server.listener.Addr().String()
|
||||
}
|
||||
@@ -93,7 +95,7 @@ func (server *httpServer) RegisterAlive(node int, alive func() bool) {
|
||||
// Streaming Endpoints
|
||||
//
|
||||
|
||||
//The server will forward all received messages to Ginkgo reporters registered with `RegisterReporters`
|
||||
// The server will forward all received messages to Ginkgo reporters registered with `RegisterReporters`
|
||||
func (server *httpServer) decode(writer http.ResponseWriter, request *http.Request, object interface{}) bool {
|
||||
defer request.Body.Close()
|
||||
if json.NewDecoder(request.Body).Decode(object) != nil {
|
||||
@@ -164,6 +166,23 @@ func (server *httpServer) emitProgressReport(writer http.ResponseWriter, request
|
||||
server.handleError(server.handler.EmitProgressReport(report, voidReceiver), writer)
|
||||
}
|
||||
|
||||
func (server *httpServer) handleReportBeforeSuiteCompleted(writer http.ResponseWriter, request *http.Request) {
|
||||
var state types.SpecState
|
||||
if !server.decode(writer, request, &state) {
|
||||
return
|
||||
}
|
||||
|
||||
server.handleError(server.handler.ReportBeforeSuiteCompleted(state, voidReceiver), writer)
|
||||
}
|
||||
|
||||
func (server *httpServer) handleReportBeforeSuiteState(writer http.ResponseWriter, request *http.Request) {
|
||||
var state types.SpecState
|
||||
if server.handleError(server.handler.ReportBeforeSuiteState(voidSender, &state), writer) {
|
||||
return
|
||||
}
|
||||
json.NewEncoder(writer).Encode(state)
|
||||
}
|
||||
|
||||
func (server *httpServer) handleBeforeSuiteCompleted(writer http.ResponseWriter, request *http.Request) {
|
||||
var beforeSuiteState BeforeSuiteState
|
||||
if !server.decode(writer, request, &beforeSuiteState) {
|
||||
|
13
vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go
generated
vendored
13
vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go
generated
vendored
@@ -76,6 +76,19 @@ func (client *rpcClient) PostEmitProgressReport(report types.ProgressReport) err
|
||||
return client.client.Call("Server.EmitProgressReport", report, voidReceiver)
|
||||
}
|
||||
|
||||
func (client *rpcClient) PostReportBeforeSuiteCompleted(state types.SpecState) error {
|
||||
return client.client.Call("Server.ReportBeforeSuiteCompleted", state, voidReceiver)
|
||||
}
|
||||
|
||||
func (client *rpcClient) BlockUntilReportBeforeSuiteCompleted() (types.SpecState, error) {
|
||||
var state types.SpecState
|
||||
err := client.poll("Server.ReportBeforeSuiteState", &state)
|
||||
if err == ErrorGone {
|
||||
return types.SpecStateFailed, nil
|
||||
}
|
||||
return state, err
|
||||
}
|
||||
|
||||
func (client *rpcClient) PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error {
|
||||
beforeSuiteState := BeforeSuiteState{
|
||||
State: state,
|
||||
|
55
vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go
generated
vendored
55
vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go
generated
vendored
@@ -18,16 +18,17 @@ var voidSender Void
|
||||
// It handles all the business logic to avoid duplication between the two servers
|
||||
|
||||
type ServerHandler struct {
|
||||
done chan interface{}
|
||||
outputDestination io.Writer
|
||||
reporter reporters.Reporter
|
||||
alives []func() bool
|
||||
lock *sync.Mutex
|
||||
beforeSuiteState BeforeSuiteState
|
||||
parallelTotal int
|
||||
counter int
|
||||
counterLock *sync.Mutex
|
||||
shouldAbort bool
|
||||
done chan interface{}
|
||||
outputDestination io.Writer
|
||||
reporter reporters.Reporter
|
||||
alives []func() bool
|
||||
lock *sync.Mutex
|
||||
beforeSuiteState BeforeSuiteState
|
||||
reportBeforeSuiteState types.SpecState
|
||||
parallelTotal int
|
||||
counter int
|
||||
counterLock *sync.Mutex
|
||||
shouldAbort bool
|
||||
|
||||
numSuiteDidBegins int
|
||||
numSuiteDidEnds int
|
||||
@@ -37,11 +38,12 @@ type ServerHandler struct {
|
||||
|
||||
func newServerHandler(parallelTotal int, reporter reporters.Reporter) *ServerHandler {
|
||||
return &ServerHandler{
|
||||
reporter: reporter,
|
||||
lock: &sync.Mutex{},
|
||||
counterLock: &sync.Mutex{},
|
||||
alives: make([]func() bool, parallelTotal),
|
||||
beforeSuiteState: BeforeSuiteState{Data: nil, State: types.SpecStateInvalid},
|
||||
reporter: reporter,
|
||||
lock: &sync.Mutex{},
|
||||
counterLock: &sync.Mutex{},
|
||||
alives: make([]func() bool, parallelTotal),
|
||||
beforeSuiteState: BeforeSuiteState{Data: nil, State: types.SpecStateInvalid},
|
||||
|
||||
parallelTotal: parallelTotal,
|
||||
outputDestination: os.Stdout,
|
||||
done: make(chan interface{}),
|
||||
@@ -140,6 +142,29 @@ func (handler *ServerHandler) haveNonprimaryProcsFinished() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (handler *ServerHandler) ReportBeforeSuiteCompleted(reportBeforeSuiteState types.SpecState, _ *Void) error {
|
||||
handler.lock.Lock()
|
||||
defer handler.lock.Unlock()
|
||||
handler.reportBeforeSuiteState = reportBeforeSuiteState
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (handler *ServerHandler) ReportBeforeSuiteState(_ Void, reportBeforeSuiteState *types.SpecState) error {
|
||||
proc1IsAlive := handler.procIsAlive(1)
|
||||
handler.lock.Lock()
|
||||
defer handler.lock.Unlock()
|
||||
if handler.reportBeforeSuiteState == types.SpecStateInvalid {
|
||||
if proc1IsAlive {
|
||||
return ErrorEarly
|
||||
} else {
|
||||
return ErrorGone
|
||||
}
|
||||
}
|
||||
*reportBeforeSuiteState = handler.reportBeforeSuiteState
|
||||
return nil
|
||||
}
|
||||
|
||||
func (handler *ServerHandler) BeforeSuiteCompleted(beforeSuiteState BeforeSuiteState, _ *Void) error {
|
||||
handler.lock.Lock()
|
||||
defer handler.lock.Unlock()
|
||||
|
681
vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
generated
vendored
681
vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
generated
vendored
@@ -12,6 +12,7 @@ import (
|
||||
"io"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/onsi/ginkgo/v2/formatter"
|
||||
@@ -23,13 +24,16 @@ type DefaultReporter struct {
|
||||
writer io.Writer
|
||||
|
||||
// managing the emission stream
|
||||
lastChar string
|
||||
lastCharWasNewline bool
|
||||
lastEmissionWasDelimiter bool
|
||||
|
||||
// rendering
|
||||
specDenoter string
|
||||
retryDenoter string
|
||||
formatter formatter.Formatter
|
||||
|
||||
runningInParallel bool
|
||||
lock *sync.Mutex
|
||||
}
|
||||
|
||||
func NewDefaultReporterUnderTest(conf types.ReporterConfig, writer io.Writer) *DefaultReporter {
|
||||
@@ -44,12 +48,13 @@ func NewDefaultReporter(conf types.ReporterConfig, writer io.Writer) *DefaultRep
|
||||
conf: conf,
|
||||
writer: writer,
|
||||
|
||||
lastChar: "\n",
|
||||
lastCharWasNewline: true,
|
||||
lastEmissionWasDelimiter: false,
|
||||
|
||||
specDenoter: "•",
|
||||
retryDenoter: "↺",
|
||||
formatter: formatter.NewWithNoColorBool(conf.NoColor),
|
||||
lock: &sync.Mutex{},
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
reporter.specDenoter = "+"
|
||||
@@ -97,230 +102,10 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) WillRun(report types.SpecReport) {
|
||||
if r.conf.Verbosity().LT(types.VerbosityLevelVerbose) || report.State.Is(types.SpecStatePending|types.SpecStateSkipped) {
|
||||
return
|
||||
}
|
||||
|
||||
r.emitDelimiter()
|
||||
indentation := uint(0)
|
||||
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
|
||||
r.emitBlock(r.f("{{bold}}[%s] %s{{/}}", report.LeafNodeType.String(), report.LeafNodeText))
|
||||
} else {
|
||||
if len(report.ContainerHierarchyTexts) > 0 {
|
||||
r.emitBlock(r.cycleJoin(report.ContainerHierarchyTexts, " "))
|
||||
indentation = 1
|
||||
}
|
||||
line := r.fi(indentation, "{{bold}}%s{{/}}", report.LeafNodeText)
|
||||
labels := report.Labels()
|
||||
if len(labels) > 0 {
|
||||
line += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels, ", "))
|
||||
}
|
||||
r.emitBlock(line)
|
||||
}
|
||||
r.emitBlock(r.fi(indentation, "{{gray}}%s{{/}}", report.LeafNodeLocation))
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) DidRun(report types.SpecReport) {
|
||||
v := r.conf.Verbosity()
|
||||
var header, highlightColor string
|
||||
includeRuntime, emitGinkgoWriterOutput, stream, denoter := true, true, false, r.specDenoter
|
||||
succinctLocationBlock := v.Is(types.VerbosityLevelSuccinct)
|
||||
|
||||
hasGW := report.CapturedGinkgoWriterOutput != ""
|
||||
hasStd := report.CapturedStdOutErr != ""
|
||||
hasEmittableReports := report.ReportEntries.HasVisibility(types.ReportEntryVisibilityAlways) || (report.ReportEntries.HasVisibility(types.ReportEntryVisibilityFailureOrVerbose) && (!report.Failure.IsZero() || v.GTE(types.VerbosityLevelVerbose)))
|
||||
|
||||
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
|
||||
denoter = fmt.Sprintf("[%s]", report.LeafNodeType)
|
||||
}
|
||||
|
||||
highlightColor = r.highlightColorForState(report.State)
|
||||
|
||||
switch report.State {
|
||||
case types.SpecStatePassed:
|
||||
succinctLocationBlock = v.LT(types.VerbosityLevelVerbose)
|
||||
emitGinkgoWriterOutput = (r.conf.AlwaysEmitGinkgoWriter || v.GTE(types.VerbosityLevelVerbose)) && hasGW
|
||||
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
|
||||
if v.GTE(types.VerbosityLevelVerbose) || hasStd || hasEmittableReports {
|
||||
header = fmt.Sprintf("%s PASSED", denoter)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
header, stream = denoter, true
|
||||
if report.NumAttempts > 1 && report.MaxFlakeAttempts > 1 {
|
||||
header, stream = fmt.Sprintf("%s [FLAKEY TEST - TOOK %d ATTEMPTS TO PASS]", r.retryDenoter, report.NumAttempts), false
|
||||
}
|
||||
if report.RunTime > r.conf.SlowSpecThreshold {
|
||||
header, stream = fmt.Sprintf("%s [SLOW TEST]", header), false
|
||||
}
|
||||
}
|
||||
if hasStd || emitGinkgoWriterOutput || hasEmittableReports {
|
||||
stream = false
|
||||
}
|
||||
case types.SpecStatePending:
|
||||
includeRuntime, emitGinkgoWriterOutput = false, false
|
||||
if v.Is(types.VerbosityLevelSuccinct) {
|
||||
header, stream = "P", true
|
||||
} else {
|
||||
header, succinctLocationBlock = "P [PENDING]", v.LT(types.VerbosityLevelVeryVerbose)
|
||||
}
|
||||
case types.SpecStateSkipped:
|
||||
if report.Failure.Message != "" || v.Is(types.VerbosityLevelVeryVerbose) {
|
||||
header = "S [SKIPPED]"
|
||||
} else {
|
||||
header, stream = "S", true
|
||||
}
|
||||
case types.SpecStateFailed:
|
||||
header = fmt.Sprintf("%s [FAILED]", denoter)
|
||||
case types.SpecStateTimedout:
|
||||
header = fmt.Sprintf("%s [TIMEDOUT]", denoter)
|
||||
case types.SpecStatePanicked:
|
||||
header = fmt.Sprintf("%s! [PANICKED]", denoter)
|
||||
case types.SpecStateInterrupted:
|
||||
header = fmt.Sprintf("%s! [INTERRUPTED]", denoter)
|
||||
case types.SpecStateAborted:
|
||||
header = fmt.Sprintf("%s! [ABORTED]", denoter)
|
||||
}
|
||||
|
||||
if report.State.Is(types.SpecStateFailureStates) && report.MaxMustPassRepeatedly > 1 {
|
||||
header, stream = fmt.Sprintf("%s DURING REPETITION #%d", header, report.NumAttempts), false
|
||||
}
|
||||
// Emit stream and return
|
||||
if stream {
|
||||
r.emit(r.f(highlightColor + header + "{{/}}"))
|
||||
return
|
||||
}
|
||||
|
||||
// Emit header
|
||||
r.emitDelimiter()
|
||||
if includeRuntime {
|
||||
header = r.f("%s [%.3f seconds]", header, report.RunTime.Seconds())
|
||||
}
|
||||
r.emitBlock(r.f(highlightColor + header + "{{/}}"))
|
||||
|
||||
// Emit Code Location Block
|
||||
r.emitBlock(r.codeLocationBlock(report, highlightColor, succinctLocationBlock, false))
|
||||
|
||||
//Emit Stdout/Stderr Output
|
||||
if hasStd {
|
||||
r.emitBlock("\n")
|
||||
r.emitBlock(r.fi(1, "{{gray}}Begin Captured StdOut/StdErr Output >>{{/}}"))
|
||||
r.emitBlock(r.fi(2, "%s", report.CapturedStdOutErr))
|
||||
r.emitBlock(r.fi(1, "{{gray}}<< End Captured StdOut/StdErr Output{{/}}"))
|
||||
}
|
||||
|
||||
//Emit Captured GinkgoWriter Output
|
||||
if emitGinkgoWriterOutput && hasGW {
|
||||
r.emitBlock("\n")
|
||||
r.emitGinkgoWriterOutput(1, report.CapturedGinkgoWriterOutput, 0)
|
||||
}
|
||||
|
||||
if hasEmittableReports {
|
||||
r.emitBlock("\n")
|
||||
r.emitBlock(r.fi(1, "{{gray}}Begin Report Entries >>{{/}}"))
|
||||
reportEntries := report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways)
|
||||
if !report.Failure.IsZero() || v.GTE(types.VerbosityLevelVerbose) {
|
||||
reportEntries = report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways, types.ReportEntryVisibilityFailureOrVerbose)
|
||||
}
|
||||
for _, entry := range reportEntries {
|
||||
r.emitBlock(r.fi(2, "{{bold}}"+entry.Name+"{{gray}} - %s @ %s{{/}}", entry.Location, entry.Time.Format(types.GINKGO_TIME_FORMAT)))
|
||||
if representation := entry.StringRepresentation(); representation != "" {
|
||||
r.emitBlock(r.fi(3, representation))
|
||||
}
|
||||
}
|
||||
r.emitBlock(r.fi(1, "{{gray}}<< End Report Entries{{/}}"))
|
||||
}
|
||||
|
||||
// Emit Failure Message
|
||||
if !report.Failure.IsZero() {
|
||||
r.emitBlock("\n")
|
||||
r.EmitFailure(1, report.State, report.Failure, false)
|
||||
}
|
||||
|
||||
if len(report.AdditionalFailures) > 0 {
|
||||
if v.GTE(types.VerbosityLevelVerbose) {
|
||||
r.emitBlock("\n")
|
||||
r.emitBlock(r.fi(1, "{{bold}}There were additional failures detected after the initial failure:{{/}}"))
|
||||
for i, additionalFailure := range report.AdditionalFailures {
|
||||
r.EmitFailure(2, additionalFailure.State, additionalFailure.Failure, true)
|
||||
if i < len(report.AdditionalFailures)-1 {
|
||||
r.emitBlock(r.fi(2, "{{gray}}%s{{/}}", strings.Repeat("-", 10)))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
r.emitBlock("\n")
|
||||
r.emitBlock(r.fi(1, "{{bold}}There were additional failures detected after the initial failure. Here's a summary - for full details run Ginkgo in verbose mode:{{/}}"))
|
||||
for _, additionalFailure := range report.AdditionalFailures {
|
||||
r.emitBlock(r.fi(2, r.highlightColorForState(additionalFailure.State)+"[%s]{{/}} in [%s] at %s",
|
||||
r.humanReadableState(additionalFailure.State),
|
||||
additionalFailure.Failure.FailureNodeType,
|
||||
additionalFailure.Failure.Location,
|
||||
))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
r.emitDelimiter()
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) highlightColorForState(state types.SpecState) string {
|
||||
switch state {
|
||||
case types.SpecStatePassed:
|
||||
return "{{green}}"
|
||||
case types.SpecStatePending:
|
||||
return "{{yellow}}"
|
||||
case types.SpecStateSkipped:
|
||||
return "{{cyan}}"
|
||||
case types.SpecStateFailed:
|
||||
return "{{red}}"
|
||||
case types.SpecStateTimedout:
|
||||
return "{{orange}}"
|
||||
case types.SpecStatePanicked:
|
||||
return "{{magenta}}"
|
||||
case types.SpecStateInterrupted:
|
||||
return "{{orange}}"
|
||||
case types.SpecStateAborted:
|
||||
return "{{coral}}"
|
||||
default:
|
||||
return "{{gray}}"
|
||||
}
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) humanReadableState(state types.SpecState) string {
|
||||
return strings.ToUpper(state.String())
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) EmitFailure(indent uint, state types.SpecState, failure types.Failure, includeState bool) {
|
||||
highlightColor := r.highlightColorForState(state)
|
||||
if includeState {
|
||||
r.emitBlock(r.fi(indent, highlightColor+"[%s]{{/}}", r.humanReadableState(state)))
|
||||
}
|
||||
r.emitBlock(r.fi(indent, highlightColor+"%s{{/}}", failure.Message))
|
||||
r.emitBlock(r.fi(indent, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}}\n", failure.FailureNodeType, failure.Location))
|
||||
if failure.ForwardedPanic != "" {
|
||||
r.emitBlock("\n")
|
||||
r.emitBlock(r.fi(indent, highlightColor+"%s{{/}}", failure.ForwardedPanic))
|
||||
}
|
||||
|
||||
if r.conf.FullTrace || failure.ForwardedPanic != "" {
|
||||
r.emitBlock("\n")
|
||||
r.emitBlock(r.fi(indent, highlightColor+"Full Stack Trace{{/}}"))
|
||||
r.emitBlock(r.fi(indent+1, "%s", failure.Location.FullStackTrace))
|
||||
}
|
||||
|
||||
if !failure.ProgressReport.IsZero() {
|
||||
r.emitBlock("\n")
|
||||
r.emitProgressReport(indent, false, failure.ProgressReport)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) SuiteDidEnd(report types.Report) {
|
||||
failures := report.SpecReports.WithState(types.SpecStateFailureStates)
|
||||
if len(failures) > 0 {
|
||||
r.emitBlock("\n\n")
|
||||
r.emitBlock("\n")
|
||||
if len(failures) > 1 {
|
||||
r.emitBlock(r.f("{{red}}{{bold}}Summarizing %d Failures:{{/}}", len(failures)))
|
||||
} else {
|
||||
@@ -338,7 +123,7 @@ func (r *DefaultReporter) SuiteDidEnd(report types.Report) {
|
||||
case types.SpecStateInterrupted:
|
||||
highlightColor, heading = "{{orange}}", "[INTERRUPTED]"
|
||||
}
|
||||
locationBlock := r.codeLocationBlock(specReport, highlightColor, true, true)
|
||||
locationBlock := r.codeLocationBlock(specReport, highlightColor, false, true)
|
||||
r.emitBlock(r.fi(1, highlightColor+"%s{{/}} %s", heading, locationBlock))
|
||||
}
|
||||
}
|
||||
@@ -387,14 +172,271 @@ func (r *DefaultReporter) SuiteDidEnd(report types.Report) {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) WillRun(report types.SpecReport) {
|
||||
v := r.conf.Verbosity()
|
||||
if v.LT(types.VerbosityLevelVerbose) || report.State.Is(types.SpecStatePending|types.SpecStateSkipped) || report.RunningInParallel {
|
||||
return
|
||||
}
|
||||
|
||||
r.emitDelimiter(0)
|
||||
r.emitBlock(r.f(r.codeLocationBlock(report, "{{/}}", v.Is(types.VerbosityLevelVeryVerbose), false)))
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) DidRun(report types.SpecReport) {
|
||||
v := r.conf.Verbosity()
|
||||
inParallel := report.RunningInParallel
|
||||
|
||||
header := r.specDenoter
|
||||
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
|
||||
header = fmt.Sprintf("[%s]", report.LeafNodeType)
|
||||
}
|
||||
highlightColor := r.highlightColorForState(report.State)
|
||||
|
||||
// have we already been streaming the timeline?
|
||||
timelineHasBeenStreaming := v.GTE(types.VerbosityLevelVerbose) && !inParallel
|
||||
|
||||
// should we show the timeline?
|
||||
var timeline types.Timeline
|
||||
showTimeline := !timelineHasBeenStreaming && (v.GTE(types.VerbosityLevelVerbose) || report.Failed())
|
||||
if showTimeline {
|
||||
timeline = report.Timeline().WithoutHiddenReportEntries()
|
||||
keepVeryVerboseSpecEvents := v.Is(types.VerbosityLevelVeryVerbose) ||
|
||||
(v.Is(types.VerbosityLevelVerbose) && r.conf.ShowNodeEvents) ||
|
||||
(report.Failed() && r.conf.ShowNodeEvents)
|
||||
if !keepVeryVerboseSpecEvents {
|
||||
timeline = timeline.WithoutVeryVerboseSpecEvents()
|
||||
}
|
||||
if len(timeline) == 0 && report.CapturedGinkgoWriterOutput == "" {
|
||||
// the timeline is completely empty - don't show it
|
||||
showTimeline = false
|
||||
}
|
||||
if v.LT(types.VerbosityLevelVeryVerbose) && report.CapturedGinkgoWriterOutput == "" && len(timeline) > 0 {
|
||||
//if we aren't -vv and the timeline only has a single failure, don't show it as it will appear at the end of the report
|
||||
failure, isFailure := timeline[0].(types.Failure)
|
||||
if isFailure && (len(timeline) == 1 || (len(timeline) == 2 && failure.AdditionalFailure != nil)) {
|
||||
showTimeline = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// should we have a separate section for always-visible reports?
|
||||
showSeparateVisibilityAlwaysReportsSection := !timelineHasBeenStreaming && !showTimeline && report.ReportEntries.HasVisibility(types.ReportEntryVisibilityAlways)
|
||||
|
||||
// should we have a separate section for captured stdout/stderr
|
||||
showSeparateStdSection := inParallel && (report.CapturedStdOutErr != "")
|
||||
|
||||
// given all that - do we have any actual content to show? or are we a single denoter in a stream?
|
||||
reportHasContent := v.Is(types.VerbosityLevelVeryVerbose) || showTimeline || showSeparateVisibilityAlwaysReportsSection || showSeparateStdSection || report.Failed() || (v.Is(types.VerbosityLevelVerbose) && !report.State.Is(types.SpecStateSkipped))
|
||||
|
||||
// should we show a runtime?
|
||||
includeRuntime := !report.State.Is(types.SpecStateSkipped|types.SpecStatePending) || (report.State.Is(types.SpecStateSkipped) && report.Failure.Message != "")
|
||||
|
||||
// should we show the codelocation block?
|
||||
showCodeLocation := !timelineHasBeenStreaming || !report.State.Is(types.SpecStatePassed)
|
||||
|
||||
switch report.State {
|
||||
case types.SpecStatePassed:
|
||||
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) && !reportHasContent {
|
||||
return
|
||||
}
|
||||
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
|
||||
header = fmt.Sprintf("%s PASSED", header)
|
||||
}
|
||||
if report.NumAttempts > 1 && report.MaxFlakeAttempts > 1 {
|
||||
header, reportHasContent = fmt.Sprintf("%s [FLAKEY TEST - TOOK %d ATTEMPTS TO PASS]", r.retryDenoter, report.NumAttempts), true
|
||||
}
|
||||
case types.SpecStatePending:
|
||||
header = "P"
|
||||
if v.GT(types.VerbosityLevelSuccinct) {
|
||||
header, reportHasContent = "P [PENDING]", true
|
||||
}
|
||||
case types.SpecStateSkipped:
|
||||
header = "S"
|
||||
if v.Is(types.VerbosityLevelVeryVerbose) || (v.Is(types.VerbosityLevelVerbose) && report.Failure.Message != "") {
|
||||
header, reportHasContent = "S [SKIPPED]", true
|
||||
}
|
||||
default:
|
||||
header = fmt.Sprintf("%s [%s]", header, r.humanReadableState(report.State))
|
||||
if report.MaxMustPassRepeatedly > 1 {
|
||||
header = fmt.Sprintf("%s DURING REPETITION #%d", header, report.NumAttempts)
|
||||
}
|
||||
}
|
||||
|
||||
// If we have no content to show, jsut emit the header and return
|
||||
if !reportHasContent {
|
||||
r.emit(r.f(highlightColor + header + "{{/}}"))
|
||||
return
|
||||
}
|
||||
|
||||
if includeRuntime {
|
||||
header = r.f("%s [%.3f seconds]", header, report.RunTime.Seconds())
|
||||
}
|
||||
|
||||
// Emit header
|
||||
if !timelineHasBeenStreaming {
|
||||
r.emitDelimiter(0)
|
||||
}
|
||||
r.emitBlock(r.f(highlightColor + header + "{{/}}"))
|
||||
if showCodeLocation {
|
||||
r.emitBlock(r.codeLocationBlock(report, highlightColor, v.Is(types.VerbosityLevelVeryVerbose), false))
|
||||
}
|
||||
|
||||
//Emit Stdout/Stderr Output
|
||||
if showSeparateStdSection {
|
||||
r.emitBlock("\n")
|
||||
r.emitBlock(r.fi(1, "{{gray}}Captured StdOut/StdErr Output >>{{/}}"))
|
||||
r.emitBlock(r.fi(1, "%s", report.CapturedStdOutErr))
|
||||
r.emitBlock(r.fi(1, "{{gray}}<< Captured StdOut/StdErr Output{{/}}"))
|
||||
}
|
||||
|
||||
if showSeparateVisibilityAlwaysReportsSection {
|
||||
r.emitBlock("\n")
|
||||
r.emitBlock(r.fi(1, "{{gray}}Report Entries >>{{/}}"))
|
||||
for _, entry := range report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways) {
|
||||
r.emitReportEntry(1, entry)
|
||||
}
|
||||
r.emitBlock(r.fi(1, "{{gray}}<< Report Entries{{/}}"))
|
||||
}
|
||||
|
||||
if showTimeline {
|
||||
r.emitBlock("\n")
|
||||
r.emitBlock(r.fi(1, "{{gray}}Timeline >>{{/}}"))
|
||||
r.emitTimeline(1, report, timeline)
|
||||
r.emitBlock(r.fi(1, "{{gray}}<< Timeline{{/}}"))
|
||||
}
|
||||
|
||||
// Emit Failure Message
|
||||
if !report.Failure.IsZero() && !v.Is(types.VerbosityLevelVeryVerbose) {
|
||||
r.emitBlock("\n")
|
||||
r.emitFailure(1, report.State, report.Failure, true)
|
||||
if len(report.AdditionalFailures) > 0 {
|
||||
r.emitBlock(r.fi(1, "\nThere were {{bold}}{{red}}additional failures{{/}} detected. To view them in detail run {{bold}}ginkgo -vv{{/}}"))
|
||||
}
|
||||
}
|
||||
|
||||
r.emitDelimiter(0)
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) highlightColorForState(state types.SpecState) string {
|
||||
switch state {
|
||||
case types.SpecStatePassed:
|
||||
return "{{green}}"
|
||||
case types.SpecStatePending:
|
||||
return "{{yellow}}"
|
||||
case types.SpecStateSkipped:
|
||||
return "{{cyan}}"
|
||||
case types.SpecStateFailed:
|
||||
return "{{red}}"
|
||||
case types.SpecStateTimedout:
|
||||
return "{{orange}}"
|
||||
case types.SpecStatePanicked:
|
||||
return "{{magenta}}"
|
||||
case types.SpecStateInterrupted:
|
||||
return "{{orange}}"
|
||||
case types.SpecStateAborted:
|
||||
return "{{coral}}"
|
||||
default:
|
||||
return "{{gray}}"
|
||||
}
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) humanReadableState(state types.SpecState) string {
|
||||
return strings.ToUpper(state.String())
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) emitTimeline(indent uint, report types.SpecReport, timeline types.Timeline) {
|
||||
isVeryVerbose := r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose)
|
||||
gw := report.CapturedGinkgoWriterOutput
|
||||
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) {
|
||||
r.emit(r.fi(indent, "%s", gw[cursor:]))
|
||||
cursor = len(gw)
|
||||
}
|
||||
switch x := entry.(type) {
|
||||
case types.Failure:
|
||||
if isVeryVerbose {
|
||||
r.emitFailure(indent, report.State, x, false)
|
||||
} else {
|
||||
r.emitShortFailure(indent, report.State, x)
|
||||
}
|
||||
case types.AdditionalFailure:
|
||||
if isVeryVerbose {
|
||||
r.emitFailure(indent, x.State, x.Failure, true)
|
||||
} else {
|
||||
r.emitShortFailure(indent, x.State, x.Failure)
|
||||
}
|
||||
case types.ReportEntry:
|
||||
r.emitReportEntry(indent, x)
|
||||
case types.ProgressReport:
|
||||
r.emitProgressReport(indent, false, x)
|
||||
case types.SpecEvent:
|
||||
if isVeryVerbose || !x.IsOnlyVisibleAtVeryVerbose() || r.conf.ShowNodeEvents {
|
||||
r.emitSpecEvent(indent, x, isVeryVerbose)
|
||||
}
|
||||
}
|
||||
}
|
||||
if cursor < len(gw) {
|
||||
r.emit(r.fi(indent, "%s", gw[cursor:]))
|
||||
}
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) EmitFailure(state types.SpecState, failure types.Failure) {
|
||||
if r.conf.Verbosity().Is(types.VerbosityLevelVerbose) {
|
||||
r.emitShortFailure(1, state, failure)
|
||||
} else if r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose) {
|
||||
r.emitFailure(1, state, failure, true)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) emitShortFailure(indent uint, state types.SpecState, failure types.Failure) {
|
||||
r.emitBlock(r.fi(indent, r.highlightColorForState(state)+"[%s]{{/}} in [%s] - %s {{gray}}@ %s{{/}}",
|
||||
r.humanReadableState(state),
|
||||
failure.FailureNodeType,
|
||||
failure.Location,
|
||||
failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT),
|
||||
))
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) emitFailure(indent uint, state types.SpecState, failure types.Failure, includeAdditionalFailure bool) {
|
||||
highlightColor := r.highlightColorForState(state)
|
||||
r.emitBlock(r.fi(indent, highlightColor+"[%s] %s{{/}}", r.humanReadableState(state), failure.Message))
|
||||
r.emitBlock(r.fi(indent, highlightColor+"In {{bold}}[%s]{{/}}"+highlightColor+" at: {{bold}}%s{{/}} {{gray}}@ %s{{/}}\n", failure.FailureNodeType, failure.Location, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT)))
|
||||
if failure.ForwardedPanic != "" {
|
||||
r.emitBlock("\n")
|
||||
r.emitBlock(r.fi(indent, highlightColor+"%s{{/}}", failure.ForwardedPanic))
|
||||
}
|
||||
|
||||
if r.conf.FullTrace || failure.ForwardedPanic != "" {
|
||||
r.emitBlock("\n")
|
||||
r.emitBlock(r.fi(indent, highlightColor+"Full Stack Trace{{/}}"))
|
||||
r.emitBlock(r.fi(indent+1, "%s", failure.Location.FullStackTrace))
|
||||
}
|
||||
|
||||
if !failure.ProgressReport.IsZero() {
|
||||
r.emitBlock("\n")
|
||||
r.emitProgressReport(indent, false, failure.ProgressReport)
|
||||
}
|
||||
|
||||
if failure.AdditionalFailure != nil && includeAdditionalFailure {
|
||||
r.emitBlock("\n")
|
||||
r.emitFailure(indent, failure.AdditionalFailure.State, failure.AdditionalFailure.Failure, true)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) EmitProgressReport(report types.ProgressReport) {
|
||||
r.emitDelimiter()
|
||||
r.emitDelimiter(1)
|
||||
|
||||
if report.RunningInParallel {
|
||||
r.emit(r.f("{{coral}}Progress Report for Ginkgo Process #{{bold}}%d{{/}}\n", report.ParallelProcess))
|
||||
r.emit(r.fi(1, "{{coral}}Progress Report for Ginkgo Process #{{bold}}%d{{/}}\n", report.ParallelProcess))
|
||||
}
|
||||
r.emitProgressReport(0, true, report)
|
||||
r.emitDelimiter()
|
||||
shouldEmitGW := report.RunningInParallel || r.conf.Verbosity().LT(types.VerbosityLevelVerbose)
|
||||
r.emitProgressReport(1, shouldEmitGW, report)
|
||||
r.emitDelimiter(1)
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput bool, report types.ProgressReport) {
|
||||
@@ -409,7 +451,7 @@ func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput
|
||||
r.emit(" ")
|
||||
subjectIndent = 0
|
||||
}
|
||||
r.emit(r.fi(subjectIndent, "{{bold}}{{orange}}%s{{/}} (Spec Runtime: %s)\n", report.LeafNodeText, report.Time.Sub(report.SpecStartTime).Round(time.Millisecond)))
|
||||
r.emit(r.fi(subjectIndent, "{{bold}}{{orange}}%s{{/}} (Spec Runtime: %s)\n", report.LeafNodeText, report.Time().Sub(report.SpecStartTime).Round(time.Millisecond)))
|
||||
r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.LeafNodeLocation))
|
||||
indent += 1
|
||||
}
|
||||
@@ -419,12 +461,12 @@ func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput
|
||||
r.emit(r.f(" {{bold}}{{orange}}%s{{/}}", report.CurrentNodeText))
|
||||
}
|
||||
|
||||
r.emit(r.f(" (Node Runtime: %s)\n", report.Time.Sub(report.CurrentNodeStartTime).Round(time.Millisecond)))
|
||||
r.emit(r.f(" (Node Runtime: %s)\n", report.Time().Sub(report.CurrentNodeStartTime).Round(time.Millisecond)))
|
||||
r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.CurrentNodeLocation))
|
||||
indent += 1
|
||||
}
|
||||
if report.CurrentStepText != "" {
|
||||
r.emit(r.fi(indent, "At {{bold}}{{orange}}[By Step] %s{{/}} (Step Runtime: %s)\n", report.CurrentStepText, report.Time.Sub(report.CurrentStepStartTime).Round(time.Millisecond)))
|
||||
r.emit(r.fi(indent, "At {{bold}}{{orange}}[By Step] %s{{/}} (Step Runtime: %s)\n", report.CurrentStepText, report.Time().Sub(report.CurrentStepStartTime).Round(time.Millisecond)))
|
||||
r.emit(r.fi(indent+1, "{{gray}}%s{{/}}\n", report.CurrentStepLocation))
|
||||
indent += 1
|
||||
}
|
||||
@@ -433,9 +475,19 @@ func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput
|
||||
indent -= 1
|
||||
}
|
||||
|
||||
if emitGinkgoWriterOutput && report.CapturedGinkgoWriterOutput != "" && (report.RunningInParallel || r.conf.Verbosity().LT(types.VerbosityLevelVerbose)) {
|
||||
if emitGinkgoWriterOutput && report.CapturedGinkgoWriterOutput != "" {
|
||||
r.emit("\n")
|
||||
r.emitGinkgoWriterOutput(indent, report.CapturedGinkgoWriterOutput, 10)
|
||||
r.emitBlock(r.fi(indent, "{{gray}}Begin Captured GinkgoWriter Output >>{{/}}"))
|
||||
limit, lines := 10, strings.Split(report.CapturedGinkgoWriterOutput, "\n")
|
||||
if len(lines) <= limit {
|
||||
r.emitBlock(r.fi(indent+1, "%s", report.CapturedGinkgoWriterOutput))
|
||||
} else {
|
||||
r.emitBlock(r.fi(indent+1, "{{gray}}...{{/}}"))
|
||||
for _, line := range lines[len(lines)-limit-1:] {
|
||||
r.emitBlock(r.fi(indent+1, "%s", line))
|
||||
}
|
||||
}
|
||||
r.emitBlock(r.fi(indent, "{{gray}}<< End Captured GinkgoWriter Output{{/}}"))
|
||||
}
|
||||
|
||||
if !report.SpecGoroutine().IsZero() {
|
||||
@@ -471,22 +523,48 @@ func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput
|
||||
}
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) emitGinkgoWriterOutput(indent uint, output string, limit int) {
|
||||
r.emitBlock(r.fi(indent, "{{gray}}Begin Captured GinkgoWriter Output >>{{/}}"))
|
||||
if limit == 0 {
|
||||
r.emitBlock(r.fi(indent+1, "%s", output))
|
||||
} else {
|
||||
lines := strings.Split(output, "\n")
|
||||
if len(lines) <= limit {
|
||||
r.emitBlock(r.fi(indent+1, "%s", output))
|
||||
} else {
|
||||
r.emitBlock(r.fi(indent+1, "{{gray}}...{{/}}"))
|
||||
for _, line := range lines[len(lines)-limit-1:] {
|
||||
r.emitBlock(r.fi(indent+1, "%s", line))
|
||||
}
|
||||
}
|
||||
func (r *DefaultReporter) EmitReportEntry(entry types.ReportEntry) {
|
||||
if r.conf.Verbosity().LT(types.VerbosityLevelVerbose) || entry.Visibility == types.ReportEntryVisibilityNever {
|
||||
return
|
||||
}
|
||||
r.emitReportEntry(1, entry)
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) emitReportEntry(indent uint, entry types.ReportEntry) {
|
||||
r.emitBlock(r.fi(indent, "{{bold}}"+entry.Name+"{{gray}} "+fmt.Sprintf("- %s @ %s{{/}}", entry.Location, entry.Time.Format(types.GINKGO_TIME_FORMAT))))
|
||||
if representation := entry.StringRepresentation(); representation != "" {
|
||||
r.emitBlock(r.fi(indent+1, representation))
|
||||
}
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) EmitSpecEvent(event types.SpecEvent) {
|
||||
v := r.conf.Verbosity()
|
||||
if v.Is(types.VerbosityLevelVeryVerbose) || (v.Is(types.VerbosityLevelVerbose) && (r.conf.ShowNodeEvents || !event.IsOnlyVisibleAtVeryVerbose())) {
|
||||
r.emitSpecEvent(1, event, r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose))
|
||||
}
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) emitSpecEvent(indent uint, event types.SpecEvent, includeLocation bool) {
|
||||
location := ""
|
||||
if includeLocation {
|
||||
location = fmt.Sprintf("- %s ", event.CodeLocation.String())
|
||||
}
|
||||
switch event.SpecEventType {
|
||||
case types.SpecEventInvalid:
|
||||
return
|
||||
case types.SpecEventByStart:
|
||||
r.emitBlock(r.fi(indent, "{{bold}}STEP:{{/}} %s {{gray}}%s@ %s{{/}}", event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT)))
|
||||
case types.SpecEventByEnd:
|
||||
r.emitBlock(r.fi(indent, "{{bold}}END STEP:{{/}} %s {{gray}}%s@ %s (%s){{/}}", event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), event.Duration.Round(time.Millisecond)))
|
||||
case types.SpecEventNodeStart:
|
||||
r.emitBlock(r.fi(indent, "> Enter {{bold}}[%s]{{/}} %s {{gray}}%s@ %s{{/}}", event.NodeType.String(), event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT)))
|
||||
case types.SpecEventNodeEnd:
|
||||
r.emitBlock(r.fi(indent, "< Exit {{bold}}[%s]{{/}} %s {{gray}}%s@ %s (%s){{/}}", event.NodeType.String(), event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), event.Duration.Round(time.Millisecond)))
|
||||
case types.SpecEventSpecRepeat:
|
||||
r.emitBlock(r.fi(indent, "\n{{bold}}Attempt #%d {{green}}Passed{{/}}{{bold}}. Repeating %s{{/}} {{gray}}@ %s{{/}}\n\n", event.Attempt, r.retryDenoter, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT)))
|
||||
case types.SpecEventSpecRetry:
|
||||
r.emitBlock(r.fi(indent, "\n{{bold}}Attempt #%d {{red}}Failed{{/}}{{bold}}. Retrying %s{{/}} {{gray}}@ %s{{/}}\n\n", event.Attempt, r.retryDenoter, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT)))
|
||||
}
|
||||
r.emitBlock(r.fi(indent, "{{gray}}<< End Captured GinkgoWriter Output{{/}}"))
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) emitGoroutines(indent uint, goroutines ...types.Goroutine) {
|
||||
@@ -544,31 +622,37 @@ func (r *DefaultReporter) emitSource(indent uint, fc types.FunctionCall) {
|
||||
|
||||
/* Emitting to the writer */
|
||||
func (r *DefaultReporter) emit(s string) {
|
||||
if len(s) > 0 {
|
||||
r.lastChar = s[len(s)-1:]
|
||||
r.lastEmissionWasDelimiter = false
|
||||
r.writer.Write([]byte(s))
|
||||
}
|
||||
r._emit(s, false, false)
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) emitBlock(s string) {
|
||||
if len(s) > 0 {
|
||||
if r.lastChar != "\n" {
|
||||
r.emit("\n")
|
||||
}
|
||||
r.emit(s)
|
||||
if r.lastChar != "\n" {
|
||||
r.emit("\n")
|
||||
}
|
||||
}
|
||||
r._emit(s, true, false)
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) emitDelimiter() {
|
||||
if r.lastEmissionWasDelimiter {
|
||||
func (r *DefaultReporter) emitDelimiter(indent uint) {
|
||||
r._emit(r.fi(indent, "{{gray}}%s{{/}}", strings.Repeat("-", 30)), true, true)
|
||||
}
|
||||
|
||||
// a bit ugly - but we're trying to minimize locking on this hot codepath
|
||||
func (r *DefaultReporter) _emit(s string, block bool, isDelimiter bool) {
|
||||
if len(s) == 0 {
|
||||
return
|
||||
}
|
||||
r.emitBlock(r.f("{{gray}}%s{{/}}", strings.Repeat("-", 30)))
|
||||
r.lastEmissionWasDelimiter = true
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
if isDelimiter && r.lastEmissionWasDelimiter {
|
||||
return
|
||||
}
|
||||
if block && !r.lastCharWasNewline {
|
||||
r.writer.Write([]byte("\n"))
|
||||
}
|
||||
r.lastCharWasNewline = (s[len(s)-1:] == "\n")
|
||||
r.writer.Write([]byte(s))
|
||||
if block && !r.lastCharWasNewline {
|
||||
r.writer.Write([]byte("\n"))
|
||||
r.lastCharWasNewline = true
|
||||
}
|
||||
r.lastEmissionWasDelimiter = isDelimiter
|
||||
}
|
||||
|
||||
/* Rendering text */
|
||||
@@ -584,13 +668,14 @@ func (r *DefaultReporter) cycleJoin(elements []string, joiner string) string {
|
||||
return r.formatter.CycleJoin(elements, joiner, []string{"{{/}}", "{{gray}}"})
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, succinct bool, usePreciseFailureLocation bool) string {
|
||||
func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, veryVerbose bool, usePreciseFailureLocation bool) string {
|
||||
texts, locations, labels := []string{}, []types.CodeLocation{}, [][]string{}
|
||||
texts, locations, labels = append(texts, report.ContainerHierarchyTexts...), append(locations, report.ContainerHierarchyLocations...), append(labels, report.ContainerHierarchyLabels...)
|
||||
|
||||
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
|
||||
texts = append(texts, r.f("[%s] %s", report.LeafNodeType, report.LeafNodeText))
|
||||
} else {
|
||||
texts = append(texts, report.LeafNodeText)
|
||||
texts = append(texts, r.f(report.LeafNodeText))
|
||||
}
|
||||
labels = append(labels, report.LeafNodeLabels)
|
||||
locations = append(locations, report.LeafNodeLocation)
|
||||
@@ -600,24 +685,58 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
|
||||
failureLocation = report.Failure.Location
|
||||
}
|
||||
|
||||
highlightIndex := -1
|
||||
switch report.Failure.FailureNodeContext {
|
||||
case types.FailureNodeAtTopLevel:
|
||||
texts = append([]string{r.f(highlightColor+"{{bold}}TOP-LEVEL [%s]{{/}}", report.Failure.FailureNodeType)}, texts...)
|
||||
texts = append([]string{fmt.Sprintf("TOP-LEVEL [%s]", report.Failure.FailureNodeType)}, texts...)
|
||||
locations = append([]types.CodeLocation{failureLocation}, locations...)
|
||||
labels = append([][]string{{}}, labels...)
|
||||
highlightIndex = 0
|
||||
case types.FailureNodeInContainer:
|
||||
i := report.Failure.FailureNodeContainerIndex
|
||||
texts[i] = r.f(highlightColor+"{{bold}}%s [%s]{{/}}", texts[i], report.Failure.FailureNodeType)
|
||||
texts[i] = fmt.Sprintf("%s [%s]", texts[i], report.Failure.FailureNodeType)
|
||||
locations[i] = failureLocation
|
||||
highlightIndex = i
|
||||
case types.FailureNodeIsLeafNode:
|
||||
i := len(texts) - 1
|
||||
texts[i] = r.f(highlightColor+"{{bold}}[%s] %s{{/}}", report.LeafNodeType, report.LeafNodeText)
|
||||
texts[i] = fmt.Sprintf("[%s] %s", report.LeafNodeType, report.LeafNodeText)
|
||||
locations[i] = failureLocation
|
||||
highlightIndex = i
|
||||
default:
|
||||
//there is no failure, so we highlight the leaf ndoe
|
||||
highlightIndex = len(texts) - 1
|
||||
}
|
||||
|
||||
out := ""
|
||||
if succinct {
|
||||
out += r.f("%s", r.cycleJoin(texts, " "))
|
||||
if veryVerbose {
|
||||
for i := range texts {
|
||||
if i == highlightIndex {
|
||||
out += r.fi(uint(i), highlightColor+"{{bold}}%s{{/}}", texts[i])
|
||||
} else {
|
||||
out += r.fi(uint(i), "%s", texts[i])
|
||||
}
|
||||
if len(labels[i]) > 0 {
|
||||
out += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels[i], ", "))
|
||||
}
|
||||
out += "\n"
|
||||
out += r.fi(uint(i), "{{gray}}%s{{/}}\n", locations[i])
|
||||
}
|
||||
} else {
|
||||
for i := range texts {
|
||||
style := "{{/}}"
|
||||
if i%2 == 1 {
|
||||
style = "{{gray}}"
|
||||
}
|
||||
if i == highlightIndex {
|
||||
style = highlightColor + "{{bold}}"
|
||||
}
|
||||
out += r.f(style+"%s", texts[i])
|
||||
if i < len(texts)-1 {
|
||||
out += " "
|
||||
} else {
|
||||
out += r.f("{{/}}")
|
||||
}
|
||||
}
|
||||
flattenedLabels := report.Labels()
|
||||
if len(flattenedLabels) > 0 {
|
||||
out += r.f(" {{coral}}[%s]{{/}}", strings.Join(flattenedLabels, ", "))
|
||||
@@ -626,17 +745,15 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
|
||||
if usePreciseFailureLocation {
|
||||
out += r.f("{{gray}}%s{{/}}", failureLocation)
|
||||
} else {
|
||||
out += r.f("{{gray}}%s{{/}}", locations[len(locations)-1])
|
||||
}
|
||||
} else {
|
||||
for i := range texts {
|
||||
out += r.fi(uint(i), "%s", texts[i])
|
||||
if len(labels[i]) > 0 {
|
||||
out += r.f(" {{coral}}[%s]{{/}}", strings.Join(labels[i], ", "))
|
||||
leafLocation := locations[len(locations)-1]
|
||||
if (report.Failure.FailureNodeLocation != types.CodeLocation{}) && (report.Failure.FailureNodeLocation != leafLocation) {
|
||||
out += r.fi(1, highlightColor+"[%s]{{/}} {{gray}}%s{{/}}\n", report.Failure.FailureNodeType, report.Failure.FailureNodeLocation)
|
||||
out += r.fi(1, "{{gray}}[%s] %s{{/}}", report.LeafNodeType, leafLocation)
|
||||
} else {
|
||||
out += r.f("{{gray}}%s{{/}}", leafLocation)
|
||||
}
|
||||
out += "\n"
|
||||
out += r.fi(uint(i), "{{gray}}%s{{/}}\n", locations[i])
|
||||
}
|
||||
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
2
vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go
generated
vendored
2
vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go
generated
vendored
@@ -35,7 +35,7 @@ func ReportViaDeprecatedReporter(reporter DeprecatedReporter, report types.Repor
|
||||
FailOnPending: report.SuiteConfig.FailOnPending,
|
||||
FailFast: report.SuiteConfig.FailFast,
|
||||
FlakeAttempts: report.SuiteConfig.FlakeAttempts,
|
||||
EmitSpecProgress: report.SuiteConfig.EmitSpecProgress,
|
||||
EmitSpecProgress: false,
|
||||
DryRun: report.SuiteConfig.DryRun,
|
||||
ParallelNode: report.SuiteConfig.ParallelProcess,
|
||||
ParallelTotal: report.SuiteConfig.ParallelTotal,
|
||||
|
113
vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
generated
vendored
113
vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
generated
vendored
@@ -15,12 +15,32 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/onsi/ginkgo/v2/config"
|
||||
"github.com/onsi/ginkgo/v2/types"
|
||||
)
|
||||
|
||||
type JunitReportConfig struct {
|
||||
// Spec States for which no timeline should be emitted for system-err
|
||||
// set this to types.SpecStatePassed|types.SpecStateSkipped|types.SpecStatePending to only match failing specs
|
||||
OmitTimelinesForSpecState types.SpecState
|
||||
|
||||
// Enable OmitFailureMessageAttr to prevent failure messages appearing in the "message" attribute of the Failure and Error tags
|
||||
OmitFailureMessageAttr bool
|
||||
|
||||
//Enable OmitCapturedStdOutErr to prevent captured stdout/stderr appearing in system-out
|
||||
OmitCapturedStdOutErr bool
|
||||
|
||||
// Enable OmitSpecLabels to prevent labels from appearing in the spec name
|
||||
OmitSpecLabels bool
|
||||
|
||||
// Enable OmitLeafNodeType to prevent the spec leaf node type from appearing in the spec name
|
||||
OmitLeafNodeType bool
|
||||
|
||||
// Enable OmitSuiteSetupNodes to prevent the creation of testcase entries for setup nodes
|
||||
OmitSuiteSetupNodes bool
|
||||
}
|
||||
|
||||
type JUnitTestSuites struct {
|
||||
XMLName xml.Name `xml:"testsuites"`
|
||||
// Tests maps onto the total number of specs in all test suites (this includes any suite nodes such as BeforeSuite)
|
||||
@@ -128,6 +148,10 @@ type JUnitFailure struct {
|
||||
}
|
||||
|
||||
func GenerateJUnitReport(report types.Report, dst string) error {
|
||||
return GenerateJUnitReportWithConfig(report, dst, JunitReportConfig{})
|
||||
}
|
||||
|
||||
func GenerateJUnitReportWithConfig(report types.Report, dst string, config JunitReportConfig) error {
|
||||
suite := JUnitTestSuite{
|
||||
Name: report.SuiteDescription,
|
||||
Package: report.SuitePath,
|
||||
@@ -149,7 +173,6 @@ func GenerateJUnitReport(report types.Report, dst string) error {
|
||||
{"FailOnPending", fmt.Sprintf("%t", report.SuiteConfig.FailOnPending)},
|
||||
{"FailFast", fmt.Sprintf("%t", report.SuiteConfig.FailFast)},
|
||||
{"FlakeAttempts", fmt.Sprintf("%d", report.SuiteConfig.FlakeAttempts)},
|
||||
{"EmitSpecProgress", fmt.Sprintf("%t", report.SuiteConfig.EmitSpecProgress)},
|
||||
{"DryRun", fmt.Sprintf("%t", report.SuiteConfig.DryRun)},
|
||||
{"ParallelTotal", fmt.Sprintf("%d", report.SuiteConfig.ParallelTotal)},
|
||||
{"OutputInterceptorMode", report.SuiteConfig.OutputInterceptorMode},
|
||||
@@ -157,22 +180,33 @@ func GenerateJUnitReport(report types.Report, dst string) error {
|
||||
},
|
||||
}
|
||||
for _, spec := range report.SpecReports {
|
||||
if config.OmitSuiteSetupNodes && spec.LeafNodeType != types.NodeTypeIt {
|
||||
continue
|
||||
}
|
||||
name := fmt.Sprintf("[%s]", spec.LeafNodeType)
|
||||
if config.OmitLeafNodeType {
|
||||
name = ""
|
||||
}
|
||||
if spec.FullText() != "" {
|
||||
name = name + " " + spec.FullText()
|
||||
}
|
||||
labels := spec.Labels()
|
||||
if len(labels) > 0 {
|
||||
if len(labels) > 0 && !config.OmitSpecLabels {
|
||||
name = name + " [" + strings.Join(labels, ", ") + "]"
|
||||
}
|
||||
name = strings.TrimSpace(name)
|
||||
|
||||
test := JUnitTestCase{
|
||||
Name: name,
|
||||
Classname: report.SuiteDescription,
|
||||
Status: spec.State.String(),
|
||||
Time: spec.RunTime.Seconds(),
|
||||
SystemOut: systemOutForUnstructuredReporters(spec),
|
||||
SystemErr: systemErrForUnstructuredReporters(spec),
|
||||
}
|
||||
if !spec.State.Is(config.OmitTimelinesForSpecState) {
|
||||
test.SystemErr = systemErrForUnstructuredReporters(spec)
|
||||
}
|
||||
if !config.OmitCapturedStdOutErr {
|
||||
test.SystemOut = systemOutForUnstructuredReporters(spec)
|
||||
}
|
||||
suite.Tests += 1
|
||||
|
||||
@@ -193,6 +227,9 @@ func GenerateJUnitReport(report types.Report, dst string) error {
|
||||
Type: "failed",
|
||||
Description: failureDescriptionForUnstructuredReporters(spec),
|
||||
}
|
||||
if config.OmitFailureMessageAttr {
|
||||
test.Failure.Message = ""
|
||||
}
|
||||
suite.Failures += 1
|
||||
case types.SpecStateTimedout:
|
||||
test.Failure = &JUnitFailure{
|
||||
@@ -200,6 +237,9 @@ func GenerateJUnitReport(report types.Report, dst string) error {
|
||||
Type: "timedout",
|
||||
Description: failureDescriptionForUnstructuredReporters(spec),
|
||||
}
|
||||
if config.OmitFailureMessageAttr {
|
||||
test.Failure.Message = ""
|
||||
}
|
||||
suite.Failures += 1
|
||||
case types.SpecStateInterrupted:
|
||||
test.Error = &JUnitError{
|
||||
@@ -207,6 +247,9 @@ func GenerateJUnitReport(report types.Report, dst string) error {
|
||||
Type: "interrupted",
|
||||
Description: failureDescriptionForUnstructuredReporters(spec),
|
||||
}
|
||||
if config.OmitFailureMessageAttr {
|
||||
test.Error.Message = ""
|
||||
}
|
||||
suite.Errors += 1
|
||||
case types.SpecStateAborted:
|
||||
test.Failure = &JUnitFailure{
|
||||
@@ -214,6 +257,9 @@ func GenerateJUnitReport(report types.Report, dst string) error {
|
||||
Type: "aborted",
|
||||
Description: failureDescriptionForUnstructuredReporters(spec),
|
||||
}
|
||||
if config.OmitFailureMessageAttr {
|
||||
test.Failure.Message = ""
|
||||
}
|
||||
suite.Errors += 1
|
||||
case types.SpecStatePanicked:
|
||||
test.Error = &JUnitError{
|
||||
@@ -221,6 +267,9 @@ func GenerateJUnitReport(report types.Report, dst string) error {
|
||||
Type: "panicked",
|
||||
Description: failureDescriptionForUnstructuredReporters(spec),
|
||||
}
|
||||
if config.OmitFailureMessageAttr {
|
||||
test.Error.Message = ""
|
||||
}
|
||||
suite.Errors += 1
|
||||
}
|
||||
|
||||
@@ -287,63 +336,25 @@ func MergeAndCleanupJUnitReports(sources []string, dst string) ([]string, error)
|
||||
|
||||
func failureDescriptionForUnstructuredReporters(spec types.SpecReport) string {
|
||||
out := &strings.Builder{}
|
||||
out.WriteString(spec.Failure.Location.String() + "\n")
|
||||
out.WriteString(spec.Failure.Location.FullStackTrace)
|
||||
if !spec.Failure.ProgressReport.IsZero() {
|
||||
out.WriteString("\n")
|
||||
NewDefaultReporter(types.ReporterConfig{NoColor: true}, out).EmitProgressReport(spec.Failure.ProgressReport)
|
||||
}
|
||||
NewDefaultReporter(types.ReporterConfig{NoColor: true, VeryVerbose: true}, out).emitFailure(0, spec.State, spec.Failure, true)
|
||||
if len(spec.AdditionalFailures) > 0 {
|
||||
out.WriteString("\nThere were additional failures detected after the initial failure:\n")
|
||||
for i, additionalFailure := range spec.AdditionalFailures {
|
||||
NewDefaultReporter(types.ReporterConfig{NoColor: true}, out).EmitFailure(0, additionalFailure.State, additionalFailure.Failure, true)
|
||||
if i < len(spec.AdditionalFailures)-1 {
|
||||
out.WriteString("----------\n")
|
||||
}
|
||||
}
|
||||
out.WriteString("\nThere were additional failures detected after the initial failure. These are visible in the timeline\n")
|
||||
}
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func systemErrForUnstructuredReporters(spec types.SpecReport) string {
|
||||
return RenderTimeline(spec, true)
|
||||
}
|
||||
|
||||
func RenderTimeline(spec types.SpecReport, noColor bool) string {
|
||||
out := &strings.Builder{}
|
||||
gw := spec.CapturedGinkgoWriterOutput
|
||||
cursor := 0
|
||||
for _, pr := range spec.ProgressReports {
|
||||
if cursor < pr.GinkgoWriterOffset {
|
||||
if pr.GinkgoWriterOffset < len(gw) {
|
||||
out.WriteString(gw[cursor:pr.GinkgoWriterOffset])
|
||||
cursor = pr.GinkgoWriterOffset
|
||||
} else if cursor < len(gw) {
|
||||
out.WriteString(gw[cursor:])
|
||||
cursor = len(gw)
|
||||
}
|
||||
}
|
||||
NewDefaultReporter(types.ReporterConfig{NoColor: true}, out).EmitProgressReport(pr)
|
||||
}
|
||||
|
||||
if cursor < len(gw) {
|
||||
out.WriteString(gw[cursor:])
|
||||
}
|
||||
|
||||
NewDefaultReporter(types.ReporterConfig{NoColor: noColor, VeryVerbose: true}, out).emitTimeline(0, spec, spec.Timeline())
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func systemOutForUnstructuredReporters(spec types.SpecReport) string {
|
||||
systemOut := spec.CapturedStdOutErr
|
||||
if len(spec.ReportEntries) > 0 {
|
||||
systemOut += "\nReport Entries:\n"
|
||||
for i, entry := range spec.ReportEntries {
|
||||
systemOut += fmt.Sprintf("%s\n%s\n%s\n", entry.Name, entry.Location, entry.Time.Format(time.RFC3339Nano))
|
||||
if representation := entry.StringRepresentation(); representation != "" {
|
||||
systemOut += representation + "\n"
|
||||
}
|
||||
if i+1 < len(spec.ReportEntries) {
|
||||
systemOut += "--\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
return systemOut
|
||||
return spec.CapturedStdOutErr
|
||||
}
|
||||
|
||||
// Deprecated JUnitReporter (so folks can still compile their suites)
|
||||
|
18
vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go
generated
vendored
18
vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go
generated
vendored
@@ -9,13 +9,21 @@ type Reporter interface {
|
||||
WillRun(report types.SpecReport)
|
||||
DidRun(report types.SpecReport)
|
||||
SuiteDidEnd(report types.Report)
|
||||
|
||||
//Timeline emission
|
||||
EmitFailure(state types.SpecState, failure types.Failure)
|
||||
EmitProgressReport(progressReport types.ProgressReport)
|
||||
EmitReportEntry(entry types.ReportEntry)
|
||||
EmitSpecEvent(event types.SpecEvent)
|
||||
}
|
||||
|
||||
type NoopReporter struct{}
|
||||
|
||||
func (n NoopReporter) SuiteWillBegin(report types.Report) {}
|
||||
func (n NoopReporter) WillRun(report types.SpecReport) {}
|
||||
func (n NoopReporter) DidRun(report types.SpecReport) {}
|
||||
func (n NoopReporter) SuiteDidEnd(report types.Report) {}
|
||||
func (n NoopReporter) EmitProgressReport(progressReport types.ProgressReport) {}
|
||||
func (n NoopReporter) SuiteWillBegin(report types.Report) {}
|
||||
func (n NoopReporter) WillRun(report types.SpecReport) {}
|
||||
func (n NoopReporter) DidRun(report types.SpecReport) {}
|
||||
func (n NoopReporter) SuiteDidEnd(report types.Report) {}
|
||||
func (n NoopReporter) EmitFailure(state types.SpecState, failure types.Failure) {}
|
||||
func (n NoopReporter) EmitProgressReport(progressReport types.ProgressReport) {}
|
||||
func (n NoopReporter) EmitReportEntry(entry types.ReportEntry) {}
|
||||
func (n NoopReporter) EmitSpecEvent(event types.SpecEvent) {}
|
||||
|
78
vendor/github.com/onsi/ginkgo/v2/types/code_location.go
generated
vendored
78
vendor/github.com/onsi/ginkgo/v2/types/code_location.go
generated
vendored
@@ -1,4 +1,5 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -6,6 +7,7 @@ import (
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type CodeLocation struct {
|
||||
@@ -37,6 +39,73 @@ func (codeLocation CodeLocation) ContentsOfLine() string {
|
||||
return lines[codeLocation.LineNumber-1]
|
||||
}
|
||||
|
||||
type codeLocationLocator struct {
|
||||
pcs map[uintptr]bool
|
||||
helpers map[string]bool
|
||||
lock *sync.Mutex
|
||||
}
|
||||
|
||||
func (c *codeLocationLocator) addHelper(pc uintptr) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
if c.pcs[pc] {
|
||||
return
|
||||
}
|
||||
c.lock.Unlock()
|
||||
f := runtime.FuncForPC(pc)
|
||||
c.lock.Lock()
|
||||
if f == nil {
|
||||
return
|
||||
}
|
||||
c.helpers[f.Name()] = true
|
||||
c.pcs[pc] = true
|
||||
}
|
||||
|
||||
func (c *codeLocationLocator) hasHelper(name string) bool {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
return c.helpers[name]
|
||||
}
|
||||
|
||||
func (c *codeLocationLocator) getCodeLocation(skip int) CodeLocation {
|
||||
pc := make([]uintptr, 40)
|
||||
n := runtime.Callers(skip+2, pc)
|
||||
if n == 0 {
|
||||
return CodeLocation{}
|
||||
}
|
||||
pc = pc[:n]
|
||||
frames := runtime.CallersFrames(pc)
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
if !c.hasHelper(frame.Function) {
|
||||
return CodeLocation{FileName: frame.File, LineNumber: frame.Line}
|
||||
}
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
return CodeLocation{}
|
||||
}
|
||||
|
||||
var clLocator = &codeLocationLocator{
|
||||
pcs: map[uintptr]bool{},
|
||||
helpers: map[string]bool{},
|
||||
lock: &sync.Mutex{},
|
||||
}
|
||||
|
||||
// MarkAsHelper is used by GinkgoHelper to mark the caller (appropriately offset by skip)as a helper. You can use this directly if you need to provide an optional `skip` to mark functions further up the call stack as helpers.
|
||||
func MarkAsHelper(optionalSkip ...int) {
|
||||
skip := 1
|
||||
if len(optionalSkip) > 0 {
|
||||
skip += optionalSkip[0]
|
||||
}
|
||||
pc, _, _, ok := runtime.Caller(skip)
|
||||
if ok {
|
||||
clLocator.addHelper(pc)
|
||||
}
|
||||
}
|
||||
|
||||
func NewCustomCodeLocation(message string) CodeLocation {
|
||||
return CodeLocation{
|
||||
CustomMessage: message,
|
||||
@@ -44,14 +113,13 @@ func NewCustomCodeLocation(message string) CodeLocation {
|
||||
}
|
||||
|
||||
func NewCodeLocation(skip int) CodeLocation {
|
||||
_, file, line, _ := runtime.Caller(skip + 1)
|
||||
return CodeLocation{FileName: file, LineNumber: line}
|
||||
return clLocator.getCodeLocation(skip + 1)
|
||||
}
|
||||
|
||||
func NewCodeLocationWithStackTrace(skip int) CodeLocation {
|
||||
_, file, line, _ := runtime.Caller(skip + 1)
|
||||
stackTrace := PruneStack(string(debug.Stack()), skip+1)
|
||||
return CodeLocation{FileName: file, LineNumber: line, FullStackTrace: stackTrace}
|
||||
cl := clLocator.getCodeLocation(skip + 1)
|
||||
cl.FullStackTrace = PruneStack(string(debug.Stack()), skip+1)
|
||||
return cl
|
||||
}
|
||||
|
||||
// PruneStack removes references to functions that are internal to Ginkgo
|
||||
|
53
vendor/github.com/onsi/ginkgo/v2/types/config.go
generated
vendored
53
vendor/github.com/onsi/ginkgo/v2/types/config.go
generated
vendored
@@ -8,6 +8,7 @@ package types
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -26,11 +27,11 @@ type SuiteConfig struct {
|
||||
FailOnPending bool
|
||||
FailFast bool
|
||||
FlakeAttempts int
|
||||
EmitSpecProgress bool
|
||||
DryRun bool
|
||||
PollProgressAfter time.Duration
|
||||
PollProgressInterval time.Duration
|
||||
Timeout time.Duration
|
||||
EmitSpecProgress bool // this is deprecated but its removal is causing compile issue for some users that were setting it manually
|
||||
OutputInterceptorMode string
|
||||
SourceRoots []string
|
||||
GracePeriod time.Duration
|
||||
@@ -81,13 +82,12 @@ func (vl VerbosityLevel) LT(comp VerbosityLevel) bool {
|
||||
|
||||
// Configuration for Ginkgo's reporter
|
||||
type ReporterConfig struct {
|
||||
NoColor bool
|
||||
SlowSpecThreshold time.Duration
|
||||
Succinct bool
|
||||
Verbose bool
|
||||
VeryVerbose bool
|
||||
FullTrace bool
|
||||
AlwaysEmitGinkgoWriter bool
|
||||
NoColor bool
|
||||
Succinct bool
|
||||
Verbose bool
|
||||
VeryVerbose bool
|
||||
FullTrace bool
|
||||
ShowNodeEvents bool
|
||||
|
||||
JSONReport string
|
||||
JUnitReport string
|
||||
@@ -110,9 +110,7 @@ func (rc ReporterConfig) WillGenerateReport() bool {
|
||||
}
|
||||
|
||||
func NewDefaultReporterConfig() ReporterConfig {
|
||||
return ReporterConfig{
|
||||
SlowSpecThreshold: 5 * time.Second,
|
||||
}
|
||||
return ReporterConfig{}
|
||||
}
|
||||
|
||||
// Configuration for the Ginkgo CLI
|
||||
@@ -235,6 +233,9 @@ type deprecatedConfig struct {
|
||||
SlowSpecThresholdWithFLoatUnits float64
|
||||
Stream bool
|
||||
Notify bool
|
||||
EmitSpecProgress bool
|
||||
SlowSpecThreshold time.Duration
|
||||
AlwaysEmitGinkgoWriter bool
|
||||
}
|
||||
|
||||
// Flags
|
||||
@@ -275,8 +276,6 @@ var SuiteConfigFlags = GinkgoFlags{
|
||||
|
||||
{KeyPath: "S.DryRun", Name: "dry-run", SectionKey: "debug", DeprecatedName: "dryRun", DeprecatedDocLink: "changed-command-line-flags",
|
||||
Usage: "If set, ginkgo will walk the test hierarchy without actually running anything. Best paired with -v."},
|
||||
{KeyPath: "S.EmitSpecProgress", Name: "progress", SectionKey: "debug",
|
||||
Usage: "If set, ginkgo will emit progress information as each spec runs to the GinkgoWriter."},
|
||||
{KeyPath: "S.PollProgressAfter", Name: "poll-progress-after", SectionKey: "debug", UsageDefaultValue: "0",
|
||||
Usage: "Emit node progress reports periodically if node hasn't completed after this duration."},
|
||||
{KeyPath: "S.PollProgressInterval", Name: "poll-progress-interval", SectionKey: "debug", UsageDefaultValue: "10s",
|
||||
@@ -303,6 +302,8 @@ var SuiteConfigFlags = GinkgoFlags{
|
||||
|
||||
{KeyPath: "D.RegexScansFilePath", DeprecatedName: "regexScansFilePath", DeprecatedDocLink: "removed--regexscansfilepath", DeprecatedVersion: "2.0.0"},
|
||||
{KeyPath: "D.DebugParallel", DeprecatedName: "debug", DeprecatedDocLink: "removed--debug", DeprecatedVersion: "2.0.0"},
|
||||
{KeyPath: "D.EmitSpecProgress", DeprecatedName: "progress", SectionKey: "debug",
|
||||
DeprecatedVersion: "2.5.0", Usage: ". The functionality provided by --progress was confusing and is no longer needed. Use --show-node-events instead to see node entry and exit events included in the timeline of failed and verbose specs. Or you can run with -vv to always see all node events. Lastly, --poll-progress-after and the PollProgressAfter decorator now provide a better mechanism for debugging specs that tend to get stuck."},
|
||||
}
|
||||
|
||||
// ParallelConfigFlags provides flags for the Ginkgo test process (not the CLI)
|
||||
@@ -319,8 +320,6 @@ var ParallelConfigFlags = GinkgoFlags{
|
||||
var ReporterConfigFlags = GinkgoFlags{
|
||||
{KeyPath: "R.NoColor", Name: "no-color", SectionKey: "output", DeprecatedName: "noColor", DeprecatedDocLink: "changed-command-line-flags",
|
||||
Usage: "If set, suppress color output in default reporter."},
|
||||
{KeyPath: "R.SlowSpecThreshold", Name: "slow-spec-threshold", SectionKey: "output", UsageArgument: "duration", UsageDefaultValue: "5s",
|
||||
Usage: "Specs that take longer to run than this threshold are flagged as slow by the default reporter."},
|
||||
{KeyPath: "R.Verbose", Name: "v", SectionKey: "output",
|
||||
Usage: "If set, emits more output including GinkgoWriter contents."},
|
||||
{KeyPath: "R.VeryVerbose", Name: "vv", SectionKey: "output",
|
||||
@@ -329,8 +328,8 @@ var ReporterConfigFlags = GinkgoFlags{
|
||||
Usage: "If set, default reporter prints out a very succinct report"},
|
||||
{KeyPath: "R.FullTrace", Name: "trace", SectionKey: "output",
|
||||
Usage: "If set, default reporter prints out the full stack trace when a failure occurs"},
|
||||
{KeyPath: "R.AlwaysEmitGinkgoWriter", Name: "always-emit-ginkgo-writer", SectionKey: "output", DeprecatedName: "reportPassed", DeprecatedDocLink: "renamed--reportpassed",
|
||||
Usage: "If set, default reporter prints out captured output of passed tests."},
|
||||
{KeyPath: "R.ShowNodeEvents", Name: "show-node-events", SectionKey: "output",
|
||||
Usage: "If set, default reporter prints node > Enter and < Exit events when specs fail"},
|
||||
|
||||
{KeyPath: "R.JSONReport", Name: "json-report", UsageArgument: "filename.json", SectionKey: "output",
|
||||
Usage: "If set, Ginkgo will generate a JSON-formatted test report at the specified location."},
|
||||
@@ -343,6 +342,8 @@ var ReporterConfigFlags = GinkgoFlags{
|
||||
Usage: "use --slow-spec-threshold instead and pass in a duration string (e.g. '5s', not '5.0')"},
|
||||
{KeyPath: "D.NoisyPendings", DeprecatedName: "noisyPendings", DeprecatedDocLink: "removed--noisypendings-and--noisyskippings", DeprecatedVersion: "2.0.0"},
|
||||
{KeyPath: "D.NoisySkippings", DeprecatedName: "noisySkippings", DeprecatedDocLink: "removed--noisypendings-and--noisyskippings", DeprecatedVersion: "2.0.0"},
|
||||
{KeyPath: "D.SlowSpecThreshold", DeprecatedName: "slow-spec-threshold", SectionKey: "output", Usage: "--slow-spec-threshold has been deprecated and will be removed in a future version of Ginkgo. This feature has proved to be more noisy than useful. You can use --poll-progress-after, instead, to get more actionable feedback about potentially slow specs and understand where they might be getting stuck.", DeprecatedVersion: "2.5.0"},
|
||||
{KeyPath: "D.AlwaysEmitGinkgoWriter", DeprecatedName: "always-emit-ginkgo-writer", SectionKey: "output", Usage: " - use -v instead, or one of Ginkgo's machine-readable report formats to get GinkgoWriter output for passing specs."},
|
||||
}
|
||||
|
||||
// BuildTestSuiteFlagSet attaches to the CommandLine flagset and provides flags for the Ginkgo test process
|
||||
@@ -600,13 +601,29 @@ func VetAndInitializeCLIAndGoConfig(cliConfig CLIConfig, goFlagsConfig GoFlagsCo
|
||||
}
|
||||
|
||||
// GenerateGoTestCompileArgs is used by the Ginkgo CLI to generate command line arguments to pass to the go test -c command when compiling the test
|
||||
func GenerateGoTestCompileArgs(goFlagsConfig GoFlagsConfig, destination string, packageToBuild string) ([]string, error) {
|
||||
func GenerateGoTestCompileArgs(goFlagsConfig GoFlagsConfig, destination string, packageToBuild string, pathToInvocationPath string) ([]string, error) {
|
||||
// if the user has set the CoverProfile run-time flag make sure to set the build-time cover flag to make sure
|
||||
// the built test binary can generate a coverprofile
|
||||
if goFlagsConfig.CoverProfile != "" {
|
||||
goFlagsConfig.Cover = true
|
||||
}
|
||||
|
||||
if goFlagsConfig.CoverPkg != "" {
|
||||
coverPkgs := strings.Split(goFlagsConfig.CoverPkg, ",")
|
||||
adjustedCoverPkgs := make([]string, len(coverPkgs))
|
||||
for i, coverPkg := range coverPkgs {
|
||||
coverPkg = strings.Trim(coverPkg, " ")
|
||||
if strings.HasPrefix(coverPkg, "./") {
|
||||
// this is a relative coverPkg - we need to reroot it
|
||||
adjustedCoverPkgs[i] = "./" + filepath.Join(pathToInvocationPath, strings.TrimPrefix(coverPkg, "./"))
|
||||
} else {
|
||||
// this is a package name - don't touch it
|
||||
adjustedCoverPkgs[i] = coverPkg
|
||||
}
|
||||
}
|
||||
goFlagsConfig.CoverPkg = strings.Join(adjustedCoverPkgs, ",")
|
||||
}
|
||||
|
||||
args := []string{"test", "-c", "-o", destination, packageToBuild}
|
||||
goArgs, err := GenerateFlagArgs(
|
||||
GoBuildFlags,
|
||||
|
9
vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go
generated
vendored
9
vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go
generated
vendored
@@ -38,7 +38,7 @@ func (d deprecations) Async() Deprecation {
|
||||
|
||||
func (d deprecations) Measure() Deprecation {
|
||||
return Deprecation{
|
||||
Message: "Measure is deprecated and will be removed in Ginkgo V2. Please migrate to gomega/gmeasure.",
|
||||
Message: "Measure is deprecated and has been removed from Ginkgo V2. Any Measure tests in your spec will not run. Please migrate to gomega/gmeasure.",
|
||||
DocLink: "removed-measure",
|
||||
Version: "1.16.3",
|
||||
}
|
||||
@@ -83,6 +83,13 @@ func (d deprecations) Nodot() Deprecation {
|
||||
}
|
||||
}
|
||||
|
||||
func (d deprecations) SuppressProgressReporting() Deprecation {
|
||||
return Deprecation{
|
||||
Message: "Improvements to how reporters emit timeline information means that SuppressProgressReporting is no longer necessary and has been deprecated.",
|
||||
Version: "2.5.0",
|
||||
}
|
||||
}
|
||||
|
||||
type DeprecationTracker struct {
|
||||
deprecations map[Deprecation][]CodeLocation
|
||||
lock *sync.Mutex
|
||||
|
19
vendor/github.com/onsi/ginkgo/v2/types/errors.go
generated
vendored
19
vendor/github.com/onsi/ginkgo/v2/types/errors.go
generated
vendored
@@ -108,8 +108,8 @@ Please ensure all assertions are inside leaf nodes such as {{bold}}BeforeEach{{/
|
||||
|
||||
func (g ginkgoErrors) SuiteNodeInNestedContext(nodeType NodeType, cl CodeLocation) error {
|
||||
docLink := "suite-setup-and-cleanup-beforesuite-and-aftersuite"
|
||||
if nodeType.Is(NodeTypeReportAfterSuite) {
|
||||
docLink = "reporting-nodes---reportaftersuite"
|
||||
if nodeType.Is(NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite) {
|
||||
docLink = "reporting-nodes---reportbeforesuite-and-reportaftersuite"
|
||||
}
|
||||
|
||||
return GinkgoError{
|
||||
@@ -125,8 +125,8 @@ func (g ginkgoErrors) SuiteNodeInNestedContext(nodeType NodeType, cl CodeLocatio
|
||||
|
||||
func (g ginkgoErrors) SuiteNodeDuringRunPhase(nodeType NodeType, cl CodeLocation) error {
|
||||
docLink := "suite-setup-and-cleanup-beforesuite-and-aftersuite"
|
||||
if nodeType.Is(NodeTypeReportAfterSuite) {
|
||||
docLink = "reporting-nodes---reportaftersuite"
|
||||
if nodeType.Is(NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite) {
|
||||
docLink = "reporting-nodes---reportbeforesuite-and-reportaftersuite"
|
||||
}
|
||||
|
||||
return GinkgoError{
|
||||
@@ -298,6 +298,15 @@ func (g ginkgoErrors) SetupNodeNotInOrderedContainer(cl CodeLocation, nodeType N
|
||||
}
|
||||
}
|
||||
|
||||
func (g ginkgoErrors) InvalidContinueOnFailureDecoration(cl CodeLocation) error {
|
||||
return GinkgoError{
|
||||
Heading: "ContinueOnFailure not decorating an outermost Ordered Container",
|
||||
Message: "ContinueOnFailure can only decorate an Ordered container, and this Ordered container must be the outermost Ordered container.",
|
||||
CodeLocation: cl,
|
||||
DocLink: "ordered-containers",
|
||||
}
|
||||
}
|
||||
|
||||
/* DeferCleanup errors */
|
||||
func (g ginkgoErrors) DeferCleanupInvalidFunction(cl CodeLocation) error {
|
||||
return GinkgoError{
|
||||
@@ -320,7 +329,7 @@ func (g ginkgoErrors) PushingCleanupNodeDuringTreeConstruction(cl CodeLocation)
|
||||
func (g ginkgoErrors) PushingCleanupInReportingNode(cl CodeLocation, nodeType NodeType) error {
|
||||
return GinkgoError{
|
||||
Heading: fmt.Sprintf("DeferCleanup cannot be called in %s", nodeType),
|
||||
Message: "Please inline your cleanup code - Ginkgo won't run cleanup code after a ReportAfterEach or ReportAfterSuite.",
|
||||
Message: "Please inline your cleanup code - Ginkgo won't run cleanup code after a Reporting node.",
|
||||
CodeLocation: cl,
|
||||
DocLink: "cleaning-up-our-cleanup-code-defercleanup",
|
||||
}
|
||||
|
11
vendor/github.com/onsi/ginkgo/v2/types/label_filter.go
generated
vendored
11
vendor/github.com/onsi/ginkgo/v2/types/label_filter.go
generated
vendored
@@ -272,12 +272,23 @@ func tokenize(input string) func() (*treeNode, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func MustParseLabelFilter(input string) LabelFilter {
|
||||
filter, err := ParseLabelFilter(input)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return filter
|
||||
}
|
||||
|
||||
func ParseLabelFilter(input string) (LabelFilter, error) {
|
||||
if DEBUG_LABEL_FILTER_PARSING {
|
||||
fmt.Println("\n==============")
|
||||
fmt.Println("Input: ", input)
|
||||
fmt.Print("Tokens: ")
|
||||
}
|
||||
if input == "" {
|
||||
return func(_ []string) bool { return true }, nil
|
||||
}
|
||||
nextToken := tokenize(input)
|
||||
|
||||
root := &treeNode{token: lfTokenRoot}
|
||||
|
14
vendor/github.com/onsi/ginkgo/v2/types/report_entry.go
generated
vendored
14
vendor/github.com/onsi/ginkgo/v2/types/report_entry.go
generated
vendored
@@ -6,8 +6,8 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
//ReportEntryValue wraps a report entry's value ensuring it can be encoded and decoded safely into reports
|
||||
//and across the network connection when running in parallel
|
||||
// ReportEntryValue wraps a report entry's value ensuring it can be encoded and decoded safely into reports
|
||||
// and across the network connection when running in parallel
|
||||
type ReportEntryValue struct {
|
||||
raw interface{} //unexported to prevent gob from freaking out about unregistered structs
|
||||
AsJSON string
|
||||
@@ -85,10 +85,12 @@ func (rev *ReportEntryValue) GobDecode(data []byte) error {
|
||||
type ReportEntry struct {
|
||||
// Visibility captures the visibility policy for this ReportEntry
|
||||
Visibility ReportEntryVisibility
|
||||
// Time captures the time the AddReportEntry was called
|
||||
Time time.Time
|
||||
// Location captures the location of the AddReportEntry call
|
||||
Location CodeLocation
|
||||
|
||||
Time time.Time //need this for backwards compatibility
|
||||
TimelineLocation TimelineLocation
|
||||
|
||||
// Name captures the name of this report
|
||||
Name string
|
||||
// Value captures the (optional) object passed into AddReportEntry - this can be
|
||||
@@ -120,7 +122,9 @@ func (entry ReportEntry) GetRawValue() interface{} {
|
||||
return entry.Value.GetRawValue()
|
||||
}
|
||||
|
||||
|
||||
func (entry ReportEntry) GetTimelineLocation() TimelineLocation {
|
||||
return entry.TimelineLocation
|
||||
}
|
||||
|
||||
type ReportEntries []ReportEntry
|
||||
|
||||
|
310
vendor/github.com/onsi/ginkgo/v2/types/types.go
generated
vendored
310
vendor/github.com/onsi/ginkgo/v2/types/types.go
generated
vendored
@@ -2,6 +2,8 @@ package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -56,19 +58,20 @@ type Report struct {
|
||||
SuiteConfig SuiteConfig
|
||||
|
||||
//SpecReports is a list of all SpecReports generated by this test run
|
||||
//It is empty when the SuiteReport is provided to ReportBeforeSuite
|
||||
SpecReports SpecReports
|
||||
}
|
||||
|
||||
//PreRunStats contains a set of stats captured before the test run begins. This is primarily used
|
||||
//by Ginkgo's reporter to tell the user how many specs are in the current suite (PreRunStats.TotalSpecs)
|
||||
//and how many it intends to run (PreRunStats.SpecsThatWillRun) after applying any relevant focus or skip filters.
|
||||
// PreRunStats contains a set of stats captured before the test run begins. This is primarily used
|
||||
// by Ginkgo's reporter to tell the user how many specs are in the current suite (PreRunStats.TotalSpecs)
|
||||
// and how many it intends to run (PreRunStats.SpecsThatWillRun) after applying any relevant focus or skip filters.
|
||||
type PreRunStats struct {
|
||||
TotalSpecs int
|
||||
SpecsThatWillRun int
|
||||
}
|
||||
|
||||
//Add is used by Ginkgo's parallel aggregation mechanisms to combine test run reports form individual parallel processes
|
||||
//to form a complete final report.
|
||||
// Add is used by Ginkgo's parallel aggregation mechanisms to combine test run reports form individual parallel processes
|
||||
// to form a complete final report.
|
||||
func (report Report) Add(other Report) Report {
|
||||
report.SuiteSucceeded = report.SuiteSucceeded && other.SuiteSucceeded
|
||||
|
||||
@@ -147,6 +150,9 @@ type SpecReport struct {
|
||||
// ParallelProcess captures the parallel process that this spec ran on
|
||||
ParallelProcess int
|
||||
|
||||
// RunningInParallel captures whether this spec is part of a suite that ran in parallel
|
||||
RunningInParallel bool
|
||||
|
||||
//Failure is populated if a spec has failed, panicked, been interrupted, or skipped by the user (e.g. calling Skip())
|
||||
//It includes detailed information about the Failure
|
||||
Failure Failure
|
||||
@@ -178,6 +184,9 @@ type SpecReport struct {
|
||||
|
||||
// AdditionalFailures contains any failures that occurred after the initial spec failure. These typically occur in cleanup nodes after the initial failure and are only emitted when running in verbose mode.
|
||||
AdditionalFailures []AdditionalFailure
|
||||
|
||||
// SpecEvents capture additional events that occur during the spec run
|
||||
SpecEvents SpecEvents
|
||||
}
|
||||
|
||||
func (report SpecReport) MarshalJSON() ([]byte, error) {
|
||||
@@ -204,6 +213,7 @@ func (report SpecReport) MarshalJSON() ([]byte, error) {
|
||||
ReportEntries ReportEntries `json:",omitempty"`
|
||||
ProgressReports []ProgressReport `json:",omitempty"`
|
||||
AdditionalFailures []AdditionalFailure `json:",omitempty"`
|
||||
SpecEvents SpecEvents `json:",omitempty"`
|
||||
}{
|
||||
ContainerHierarchyTexts: report.ContainerHierarchyTexts,
|
||||
ContainerHierarchyLocations: report.ContainerHierarchyLocations,
|
||||
@@ -238,6 +248,9 @@ func (report SpecReport) MarshalJSON() ([]byte, error) {
|
||||
if len(report.AdditionalFailures) > 0 {
|
||||
out.AdditionalFailures = report.AdditionalFailures
|
||||
}
|
||||
if len(report.SpecEvents) > 0 {
|
||||
out.SpecEvents = report.SpecEvents
|
||||
}
|
||||
|
||||
return json.Marshal(out)
|
||||
}
|
||||
@@ -255,13 +268,13 @@ func (report SpecReport) CombinedOutput() string {
|
||||
return report.CapturedStdOutErr + "\n" + report.CapturedGinkgoWriterOutput
|
||||
}
|
||||
|
||||
//Failed returns true if report.State is one of the SpecStateFailureStates
|
||||
// Failed returns true if report.State is one of the SpecStateFailureStates
|
||||
// (SpecStateFailed, SpecStatePanicked, SpecStateinterrupted, SpecStateAborted)
|
||||
func (report SpecReport) Failed() bool {
|
||||
return report.State.Is(SpecStateFailureStates)
|
||||
}
|
||||
|
||||
//FullText returns a concatenation of all the report.ContainerHierarchyTexts and report.LeafNodeText
|
||||
// FullText returns a concatenation of all the report.ContainerHierarchyTexts and report.LeafNodeText
|
||||
func (report SpecReport) FullText() string {
|
||||
texts := []string{}
|
||||
texts = append(texts, report.ContainerHierarchyTexts...)
|
||||
@@ -271,7 +284,7 @@ func (report SpecReport) FullText() string {
|
||||
return strings.Join(texts, " ")
|
||||
}
|
||||
|
||||
//Labels returns a deduped set of all the spec's Labels.
|
||||
// Labels returns a deduped set of all the spec's Labels.
|
||||
func (report SpecReport) Labels() []string {
|
||||
out := []string{}
|
||||
seen := map[string]bool{}
|
||||
@@ -293,7 +306,7 @@ func (report SpecReport) Labels() []string {
|
||||
return out
|
||||
}
|
||||
|
||||
//MatchesLabelFilter returns true if the spec satisfies the passed in label filter query
|
||||
// MatchesLabelFilter returns true if the spec satisfies the passed in label filter query
|
||||
func (report SpecReport) MatchesLabelFilter(query string) (bool, error) {
|
||||
filter, err := ParseLabelFilter(query)
|
||||
if err != nil {
|
||||
@@ -302,29 +315,54 @@ func (report SpecReport) MatchesLabelFilter(query string) (bool, error) {
|
||||
return filter(report.Labels()), nil
|
||||
}
|
||||
|
||||
//FileName() returns the name of the file containing the spec
|
||||
// FileName() returns the name of the file containing the spec
|
||||
func (report SpecReport) FileName() string {
|
||||
return report.LeafNodeLocation.FileName
|
||||
}
|
||||
|
||||
//LineNumber() returns the line number of the leaf node
|
||||
// LineNumber() returns the line number of the leaf node
|
||||
func (report SpecReport) LineNumber() int {
|
||||
return report.LeafNodeLocation.LineNumber
|
||||
}
|
||||
|
||||
//FailureMessage() returns the failure message (or empty string if the test hasn't failed)
|
||||
// FailureMessage() returns the failure message (or empty string if the test hasn't failed)
|
||||
func (report SpecReport) FailureMessage() string {
|
||||
return report.Failure.Message
|
||||
}
|
||||
|
||||
//FailureLocation() returns the location of the failure (or an empty CodeLocation if the test hasn't failed)
|
||||
// FailureLocation() returns the location of the failure (or an empty CodeLocation if the test hasn't failed)
|
||||
func (report SpecReport) FailureLocation() CodeLocation {
|
||||
return report.Failure.Location
|
||||
}
|
||||
|
||||
// Timeline() returns a timeline view of the report
|
||||
func (report SpecReport) Timeline() Timeline {
|
||||
timeline := Timeline{}
|
||||
if !report.Failure.IsZero() {
|
||||
timeline = append(timeline, report.Failure)
|
||||
if report.Failure.AdditionalFailure != nil {
|
||||
timeline = append(timeline, *(report.Failure.AdditionalFailure))
|
||||
}
|
||||
}
|
||||
for _, additionalFailure := range report.AdditionalFailures {
|
||||
timeline = append(timeline, additionalFailure)
|
||||
}
|
||||
for _, reportEntry := range report.ReportEntries {
|
||||
timeline = append(timeline, reportEntry)
|
||||
}
|
||||
for _, progressReport := range report.ProgressReports {
|
||||
timeline = append(timeline, progressReport)
|
||||
}
|
||||
for _, specEvent := range report.SpecEvents {
|
||||
timeline = append(timeline, specEvent)
|
||||
}
|
||||
sort.Sort(timeline)
|
||||
return timeline
|
||||
}
|
||||
|
||||
type SpecReports []SpecReport
|
||||
|
||||
//WithLeafNodeType returns the subset of SpecReports with LeafNodeType matching one of the requested NodeTypes
|
||||
// WithLeafNodeType returns the subset of SpecReports with LeafNodeType matching one of the requested NodeTypes
|
||||
func (reports SpecReports) WithLeafNodeType(nodeTypes NodeType) SpecReports {
|
||||
count := 0
|
||||
for i := range reports {
|
||||
@@ -344,7 +382,7 @@ func (reports SpecReports) WithLeafNodeType(nodeTypes NodeType) SpecReports {
|
||||
return out
|
||||
}
|
||||
|
||||
//WithState returns the subset of SpecReports with State matching one of the requested SpecStates
|
||||
// WithState returns the subset of SpecReports with State matching one of the requested SpecStates
|
||||
func (reports SpecReports) WithState(states SpecState) SpecReports {
|
||||
count := 0
|
||||
for i := range reports {
|
||||
@@ -363,7 +401,7 @@ func (reports SpecReports) WithState(states SpecState) SpecReports {
|
||||
return out
|
||||
}
|
||||
|
||||
//CountWithState returns the number of SpecReports with State matching one of the requested SpecStates
|
||||
// CountWithState returns the number of SpecReports with State matching one of the requested SpecStates
|
||||
func (reports SpecReports) CountWithState(states SpecState) int {
|
||||
n := 0
|
||||
for i := range reports {
|
||||
@@ -374,7 +412,7 @@ func (reports SpecReports) CountWithState(states SpecState) int {
|
||||
return n
|
||||
}
|
||||
|
||||
//If the Spec passes, CountOfFlakedSpecs returns the number of SpecReports that failed after multiple attempts.
|
||||
// If the Spec passes, CountOfFlakedSpecs returns the number of SpecReports that failed after multiple attempts.
|
||||
func (reports SpecReports) CountOfFlakedSpecs() int {
|
||||
n := 0
|
||||
for i := range reports {
|
||||
@@ -385,7 +423,7 @@ func (reports SpecReports) CountOfFlakedSpecs() int {
|
||||
return n
|
||||
}
|
||||
|
||||
//If the Spec fails, CountOfRepeatedSpecs returns the number of SpecReports that passed after multiple attempts
|
||||
// If the Spec fails, CountOfRepeatedSpecs returns the number of SpecReports that passed after multiple attempts
|
||||
func (reports SpecReports) CountOfRepeatedSpecs() int {
|
||||
n := 0
|
||||
for i := range reports {
|
||||
@@ -396,6 +434,53 @@ func (reports SpecReports) CountOfRepeatedSpecs() int {
|
||||
return n
|
||||
}
|
||||
|
||||
// TimelineLocation captures the location of an event in the spec's timeline
|
||||
type TimelineLocation struct {
|
||||
//Offset is the offset (in bytes) of the event relative to the GinkgoWriter stream
|
||||
Offset int `json:",omitempty"`
|
||||
|
||||
//Order is the order of the event with respect to other events. The absolute value of Order
|
||||
//is irrelevant. All that matters is that an event with a lower Order occurs before ane vent with a higher Order
|
||||
Order int `json:",omitempty"`
|
||||
|
||||
Time time.Time
|
||||
}
|
||||
|
||||
// TimelineEvent represent an event on the timeline
|
||||
// consumers of Timeline will need to check the concrete type of each entry to determine how to handle it
|
||||
type TimelineEvent interface {
|
||||
GetTimelineLocation() TimelineLocation
|
||||
}
|
||||
|
||||
type Timeline []TimelineEvent
|
||||
|
||||
func (t Timeline) Len() int { return len(t) }
|
||||
func (t Timeline) Less(i, j int) bool {
|
||||
return t[i].GetTimelineLocation().Order < t[j].GetTimelineLocation().Order
|
||||
}
|
||||
func (t Timeline) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
|
||||
func (t Timeline) WithoutHiddenReportEntries() Timeline {
|
||||
out := Timeline{}
|
||||
for _, event := range t {
|
||||
if reportEntry, isReportEntry := event.(ReportEntry); isReportEntry && reportEntry.Visibility == ReportEntryVisibilityNever {
|
||||
continue
|
||||
}
|
||||
out = append(out, event)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (t Timeline) WithoutVeryVerboseSpecEvents() Timeline {
|
||||
out := Timeline{}
|
||||
for _, event := range t {
|
||||
if specEvent, isSpecEvent := event.(SpecEvent); isSpecEvent && specEvent.IsOnlyVisibleAtVeryVerbose() {
|
||||
continue
|
||||
}
|
||||
out = append(out, event)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Failure captures failure information for an individual test
|
||||
type Failure struct {
|
||||
// Message - the failure message passed into Fail(...). When using a matcher library
|
||||
@@ -408,6 +493,8 @@ type Failure struct {
|
||||
// This CodeLocation will include a fully-populated StackTrace
|
||||
Location CodeLocation
|
||||
|
||||
TimelineLocation TimelineLocation
|
||||
|
||||
// ForwardedPanic - if the failure represents a captured panic (i.e. Summary.State == SpecStatePanicked)
|
||||
// then ForwardedPanic will be populated with a string representation of the captured panic.
|
||||
ForwardedPanic string `json:",omitempty"`
|
||||
@@ -420,19 +507,29 @@ type Failure struct {
|
||||
// FailureNodeType will contain the NodeType of the node in which the failure occurred.
|
||||
// FailureNodeLocation will contain the CodeLocation of the node in which the failure occurred.
|
||||
// If populated, FailureNodeContainerIndex will be the index into SpecReport.ContainerHierarchyTexts and SpecReport.ContainerHierarchyLocations that represents the parent container of the node in which the failure occurred.
|
||||
FailureNodeContext FailureNodeContext
|
||||
FailureNodeType NodeType
|
||||
FailureNodeLocation CodeLocation
|
||||
FailureNodeContainerIndex int
|
||||
FailureNodeContext FailureNodeContext `json:",omitempty"`
|
||||
|
||||
FailureNodeType NodeType `json:",omitempty"`
|
||||
|
||||
FailureNodeLocation CodeLocation `json:",omitempty"`
|
||||
|
||||
FailureNodeContainerIndex int `json:",omitempty"`
|
||||
|
||||
//ProgressReport is populated if the spec was interrupted or timed out
|
||||
ProgressReport ProgressReport
|
||||
ProgressReport ProgressReport `json:",omitempty"`
|
||||
|
||||
//AdditionalFailure is non-nil if a follow-on failure occurred within the same node after the primary failure. This only happens when a node has timed out or been interrupted. In such cases the AdditionalFailure can include information about where/why the spec was stuck.
|
||||
AdditionalFailure *AdditionalFailure `json:",omitempty"`
|
||||
}
|
||||
|
||||
func (f Failure) IsZero() bool {
|
||||
return f.Message == "" && (f.Location == CodeLocation{})
|
||||
}
|
||||
|
||||
func (f Failure) GetTimelineLocation() TimelineLocation {
|
||||
return f.TimelineLocation
|
||||
}
|
||||
|
||||
// FailureNodeContext captures the location context for the node containing the failing line of code
|
||||
type FailureNodeContext uint
|
||||
|
||||
@@ -471,6 +568,10 @@ type AdditionalFailure struct {
|
||||
Failure Failure
|
||||
}
|
||||
|
||||
func (f AdditionalFailure) GetTimelineLocation() TimelineLocation {
|
||||
return f.Failure.TimelineLocation
|
||||
}
|
||||
|
||||
// SpecState captures the state of a spec
|
||||
// To determine if a given `state` represents a failure state, use `state.Is(SpecStateFailureStates)`
|
||||
type SpecState uint
|
||||
@@ -503,6 +604,9 @@ var ssEnumSupport = NewEnumSupport(map[uint]string{
|
||||
func (ss SpecState) String() string {
|
||||
return ssEnumSupport.String(uint(ss))
|
||||
}
|
||||
func (ss SpecState) GomegaString() string {
|
||||
return ssEnumSupport.String(uint(ss))
|
||||
}
|
||||
func (ss *SpecState) UnmarshalJSON(b []byte) error {
|
||||
out, err := ssEnumSupport.UnmarshJSON(b)
|
||||
*ss = SpecState(out)
|
||||
@@ -520,38 +624,40 @@ func (ss SpecState) Is(states SpecState) bool {
|
||||
|
||||
// ProgressReport captures the progress of the current spec. It is, effectively, a structured Ginkgo-aware stack trace
|
||||
type ProgressReport struct {
|
||||
Message string
|
||||
ParallelProcess int
|
||||
RunningInParallel bool
|
||||
Message string `json:",omitempty"`
|
||||
ParallelProcess int `json:",omitempty"`
|
||||
RunningInParallel bool `json:",omitempty"`
|
||||
|
||||
Time time.Time
|
||||
ContainerHierarchyTexts []string `json:",omitempty"`
|
||||
LeafNodeText string `json:",omitempty"`
|
||||
LeafNodeLocation CodeLocation `json:",omitempty"`
|
||||
SpecStartTime time.Time `json:",omitempty"`
|
||||
|
||||
ContainerHierarchyTexts []string
|
||||
LeafNodeText string
|
||||
LeafNodeLocation CodeLocation
|
||||
SpecStartTime time.Time
|
||||
CurrentNodeType NodeType `json:",omitempty"`
|
||||
CurrentNodeText string `json:",omitempty"`
|
||||
CurrentNodeLocation CodeLocation `json:",omitempty"`
|
||||
CurrentNodeStartTime time.Time `json:",omitempty"`
|
||||
|
||||
CurrentNodeType NodeType
|
||||
CurrentNodeText string
|
||||
CurrentNodeLocation CodeLocation
|
||||
CurrentNodeStartTime time.Time
|
||||
CurrentStepText string `json:",omitempty"`
|
||||
CurrentStepLocation CodeLocation `json:",omitempty"`
|
||||
CurrentStepStartTime time.Time `json:",omitempty"`
|
||||
|
||||
CurrentStepText string
|
||||
CurrentStepLocation CodeLocation
|
||||
CurrentStepStartTime time.Time
|
||||
AdditionalReports []string `json:",omitempty"`
|
||||
|
||||
AdditionalReports []string
|
||||
CapturedGinkgoWriterOutput string `json:",omitempty"`
|
||||
TimelineLocation TimelineLocation `json:",omitempty"`
|
||||
|
||||
CapturedGinkgoWriterOutput string `json:",omitempty"`
|
||||
GinkgoWriterOffset int
|
||||
|
||||
Goroutines []Goroutine
|
||||
Goroutines []Goroutine `json:",omitempty"`
|
||||
}
|
||||
|
||||
func (pr ProgressReport) IsZero() bool {
|
||||
return pr.CurrentNodeType == NodeTypeInvalid
|
||||
}
|
||||
|
||||
func (pr ProgressReport) Time() time.Time {
|
||||
return pr.TimelineLocation.Time
|
||||
}
|
||||
|
||||
func (pr ProgressReport) SpecGoroutine() Goroutine {
|
||||
for _, goroutine := range pr.Goroutines {
|
||||
if goroutine.IsSpecGoroutine {
|
||||
@@ -589,6 +695,22 @@ func (pr ProgressReport) WithoutCapturedGinkgoWriterOutput() ProgressReport {
|
||||
return out
|
||||
}
|
||||
|
||||
func (pr ProgressReport) WithoutOtherGoroutines() ProgressReport {
|
||||
out := pr
|
||||
filteredGoroutines := []Goroutine{}
|
||||
for _, goroutine := range pr.Goroutines {
|
||||
if goroutine.IsSpecGoroutine || goroutine.HasHighlights() {
|
||||
filteredGoroutines = append(filteredGoroutines, goroutine)
|
||||
}
|
||||
}
|
||||
out.Goroutines = filteredGoroutines
|
||||
return out
|
||||
}
|
||||
|
||||
func (pr ProgressReport) GetTimelineLocation() TimelineLocation {
|
||||
return pr.TimelineLocation
|
||||
}
|
||||
|
||||
type Goroutine struct {
|
||||
ID uint64
|
||||
State string
|
||||
@@ -643,6 +765,7 @@ const (
|
||||
|
||||
NodeTypeReportBeforeEach
|
||||
NodeTypeReportAfterEach
|
||||
NodeTypeReportBeforeSuite
|
||||
NodeTypeReportAfterSuite
|
||||
|
||||
NodeTypeCleanupInvalid
|
||||
@@ -652,9 +775,9 @@ const (
|
||||
)
|
||||
|
||||
var NodeTypesForContainerAndIt = NodeTypeContainer | NodeTypeIt
|
||||
var NodeTypesForSuiteLevelNodes = NodeTypeBeforeSuite | NodeTypeSynchronizedBeforeSuite | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeReportAfterSuite | NodeTypeCleanupAfterSuite
|
||||
var NodeTypesForSuiteLevelNodes = NodeTypeBeforeSuite | NodeTypeSynchronizedBeforeSuite | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite | NodeTypeCleanupAfterSuite
|
||||
var NodeTypesAllowedDuringCleanupInterrupt = NodeTypeAfterEach | NodeTypeJustAfterEach | NodeTypeAfterAll | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeCleanupAfterEach | NodeTypeCleanupAfterAll | NodeTypeCleanupAfterSuite
|
||||
var NodeTypesAllowedDuringReportInterrupt = NodeTypeReportBeforeEach | NodeTypeReportAfterEach | NodeTypeReportAfterSuite
|
||||
var NodeTypesAllowedDuringReportInterrupt = NodeTypeReportBeforeEach | NodeTypeReportAfterEach | NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite
|
||||
|
||||
var ntEnumSupport = NewEnumSupport(map[uint]string{
|
||||
uint(NodeTypeInvalid): "INVALID NODE TYPE",
|
||||
@@ -672,6 +795,7 @@ var ntEnumSupport = NewEnumSupport(map[uint]string{
|
||||
uint(NodeTypeSynchronizedAfterSuite): "SynchronizedAfterSuite",
|
||||
uint(NodeTypeReportBeforeEach): "ReportBeforeEach",
|
||||
uint(NodeTypeReportAfterEach): "ReportAfterEach",
|
||||
uint(NodeTypeReportBeforeSuite): "ReportBeforeSuite",
|
||||
uint(NodeTypeReportAfterSuite): "ReportAfterSuite",
|
||||
uint(NodeTypeCleanupInvalid): "DeferCleanup",
|
||||
uint(NodeTypeCleanupAfterEach): "DeferCleanup (Each)",
|
||||
@@ -694,3 +818,99 @@ func (nt NodeType) MarshalJSON() ([]byte, error) {
|
||||
func (nt NodeType) Is(nodeTypes NodeType) bool {
|
||||
return nt&nodeTypes != 0
|
||||
}
|
||||
|
||||
/*
|
||||
SpecEvent captures a vareity of events that can occur when specs run. See SpecEventType for the list of available events.
|
||||
*/
|
||||
type SpecEvent struct {
|
||||
SpecEventType SpecEventType
|
||||
|
||||
CodeLocation CodeLocation
|
||||
TimelineLocation TimelineLocation
|
||||
|
||||
Message string `json:",omitempty"`
|
||||
Duration time.Duration `json:",omitempty"`
|
||||
NodeType NodeType `json:",omitempty"`
|
||||
Attempt int `json:",omitempty"`
|
||||
}
|
||||
|
||||
func (se SpecEvent) GetTimelineLocation() TimelineLocation {
|
||||
return se.TimelineLocation
|
||||
}
|
||||
|
||||
func (se SpecEvent) IsOnlyVisibleAtVeryVerbose() bool {
|
||||
return se.SpecEventType.Is(SpecEventByEnd | SpecEventNodeStart | SpecEventNodeEnd)
|
||||
}
|
||||
|
||||
func (se SpecEvent) GomegaString() string {
|
||||
out := &strings.Builder{}
|
||||
out.WriteString("[" + se.SpecEventType.String() + " SpecEvent] ")
|
||||
if se.Message != "" {
|
||||
out.WriteString("Message=")
|
||||
out.WriteString(`"` + se.Message + `",`)
|
||||
}
|
||||
if se.Duration != 0 {
|
||||
out.WriteString("Duration=" + se.Duration.String() + ",")
|
||||
}
|
||||
if se.NodeType != NodeTypeInvalid {
|
||||
out.WriteString("NodeType=" + se.NodeType.String() + ",")
|
||||
}
|
||||
if se.Attempt != 0 {
|
||||
out.WriteString(fmt.Sprintf("Attempt=%d", se.Attempt) + ",")
|
||||
}
|
||||
out.WriteString("CL=" + se.CodeLocation.String() + ",")
|
||||
out.WriteString(fmt.Sprintf("TL.Offset=%d", se.TimelineLocation.Offset))
|
||||
|
||||
return out.String()
|
||||
}
|
||||
|
||||
type SpecEvents []SpecEvent
|
||||
|
||||
func (se SpecEvents) WithType(seType SpecEventType) SpecEvents {
|
||||
out := SpecEvents{}
|
||||
for _, event := range se {
|
||||
if event.SpecEventType.Is(seType) {
|
||||
out = append(out, event)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
type SpecEventType uint
|
||||
|
||||
const (
|
||||
SpecEventInvalid SpecEventType = 0
|
||||
|
||||
SpecEventByStart SpecEventType = 1 << iota
|
||||
SpecEventByEnd
|
||||
SpecEventNodeStart
|
||||
SpecEventNodeEnd
|
||||
SpecEventSpecRepeat
|
||||
SpecEventSpecRetry
|
||||
)
|
||||
|
||||
var seEnumSupport = NewEnumSupport(map[uint]string{
|
||||
uint(SpecEventInvalid): "INVALID SPEC EVENT",
|
||||
uint(SpecEventByStart): "By",
|
||||
uint(SpecEventByEnd): "By (End)",
|
||||
uint(SpecEventNodeStart): "Node",
|
||||
uint(SpecEventNodeEnd): "Node (End)",
|
||||
uint(SpecEventSpecRepeat): "Repeat",
|
||||
uint(SpecEventSpecRetry): "Retry",
|
||||
})
|
||||
|
||||
func (se SpecEventType) String() string {
|
||||
return seEnumSupport.String(uint(se))
|
||||
}
|
||||
func (se *SpecEventType) UnmarshalJSON(b []byte) error {
|
||||
out, err := seEnumSupport.UnmarshJSON(b)
|
||||
*se = SpecEventType(out)
|
||||
return err
|
||||
}
|
||||
func (se SpecEventType) MarshalJSON() ([]byte, error) {
|
||||
return seEnumSupport.MarshJSON(uint(se))
|
||||
}
|
||||
|
||||
func (se SpecEventType) Is(specEventTypes SpecEventType) bool {
|
||||
return se&specEventTypes != 0
|
||||
}
|
||||
|
2
vendor/github.com/onsi/ginkgo/v2/types/version.go
generated
vendored
2
vendor/github.com/onsi/ginkgo/v2/types/version.go
generated
vendored
@@ -1,3 +1,3 @@
|
||||
package types
|
||||
|
||||
const VERSION = "2.4.0"
|
||||
const VERSION = "2.9.5"
|
||||
|
Reference in New Issue
Block a user