diff --git a/Makefile b/Makefile index ea3554e6..aafd05d2 100644 --- a/Makefile +++ b/Makefile @@ -72,6 +72,7 @@ SHELL = /usr/bin/env bash -o pipefail NAMESPACE_FOR_TESTING ?= "jws-operator-tests" TEST_IMG ?= "quay.io/web-servers/tomcat10:latest" +TEST_IMG_UPDATE ?= "quay.io/web-servers/tomcat10update:latest" EXECUTE_TEST ?= "WebServerControllerTest" .PHONY: all @@ -153,7 +154,7 @@ cleanup-test-e2e: ## Tear down the Kind cluster used for e2e tests # Prerequisite: the operator is installed and avialable in the cluster .PHONY: test-e2e-real test-e2e-real: setup-namespace generate fmt vet - NAMESPACE_FOR_TESTING=$(NAMESPACE_FOR_TESTING) TEST_IMG=$(TEST_IMG) go test ./test/e2e/ -v -timeout=60m -ginkgo.vv -ginkgo.focus $(EXECUTE_TEST) $(TEST_PARAM) + NAMESPACE_FOR_TESTING=$(NAMESPACE_FOR_TESTING) TEST_IMG_UPDATE=$(TEST_IMG_UPDATE) TEST_IMG=$(TEST_IMG) go test ./test/e2e/ -v -timeout=60m -ginkgo.vv -ginkgo.focus $(EXECUTE_TEST) $(TEST_PARAM) .PHONY: setup-namespace setup-namespace: diff --git a/README.md b/README.md index 543837d6..14642ae2 100644 --- a/README.md +++ b/README.md @@ -307,7 +307,8 @@ make test-e2e-real Testing can be configured via environment variables: - NAMESPACE_FOR_TESTING - Namespace where webservers will be deployed. Default value: ```jws-operator-tests``` - - TEST_IMG - Default image for tests which do not require specific image. Default value: ```quay.io/web-servers/tomcat-demo``` + - TEST_IMG_UPDATE - The image required for the Update test. Default value: ```quay.io/web-servers/tomcat10update:latest``` + - TEST_IMG - Default image for tests which do not require specific image. Default value: ```quay.io/web-servers/tomcat10:latest``` - EXECUTE_TEST - Comma-separated list of test which will be executed. - TEST_PARAM - additional ginkgo settings. diff --git a/test/e2e/application_image_test.go b/test/e2e/application_image_test.go index 89f080b6..e58ee517 100644 --- a/test/e2e/application_image_test.go +++ b/test/e2e/application_image_test.go @@ -23,11 +23,8 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/types" - webserversv1alpha1 "github.com/web-servers/jws-operator/api/v1alpha1" "github.com/web-servers/jws-operator/test/utils" - kbappsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -39,8 +36,6 @@ var _ = Describe("WebServerControllerTest", Ordered, func() { name := "image-basic-test" appName := "test-tomcat-demo" testURI := "/health" - image := "quay.io/web-servers/tomcat10:latest" - newImage := "quay.io/web-servers/tomcat10update:latest" webserver := &webserversv1alpha1.WebServer{ TypeMeta: metav1.TypeMeta{ @@ -55,7 +50,7 @@ var _ = Describe("WebServerControllerTest", Ordered, func() { ApplicationName: appName, Replicas: int32(2), WebImage: &webserversv1alpha1.WebImageSpec{ - ApplicationImage: image, + ApplicationImage: testImg, }, }, } @@ -70,6 +65,8 @@ var _ = Describe("WebServerControllerTest", Ordered, func() { Context("ApplicationImageTest", func() { It("Basic Test", func() { + // Checks if Web Server was deployed with the PREVIOUS version of the image + waitForPodsActiveState(name) _, err := utils.WebServerRouteTest(k8sClient, ctx, thetest, webserver, testURI, false, nil, false) Expect(err).Should(Succeed()) }) @@ -80,7 +77,7 @@ var _ = Describe("WebServerControllerTest", Ordered, func() { // Update WebImage and update WebServer Eventually(func() bool { createdWebserver = getWebServer(name) - createdWebserver.Spec.WebImage.ApplicationImage = newImage + createdWebserver.Spec.WebImage.ApplicationImage = testImgUpdate err := k8sClient.Update(ctx, createdWebserver) if err != nil { @@ -91,24 +88,10 @@ var _ = Describe("WebServerControllerTest", Ordered, func() { return true }, time.Second*30, time.Millisecond*250).Should(BeTrue()) - foundDeployment := &kbappsv1.Deployment{} - - // Wait until the replicas are available - Eventually(func() bool { - err := k8sClient.Get(ctx, types.NamespacedName{Name: appName, Namespace: namespace}, foundDeployment) - if err != nil { - thetest.Fatalf("can't read Deployment") - return false - } - - foundImage := foundDeployment.Spec.Template.Spec.Containers[0].Image - if foundImage != newImage { - return false - } - - return createdWebserver.Spec.Replicas == foundDeployment.Status.AvailableReplicas - }, time.Second*420, time.Second*30).Should(BeTrue(), "Image Update Test: Required amount of replicas with updated image were not achieved") + waitForPodsActiveState(name) + isApplicationImageWasUpdated(createdWebserver, testImg) + // Checks if Web Server was deployed with the NEW version of the image _, err := utils.WebServerRouteTest(k8sClient, ctx, thetest, webserver, testURI, false, nil, false) Expect(err).Should(Succeed()) }) diff --git a/test/e2e/e2e_suite_test.go b/test/e2e/e2e_suite_test.go index edbddadd..674c7376 100644 --- a/test/e2e/e2e_suite_test.go +++ b/test/e2e/e2e_suite_test.go @@ -55,14 +55,15 @@ var ( // isCertManagerAlreadyInstalled will be set true when CertManager CRDs be found on the cluster isCertManagerAlreadyInstalled = false - cfg *rest.Config - k8sClient client.Client - restClient *rest.RESTClient - clientset *kubernetes.Clientset - ctx context.Context - thetest *testing.T - testImg = os.Getenv("TEST_IMG") - namespace = os.Getenv("NAMESPACE_FOR_TESTING") + cfg *rest.Config + k8sClient client.Client + restClient *rest.RESTClient + clientset *kubernetes.Clientset + ctx context.Context + thetest *testing.T + testImg = os.Getenv("TEST_IMG") + testImgUpdate = os.Getenv("TEST_IMG_UPDATE") + namespace = os.Getenv("NAMESPACE_FOR_TESTING") ) // TestE2E runs the end-to-end (e2e) test suite for the project. These tests execute in an isolated, diff --git a/test/e2e/testHelper_test.go b/test/e2e/testHelper_test.go index b08ef177..532ef955 100644 --- a/test/e2e/testHelper_test.go +++ b/test/e2e/testHelper_test.go @@ -12,6 +12,7 @@ import ( . "github.com/onsi/gomega" imagev1 "github.com/openshift/api/image/v1" webserversv1alpha1 "github.com/web-servers/jws-operator/api/v1alpha1" + kbappsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" @@ -214,7 +215,7 @@ func checkOperatorLogs() { fmt.Println(">>>> Pod's log <<<<") fmt.Println(buffer.String()) fmt.Println(">>>> Pod's log <<<<") - Expect(true).Should(BeFalse()) + Expect(true).Should(BeFalse(), "The operator logs should not contain an error massage") } } @@ -370,3 +371,48 @@ func waitForBuildPodsToSucceed() { return true }, time.Minute*5, time.Second*5).Should(BeTrue(), "Building pods took too long time.") } + +func waitForPodsActiveState(webserverName string) { + foundDeployment := &kbappsv1.Deployment{} + + Eventually(func() bool { + createdWebserver := getWebServer(webserverName) + webserverNamespacedName := types.NamespacedName{Name: webserverName, Namespace: createdWebserver.ObjectMeta.Namespace} + + err := k8sClient.Get(ctx, webserverNamespacedName, foundDeployment) + + if err != nil { + thetest.Fatalf("can't read Deployment") + return false + } + + // Checks pods state in the operator + if int(createdWebserver.Spec.Replicas) != len(createdWebserver.Status.Pods) { + return false + } + for _, pod := range createdWebserver.Status.Pods { + if pod.State != webserversv1alpha1.PodStateActive { + fmt.Printf("Pod %s is in state %s\n", pod.Name, pod.State) + return false + } + } + + // Checks pods state in the cluster + return createdWebserver.Spec.Replicas == foundDeployment.Status.AvailableReplicas + }, time.Second*420, time.Second*30).Should(BeTrue(), "Image Update Test: Required amount of replicas with updated image were not achieved") +} + +func isApplicationImageWasUpdated(createdWebserver *webserversv1alpha1.WebServer, oldImage string) bool { + foundDeployment := &kbappsv1.Deployment{} + webserverNamespacedName := types.NamespacedName{Name: createdWebserver.Name, Namespace: createdWebserver.Namespace} + + err := k8sClient.Get(ctx, webserverNamespacedName, foundDeployment) + + if err != nil { + thetest.Fatalf("can't read Deployment") + return false + } + + foundImage := foundDeployment.Spec.Template.Spec.Containers[0].Image + return foundImage != oldImage +}