diff --git a/test/e2e/pkg/resources_test.go b/test/e2e/pkg/resources_test.go index 7e400d6b..eca500f7 100644 --- a/test/e2e/pkg/resources_test.go +++ b/test/e2e/pkg/resources_test.go @@ -27,17 +27,29 @@ var _ = Describe("Resources", Ordered, Label("e2e-tests-resources"), func() { Expect(err).ShouldNot(HaveOccurred()) Expect(resp.StatusCode).To(Equal(http.StatusCreated)) Expect(*resource.Id).ShouldNot(BeEmpty()) + Expect(*resource.Version).To(Equal(int32(1))) Eventually(func() error { - _, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + deploy, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) if err != nil { return err } + if *deploy.Spec.Replicas != 1 { + return fmt.Errorf("unexpected replicas, expected 1, got %d", *deploy.Spec.Replicas) + } return nil }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) }) - It("patch the nginx resource", func() { + It("get the nginx resource from the maestro api", func() { + gotResource, resp, err := apiClient.DefaultApi.ApiMaestroV1ResourcesIdGet(context.Background(), *resource.Id).Execute() + Expect(err).ShouldNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + Expect(*gotResource.Id).To(Equal(*resource.Id)) + Expect(*gotResource.Version).To(Equal(*resource.Version)) + }) + + It("patch the nginx resource with the maestro api", func() { newRes := helper.NewAPIResource(consumer_name, 2) patchedResource, resp, err := apiClient.DefaultApi.ApiMaestroV1ResourcesIdPatch(context.Background(), *resource.Id). @@ -51,10 +63,10 @@ var _ = Describe("Resources", Ordered, Label("e2e-tests-resources"), func() { if err != nil { return err } - if *deploy.Spec.Replicas == 2 { - return nil + if *deploy.Spec.Replicas != 2 { + return fmt.Errorf("unexpected replicas, expected 2, got %d", *deploy.Spec.Replicas) } - return fmt.Errorf("replicas is not 2") + return nil }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) }) @@ -88,10 +100,13 @@ var _ = Describe("Resources", Ordered, Label("e2e-tests-resources"), func() { Expect(*resource.Id).ShouldNot(BeEmpty()) Eventually(func() error { - _, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + deploy, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) if err != nil { return err } + if *deploy.Spec.Replicas != 1 { + return fmt.Errorf("unexpected replicas, expected 1, got %d", *deploy.Spec.Replicas) + } return nil }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) }) @@ -167,10 +182,13 @@ var _ = Describe("Resources", Ordered, Label("e2e-tests-resources"), func() { Expect(*resource.Id).ShouldNot(BeEmpty()) Eventually(func() error { - _, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + deploy, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) if err != nil { return err } + if *deploy.Spec.Replicas != 1 { + return fmt.Errorf("unexpected replicas, expected 1, got %d", *deploy.Spec.Replicas) + } return nil }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) }) @@ -189,10 +207,10 @@ var _ = Describe("Resources", Ordered, Label("e2e-tests-resources"), func() { if err != nil { return err } - if *deploy.Spec.Replicas == 1 { - return nil + if *deploy.Spec.Replicas != 1 { + return fmt.Errorf("unexpected replicas, expected 1, got %d", *deploy.Spec.Replicas) } - return fmt.Errorf("replicas is not 1") + return nil }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) }) @@ -214,5 +232,4 @@ var _ = Describe("Resources", Ordered, Label("e2e-tests-resources"), func() { }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) }) }) - }) diff --git a/test/e2e/pkg/spec_resync_test.go b/test/e2e/pkg/spec_resync_test.go new file mode 100644 index 00000000..ecb7f5d9 --- /dev/null +++ b/test/e2e/pkg/spec_resync_test.go @@ -0,0 +1,355 @@ +package e2e_test + +import ( + "context" + "fmt" + "net/http" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/openshift-online/maestro/pkg/api/openapi" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +var _ = Describe("Spec resync", Ordered, Label("e2e-tests-spec-resync"), func() { + + var resource *openapi.Resource + + Context("Resource resync created resource spec", func() { + + It("shut down maestro agent", func() { + + // patch marstro agent replicas to 0 + deploy, err := kubeClient.AppsV1().Deployments("maestro-agent").Patch(context.Background(), "maestro-agent", types.MergePatchType, []byte(`{"spec":{"replicas":0}}`), metav1.PatchOptions{ + FieldManager: "testKubeClient", + }) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*deploy.Spec.Replicas).To(Equal(int32(0))) + + // ensure no running maestro agent pods + Eventually(func() error { + pods, err := kubeClient.CoreV1().Pods("maestro-agent").List(context.Background(), metav1.ListOptions{ + LabelSelector: "app=maestro-agent", + }) + if err != nil { + return err + } + if len(pods.Items) > 0 { + return fmt.Errorf("maestro-agent pods still running") + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + It("post the nginx resource to the maestro api", func() { + + res := helper.NewAPIResource(consumer_name, 1) + var resp *http.Response + var err error + resource, resp, err = apiClient.DefaultApi.ApiMaestroV1ResourcesPost(context.Background()).Resource(res).Execute() + Expect(err).ShouldNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(http.StatusCreated)) + Expect(*resource.Id).ShouldNot(BeEmpty()) + }) + + It("ensure the resource is not created", func() { + + _, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + Expect(err).Should(HaveOccurred()) + Expect(errors.IsNotFound(err)).To(BeTrue()) + }) + + It("start maestro agent", func() { + + // patch marstro agent replicas to 1 + deploy, err := kubeClient.AppsV1().Deployments("maestro-agent").Patch(context.Background(), "maestro-agent", types.MergePatchType, []byte(`{"spec":{"replicas":1}}`), metav1.PatchOptions{ + FieldManager: "testKubeClient", + }) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*deploy.Spec.Replicas).To(Equal(int32(1))) + + // ensure maestro agent pod is up and running + Eventually(func() error { + pods, err := kubeClient.CoreV1().Pods("maestro-agent").List(context.Background(), metav1.ListOptions{ + LabelSelector: "app=maestro-agent", + }) + if err != nil { + return err + } + if len(pods.Items) != 1 { + return fmt.Errorf("unexpected maestro-agent pod count, expected 1, got %d", len(pods.Items)) + } + if pods.Items[0].Status.Phase != "Running" { + return fmt.Errorf("maestro-agent pod not in running state") + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + It("ensure the resource is created", func() { + + Eventually(func() error { + deploy, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + if err != nil { + return err + } + if *deploy.Spec.Replicas != 1 { + return fmt.Errorf("unexpected replicas, expected 1, got %d", *deploy.Spec.Replicas) + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + It("delete the nginx resource", func() { + + resp, err := apiClient.DefaultApi.ApiMaestroV1ResourcesIdDelete(context.Background(), *resource.Id).Execute() + Expect(err).ShouldNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(http.StatusNoContent)) + + Eventually(func() error { + _, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + if err != nil { + if errors.IsNotFound(err) { + return nil + } + return err + } + return fmt.Errorf("nginx deployment still exists") + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + }) + + Context("Resource resync updated resource spec", func() { + + It("post the nginx resource to the maestro api", func() { + + res := helper.NewAPIResource(consumer_name, 1) + var resp *http.Response + var err error + resource, resp, err = apiClient.DefaultApi.ApiMaestroV1ResourcesPost(context.Background()).Resource(res).Execute() + Expect(err).ShouldNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(http.StatusCreated)) + Expect(*resource.Id).ShouldNot(BeEmpty()) + + Eventually(func() error { + deploy, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + if err != nil { + return err + } + if *deploy.Spec.Replicas != 1 { + return fmt.Errorf("unexpected replicas, expected 1, got %d", *deploy.Spec.Replicas) + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + It("shut down maestro agent", func() { + + // patch marstro agent replicas to 0 + deploy, err := kubeClient.AppsV1().Deployments("maestro-agent").Patch(context.Background(), "maestro-agent", types.MergePatchType, []byte(`{"spec":{"replicas":0}}`), metav1.PatchOptions{ + FieldManager: "testKubeClient", + }) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*deploy.Spec.Replicas).To(Equal(int32(0))) + + // ensure no running maestro agent pods + Eventually(func() error { + pods, err := kubeClient.CoreV1().Pods("maestro-agent").List(context.Background(), metav1.ListOptions{ + LabelSelector: "app=maestro-agent", + }) + if err != nil { + return err + } + if len(pods.Items) > 0 { + return fmt.Errorf("maestro-agent pods still running") + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + It("patch the nginx resource", func() { + + newRes := helper.NewAPIResource(consumer_name, 2) + patchedResource, resp, err := apiClient.DefaultApi.ApiMaestroV1ResourcesIdPatch(context.Background(), *resource.Id). + ResourcePatchRequest(openapi.ResourcePatchRequest{Version: resource.Version, Manifest: newRes.Manifest}).Execute() + Expect(err).ShouldNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + Expect(*patchedResource.Version).To(Equal(*resource.Version + 1)) + + }) + + It("ensure the resource is not updated", func() { + + deploy, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*deploy.Spec.Replicas).To(Equal(int32(1))) + }) + + It("start maestro agent", func() { + + // patch marstro agent replicas to 1 + deploy, err := kubeClient.AppsV1().Deployments("maestro-agent").Patch(context.Background(), "maestro-agent", types.MergePatchType, []byte(`{"spec":{"replicas":1}}`), metav1.PatchOptions{ + FieldManager: "testKubeClient", + }) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*deploy.Spec.Replicas).To(Equal(int32(1))) + + // ensure maestro agent pod is up and running + Eventually(func() error { + pods, err := kubeClient.CoreV1().Pods("maestro-agent").List(context.Background(), metav1.ListOptions{ + LabelSelector: "app=maestro-agent", + }) + if err != nil { + return err + } + if len(pods.Items) != 1 { + return fmt.Errorf("unexpected maestro-agent pod count, expected 1, got %d", len(pods.Items)) + } + if pods.Items[0].Status.Phase != "Running" { + return fmt.Errorf("maestro-agent pod not in running state") + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + It("ensure the resource is updated", func() { + + Eventually(func() error { + deploy, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + if err != nil { + return err + } + if *deploy.Spec.Replicas != 2 { + return fmt.Errorf("unexpected replicas, expected 2, got %d", *deploy.Spec.Replicas) + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + It("delete the nginx resource", func() { + + resp, err := apiClient.DefaultApi.ApiMaestroV1ResourcesIdDelete(context.Background(), *resource.Id).Execute() + Expect(err).ShouldNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(http.StatusNoContent)) + + Eventually(func() error { + _, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + if err != nil { + if errors.IsNotFound(err) { + return nil + } + return err + } + return fmt.Errorf("nginx deployment still exists") + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + }) + + Context("Resource resync deleted resource spec", func() { + + It("post the nginx resource to the maestro api", func() { + + res := helper.NewAPIResource(consumer_name, 1) + var resp *http.Response + var err error + resource, resp, err = apiClient.DefaultApi.ApiMaestroV1ResourcesPost(context.Background()).Resource(res).Execute() + Expect(err).ShouldNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(http.StatusCreated)) + Expect(*resource.Id).ShouldNot(BeEmpty()) + + Eventually(func() error { + deploy, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + if err != nil { + return err + } + if *deploy.Spec.Replicas != 1 { + return fmt.Errorf("unexpected replicas, expected 1, got %d", *deploy.Spec.Replicas) + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + It("shut down maestro agent", func() { + + // patch marstro agent replicas to 0 + deploy, err := kubeClient.AppsV1().Deployments("maestro-agent").Patch(context.Background(), "maestro-agent", types.MergePatchType, []byte(`{"spec":{"replicas":0}}`), metav1.PatchOptions{ + FieldManager: "testKubeClient", + }) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*deploy.Spec.Replicas).To(Equal(int32(0))) + + // ensure no running maestro agent pods + Eventually(func() error { + pods, err := kubeClient.CoreV1().Pods("maestro-agent").List(context.Background(), metav1.ListOptions{ + LabelSelector: "app=maestro-agent", + }) + if err != nil { + return err + } + if len(pods.Items) > 0 { + return fmt.Errorf("maestro-agent pods still running") + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + It("delete the nginx resource", func() { + + resp, err := apiClient.DefaultApi.ApiMaestroV1ResourcesIdDelete(context.Background(), *resource.Id).Execute() + Expect(err).ShouldNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(http.StatusNoContent)) + }) + + It("ensure the resource is not deleted", func() { + + deploy, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*deploy.Spec.Replicas).To(Equal(int32(1))) + }) + + It("start maestro agent", func() { + + // patch marstro agent replicas to 1 + deploy, err := kubeClient.AppsV1().Deployments("maestro-agent").Patch(context.Background(), "maestro-agent", types.MergePatchType, []byte(`{"spec":{"replicas":1}}`), metav1.PatchOptions{ + FieldManager: "testKubeClient", + }) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*deploy.Spec.Replicas).To(Equal(int32(1))) + + // ensure maestro agent pod is up and running + Eventually(func() error { + pods, err := kubeClient.CoreV1().Pods("maestro-agent").List(context.Background(), metav1.ListOptions{ + LabelSelector: "app=maestro-agent", + }) + if err != nil { + return err + } + if len(pods.Items) != 1 { + return fmt.Errorf("unexpected maestro-agent pod count, expected 1, got %d", len(pods.Items)) + } + if pods.Items[0].Status.Phase != "Running" { + return fmt.Errorf("maestro-agent pod not in running state") + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + It("ensure the resource is deleted", func() { + + Eventually(func() error { + _, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + if err != nil { + if errors.IsNotFound(err) { + return nil + } + return err + } + return fmt.Errorf("nginx deployment still exists") + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + }) +}) diff --git a/test/e2e/pkg/status_resync_test.go b/test/e2e/pkg/status_resync_test.go new file mode 100644 index 00000000..6d62da3d --- /dev/null +++ b/test/e2e/pkg/status_resync_test.go @@ -0,0 +1,164 @@ +package e2e_test + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strings" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/openshift-online/maestro/pkg/api/openapi" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +var _ = Describe("Status resync", Ordered, Label("e2e-tests-status-resync"), func() { + + var resource *openapi.Resource + + Context("Resource resync resource status", func() { + + It("post the nginx resource to the maestro api", func() { + + res := helper.NewAPIResource(consumer_name, 1) + var resp *http.Response + var err error + resource, resp, err = apiClient.DefaultApi.ApiMaestroV1ResourcesPost(context.Background()).Resource(res).Execute() + Expect(err).ShouldNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(http.StatusCreated)) + Expect(*resource.Id).ShouldNot(BeEmpty()) + + Eventually(func() error { + deploy, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + if err != nil { + return err + } + if *deploy.Spec.Replicas != 1 { + return fmt.Errorf("unexpected replicas, expected 1, got %d", *deploy.Spec.Replicas) + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + + gotResource, resp, err := apiClient.DefaultApi.ApiMaestroV1ResourcesIdGet(context.Background(), *resource.Id).Execute() + Expect(err).ShouldNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + Expect(*gotResource.Id).To(Equal(*resource.Id)) + Expect(*gotResource.Version).To(Equal(*resource.Version)) + + statusJSON, err := json.Marshal(gotResource.Status) + Expect(err).ShouldNot(HaveOccurred()) + Expect(strings.Contains(string(statusJSON), "testKubeClient")).To(BeFalse()) + }) + + It("shut down maestro server", func() { + + // patch marstro server replicas to 0 + deploy, err := kubeClient.AppsV1().Deployments("maestro").Patch(context.Background(), "maestro", types.MergePatchType, []byte(`{"spec":{"replicas":0}}`), metav1.PatchOptions{ + FieldManager: "testKubeClient", + }) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*deploy.Spec.Replicas).To(Equal(int32(0))) + + // ensure no running maestro server pods + Eventually(func() error { + pods, err := kubeClient.CoreV1().Pods("maestro").List(context.Background(), metav1.ListOptions{ + LabelSelector: "app=maestro", + }) + if err != nil { + return err + } + if len(pods.Items) > 0 { + return fmt.Errorf("maestro server pods still running") + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + It("patch the resource in the cluster", func() { + + deploy, err := kubeClient.AppsV1().Deployments("default").Patch(context.Background(), "nginx", types.MergePatchType, []byte(`{"spec":{"replicas":0}}`), metav1.PatchOptions{ + FieldManager: "testKubeClient", + }) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*deploy.Spec.Replicas).To(Equal(int32(0))) + }) + + It("start maestro server", func() { + + // patch marstro server replicas to 1 + deploy, err := kubeClient.AppsV1().Deployments("maestro").Patch(context.Background(), "maestro", types.MergePatchType, []byte(`{"spec":{"replicas":1}}`), metav1.PatchOptions{ + FieldManager: "testKubeClient", + }) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*deploy.Spec.Replicas).To(Equal(int32(1))) + + // ensure maestro server pod is up and running + Eventually(func() error { + pods, err := kubeClient.CoreV1().Pods("maestro").List(context.Background(), metav1.ListOptions{ + LabelSelector: "app=maestro", + }) + if err != nil { + return err + } + if len(pods.Items) != 1 { + return fmt.Errorf("unexpected maestro server pod count, expected 1, got %d", len(pods.Items)) + } + if pods.Items[0].Status.Phase != "Running" { + return fmt.Errorf("maestro server pod not in running state") + } + return nil + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + It("ensure the resource status is resynced", func() { + Eventually(func() error { + gotResource, resp, err := apiClient.DefaultApi.ApiMaestroV1ResourcesIdGet(context.Background(), *resource.Id).Execute() + if err != nil { + return err + } + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("unexpected status code, expected 200, got %d", resp.StatusCode) + } + if *gotResource.Id != *resource.Id { + return fmt.Errorf("unexpected resource id, expected %s, got %s", *resource.Id, *gotResource.Id) + } + if *gotResource.Version != *resource.Version { + return fmt.Errorf("unexpected resource version, expected %d, got %d", *resource.Version, *gotResource.Version) + } + + statusJSON, err := json.Marshal(gotResource.Status) + if err != nil { + return err + } + if !strings.Contains(string(statusJSON), "testKubeClient") { + return fmt.Errorf("unexpected status, expected testKubeClient, got %s", string(statusJSON)) + } + return nil + }, 2*time.Minute, 2*time.Second).ShouldNot(HaveOccurred()) + }) + + It("delete the nginx resource", func() { + + resp, err := apiClient.DefaultApi.ApiMaestroV1ResourcesIdDelete(context.Background(), *resource.Id).Execute() + Expect(err).ShouldNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(http.StatusNoContent)) + + Eventually(func() error { + _, err := kubeClient.AppsV1().Deployments("default").Get(context.Background(), "nginx", metav1.GetOptions{}) + if err != nil { + if errors.IsNotFound(err) { + return nil + } + return err + } + return fmt.Errorf("nginx deployment still exists") + }, 1*time.Minute, 1*time.Second).ShouldNot(HaveOccurred()) + }) + + }) + +})