Skip to content
This repository has been archived by the owner on Feb 16, 2024. It is now read-only.

[Feature] : Halt testing upon the first failure #31

Merged
merged 4 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crds/testsuite-json-schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ properties:
description: If set, do not delete the mocked control plane or kind cluster.
type: boolean
default: false
stopOnFirstFailure:
description: StopOnFirstFailure determines whether the test should stop upon encountering the first failure.
type: boolean
default: false
timeout:
description: Override the default timeout of 30 seconds (in seconds).
type: integer
Expand Down
4 changes: 4 additions & 0 deletions crds/testsuite_crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ spec:
description: If set, do not delete the mocked control plane or kind cluster.
type: boolean
default: false
stopOnFirstFailure:
description: StopOnFirstFailure determines whether the test should stop upon encountering the first failure.
type: boolean
default: false
timeout:
description: Override the default timeout of 30 seconds (in seconds).
type: integer
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/testharness/v1beta1/test_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ type TestSuite struct {
SkipDelete bool `json:"skipDelete"`
// If set, do not delete the mocked control plane or kind cluster.
SkipClusterDelete bool `json:"skipClusterDelete"`
// StopOnFirstFailure determines whether the test should stop upon encountering the first failure.
StopOnFirstFailure bool `json:"stopOnFirstFailure"`
// Override the default timeout of 30 seconds (in seconds).
// +kubebuilder:validation:Format:=int64
Timeout int `json:"timeout"`
Expand Down
6 changes: 6 additions & 0 deletions pkg/kuttlctl/cmd/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func newTestCmd() *cobra.Command { //nolint:gocyclo
kindContext := ""
skipDelete := false
skipClusterDelete := false
stopOnFirstFailure := false
parallel := 0
artifactsDir := ""
mockControllerFile := ""
Expand Down Expand Up @@ -161,6 +162,10 @@ For more detailed documentation, visit: https://kuttl.dev`,
options.SkipClusterDelete = skipClusterDelete
}

if isSet(flags, "stop-on-first-failure") {
options.StopOnFirstFailure = stopOnFirstFailure
}

if isSet(flags, "parallel") {
options.Parallel = parallel
}
Expand Down Expand Up @@ -253,6 +258,7 @@ For more detailed documentation, visit: https://kuttl.dev`,
testCmd.Flags().StringVar(&artifactsDir, "artifacts-dir", "", "Directory to output kind logs to (if not specified, the current working directory).")
testCmd.Flags().BoolVar(&skipDelete, "skip-delete", false, "If set, do not delete resources created during tests (helpful for debugging test failures, implies --skip-cluster-delete).")
testCmd.Flags().BoolVar(&skipClusterDelete, "skip-cluster-delete", false, "If set, do not delete the mocked control plane or kind cluster.")
testCmd.Flags().BoolVar(&stopOnFirstFailure, "stop-on-first-failure", false, "Stop testing upon the first failure encountered")
// The default value here is only used for the help message. The default is actually enforced in RunTests.
testCmd.Flags().IntVar(&parallel, "parallel", 8, "The maximum number of tests to run at once.")
testCmd.Flags().IntVar(&timeout, "timeout", 30, "The timeout to use as default for TestSuite configuration.")
Expand Down
17 changes: 17 additions & 0 deletions pkg/test/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ func (h *Harness) RunTests() {
}
}

failureOccurred := false

h.T.Run("harness", func(t *testing.T) {
for testDir, tests := range realTestSuite {
h.T.Logf("testsuite: %s has %d tests", testDir, len(tests))
Expand Down Expand Up @@ -428,8 +430,23 @@ func (h *Harness) RunTests() {

tc := report.NewCase(name)
test.Run(t, tc)
if tc.Failure != nil {
// assuming tc.Failure is set when a test case fails
failureOccurred = true
}
suite.AddTestcase(tc)
// Check after every test case if a failure has occurred
if failureOccurred && h.TestSuite.StopOnFirstFailure {
t.SkipNow()
return
}
})
if failureOccurred && h.TestSuite.StopOnFirstFailure {
break
}
}
if failureOccurred && h.TestSuite.StopOnFirstFailure {
break
}
}
})
Expand Down