From 271504568ad9f618080bb6281593923c9ecfa4d8 Mon Sep 17 00:00:00 2001 From: Vincent Hou Date: Wed, 5 Feb 2020 10:24:15 -0500 Subject: [PATCH 1/3] Add upgrade tests into the e2e-tests-latest-eventing This PR adds the tests to verify the correct number and names of knative eventing deployments. The test tag postupgrade is added, marking the tests to run after upgrade to the latest HEAD of operator, with the latest generated manifest of knative eventing. --- test/{e2e/e2e.go => client/common.go} | 5 +- test/e2e-upgrade-tests.sh | 6 +- test/e2e/knativeeventingdeployment_test.go | 115 ++-------------- test/resources/verify.go | 139 ++++++++++++++++++++ test/upgrade/knativeeventingupgrade_test.go | 95 +++++++++++++ 5 files changed, 250 insertions(+), 110 deletions(-) rename test/{e2e/e2e.go => client/common.go} (95%) create mode 100644 test/resources/verify.go create mode 100644 test/upgrade/knativeeventingupgrade_test.go diff --git a/test/e2e/e2e.go b/test/client/common.go similarity index 95% rename from test/e2e/e2e.go rename to test/client/common.go index 1d250ae4..2a105607 100644 --- a/test/e2e/e2e.go +++ b/test/client/common.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +Copyright 2020 The Knative Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -11,7 +11,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package e2e +package client import ( "testing" @@ -20,6 +20,7 @@ import ( // Apparently just importing it is enough. @_@ side effects @_@. // https://github.com/kubernetes/client-go/issues/242 _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" + "knative.dev/eventing-operator/test" pkgTest "knative.dev/pkg/test" ) diff --git a/test/e2e-upgrade-tests.sh b/test/e2e-upgrade-tests.sh index 9115b81a..ab35cd65 100755 --- a/test/e2e-upgrade-tests.sh +++ b/test/e2e-upgrade-tests.sh @@ -95,12 +95,14 @@ function generate_latest_eventing_manifest() { # Skip installing istio as an add-on initialize $@ --skip-istio-addon +TIMEOUT=20m + # If we got this far, the operator installed Knative Eventing header "Running tests for Knative Eventing Operator" failed=0 -# Run the integration tests -go_test_e2e -timeout=20m ./test/e2e || failed=1 +# Run the postupgrade tests +go_test_e2e -tags=postupgrade -timeout=${TIMEOUT} ./test/upgrade || failed=1 # Require that tests succeeded. (( failed )) && fail_test diff --git a/test/e2e/knativeeventingdeployment_test.go b/test/e2e/knativeeventingdeployment_test.go index bb4ff847..f0c96ea8 100644 --- a/test/e2e/knativeeventingdeployment_test.go +++ b/test/e2e/knativeeventingdeployment_test.go @@ -1,7 +1,7 @@ // +build e2e /* -Copyright 2019 The Knative Authors +Copyright 2020 The Knative Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -16,17 +16,15 @@ limitations under the License. package e2e import ( - "errors" - "path/filepath" - "runtime" + "knative.dev/eventing-operator/test/client" "testing" "k8s.io/apimachinery/pkg/api/meta" - mf "github.com/manifestival/manifestival" apierrs "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" + "knative.dev/eventing-operator/test" "knative.dev/eventing-operator/test/resources" "knative.dev/pkg/test/logstream" @@ -36,7 +34,7 @@ import ( func TestKnativeEventingDeployment(t *testing.T) { cancel := logstream.Start(t) defer cancel() - clients := Setup(t) + clients := client.Setup(t) names := test.ResourceNames{ KnativeEventing: test.EventingOperatorName, @@ -53,113 +51,18 @@ func TestKnativeEventingDeployment(t *testing.T) { // Test if KnativeEventing can reach the READY status t.Run("create", func(t *testing.T) { - knativeEventingVerify(t, clients, names) + resources.KnativeEventingVerify(t, clients, names) }) // Delete the deployments one by one to see if they will be recreated. t.Run("restore", func(t *testing.T) { - knativeEventingVerify(t, clients, names) - deploymentRecreation(t, clients, names) + resources.KnativeEventingVerify(t, clients, names) + resources.DeploymentRecreation(t, clients, names) }) // Delete the KnativeEventing to see if all resources will be removed t.Run("delete", func(t *testing.T) { - knativeEventingVerify(t, clients, names) - knativeEventingDelete(t, clients, names) - }) -} - -// knativeEventingVerify verifies if the KnativeEventing can reach the READY status. -func knativeEventingVerify(t *testing.T, clients *test.Clients, names test.ResourceNames) { - if _, err := resources.WaitForKnativeEventingState(clients.KnativeEventing(), names.KnativeEventing, - resources.IsKnativeEventingReady); err != nil { - t.Fatalf("KnativeService %q failed to get to the READY status: %v", names.KnativeEventing, err) - } - -} - -// deploymentRecreation verify whether all the deployments for knative eventing are able to recreate, when they are deleted. -func deploymentRecreation(t *testing.T, clients *test.Clients, names test.ResourceNames) { - dpList, err := clients.KubeClient.Kube.AppsV1().Deployments(names.Namespace).List(metav1.ListOptions{}) - if err != nil { - t.Fatalf("Failed to get any deployment under the namespace %q: %v", - test.EventingOperatorNamespace, err) - } - if len(dpList.Items) == 0 { - t.Fatalf("No deployment under the namespace %q was found", - test.EventingOperatorNamespace) - } - // Delete the first deployment and verify the operator recreates it - deployment := dpList.Items[0] - if err := clients.KubeClient.Kube.AppsV1().Deployments(deployment.Namespace).Delete(deployment.Name, - &metav1.DeleteOptions{}); err != nil { - t.Fatalf("Failed to delete deployment %s/%s: %v", deployment.Namespace, deployment.Name, err) - } - - waitErr := wait.PollImmediate(resources.Interval, resources.Timeout, func() (bool, error) { - dep, err := clients.KubeClient.Kube.AppsV1().Deployments(deployment.Namespace).Get(deployment.Name, metav1.GetOptions{}) - if err != nil { - // If the deployment is not found, we continue to wait for the availability. - if apierrs.IsNotFound(err) { - return false, nil - } - return false, err - } - return resources.IsDeploymentAvailable(dep) + resources.KnativeEventingVerify(t, clients, names) + resources.KnativeEventingDelete(t, clients, names) }) - - if waitErr != nil { - t.Fatalf("The deployment %s/%s failed to reach the desired state: %v", deployment.Namespace, deployment.Name, err) - } - - if _, err := resources.WaitForKnativeEventingState(clients.KnativeEventing(), test.EventingOperatorName, - resources.IsKnativeEventingReady); err != nil { - t.Fatalf("KnativeService %q failed to reach the desired state: %v", test.EventingOperatorName, err) - } - t.Logf("The deployment %s/%s reached the desired state.", deployment.Namespace, deployment.Name) -} - -// knativeEventingDelete deletes tha KnativeEventing to see if all resources will be deleted -func knativeEventingDelete(t *testing.T, clients *test.Clients, names test.ResourceNames) { - if err := clients.KnativeEventing().Delete(names.KnativeEventing, &metav1.DeleteOptions{}); err != nil { - t.Fatalf("KnativeEventing %q failed to delete: %v", names.KnativeEventing, err) - } - _, b, _, _ := runtime.Caller(0) - m, err := mf.NewManifest(filepath.Join((filepath.Dir(b)+"/.."), "config/"), false, clients.Config) - if err != nil { - t.Fatal("Failed to load manifest", err) - } - if err := verifyNoKnativeEventings(clients); err != nil { - t.Fatal(err) - } - for _, u := range m.Resources { - if u.GetKind() == "Namespace" { - // The namespace should be skipped, because when the CR is removed, the Manifest to be removed has - // been modified, since the namespace can be injected. - continue - } - waitErr := wait.PollImmediate(resources.Interval, resources.Timeout, func() (bool, error) { - gvrs, _ := meta.UnsafeGuessKindToResource(u.GroupVersionKind()) - if _, err := clients.Dynamic.Resource(gvrs).Get(u.GetName(), metav1.GetOptions{}); apierrs.IsNotFound(err) { - return true, nil - } - return false, err - }) - - if waitErr != nil { - t.Fatalf("The %s %s failed to be deleted: %v", u.GetKind(), u.GetName(), waitErr) - } - t.Logf("The %s %s has been deleted.", u.GetKind(), u.GetName()) - } -} - -func verifyNoKnativeEventings(clients *test.Clients) error { - eventings, err := clients.KnativeEventingAll().List(metav1.ListOptions{}) - if err != nil { - return err - } - if len(eventings.Items) > 0 { - return errors.New("Unable to verify cluster-scoped resources are deleted if any KnativeEventing exists") - } - return nil } diff --git a/test/resources/verify.go b/test/resources/verify.go new file mode 100644 index 00000000..1bc23231 --- /dev/null +++ b/test/resources/verify.go @@ -0,0 +1,139 @@ +/* +Copyright 2020 The Knative Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resources + +import ( + "errors" + "path/filepath" + "runtime" + "testing" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/util/wait" + apierrs "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + // Mysteriously required to support GCP auth (required by k8s libs). + // Apparently just importing it is enough. @_@ side effects @_@. + // https://github.com/kubernetes/client-go/issues/242 + _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" + mf "github.com/jcrossley3/manifestival" + + pkgTest "knative.dev/pkg/test" + "knative.dev/eventing-operator/test" +) + +// Setup creates the client objects needed in the e2e tests. +func Setup(t *testing.T) *test.Clients { + clients, err := test.NewClients( + pkgTest.Flags.Kubeconfig, + pkgTest.Flags.Cluster) + if err != nil { + t.Fatalf("Couldn't initialize clients: %v", err) + } + return clients +} + +// KnativeEventingVerify verifies if the KnativeEventing can reach the READY status. +func KnativeEventingVerify(t *testing.T, clients *test.Clients, names test.ResourceNames) { + if _, err := WaitForKnativeEventingState(clients.KnativeEventing(), names.KnativeEventing, + IsKnativeEventingReady); err != nil { + t.Fatalf("KnativeService %q failed to get to the READY status: %v", names.KnativeEventing, err) + } +} + +// DeploymentRecreation verify whether all the deployments for knative eventing are able to recreate, when they are deleted. +func DeploymentRecreation(t *testing.T, clients *test.Clients, names test.ResourceNames) { + dpList, err := clients.KubeClient.Kube.AppsV1().Deployments(names.Namespace).List(metav1.ListOptions{}) + if err != nil { + t.Fatalf("Failed to get any deployment under the namespace %q: %v", + test.EventingOperatorNamespace, err) + } + if len(dpList.Items) == 0 { + t.Fatalf("No deployment under the namespace %q was found", + test.EventingOperatorNamespace) + } + // Delete the first deployment and verify the operator recreates it + deployment := dpList.Items[0] + if err := clients.KubeClient.Kube.AppsV1().Deployments(deployment.Namespace).Delete(deployment.Name, + &metav1.DeleteOptions{}); err != nil { + t.Fatalf("Failed to delete deployment %s/%s: %v", deployment.Namespace, deployment.Name, err) + } + + waitErr := wait.PollImmediate(Interval, Timeout, func() (bool, error) { + dep, err := clients.KubeClient.Kube.AppsV1().Deployments(deployment.Namespace).Get(deployment.Name, metav1.GetOptions{}) + if err != nil { + // If the deployment is not found, we continue to wait for the availability. + if apierrs.IsNotFound(err) { + return false, nil + } + return false, err + } + return IsDeploymentAvailable(dep) + }) + + if waitErr != nil { + t.Fatalf("The deployment %s/%s failed to reach the desired state: %v", deployment.Namespace, deployment.Name, err) + } + + if _, err := WaitForKnativeEventingState(clients.KnativeEventing(), test.EventingOperatorName, + IsKnativeEventingReady); err != nil { + t.Fatalf("KnativeService %q failed to reach the desired state: %v", test.EventingOperatorName, err) + } + t.Logf("The deployment %s/%s reached the desired state.", deployment.Namespace, deployment.Name) +} + +// KnativeEventingDelete deletes tha KnativeEventing to see if all resources will be deleted +func KnativeEventingDelete(t *testing.T, clients *test.Clients, names test.ResourceNames) { + if err := clients.KnativeEventing().Delete(names.KnativeEventing, &metav1.DeleteOptions{}); err != nil { + t.Fatalf("KnativeEventing %q failed to delete: %v", names.KnativeEventing, err) + } + _, b, _, _ := runtime.Caller(0) + m, err := mf.NewManifest(filepath.Join((filepath.Dir(b)+"/.."), "config/"), false, clients.Config) + if err != nil { + t.Fatal("Failed to load manifest", err) + } + if err := verifyNoKnativeEventings(clients); err != nil { + t.Fatal(err) + } + for _, u := range m.Resources { + if u.GetKind() == "Namespace" { + // The namespace should be skipped, because when the CR is removed, the Manifest to be removed has + // been modified, since the namespace can be injected. + continue + } + waitErr := wait.PollImmediate(Interval, Timeout, func() (bool, error) { + gvrs, _ := meta.UnsafeGuessKindToResource(u.GroupVersionKind()) + if _, err := clients.Dynamic.Resource(gvrs).Get(u.GetName(), metav1.GetOptions{}); apierrs.IsNotFound(err) { + return true, nil + } + return false, err + }) + + if waitErr != nil { + t.Fatalf("The %s %s failed to be deleted: %v", u.GetKind(), u.GetName(), waitErr) + } + t.Logf("The %s %s has been deleted.", u.GetKind(), u.GetName()) + } +} + +func verifyNoKnativeEventings(clients *test.Clients) error { + eventings, err := clients.KnativeEventingAll().List(metav1.ListOptions{}) + if err != nil { + return err + } + if len(eventings.Items) > 0 { + return errors.New("Unable to verify cluster-scoped resources are deleted if any KnativeEventing exists") + } + return nil +} diff --git a/test/upgrade/knativeeventingupgrade_test.go b/test/upgrade/knativeeventingupgrade_test.go new file mode 100644 index 00000000..1dab97a4 --- /dev/null +++ b/test/upgrade/knativeeventingupgrade_test.go @@ -0,0 +1,95 @@ +//// +build postupgrade + +/* +Copyright 2020 The Knative Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package e2e + +import ( + "knative.dev/eventing-operator/test/client" + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/eventing-operator/test" + "knative.dev/eventing-operator/test/resources" + "knative.dev/pkg/test/logstream" +) + +// TestKnativeEventingUpgrade verifies the KnativeEventing creation, deployment recreation, and KnativeEventing deletion +// after upgraded to the latest HEAD at master, with the latest generated manifest of KnativeEventing. +func TestKnativeEventingUpgrade(t *testing.T) { + cancel := logstream.Start(t) + defer cancel() + clients := client.Setup(t) + + names := test.ResourceNames{ + KnativeEventing: test.EventingOperatorName, + Namespace: test.EventingOperatorNamespace, + } + + test.CleanupOnInterrupt(func() { test.TearDown(clients, names) }) + defer test.TearDown(clients, names) + + // Create a KnativeEventing + if _, err := resources.CreateKnativeEventing(clients.KnativeEventing(), names); err != nil { + t.Fatalf("KnativeService %q failed to create: %v", names.KnativeEventing, err) + } + + // Test if KnativeEventing can reach the READY status + t.Run("create", func(t *testing.T) { + resources.KnativeEventingVerify(t, clients, names) + expectedDeployments := []string{"eventing-controller", "eventing-webhook", "imc-controller", + "imc-dispatcher", "broker-controller"} + knativeEventingVerifyDeployment(t, clients, names, expectedDeployments) + }) + + // Delete the deployments one by one to see if they will be recreated. + t.Run("restore", func(t *testing.T) { + resources.KnativeEventingVerify(t, clients, names) + resources.DeploymentRecreation(t, clients, names) + }) + + // Delete the KnativeEventing to see if all resources will be removed + t.Run("delete", func(t *testing.T) { + resources.KnativeEventingVerify(t, clients, names) + resources.KnativeEventingDelete(t, clients, names) + }) +} + +// knativeEventingVerifyDeployment verify whether the deployments have the correct number and names. +func knativeEventingVerifyDeployment(t *testing.T, clients *test.Clients, names test.ResourceNames, + expectedDeployments []string) { + dpList, err := clients.KubeClient.Kube.AppsV1().Deployments(names.Namespace).List(metav1.ListOptions{}) + assertEqual(t, err, nil) + assertEqual(t, len(dpList.Items), len(expectedDeployments)) + for _, deployment := range dpList.Items { + assertEqual(t, stringInList(deployment.Name, expectedDeployments), true) + } +} + +func assertEqual(t *testing.T, actual, expected interface{}) { + if actual == expected { + return + } + t.Fatalf("expected does not equal actual. \nExpected: %v\nActual: %v", expected, actual) +} + +func stringInList(a string, list []string) bool { + for _, b := range list { + if b == a { + return true + } + } + return false +} + From 51b5665cf80a9dd72ddba46cf2f7cf814afa7bbc Mon Sep 17 00:00:00 2001 From: Vincent Hou Date: Mon, 10 Feb 2020 14:41:36 -0500 Subject: [PATCH 2/3] Add the installation of the previous release and upgrade to the latest --- .../knativeeventing/knativeeventing.go | 3 +- test/client/{common.go => setup.go} | 0 test/e2e-upgrade-tests.sh | 33 +++++++++++++++++++ test/e2e/knativeeventingdeployment_test.go | 12 +++---- test/resources/knativeeventing.go | 26 +++++++++------ test/resources/verify.go | 12 +++---- test/upgrade/knativeeventingupgrade_test.go | 22 +++++++------ 7 files changed, 74 insertions(+), 34 deletions(-) rename test/client/{common.go => setup.go} (100%) diff --git a/pkg/reconciler/knativeeventing/knativeeventing.go b/pkg/reconciler/knativeeventing/knativeeventing.go index cac2ba86..2ca621b9 100644 --- a/pkg/reconciler/knativeeventing/knativeeventing.go +++ b/pkg/reconciler/knativeeventing/knativeeventing.go @@ -214,8 +214,7 @@ func (r *Reconciler) updateStatus(desired *eventingv1alpha1.KnativeEventing) (*e // Delete obsolete resources from previous versions func (r *Reconciler) deleteObsoleteResources(manifest *mf.Manifest, instance *eventingv1alpha1.KnativeEventing) error { resource := &unstructured.Unstructured{} - - resource.SetNamespace("knative-eventing") + resource.SetNamespace(instance.GetNamespace()) // Remove old resources from 0.12 // https://github.com/knative/eventing-operator/issues/90 diff --git a/test/client/common.go b/test/client/setup.go similarity index 100% rename from test/client/common.go rename to test/client/setup.go diff --git a/test/e2e-upgrade-tests.sh b/test/e2e-upgrade-tests.sh index ab35cd65..e15a06cf 100755 --- a/test/e2e-upgrade-tests.sh +++ b/test/e2e-upgrade-tests.sh @@ -28,6 +28,9 @@ source $(dirname $0)/../vendor/knative.dev/test-infra/scripts/e2e-tests.sh +# Latest eventing operator release. +readonly LATEST_EVENTING_RELEASE_VERSION=$(git describe --match "v[0-9]*" --abbrev=0) + OPERATOR_DIR=$(dirname $0)/.. KNATIVE_EVENTING_DIR=${OPERATOR_DIR}/.. @@ -48,9 +51,37 @@ function install_eventing_operator() { wait_until_pods_running default || fail_test "Eventing Operator did not come up" } +function install_latest_operator_release() { + header "Installing Knative Eventing operator latest public release" + local full_url="https://github.com/knative/eventing-operator/releases/download/${LATEST_EVENTING_RELEASE_VERSION}/eventing-operator.yaml" + + local RELEASE_YAML="$(mktemp)" + wget "${full_url}" -O "${RELEASE_YAML}" \ + || fail_test "Unable to download latest Knative Eventing Operator release." + + kubectl apply -f "${RELEASE_YAML}" || fail_test "Knative Eventing Operator latest release installation failed" + create_custom_resource + wait_until_pods_running ${TEST_NAMESPACE} +} + +function create_custom_resource() { + echo ">> Creating the custom resource of Knative Eventing:" + cat <> Creating test namespaces" kubectl create namespace $TEST_NAMESPACE + install_latest_operator_release +} + +function install_head() { generate_latest_eventing_manifest install_eventing_operator } @@ -97,6 +128,8 @@ initialize $@ --skip-istio-addon TIMEOUT=20m +install_head + # If we got this far, the operator installed Knative Eventing header "Running tests for Knative Eventing Operator" failed=0 diff --git a/test/e2e/knativeeventingdeployment_test.go b/test/e2e/knativeeventingdeployment_test.go index f0c96ea8..2a5ef04f 100644 --- a/test/e2e/knativeeventingdeployment_test.go +++ b/test/e2e/knativeeventingdeployment_test.go @@ -45,24 +45,24 @@ func TestKnativeEventingDeployment(t *testing.T) { defer test.TearDown(clients, names) // Create a KnativeEventing - if _, err := resources.CreateKnativeEventing(clients.KnativeEventing(), names); err != nil { + if _, err := resources.EnsureKnativeEventingExists(clients.KnativeEventing(), names); err != nil { t.Fatalf("KnativeService %q failed to create: %v", names.KnativeEventing, err) } // Test if KnativeEventing can reach the READY status t.Run("create", func(t *testing.T) { - resources.KnativeEventingVerify(t, clients, names) + resources.AssertKEOperatorCRReadyStatus(t, clients, names) }) // Delete the deployments one by one to see if they will be recreated. t.Run("restore", func(t *testing.T) { - resources.KnativeEventingVerify(t, clients, names) - resources.DeploymentRecreation(t, clients, names) + resources.AssertKEOperatorCRReadyStatus(t, clients, names) + resources.DeleteAndVerifyDeployments(t, clients, names) }) // Delete the KnativeEventing to see if all resources will be removed t.Run("delete", func(t *testing.T) { - resources.KnativeEventingVerify(t, clients, names) - resources.KnativeEventingDelete(t, clients, names) + resources.AssertKEOperatorCRReadyStatus(t, clients, names) + resources.KEOperatorCRDelete(t, clients, names) }) } diff --git a/test/resources/knativeeventing.go b/test/resources/knativeeventing.go index 70504443..49110bd4 100644 --- a/test/resources/knativeeventing.go +++ b/test/resources/knativeeventing.go @@ -26,12 +26,14 @@ import ( "github.com/pkg/errors" v1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + apierrs "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" + + "knative.dev/pkg/test/logging" "knative.dev/eventing-operator/pkg/apis/eventing/v1alpha1" eventingv1alpha1 "knative.dev/eventing-operator/pkg/client/clientset/versioned/typed/eventing/v1alpha1" "knative.dev/eventing-operator/test" - "knative.dev/pkg/test/logging" ) const ( @@ -61,16 +63,20 @@ func WaitForKnativeEventingState(clients eventingv1alpha1.KnativeEventingInterfa return lastState, nil } -// CreateKnativeEventing creates a KnativeEventingServing with the name names.KnativeEventing under the namespace names.Namespace. -func CreateKnativeEventing(clients eventingv1alpha1.KnativeEventingInterface, names test.ResourceNames) (*v1alpha1.KnativeEventing, error) { - ks := &v1alpha1.KnativeEventing{ - ObjectMeta: metav1.ObjectMeta{ - Name: names.KnativeEventing, - Namespace: names.Namespace, - }, +// EnsureKnativeEventingExists creates a KnativeEventingServing with the name names.KnativeEventing under the namespace names.Namespace. +func EnsureKnativeEventingExists(clients eventingv1alpha1.KnativeEventingInterface, names test.ResourceNames) (*v1alpha1.KnativeEventing, error) { + // If this function is called by the upgrade tests, we only create the custom resource, if it does not exist. + ke, err := clients.Get(names.KnativeEventing, metav1.GetOptions{}) + if apierrs.IsNotFound(err) { + ke := &v1alpha1.KnativeEventing{ + ObjectMeta: metav1.ObjectMeta{ + Name: names.KnativeEventing, + Namespace: names.Namespace, + }, + } + return clients.Create(ke) } - svc, err := clients.Create(ks) - return svc, err + return ke, err } // IsKnativeEventingReady will check the status conditions of the KnativeEventing and return true if the KnativeEventing is ready. diff --git a/test/resources/verify.go b/test/resources/verify.go index 1bc23231..a820029e 100644 --- a/test/resources/verify.go +++ b/test/resources/verify.go @@ -44,16 +44,16 @@ func Setup(t *testing.T) *test.Clients { return clients } -// KnativeEventingVerify verifies if the KnativeEventing can reach the READY status. -func KnativeEventingVerify(t *testing.T, clients *test.Clients, names test.ResourceNames) { +// AssertKEOperatorCRReadyStatus verifies if the KnativeEventing can reach the READY status. +func AssertKEOperatorCRReadyStatus(t *testing.T, clients *test.Clients, names test.ResourceNames) { if _, err := WaitForKnativeEventingState(clients.KnativeEventing(), names.KnativeEventing, IsKnativeEventingReady); err != nil { t.Fatalf("KnativeService %q failed to get to the READY status: %v", names.KnativeEventing, err) } } -// DeploymentRecreation verify whether all the deployments for knative eventing are able to recreate, when they are deleted. -func DeploymentRecreation(t *testing.T, clients *test.Clients, names test.ResourceNames) { +// DeleteAndVerifyDeployments verify whether all the deployments for knative eventing are able to recreate, when they are deleted. +func DeleteAndVerifyDeployments(t *testing.T, clients *test.Clients, names test.ResourceNames) { dpList, err := clients.KubeClient.Kube.AppsV1().Deployments(names.Namespace).List(metav1.ListOptions{}) if err != nil { t.Fatalf("Failed to get any deployment under the namespace %q: %v", @@ -93,8 +93,8 @@ func DeploymentRecreation(t *testing.T, clients *test.Clients, names test.Resour t.Logf("The deployment %s/%s reached the desired state.", deployment.Namespace, deployment.Name) } -// KnativeEventingDelete deletes tha KnativeEventing to see if all resources will be deleted -func KnativeEventingDelete(t *testing.T, clients *test.Clients, names test.ResourceNames) { +// KEOperatorCRDelete deletes tha KnativeEventing to see if all resources will be deleted +func KEOperatorCRDelete(t *testing.T, clients *test.Clients, names test.ResourceNames) { if err := clients.KnativeEventing().Delete(names.KnativeEventing, &metav1.DeleteOptions{}); err != nil { t.Fatalf("KnativeEventing %q failed to delete: %v", names.KnativeEventing, err) } diff --git a/test/upgrade/knativeeventingupgrade_test.go b/test/upgrade/knativeeventingupgrade_test.go index 1dab97a4..606ebab5 100644 --- a/test/upgrade/knativeeventingupgrade_test.go +++ b/test/upgrade/knativeeventingupgrade_test.go @@ -1,4 +1,4 @@ -//// +build postupgrade +// +build postupgrade /* Copyright 2020 The Knative Authors @@ -41,28 +41,30 @@ func TestKnativeEventingUpgrade(t *testing.T) { defer test.TearDown(clients, names) // Create a KnativeEventing - if _, err := resources.CreateKnativeEventing(clients.KnativeEventing(), names); err != nil { + if _, err := resources.EnsureKnativeEventingExists(clients.KnativeEventing(), names); err != nil { t.Fatalf("KnativeService %q failed to create: %v", names.KnativeEventing, err) } // Test if KnativeEventing can reach the READY status t.Run("create", func(t *testing.T) { - resources.KnativeEventingVerify(t, clients, names) + resources.AssertKEOperatorCRReadyStatus(t, clients, names) + }) + + // Verify if resources match the latest requirement after upgrade + t.Run("verify resources", func(t *testing.T) { + resources.AssertKEOperatorCRReadyStatus(t, clients, names) + // TODO: We only verify the deployment, but we need to add other resources as well, like ServiceAccount, ClusterRoleBinding, etc. expectedDeployments := []string{"eventing-controller", "eventing-webhook", "imc-controller", "imc-dispatcher", "broker-controller"} knativeEventingVerifyDeployment(t, clients, names, expectedDeployments) }) - // Delete the deployments one by one to see if they will be recreated. - t.Run("restore", func(t *testing.T) { - resources.KnativeEventingVerify(t, clients, names) - resources.DeploymentRecreation(t, clients, names) - }) + // TODO: We will add one or sections here to run the tests tagged with postupgrade in knative evening. // Delete the KnativeEventing to see if all resources will be removed t.Run("delete", func(t *testing.T) { - resources.KnativeEventingVerify(t, clients, names) - resources.KnativeEventingDelete(t, clients, names) + resources.AssertKEOperatorCRReadyStatus(t, clients, names) + resources.KEOperatorCRDelete(t, clients, names) }) } From 43d78529bdc9a50cf17cb6ce6f1ab20a074a6788 Mon Sep 17 00:00:00 2001 From: Vincent Hou Date: Wed, 12 Feb 2020 17:39:29 -0500 Subject: [PATCH 3/3] Fixes this PR based on the latest comments --- test/e2e-upgrade-tests.sh | 6 +++--- test/e2e/knativeeventingdeployment_test.go | 8 +------- test/resources/verify.go | 2 +- test/upgrade/knativeeventingupgrade_test.go | 5 +++-- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/test/e2e-upgrade-tests.sh b/test/e2e-upgrade-tests.sh index e15a06cf..22a660b4 100755 --- a/test/e2e-upgrade-tests.sh +++ b/test/e2e-upgrade-tests.sh @@ -55,11 +55,11 @@ function install_latest_operator_release() { header "Installing Knative Eventing operator latest public release" local full_url="https://github.com/knative/eventing-operator/releases/download/${LATEST_EVENTING_RELEASE_VERSION}/eventing-operator.yaml" - local RELEASE_YAML="$(mktemp)" - wget "${full_url}" -O "${RELEASE_YAML}" \ + local release_yaml="$(mktemp)" + wget "${full_url}" -O "${release_yaml}" \ || fail_test "Unable to download latest Knative Eventing Operator release." - kubectl apply -f "${RELEASE_YAML}" || fail_test "Knative Eventing Operator latest release installation failed" + kubectl apply -f "${release_yaml}" || fail_test "Knative Eventing Operator latest release installation failed" create_custom_resource wait_until_pods_running ${TEST_NAMESPACE} } diff --git a/test/e2e/knativeeventingdeployment_test.go b/test/e2e/knativeeventingdeployment_test.go index 2a5ef04f..c79da269 100644 --- a/test/e2e/knativeeventingdeployment_test.go +++ b/test/e2e/knativeeventingdeployment_test.go @@ -16,16 +16,10 @@ limitations under the License. package e2e import ( - "knative.dev/eventing-operator/test/client" "testing" - "k8s.io/apimachinery/pkg/api/meta" - mf "github.com/manifestival/manifestival" - apierrs "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/wait" - "knative.dev/eventing-operator/test" + "knative.dev/eventing-operator/test/client" "knative.dev/eventing-operator/test/resources" "knative.dev/pkg/test/logstream" ) diff --git a/test/resources/verify.go b/test/resources/verify.go index a820029e..1a108521 100644 --- a/test/resources/verify.go +++ b/test/resources/verify.go @@ -27,7 +27,7 @@ import ( // Apparently just importing it is enough. @_@ side effects @_@. // https://github.com/kubernetes/client-go/issues/242 _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" - mf "github.com/jcrossley3/manifestival" + mf "github.com/manifestival/manifestival" pkgTest "knative.dev/pkg/test" "knative.dev/eventing-operator/test" diff --git a/test/upgrade/knativeeventingupgrade_test.go b/test/upgrade/knativeeventingupgrade_test.go index 606ebab5..ae53b557 100644 --- a/test/upgrade/knativeeventingupgrade_test.go +++ b/test/upgrade/knativeeventingupgrade_test.go @@ -16,13 +16,14 @@ limitations under the License. package e2e import ( - "knative.dev/eventing-operator/test/client" "testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "knative.dev/pkg/test/logstream" "knative.dev/eventing-operator/test" "knative.dev/eventing-operator/test/resources" - "knative.dev/pkg/test/logstream" + "knative.dev/eventing-operator/test/client" ) // TestKnativeEventingUpgrade verifies the KnativeEventing creation, deployment recreation, and KnativeEventing deletion