Skip to content
Open
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
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 @@ -65,6 +65,8 @@ type TestSuite struct {
// Any other value is the name of the namespace to use. This namespace will be created if it does not exist and will
// be removed it was created (unless --skipDelete is used).
Namespace string `json:"namespace"`
// BlockOnNamespaceDelete determines if the test suite should wait until a namespace is deleted before it finishes
BlockOnNamespaceDelete bool `json:"blockOnNamespaceDelete"`
// Suppress is used to suppress logs
Suppress []string `json:"suppress"`
}
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 @@ -51,6 +51,7 @@ func newTestCmd() *cobra.Command {
startKIND := false
kindConfig := ""
kindContext := ""
blockOnNamespaceDelete := false
skipDelete := false
skipClusterDelete := false
parallel := 0
Expand Down Expand Up @@ -182,6 +183,10 @@ For more detailed documentation, visit: https://kuttl.dev`,
options.Namespace = namespace
}

if isSet(flags, "block-on-namespace-delete") {
options.BlockOnNamespaceDelete = blockOnNamespaceDelete
}

if isSet(flags, "suppress-log") {
suppressSet := make(map[string]struct{})
for _, s := range append(options.Suppress, suppress...) {
Expand Down Expand Up @@ -251,6 +256,7 @@ For more detailed documentation, visit: https://kuttl.dev`,
testCmd.Flags().IntVar(&timeout, "timeout", 30, "The timeout to use as default for TestSuite configuration.")
testCmd.Flags().StringVar(&reportFormat, "report", "", "Specify JSON|XML for report. Report location determined by --artifacts-dir.")
testCmd.Flags().StringVarP(&namespace, "namespace", "n", "", "Namespace to use for tests. Provided namespaces must exist prior to running tests.")
testCmd.Flags().BoolVar(&blockOnNamespaceDelete, "block-on-namespace-delete", false, "Block the test harness until the namespace is deleted")
testCmd.Flags().StringSliceVar(&suppress, "suppress-log", []string{}, "Suppress logging for these kinds of logs (events).")
// This cannot be a global flag because pkg/test/utils.RunTests calls flag.Parse which barfs on unknown top-level flags.
// Putting it here at least does not advertise it on a level where using it is impossible.
Expand Down
38 changes: 29 additions & 9 deletions pkg/test/case.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
eventsbeta1 "k8s.io/api/events/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/discovery"
"sigs.k8s.io/controller-runtime/pkg/client"

Expand All @@ -33,12 +34,13 @@ var testStepRegex = regexp.MustCompile(`^(\d+)-(?:[^\.]+)(?:\.yaml)?$`)
// Case contains all of the test steps and the Kubernetes client and other global configuration
// for a test.
type Case struct {
Steps []*Step
Name string
Dir string
SkipDelete bool
Timeout int
PreferredNamespace string
Steps []*Step
Name string
Dir string
SkipDelete bool
Timeout int
PreferredNamespace string
BlockOnNamespaceDelete bool

Client func(forceNew bool) (client.Client, error)
DiscoveryClient func() (discovery.DiscoveryInterface, error)
Expand Down Expand Up @@ -69,14 +71,32 @@ func (t *Case) DeleteNamespace(cl client.Client, ns *namespace) error {
defer cancel()
}

return cl.Delete(ctx, &corev1.Namespace{
nsobj := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: ns.Name,
},
TypeMeta: metav1.TypeMeta{
Kind: "Namespace",
Kind: "Namespace",
APIVersion: "v1",
},
})
}

if err := cl.Delete(ctx, nsobj); err != nil {
return err
}

if t.BlockOnNamespaceDelete {
t.Logger.Log("Blocking until namespace is deleted:", ns.Name)
return wait.PollImmediateUntil(100*time.Millisecond, func() (done bool, err error) {
err = cl.Get(ctx, client.ObjectKeyFromObject(nsobj), &corev1.Namespace{})
if err == nil || !errors.IsNotFound(err) {
return false, err
}
return true, nil
}, ctx.Done())
}

return nil
}

// CreateNamespace creates a namespace in Kubernetes to use for a test.
Expand Down
15 changes: 8 additions & 7 deletions pkg/test/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,14 @@ func (h *Harness) LoadTests(dir string) ([]*Case, error) {
}

tests = append(tests, &Case{
Timeout: timeout,
Steps: []*Step{},
Name: file.Name(),
PreferredNamespace: h.TestSuite.Namespace,
Dir: filepath.Join(dir, file.Name()),
SkipDelete: h.TestSuite.SkipDelete,
Suppress: h.TestSuite.Suppress,
Timeout: timeout,
Steps: []*Step{},
Name: file.Name(),
PreferredNamespace: h.TestSuite.Namespace,
Dir: filepath.Join(dir, file.Name()),
BlockOnNamespaceDelete: h.TestSuite.BlockOnNamespaceDelete,
SkipDelete: h.TestSuite.SkipDelete,
Suppress: h.TestSuite.Suppress,
})
}

Expand Down