Merge pull request #1267 from containers/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.6.0

build(deps): bump github.com/onsi/ginkgo/v2 from 2.5.1 to 2.6.0
This commit is contained in:
OpenShift Merge Robot 2022-12-12 15:03:14 -05:00 committed by GitHub
commit fdd51bbec5
17 changed files with 1538 additions and 81 deletions

View File

@ -24,7 +24,7 @@ require (
github.com/hashicorp/go-multierror v1.1.1
github.com/jinzhu/copier v0.3.5
github.com/json-iterator/go v1.1.12
github.com/onsi/ginkgo/v2 v2.5.1
github.com/onsi/ginkgo/v2 v2.6.0
github.com/onsi/gomega v1.24.1
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.0-rc2

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,13 @@
## 2.6.0
### Features
- `ReportBeforeSuite` provides access to the suite report before the suite begins.
- Add junit config option for omitting leafnodetype (#1088) [956e6d2]
- Add support to customize junit report config to omit spec labels (#1087) [de44005]
### Fixes
- Fix stack trace pruning so that it has a chance of working on windows [2165648]
## 2.5.1
### Fixes

View File

@ -44,8 +44,8 @@ type Node struct {
SynchronizedAfterSuiteProc1Body func(SpecContext)
SynchronizedAfterSuiteProc1BodyHasContext bool
ReportEachBody func(types.SpecReport)
ReportAfterSuiteBody func(types.Report)
ReportEachBody func(types.SpecReport)
ReportSuiteBody func(types.Report)
MarkedFocus bool
MarkedPending bool
@ -317,9 +317,9 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
trackedFunctionError = true
break
}
} else if nodeType.Is(types.NodeTypeReportAfterSuite) {
if node.ReportAfterSuiteBody == nil {
node.ReportAfterSuiteBody = arg.(func(types.Report))
} else if nodeType.Is(types.NodeTypeReportBeforeSuite | types.NodeTypeReportAfterSuite) {
if node.ReportSuiteBody == nil {
node.ReportSuiteBody = arg.(func(types.Report))
} else {
appendError(types.GinkgoErrors.MultipleBodyFunctions(node.CodeLocation, nodeType))
trackedFunctionError = true
@ -392,7 +392,7 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
appendError(types.GinkgoErrors.InvalidTimeoutOrGracePeriodForNonContextNode(node.CodeLocation, nodeType))
}
if !node.NodeType.Is(types.NodeTypeReportBeforeEach|types.NodeTypeReportAfterEach|types.NodeTypeSynchronizedBeforeSuite|types.NodeTypeSynchronizedAfterSuite|types.NodeTypeReportAfterSuite) && node.Body == nil && !node.MarkedPending && !trackedFunctionError {
if !node.NodeType.Is(types.NodeTypeReportBeforeEach|types.NodeTypeReportAfterEach|types.NodeTypeSynchronizedBeforeSuite|types.NodeTypeSynchronizedAfterSuite|types.NodeTypeReportBeforeSuite|types.NodeTypeReportAfterSuite) && node.Body == nil && !node.MarkedPending && !trackedFunctionError {
appendError(types.GinkgoErrors.MissingBodyFunction(node.CodeLocation, nodeType))
}

View File

@ -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

View File

@ -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,

View File

@ -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) {

View File

@ -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,

View File

@ -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()

View File

@ -183,7 +183,6 @@ func extractRunningGoroutines() ([]types.Goroutine, error) {
break
}
}
r := bufio.NewReader(bytes.NewReader(stack))
out := []types.Goroutine{}
idx := -1
@ -231,12 +230,12 @@ func extractRunningGoroutines() ([]types.Goroutine, error) {
return nil, types.GinkgoErrors.FailedToParseStackTrace(fmt.Sprintf("Invalid function call: %s -- missing file name and line number", functionCall.Function))
}
line = strings.TrimLeft(line, " \t")
fields := strings.SplitN(line, ":", 2)
if len(fields) != 2 {
return nil, types.GinkgoErrors.FailedToParseStackTrace(fmt.Sprintf("Invalid filename nad line number: %s", line))
delimiterIdx := strings.LastIndex(line, ":")
if delimiterIdx == -1 {
return nil, types.GinkgoErrors.FailedToParseStackTrace(fmt.Sprintf("Invalid filename and line number: %s", line))
}
functionCall.Filename = fields[0]
line = strings.Split(fields[1], " ")[0]
functionCall.Filename = line[:delimiterIdx]
line = strings.Split(line[delimiterIdx+1:], " ")[0]
lineNumber, err := strconv.ParseInt(line, 10, 64)
functionCall.Line = int(lineNumber)
if err != nil {

View File

@ -129,7 +129,7 @@ func (suite *Suite) PushNode(node Node) error {
return suite.pushCleanupNode(node)
}
if node.NodeType.Is(types.NodeTypeBeforeSuite | types.NodeTypeAfterSuite | types.NodeTypeSynchronizedBeforeSuite | types.NodeTypeSynchronizedAfterSuite | types.NodeTypeReportAfterSuite) {
if node.NodeType.Is(types.NodeTypeBeforeSuite | types.NodeTypeAfterSuite | types.NodeTypeSynchronizedBeforeSuite | types.NodeTypeSynchronizedAfterSuite | types.NodeTypeBeforeSuite | types.NodeTypeReportBeforeSuite | types.NodeTypeReportAfterSuite) {
return suite.pushSuiteNode(node)
}
@ -222,7 +222,7 @@ func (suite *Suite) pushCleanupNode(node Node) error {
node.NodeType = types.NodeTypeCleanupAfterSuite
case types.NodeTypeBeforeAll, types.NodeTypeAfterAll:
node.NodeType = types.NodeTypeCleanupAfterAll
case types.NodeTypeReportBeforeEach, types.NodeTypeReportAfterEach, types.NodeTypeReportAfterSuite:
case types.NodeTypeReportBeforeEach, types.NodeTypeReportAfterEach, types.NodeTypeReportBeforeSuite, types.NodeTypeReportAfterSuite:
return types.GinkgoErrors.PushingCleanupInReportingNode(node.CodeLocation, suite.currentNode.NodeType)
case types.NodeTypeCleanupInvalid, types.NodeTypeCleanupAfterEach, types.NodeTypeCleanupAfterAll, types.NodeTypeCleanupAfterSuite:
return types.GinkgoErrors.PushingCleanupInCleanupNode(node.CodeLocation)
@ -408,7 +408,13 @@ func (suite *Suite) runSpecs(description string, suiteLabels Labels, suitePath s
}
suite.report.SuiteSucceeded = true
suite.runBeforeSuite(numSpecsThatWillBeRun)
suite.runReportSuiteNodesIfNeedBe(types.NodeTypeReportBeforeSuite)
ranBeforeSuite := suite.report.SuiteSucceeded
if suite.report.SuiteSucceeded {
suite.runBeforeSuite(numSpecsThatWillBeRun)
}
if suite.report.SuiteSucceeded {
groupedSpecIndices, serialGroupedSpecIndices := OrderSpecs(specs, suite.config)
@ -447,7 +453,9 @@ func (suite *Suite) runSpecs(description string, suiteLabels Labels, suitePath s
}
}
suite.runAfterSuiteCleanup(numSpecsThatWillBeRun)
if ranBeforeSuite {
suite.runAfterSuiteCleanup(numSpecsThatWillBeRun)
}
interruptStatus := suite.interruptHandler.Status()
if interruptStatus.Interrupted() {
@ -461,9 +469,7 @@ func (suite *Suite) runSpecs(description string, suiteLabels Labels, suitePath s
suite.report.SuiteSucceeded = false
}
if suite.config.ParallelProcess == 1 {
suite.runReportAfterSuite()
}
suite.runReportSuiteNodesIfNeedBe(types.NodeTypeReportAfterSuite)
suite.reporter.SuiteDidEnd(suite.report)
if suite.isRunningInParallel() {
suite.client.PostSuiteDidEnd(suite.report)
@ -530,24 +536,6 @@ func (suite *Suite) runAfterSuiteCleanup(numSpecsThatWillBeRun int) {
}
}
func (suite *Suite) runReportAfterSuite() {
for _, node := range suite.suiteNodes.WithType(types.NodeTypeReportAfterSuite) {
suite.selectiveLock.Lock()
suite.currentSpecReport = types.SpecReport{
LeafNodeType: node.NodeType,
LeafNodeLocation: node.CodeLocation,
LeafNodeText: node.Text,
ParallelProcess: suite.config.ParallelProcess,
RunningInParallel: suite.isRunningInParallel(),
}
suite.selectiveLock.Unlock()
suite.reporter.WillRun(suite.currentSpecReport)
suite.runReportAfterSuiteNode(node, suite.report)
suite.processCurrentSpecReport()
}
}
func (suite *Suite) reportEach(spec Spec, nodeType types.NodeType) {
nodes := spec.Nodes.WithType(nodeType)
if nodeType == types.NodeTypeReportAfterEach {
@ -672,16 +660,57 @@ func (suite *Suite) runSuiteNode(node Node) {
suite.currentSpecReport.RunTime = suite.currentSpecReport.EndTime.Sub(suite.currentSpecReport.StartTime)
suite.currentSpecReport.CapturedGinkgoWriterOutput = string(suite.writer.Bytes())
suite.currentSpecReport.CapturedStdOutErr += suite.outputInterceptor.StopInterceptingAndReturnOutput()
return
}
func (suite *Suite) runReportAfterSuiteNode(node Node, report types.Report) {
func (suite *Suite) runReportSuiteNodesIfNeedBe(nodeType types.NodeType) {
nodes := suite.suiteNodes.WithType(nodeType)
// only run ReportAfterSuite on proc 1
if nodeType.Is(types.NodeTypeReportAfterSuite) && suite.config.ParallelProcess != 1 {
return
}
// if we're running ReportBeforeSuite on proc > 1 - we should wait until proc 1 has completed
if nodeType.Is(types.NodeTypeReportBeforeSuite) && suite.config.ParallelProcess != 1 && len(nodes) > 0 {
state, err := suite.client.BlockUntilReportBeforeSuiteCompleted()
if err != nil || state.Is(types.SpecStateFailed) {
suite.report.SuiteSucceeded = false
}
return
}
for _, node := range nodes {
suite.selectiveLock.Lock()
suite.currentSpecReport = types.SpecReport{
LeafNodeType: node.NodeType,
LeafNodeLocation: node.CodeLocation,
LeafNodeText: node.Text,
ParallelProcess: suite.config.ParallelProcess,
RunningInParallel: suite.isRunningInParallel(),
}
suite.selectiveLock.Unlock()
suite.reporter.WillRun(suite.currentSpecReport)
suite.runReportSuiteNode(node, suite.report)
suite.processCurrentSpecReport()
}
// if we're running ReportBeforeSuite and we're running in parallel - we shuld tell the other procs that we're done
if nodeType.Is(types.NodeTypeReportBeforeSuite) && suite.isRunningInParallel() && len(nodes) > 0 {
if suite.report.SuiteSucceeded {
suite.client.PostReportBeforeSuiteCompleted(types.SpecStatePassed)
} else {
suite.client.PostReportBeforeSuiteCompleted(types.SpecStateFailed)
}
}
}
func (suite *Suite) runReportSuiteNode(node Node, report types.Report) {
suite.writer.Truncate()
suite.outputInterceptor.StartInterceptingOutput()
suite.currentSpecReport.StartTime = time.Now()
if suite.config.ParallelTotal > 1 {
// if we're running a ReportAfterSuite in parallel (on proc 1) we (a) wait until other procs have exited and
// (b) always fetch the latest report as prior ReportAfterSuites will contribute to it
if node.NodeType.Is(types.NodeTypeReportAfterSuite) && suite.isRunningInParallel() {
aggregatedReport, err := suite.client.BlockUntilAggregatedNonprimaryProcsReport()
if err != nil {
suite.currentSpecReport.State, suite.currentSpecReport.Failure = types.SpecStateFailed, suite.failureForLeafNodeWithMessage(node, err.Error())
@ -691,15 +720,13 @@ func (suite *Suite) runReportAfterSuiteNode(node Node, report types.Report) {
report = report.Add(aggregatedReport)
}
node.Body = func(SpecContext) { node.ReportAfterSuiteBody(report) }
node.Body = func(SpecContext) { node.ReportSuiteBody(report) }
suite.currentSpecReport.State, suite.currentSpecReport.Failure = suite.runNode(node, time.Time{}, "")
suite.currentSpecReport.EndTime = time.Now()
suite.currentSpecReport.RunTime = suite.currentSpecReport.EndTime.Sub(suite.currentSpecReport.StartTime)
suite.currentSpecReport.CapturedGinkgoWriterOutput = string(suite.writer.Bytes())
suite.currentSpecReport.CapturedStdOutErr = suite.outputInterceptor.StopInterceptingAndReturnOutput()
return
}
func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (types.SpecState, types.Failure) {

View File

@ -30,6 +30,12 @@ type JunitReportConfig struct {
//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
}
type JUnitTestSuites struct {
@ -172,13 +178,17 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit
}
for _, spec := range report.SpecReports {
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,

View File

@ -35,7 +35,7 @@ func CurrentSpecReport() SpecReport {
}
/*
ReportEntryVisibility governs the visibility of ReportEntries in Ginkgo's console reporter
ReportEntryVisibility governs the visibility of ReportEntries in Ginkgo's console reporter
- ReportEntryVisibilityAlways: the default behavior - the ReportEntry is always emitted.
- ReportEntryVisibilityFailureOrVerbose: the ReportEntry is only emitted if the spec fails or if the tests are run with -v (similar to GinkgoWriters behavior).
@ -50,9 +50,9 @@ const ReportEntryVisibilityAlways, ReportEntryVisibilityFailureOrVerbose, Report
/*
AddReportEntry generates and adds a new ReportEntry to the current spec's SpecReport.
It can take any of the following arguments:
- A single arbitrary object to attach as the Value of the ReportEntry. This object will be included in any generated reports and will be emitted to the console when the report is emitted.
- A ReportEntryVisibility enum to control the visibility of the ReportEntry
- An Offset or CodeLocation decoration to control the reported location of the ReportEntry
- A single arbitrary object to attach as the Value of the ReportEntry. This object will be included in any generated reports and will be emitted to the console when the report is emitted.
- A ReportEntryVisibility enum to control the visibility of the ReportEntry
- An Offset or CodeLocation decoration to control the reported location of the ReportEntry
If the Value object implements `fmt.Stringer`, it's `String()` representation is used when emitting to the console.
@ -100,6 +100,25 @@ func ReportAfterEach(body func(SpecReport), args ...interface{}) bool {
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportAfterEach, "", combinedArgs...))
}
/*
ReportBeforeSuite nodes are run at the beginning of the suite. ReportBeforeSuite nodes take a function that receives a suite Report.
They are called at the beginning of the suite, before any specs have run and any BeforeSuite or SynchronizedBeforeSuite nodes, and are passed in the initial report for the suite.
ReportBeforeSuite nodes must be created at the top-level (i.e. not nested in a Context/Describe/When node)
# When running in parallel, Ginkgo ensures that only one of the parallel nodes runs the ReportBeforeSuite
You cannot nest any other Ginkgo nodes within a ReportAfterSuite node's closure.
You can learn more about ReportAfterSuite here: https://onsi.github.io/ginkgo/#generating-reports-programmatically
You can learn more about Ginkgo's reporting infrastructure, including generating reports with the CLI here: https://onsi.github.io/ginkgo/#generating-machine-readable-reports
*/
func ReportBeforeSuite(body func(Report), args ...interface{}) bool {
combinedArgs := []interface{}{body}
combinedArgs = append(combinedArgs, args...)
return pushNode(internal.NewNode(deprecationTracker, types.NodeTypeReportBeforeSuite, "", combinedArgs...))
}
/*
ReportAfterSuite nodes are run at the end of the suite. ReportAfterSuite nodes take a function that receives a suite Report.
@ -113,6 +132,7 @@ In addition to using ReportAfterSuite to programmatically generate suite reports
You cannot nest any other Ginkgo nodes within a ReportAfterSuite node's closure.
You can learn more about ReportAfterSuite here: https://onsi.github.io/ginkgo/#generating-reports-programmatically
You can learn more about Ginkgo's reporting infrastructure, including generating reports with the CLI here: https://onsi.github.io/ginkgo/#generating-machine-readable-reports
*/
func ReportAfterSuite(text string, body func(Report), args ...interface{}) bool {

View File

@ -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{
@ -320,7 +320,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",
}

View File

@ -58,6 +58,7 @@ 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
}
@ -761,6 +762,7 @@ const (
NodeTypeReportBeforeEach
NodeTypeReportAfterEach
NodeTypeReportBeforeSuite
NodeTypeReportAfterSuite
NodeTypeCleanupInvalid
@ -770,9 +772,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",
@ -790,6 +792,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)",

View File

@ -1,3 +1,3 @@
package types
const VERSION = "2.5.1"
const VERSION = "2.6.0"

View File

@ -374,7 +374,7 @@ github.com/modern-go/concurrent
# github.com/modern-go/reflect2 v1.0.2
## explicit; go 1.12
github.com/modern-go/reflect2
# github.com/onsi/ginkgo/v2 v2.5.1
# github.com/onsi/ginkgo/v2 v2.6.0
## explicit; go 1.18
github.com/onsi/ginkgo/v2
github.com/onsi/ginkgo/v2/config