From 66440d9796eacf4f6c5f158fd209d0978c848e80 Mon Sep 17 00:00:00 2001 From: Pablo Chacin Date: Tue, 27 Jun 2023 20:53:31 +0200 Subject: [PATCH 1/4] Implement namespace helper for e2e tests Signed-off-by: Pablo Chacin --- pkg/testutils/e2e/kubernetes/doc.go | 2 + .../kubernetes/namespace/keeponfail_test.go | 43 +++++++ .../e2e/kubernetes/namespace/namespace.go | 113 ++++++++++++++++++ .../kubernetes/namespace/namespace_test.go | 66 ++++++++++ 4 files changed, 224 insertions(+) create mode 100644 pkg/testutils/e2e/kubernetes/doc.go create mode 100644 pkg/testutils/e2e/kubernetes/namespace/keeponfail_test.go create mode 100644 pkg/testutils/e2e/kubernetes/namespace/namespace.go create mode 100644 pkg/testutils/e2e/kubernetes/namespace/namespace_test.go diff --git a/pkg/testutils/e2e/kubernetes/doc.go b/pkg/testutils/e2e/kubernetes/doc.go new file mode 100644 index 00000000..e48d324f --- /dev/null +++ b/pkg/testutils/e2e/kubernetes/doc.go @@ -0,0 +1,2 @@ +// Package kubernetes implements helper functions for handling k8s resources in e2e tests +package kubernetes diff --git a/pkg/testutils/e2e/kubernetes/namespace/keeponfail_test.go b/pkg/testutils/e2e/kubernetes/namespace/keeponfail_test.go new file mode 100644 index 00000000..1ad1f893 --- /dev/null +++ b/pkg/testutils/e2e/kubernetes/namespace/keeponfail_test.go @@ -0,0 +1,43 @@ +//go:build keeponfail +// +build keeponfail + +package namespace + +import ( + "context" + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" +) + +// Test_KeepOnFail is expected to fail as it tests the preservation of namespace +// in case of a test failure +// It only runs if the TEST_KEEPONFAIL=true is specified. +func Test_KeepOnFail(t *testing.T) { + client := fake.NewSimpleClientset() + + t.Run("Sub-test", func(t *testing.T) { + _, err := CreateTestNamespace( + context.TODO(), + t, + client, + WithKeepOnFail(true), + WithName("testns"), + ) + if err != nil { + t.Errorf("unexpected error %v", err) + return + } + + t.Fail() + }) + + _, err := client.CoreV1().Namespaces().Get(context.TODO(), "testns", metav1.GetOptions{}) + if err != nil { + t.Errorf("namespace could not be accessed after test failed: %v", err) + return + } + + t.Logf("test succeeded. Namespace %s was preserved after subtest failed", "testns") +} diff --git a/pkg/testutils/e2e/kubernetes/namespace/namespace.go b/pkg/testutils/e2e/kubernetes/namespace/namespace.go new file mode 100644 index 00000000..dd53640c --- /dev/null +++ b/pkg/testutils/e2e/kubernetes/namespace/namespace.go @@ -0,0 +1,113 @@ +// Package namespace implements helper functions for manipulating kubernetes namespaces +package namespace + +import ( + "context" + "fmt" + "testing" + + "github.com/grafana/xk6-disruptor/pkg/utils" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +// TestNamespaceOption allows modifying an TestNamespaceConfig +type TestNamespaceOption func(TestNamespaceConfig) (TestNamespaceConfig, error) + +// TestNamespaceConfig defines the options for creating a test mamespace +type TestNamespaceConfig struct { + keepOnFail bool + random bool + name string +} + +// DefaultNamespaceConfig defines the default options for creating a test namespace +func DefaultNamespaceConfig() TestNamespaceConfig { + return TestNamespaceConfig{ + keepOnFail: true, + random: true, + name: "testns-", + } +} + +// WithPrefix sets the name of the namespace to a random name with the given prefix +func WithPrefix(prefix string) TestNamespaceOption { + return func(c TestNamespaceConfig) (TestNamespaceConfig, error) { + if prefix == "" { + return c, fmt.Errorf("prefix cannot be empty") + } + + c.name = prefix + c.random = true + return c, nil + } +} + +// WithName sets the name of the namespace +func WithName(name string) TestNamespaceOption { + return func(c TestNamespaceConfig) (TestNamespaceConfig, error) { + if name == "" { + return c, fmt.Errorf("name cannot be empty") + } + + c.name = name + c.random = false + return c, nil + } +} + +// WithKeepOnFail indicates if the namespace must be kept in case the test fails +func WithKeepOnFail(keepOnFail bool) TestNamespaceOption { + return func(c TestNamespaceConfig) (TestNamespaceConfig, error) { + c.keepOnFail = keepOnFail + return c, nil + } +} + +func mergeEnvVariables(config TestNamespaceConfig) TestNamespaceConfig { + config.keepOnFail = utils.GetBooleanEnvVar("E2E_KEEPONFAIL", config.keepOnFail) + return config +} + +// CreateTestNamespace creates a namespace for testing +func CreateTestNamespace( + ctx context.Context, + t *testing.T, + k8s kubernetes.Interface, + options ...TestNamespaceOption, +) (string, error) { + var err error + + config := DefaultNamespaceConfig() + for _, option := range options { + config, err = option(config) + if err != nil { + return "", err + } + } + + config = mergeEnvVariables(config) + + ns := &corev1.Namespace{} + if config.random { + ns.ObjectMeta = metav1.ObjectMeta{GenerateName: config.name} + } else { + ns.ObjectMeta = metav1.ObjectMeta{Name: config.name} + } + + ns, err = k8s.CoreV1().Namespaces().Create(ctx, ns, metav1.CreateOptions{}) + if err != nil { + return "", fmt.Errorf("failed to create test namespace %q: %w", config.name, err) + } + + t.Cleanup(func() { + if t.Failed() && config.keepOnFail { + return + } + + _ = k8s.CoreV1().Namespaces().Delete(ctx, config.name, metav1.DeleteOptions{}) + }) + + return ns.GetName(), nil +} diff --git a/pkg/testutils/e2e/kubernetes/namespace/namespace_test.go b/pkg/testutils/e2e/kubernetes/namespace/namespace_test.go new file mode 100644 index 00000000..97fa1114 --- /dev/null +++ b/pkg/testutils/e2e/kubernetes/namespace/namespace_test.go @@ -0,0 +1,66 @@ +package namespace + +import ( + "context" + "testing" + + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/fake" +) + +func Test_CreateNamespace(t *testing.T) { + t.Parallel() + + testCases := []struct { + title string + options []TestNamespaceOption + expectError bool + check func(kubernetes.Interface, string) error + }{ + { + title: "default options", + options: []TestNamespaceOption{}, + expectError: false, + check: func(k8s kubernetes.Interface, ns string) error { + return nil + }, + }, + { + title: "random namespace", + options: []TestNamespaceOption{WithPrefix("prefix-")}, + expectError: false, + check: func(k8s kubernetes.Interface, ns string) error { + return nil + }, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.title, func(t *testing.T) { + t.Parallel() + + client := fake.NewSimpleClientset() + ns, err := CreateTestNamespace(context.TODO(), t, client, tc.options...) + if err != nil && !tc.expectError { + t.Errorf("unexpected error %v", err) + return + } + + if err == nil && tc.expectError { + t.Errorf("should had failed") + return + } + + if err != nil && tc.expectError { + return + } + + err = tc.check(client, ns) + if err != nil { + t.Errorf("%v", err) + return + } + }) + } +} From 676916e55d834b80c0cb30d31688a14d1c185651 Mon Sep 17 00:00:00 2001 From: Pablo Chacin Date: Tue, 27 Jun 2023 20:54:44 +0200 Subject: [PATCH 2/4] Use namespace helper in e2e tests Signed-off-by: Pablo Chacin --- docs/01-development/01-contributing.md | 14 +++++++++----- e2e/agent/agent_e2e_test.go | 18 ++++++++---------- e2e/disruptors/pod_e2e_test.go | 7 +++---- e2e/disruptors/service_e2e_test.go | 8 ++++---- e2e/kubernetes/kubernetes_e2e_test.go | 22 ++++++++++------------ 5 files changed, 34 insertions(+), 35 deletions(-) diff --git a/docs/01-development/01-contributing.md b/docs/01-development/01-contributing.md index 82073866..a0d6df8a 100644 --- a/docs/01-development/01-contributing.md +++ b/docs/01-development/01-contributing.md @@ -205,14 +205,12 @@ func Test_E2E(t *testing.T) { // Execute test on cluster t.Run("Test", func(t *testing.T){ - // create namespace for test - namespace, err := k8s.NamespaceHelper().CreateRandomNamespace(context.TODO(), "test") + // create namespace for test. Will be deleted automatically when the test ends + namespace, err := namespace.CreateNamespace(context.TODO(), t, k8s.Client()) if err != nil { t.Errorf("error creating test namespace: %v", err) return } - // delete test resources when test ends - defer k8s.Client().CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{}) // create test resources using k8s fixtures @@ -260,4 +258,10 @@ It is possible to specify that we want to reuse a test cluster is one exists wit When you don't longer needs the cluster, you can delete it using kind: ```sh kind delete cluster --name= -``` \ No newline at end of file +``` + +### Keeping Kubernetes resources for debugging + +By default, test namespaces created with `CreateTestNamespace` are automatically deleted when a test ends. This is inconvenient for debugging failed tests. + +This behavior is controlled by passing the `WithKeepOnFail` option when creating the namespace or by setting `E2E_KEEPONFAIL=true` in the environment when running an e2e test. \ No newline at end of file diff --git a/e2e/agent/agent_e2e_test.go b/e2e/agent/agent_e2e_test.go index f34c198f..9d69f73e 100644 --- a/e2e/agent/agent_e2e_test.go +++ b/e2e/agent/agent_e2e_test.go @@ -14,10 +14,10 @@ import ( "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/cluster" "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/deploy" "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/fixtures" + "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/kubernetes/namespace" "github.com/grafana/xk6-disruptor/pkg/testutils/kubernetes/builders" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -222,12 +222,12 @@ func Test_Agent(t *testing.T) { tc := tc t.Run(tc.title, func(t *testing.T) { t.Parallel() - namespace, err := k8s.NamespaceHelper().CreateRandomNamespace(context.TODO(), "test-") + + namespace, err := namespace.CreateTestNamespace(context.TODO(), t, k8s.Client()) if err != nil { - t.Errorf("error creating test namespace: %v", err) + t.Errorf("failed to create test namespace: %v", err) return } - defer k8s.Client().CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{}) err = deploy.ExposeApp( k8s, @@ -254,12 +254,11 @@ func Test_Agent(t *testing.T) { t.Run("Prevent execution of multiple commands", func(t *testing.T) { t.Parallel() - namespace, err := k8s.NamespaceHelper().CreateRandomNamespace(context.TODO(), "test-") + namespace, err := namespace.CreateTestNamespace(context.TODO(), t, k8s.Client()) if err != nil { - t.Errorf("error creating test namespace: %v", err) + t.Errorf("failed to create test namespace: %v", err) return } - defer k8s.Client().CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{}) err = deploy.RunPod( k8s, @@ -290,12 +289,11 @@ func Test_Agent(t *testing.T) { t.Run("Non-transparent proxy to upstream service", func(t *testing.T) { t.Parallel() - namespace, err := k8s.NamespaceHelper().CreateRandomNamespace(context.TODO(), "test-") + namespace, err := namespace.CreateTestNamespace(context.TODO(), t, k8s.Client()) if err != nil { - t.Errorf("error creating test namespace: %v", err) + t.Errorf("failed to create test namespace: %v", err) return } - defer k8s.Client().CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{}) err = deploy.ExposeApp( k8s, diff --git a/e2e/disruptors/pod_e2e_test.go b/e2e/disruptors/pod_e2e_test.go index 8ecd43da..a7745ed0 100644 --- a/e2e/disruptors/pod_e2e_test.go +++ b/e2e/disruptors/pod_e2e_test.go @@ -9,7 +9,6 @@ import ( "time" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "github.com/grafana/xk6-disruptor/pkg/disruptors" @@ -18,6 +17,7 @@ import ( "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/cluster" "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/deploy" "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/fixtures" + "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/kubernetes/namespace" ) func Test_PodDisruptor(t *testing.T) { @@ -111,12 +111,11 @@ func Test_PodDisruptor(t *testing.T) { t.Run(tc.title, func(t *testing.T) { t.Parallel() - namespace, err := k8s.NamespaceHelper().CreateRandomNamespace(context.TODO(), "test-pods") + namespace, err := namespace.CreateTestNamespace(context.TODO(), t, k8s.Client()) if err != nil { - t.Errorf("error creating test namespace: %v", err) + t.Errorf("failed to create test namespace: %v", err) return } - defer k8s.Client().CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{}) err = deploy.ExposeApp( k8s, diff --git a/e2e/disruptors/service_e2e_test.go b/e2e/disruptors/service_e2e_test.go index b3dc856a..c995cc84 100644 --- a/e2e/disruptors/service_e2e_test.go +++ b/e2e/disruptors/service_e2e_test.go @@ -9,7 +9,6 @@ import ( "time" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "github.com/grafana/xk6-disruptor/pkg/disruptors" @@ -18,6 +17,8 @@ import ( "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/cluster" "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/deploy" "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/fixtures" + "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/kubernetes/namespace" + ) func Test_ServiceDisruptor(t *testing.T) { @@ -80,12 +81,11 @@ func Test_ServiceDisruptor(t *testing.T) { t.Run(tc.title, func(t *testing.T) { t.Parallel() - namespace, err := k8s.NamespaceHelper().CreateRandomNamespace(context.TODO(), "test-pods") + namespace, err := namespace.CreateTestNamespace(context.TODO(), t, k8s.Client()) if err != nil { - t.Errorf("error creating test namespace: %v", err) + t.Errorf("failed to create test namespace: %v", err) return } - defer k8s.Client().CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{}) err = deploy.ExposeApp( k8s, diff --git a/e2e/kubernetes/kubernetes_e2e_test.go b/e2e/kubernetes/kubernetes_e2e_test.go index 6efa43af..208befb4 100644 --- a/e2e/kubernetes/kubernetes_e2e_test.go +++ b/e2e/kubernetes/kubernetes_e2e_test.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/cluster" "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/deploy" "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/fixtures" + "github.com/grafana/xk6-disruptor/pkg/testutils/e2e/kubernetes/namespace" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -58,14 +59,14 @@ func Test_Kubernetes(t *testing.T) { } }) + // Test Wait Pod Running t.Run("Wait Pod is Running", func(t *testing.T) { - namespace, err := k8s.NamespaceHelper().CreateRandomNamespace(context.TODO(), "test-") + namespace, err := namespace.CreateTestNamespace(context.TODO(), t, k8s.Client()) if err != nil { - t.Errorf("error creating test namespace: %v", err) + t.Errorf("failed to create test namespace: %v", err) return } - defer k8s.Client().CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{}) // Deploy nginx _, err = k8s.Client().CoreV1().Pods(namespace).Create( @@ -92,12 +93,11 @@ func Test_Kubernetes(t *testing.T) { // Test Wait Service Ready helper t.Run("Wait Service Ready", func(t *testing.T) { - namespace, err := k8s.NamespaceHelper().CreateRandomNamespace(context.TODO(), "test-") + namespace, err := namespace.CreateTestNamespace(context.TODO(), t, k8s.Client()) if err != nil { - t.Errorf("error creating test namespace: %v", err) + t.Errorf("failed to create test namespace: %v", err) return } - defer k8s.Client().CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{}) // Deploy nginx and expose it as a service. Intentionally not using e2e fixures // because these functions rely on WaitPodRunnin and WaitServiceReady which we @@ -131,12 +131,11 @@ func Test_Kubernetes(t *testing.T) { }) t.Run("Exec Command", func(t *testing.T) { - namespace, err := k8s.NamespaceHelper().CreateRandomNamespace(context.TODO(), "test-") + namespace, err := namespace.CreateTestNamespace(context.TODO(), t, k8s.Client()) if err != nil { - t.Errorf("error creating test namespace: %v", err) + t.Errorf("failed to create test namespace: %v", err) return } - defer k8s.Client().CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{}) err = deploy.RunPod(k8s, namespace, fixtures.BuildBusyBoxPod(), 10*time.Second) if err != nil { @@ -163,12 +162,11 @@ func Test_Kubernetes(t *testing.T) { }) t.Run("Attach Ephemeral Container", func(t *testing.T) { - namespace, err := k8s.NamespaceHelper().CreateRandomNamespace(context.TODO(), "test-") + namespace, err := namespace.CreateTestNamespace(context.TODO(), t, k8s.Client()) if err != nil { - t.Errorf("error creating test namespace: %v", err) + t.Errorf("failed to create test namespace: %v", err) return } - defer k8s.Client().CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{}) err = deploy.RunPod(k8s, namespace, fixtures.BuildPausedPod(), 10*time.Second) if err != nil { From a14874871ed61fe9aec938765d47c039e80a042d Mon Sep 17 00:00:00 2001 From: Pablo Chacin Date: Tue, 27 Jun 2023 20:57:40 +0200 Subject: [PATCH 3/4] Remove unused namepace helper Signed-off-by: Pablo Chacin --- e2e/kubernetes/kubernetes_e2e_test.go | 22 -------------- pkg/kubernetes/fake.go | 7 ----- pkg/kubernetes/helpers/fake.go | 14 --------- pkg/kubernetes/helpers/namespaces.go | 43 --------------------------- pkg/kubernetes/kubernetes.go | 9 ------ 5 files changed, 95 deletions(-) delete mode 100644 pkg/kubernetes/helpers/namespaces.go diff --git a/e2e/kubernetes/kubernetes_e2e_test.go b/e2e/kubernetes/kubernetes_e2e_test.go index 208befb4..ce635ae7 100644 --- a/e2e/kubernetes/kubernetes_e2e_test.go +++ b/e2e/kubernetes/kubernetes_e2e_test.go @@ -5,7 +5,6 @@ package e2e import ( "context" - "strings" "testing" "time" @@ -39,27 +38,6 @@ func Test_Kubernetes(t *testing.T) { return } - kubeconfig := cluster.Kubeconfig() - - // Test Creating a random namespace - t.Run("Create Random Namespace", func(t *testing.T) { - k8s, err := kubernetes.NewFromKubeconfig(kubeconfig) - if err != nil { - t.Errorf("error creating kubernetes client: %v", err) - return - } - prefix := "test" - ns, err := k8s.NamespaceHelper().CreateRandomNamespace(context.TODO(), prefix) - if err != nil { - t.Errorf("unexpected error creating namespace: %v", err) - return - } - if !strings.HasPrefix(ns, prefix) { - t.Errorf("returned namespace does not have expected prefix '%s': %s", prefix, ns) - } - }) - - // Test Wait Pod Running t.Run("Wait Pod is Running", func(t *testing.T) { namespace, err := namespace.CreateTestNamespace(context.TODO(), t, k8s.Client()) diff --git a/pkg/kubernetes/fake.go b/pkg/kubernetes/fake.go index 8feecb05..ad51829c 100644 --- a/pkg/kubernetes/fake.go +++ b/pkg/kubernetes/fake.go @@ -43,13 +43,6 @@ func (f *FakeKubernetes) ServiceHelper(namespace string) helpers.ServiceHelper { ) } -// NamespaceHelper returns a NamespaceHelper for the given namespace -func (f *FakeKubernetes) NamespaceHelper() helpers.NamespaceHelper { - return helpers.NewFakeNamespaceHelper( - f.client, - ) -} - // Client return a kubernetes client func (f *FakeKubernetes) Client() kubernetes.Interface { return f.client diff --git a/pkg/kubernetes/helpers/fake.go b/pkg/kubernetes/helpers/fake.go index f443d2e7..196499ab 100644 --- a/pkg/kubernetes/helpers/fake.go +++ b/pkg/kubernetes/helpers/fake.go @@ -105,20 +105,6 @@ func NewFakeServiceHelper( } } -// fakeNamespaceHelper is an fake instance of a NamespaceHelper. It can delegate to the actual -// helper the execution of actions or override them when needed -type fakeNamespaceHelper struct { - NamespaceHelper -} - -// NewFakeNamespaceHelper creates a set of a NamespaceHelper on the default namespace -func NewFakeNamespaceHelper(client kubernetes.Interface) NamespaceHelper { - h := NewNamespaceHelper(client) - return &fakeNamespaceHelper{ - h, - } -} - // FakeHTTPClient implement a fake HTTPClient that returns a fixed response. // When invoked, it records the request it received type FakeHTTPClient struct { diff --git a/pkg/kubernetes/helpers/namespaces.go b/pkg/kubernetes/helpers/namespaces.go deleted file mode 100644 index e8871ae9..00000000 --- a/pkg/kubernetes/helpers/namespaces.go +++ /dev/null @@ -1,43 +0,0 @@ -package helpers - -import ( - "context" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" -) - -// NamespaceHelper defines helper methods for handling namespaces -type NamespaceHelper interface { - // CreateRandomNamespace creates a namespace with a random name starting with - // the provided prefix and returns its name - CreateRandomNamespace(ctx context.Context, prefix string) (string, error) -} - -// helpers struct holds the data required by the helpers -type nsHelper struct { - client kubernetes.Interface -} - -// NewNamespaceHelper creates a namespace helper -func NewNamespaceHelper(client kubernetes.Interface) NamespaceHelper { - return &nsHelper{ - client: client, - } -} - -func (h *nsHelper) CreateRandomNamespace(ctx context.Context, prefix string) (string, error) { - ns, err := h.client.CoreV1().Namespaces().Create( - ctx, - &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{GenerateName: prefix}, - }, - metav1.CreateOptions{}, - ) - if err != nil { - return "", err - } - - return ns.GetName(), nil -} diff --git a/pkg/kubernetes/kubernetes.go b/pkg/kubernetes/kubernetes.go index c8f6d82d..d15f22c3 100644 --- a/pkg/kubernetes/kubernetes.go +++ b/pkg/kubernetes/kubernetes.go @@ -23,8 +23,6 @@ type Kubernetes interface { ServiceHelper(namespace string) helpers.ServiceHelper // PodHelper returns a helpers.PodHelper scoped for the given namespace PodHelper(namespace string) helpers.PodHelper - // NamespaceHelper returns a namespace helper - NamespaceHelper() helpers.NamespaceHelper } // k8s Holds the reference to the helpers for interacting with kubernetes @@ -127,13 +125,6 @@ func (k *k8s) PodHelper(namespace string) helpers.PodHelper { ) } -// NamespaceHelper returns a NamespaceHelper -func (k *k8s) NamespaceHelper() helpers.NamespaceHelper { - return helpers.NewNamespaceHelper( - k.Interface, - ) -} - func (k *k8s) Client() kubernetes.Interface { return k.Interface } From 24aa071b09a9d1cde0dbb332b79a617445672f7f Mon Sep 17 00:00:00 2001 From: Pablo Chacin Date: Fri, 30 Jun 2023 11:43:47 +0200 Subject: [PATCH 4/4] Fix namespace tests Signed-off-by: Pablo Chacin --- .../kubernetes/namespace/namespace_test.go | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/pkg/testutils/e2e/kubernetes/namespace/namespace_test.go b/pkg/testutils/e2e/kubernetes/namespace/namespace_test.go index 97fa1114..59c66b41 100644 --- a/pkg/testutils/e2e/kubernetes/namespace/namespace_test.go +++ b/pkg/testutils/e2e/kubernetes/namespace/namespace_test.go @@ -2,12 +2,34 @@ package namespace import ( "context" + "fmt" + "regexp" "testing" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/rand" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/fake" + k8stesting "k8s.io/client-go/testing" ) +// generates name for a resource +func generateName(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { + //nolint:forcetypeassert + ret = action.(k8stesting.CreateAction).GetObject() + meta, ok := ret.(metav1.Object) + if !ok { + return + } + + if meta.GetName() == "" && meta.GetGenerateName() != "" { + meta.SetName(meta.GetGenerateName() + rand.String(5)) + } + + return +} + func Test_CreateNamespace(t *testing.T) { t.Parallel() @@ -22,14 +44,22 @@ func Test_CreateNamespace(t *testing.T) { options: []TestNamespaceOption{}, expectError: false, check: func(k8s kubernetes.Interface, ns string) error { + match, _ := regexp.MatchString(`testns-[a-z|0-9]+`, ns) + if !match { + return fmt.Errorf("expected pattern 'testns-xxxxx' got %q", ns) + } return nil }, }, { - title: "random namespace", - options: []TestNamespaceOption{WithPrefix("prefix-")}, + title: "fixed name", + options: []TestNamespaceOption{WithName("testns")}, expectError: false, check: func(k8s kubernetes.Interface, ns string) error { + if ns != "testns" { + return fmt.Errorf("expected 'testns' got %q", ns) + } + return nil }, }, @@ -41,6 +71,9 @@ func Test_CreateNamespace(t *testing.T) { t.Parallel() client := fake.NewSimpleClientset() + // Fake client does not support generated named + client.PrependReactor("create", "*", generateName) + ns, err := CreateTestNamespace(context.TODO(), t, client, tc.options...) if err != nil && !tc.expectError { t.Errorf("unexpected error %v", err)