This is an automated email from the ASF dual-hosted git repository. pcongiusti pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit d5c298ee082103db6f768142b20eff39c168830b Author: Pasquale Congiusti <[email protected]> AuthorDate: Mon Aug 5 12:16:17 2024 +0200 chore(e2e): upgrade test independent from install method The upgrade test should be generic and test the expected logic regardless the way the operator is installed. --- .github/actions/infra-setting/action.yml | 2 + e2e/install/upgrade/olm_upgrade_test.go | 251 --------------------- .../{kustomize_upgrade_test.go => upgrade_test.go} | 92 ++++---- 3 files changed, 49 insertions(+), 296 deletions(-) diff --git a/.github/actions/infra-setting/action.yml b/.github/actions/infra-setting/action.yml index 10f318581..9b217c551 100644 --- a/.github/actions/infra-setting/action.yml +++ b/.github/actions/infra-setting/action.yml @@ -51,4 +51,6 @@ runs: eval $(minikube -p minikube docker-env) echo "KAMEL_INSTALL_REGISTRY=$(kubectl -n kube-system get service registry -o jsonpath='{.spec.clusterIP}')" >> $GITHUB_ENV echo "Setting registry as $KAMEL_INSTALL_REGISTRY which is required by certain tests" + echo "LAST_RELEASED_VERSION=$(make get-last-released-version)" >> $GITHUB_ENV + echo "Setting last released version as as $LAST_RELEASED_VERSION which is required by certain tests" NOTEST=true make images diff --git a/e2e/install/upgrade/olm_upgrade_test.go b/e2e/install/upgrade/olm_upgrade_test.go deleted file mode 100644 index c2b0abc70..000000000 --- a/e2e/install/upgrade/olm_upgrade_test.go +++ /dev/null @@ -1,251 +0,0 @@ -//go:build integration -// +build integration - -// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration" - -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You 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 upgrade - -import ( - "context" - "fmt" - "os" - "testing" - "time" - - . "github.com/apache/camel-k/v2/e2e/support" - v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" - . "github.com/onsi/gomega" - "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/operator-framework/api/pkg/lib/version" - olm "github.com/operator-framework/api/pkg/operators/v1alpha1" - corev1 "k8s.io/api/core/v1" - - "github.com/apache/camel-k/v2/pkg/util/defaults" - "github.com/apache/camel-k/v2/pkg/util/openshift" -) - -const catalogSourceName = "test-camel-k-source" - -func TestOLMOperatorUpgrade(t *testing.T) { - prevIIB := os.Getenv("CAMEL_K_PREV_IIB") - newIIB := os.Getenv("CAMEL_K_NEW_IIB") - kamel := os.Getenv("RELEASED_KAMEL_BIN") - - // optional options - prevUpdateChannel := os.Getenv("CAMEL_K_PREV_UPGRADE_CHANNEL") - newUpdateChannel := os.Getenv("CAMEL_K_NEW_UPGRADE_CHANNEL") - - if prevIIB == "" || newIIB == "" { - t.Skip("OLM Upgrade test requires the CAMEL_K_PREV_IIB and CAMEL_K_NEW_IIB environment variables") - } - - crossChannelUpgrade := false - if prevUpdateChannel != "" && newUpdateChannel != "" && prevUpdateChannel != newUpdateChannel { - crossChannelUpgrade = true - t.Logf("Testing cross-OLM channel upgrade %s -> %s", prevUpdateChannel, newUpdateChannel) - } - - WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { - g.Expect(CreateOrUpdateCatalogSource(t, ctx, ns, catalogSourceName, prevIIB)).To(Succeed()) - ocp, err := openshift.IsOpenShift(TestClient(t)) - require.NoError(t, err) - - if ocp { - // Wait for pull secret to be created in namespace - // e.g. test-camel-k-source-dockercfg-zlltn - secretPrefix := fmt.Sprintf("%s-dockercfg-", catalogSourceName) - g.Eventually(SecretByName(t, ctx, ns, secretPrefix), TestTimeoutLong).Should(Not(BeNil())) - } - - g.Eventually(CatalogSourcePodRunning(t, ctx, ns, catalogSourceName), TestTimeoutMedium).Should(BeNil()) - g.Eventually(CatalogSourcePhase(t, ctx, ns, catalogSourceName), TestTimeoutMedium).Should(Equal("READY")) - - // Set KAMEL_BIN only for this test - don't override the ENV variable for all tests - g.Expect(os.Setenv("KAMEL_BIN", kamel)).To(Succeed()) - - args := []string{ - "install", - "-n", ns, - "--olm=true", - "--force", - "--olm-source", catalogSourceName, - "--olm-source-namespace", ns, - "--base-image", defaults.BaseImage(), - } - - if prevUpdateChannel != "" { - args = append(args, "--olm-channel", prevUpdateChannel) - } - - g.Expect(Kamel(t, ctx, args...).Execute()).To(Succeed()) - - // Find the only one Camel K CSV - noAdditionalConditions := func(csv olm.ClusterServiceVersion) bool { - return true - } - g.Eventually(ClusterServiceVersionPhase(t, ctx, noAdditionalConditions, ns), TestTimeoutMedium). - Should(Equal(olm.CSVPhaseSucceeded)) - - // Refresh the test client to account for the newly installed CRDs - RefreshClient(t) - - var prevCSVVersion version.OperatorVersion - var newCSVVersion version.OperatorVersion - - // IntegrationPlatform should match at least on the version prefix - // CSV patch version can be increased with the OperatorHub respin of the same Camel K release - var prevIPVersionPrefix string - var newIPVersionMajorMinorPatch string - - prevCSVVersion = ClusterServiceVersion(t, ctx, noAdditionalConditions, ns)().Spec.Version - prevIPVersionPrefix = fmt.Sprintf("%d.%d", prevCSVVersion.Version.Major, prevCSVVersion.Version.Minor) - t.Logf("Using Previous CSV Version: %s", prevCSVVersion.Version.String()) - - // Check the operator pod is running - g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - - // Check the IntegrationPlatform has been reconciled - g.Eventually(PlatformVersion(t, ctx, ns)).Should(ContainSubstring(prevIPVersionPrefix)) - - name := "yaml" - g.Expect(Kamel(t, ctx, "run", "-n", ns, "files/yaml.yaml").Execute()).To(Succeed()) - kbindName := "timer-to-log" - g.Expect(KamelBind(t, ctx, ns, "timer-source?message=Hello", "log-sink", "--name", kbindName).Execute()).To(Succeed()) - - // Check the Integration runs correctly - g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutLong). - Should(Equal(corev1.ConditionTrue)) - if prevCSVVersion.Version.String() >= "2" { // since 2.0 Pipe, previously KameletBinding - g.Eventually(PipeConditionStatus(t, ctx, ns, kbindName, v1.PipeConditionReady), TestTimeoutShort). - Should(Equal(corev1.ConditionTrue)) - } - g.Eventually(IntegrationPodPhase(t, ctx, ns, kbindName), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - g.Eventually(IntegrationConditionStatus(t, ctx, ns, kbindName, v1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(corev1.ConditionTrue)) - - // Check the Integration version matches that of the current operator - g.Expect(IntegrationVersion(t, ctx, ns, name)()).To(ContainSubstring(prevIPVersionPrefix)) - g.Expect(IntegrationVersion(t, ctx, ns, kbindName)()).To(ContainSubstring(prevIPVersionPrefix)) - - t.Run("OLM upgrade", func(t *testing.T) { - // Trigger Camel K operator upgrade by updating the CatalogSource with the new index image - g.Expect(CreateOrUpdateCatalogSource(t, ctx, ns, catalogSourceName, newIIB)).To(Succeed()) - - if crossChannelUpgrade { - t.Log("Patching Camel K OLM subscription channel.") - subscription, err := GetSubscription(t, ctx, ns) - g.Expect(err).To(BeNil()) - g.Expect(subscription).NotTo(BeNil()) - - // Patch the Subscription to avoid conflicts with concurrent updates performed by OLM - patch := fmt.Sprintf("{\"spec\":{\"channel\":%q}}", newUpdateChannel) - g.Expect( - TestClient(t).Patch(ctx, subscription, ctrl.RawPatch(types.MergePatchType, []byte(patch))), - ).To(Succeed()) - // Assert the response back from the API server - g.Expect(subscription.Spec.Channel).To(Equal(newUpdateChannel)) - } - - // The new CSV is installed - g.Eventually(ClusterServiceVersionPhase(t, ctx, func(csv olm.ClusterServiceVersion) bool { - return csv.Spec.Version.Version.String() != prevCSVVersion.Version.String() - }, ns), TestTimeoutMedium).Should(Equal(olm.CSVPhaseSucceeded)) - - // The old CSV is gone - g.Eventually(ClusterServiceVersion(t, ctx, func(csv olm.ClusterServiceVersion) bool { - return csv.Spec.Version.Version.String() == prevCSVVersion.Version.String() - }, ns), TestTimeoutMedium).Should(BeNil()) - - newCSVVersion = ClusterServiceVersion(t, ctx, noAdditionalConditions, ns)().Spec.Version - newIPVersionMajorMinorPatch = fmt.Sprintf("%d.%d.%d", newCSVVersion.Version.Major, newCSVVersion.Version.Minor, newCSVVersion.Version.Patch) - - g.Expect(prevCSVVersion.Version.String()).NotTo(Equal(newCSVVersion.Version.String())) - - g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - g.Eventually(OperatorImage(t, ctx, ns), TestTimeoutShort).Should(Equal(defaults.OperatorImage())) - - // Check the IntegrationPlatform has been reconciled - g.Eventually(PlatformVersion(t, ctx, ns)).Should(ContainSubstring(newIPVersionMajorMinorPatch)) - }) - - t.Run("Integration upgrade", func(t *testing.T) { - // Clear the KAMEL_BIN environment variable so that the current version is used from now on - g.Expect(os.Setenv("KAMEL_BIN", "")).To(Succeed()) - - // Check the Integration hasn't been upgraded - g.Consistently(IntegrationVersion(t, ctx, ns, name), 5*time.Second, 1*time.Second). - Should(ContainSubstring(prevIPVersionPrefix)) - - // Make sure that any Pod rollout is completing successfully - // otherwise we are probably in front of a non breaking compatibility change - g.Consistently(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), - 2*time.Minute, 15*time.Second).Should(Equal(corev1.ConditionTrue)) - g.Consistently(IntegrationConditionStatus(t, ctx, ns, kbindName, v1.IntegrationConditionReady), - 2*time.Minute, 15*time.Second).Should(Equal(corev1.ConditionTrue)) - - // Rebuild the Integration - g.Expect(Kamel(t, ctx, "rebuild", "--all", "-n", ns).Execute()).To(Succeed()) - if prevCSVVersion.Version.String() >= "2" { - g.Eventually(PipeConditionStatus(t, ctx, ns, kbindName, v1.PipeConditionReady), TestTimeoutMedium). - Should(Equal(corev1.ConditionTrue)) - } - - // Check the Integration runs correctly - g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutMedium). - Should(Equal(corev1.ConditionTrue)) - - // Check the Integration version has been upgraded - g.Eventually(IntegrationVersion(t, ctx, ns, name)).Should(ContainSubstring(newIPVersionMajorMinorPatch)) - g.Eventually(IntegrationVersion(t, ctx, ns, kbindName)).Should(ContainSubstring(newIPVersionMajorMinorPatch)) - - // Check the previous kit is not garbage collected (skip Build - present in case of respin) - prevCSVVersionMajorMinorPatch := fmt.Sprintf("%d.%d.%d", - prevCSVVersion.Version.Major, prevCSVVersion.Version.Minor, prevCSVVersion.Version.Patch) - g.Eventually(Kits(t, ctx, ns, KitWithVersion(prevCSVVersionMajorMinorPatch))).Should(HaveLen(2)) - // Check a new kit is created with the current version - g.Eventually(Kits(t, ctx, ns, KitWithVersionPrefix(newIPVersionMajorMinorPatch))).Should(HaveLen(2)) - // Check the new kit is ready - g.Eventually(Kits(t, ctx, ns, KitWithVersionPrefix(newIPVersionMajorMinorPatch), KitWithPhase(v1.IntegrationKitPhaseReady)), - TestTimeoutMedium).Should(HaveLen(2)) - - kit := Kits(t, ctx, ns, KitWithVersionPrefix(newIPVersionMajorMinorPatch), KitWithLabels(map[string]string{"camel.apache.org/created.by.name": name}))()[0] - kitKbind := Kits(t, ctx, ns, KitWithVersionPrefix(newIPVersionMajorMinorPatch), KitWithLabels(map[string]string{"camel.apache.org/created.by.name": kbindName}))()[0] - - // Check the Integration uses the new kit - g.Eventually(IntegrationKit(t, ctx, ns, name), TestTimeoutMedium).Should(Equal(kit.Name)) - g.Eventually(IntegrationKit(t, ctx, ns, kbindName), TestTimeoutMedium).Should(Equal(kitKbind.Name)) - // Check the Integration Pod uses the new image - g.Eventually(IntegrationPodImage(t, ctx, ns, name)).Should(Equal(kit.Status.Image)) - g.Eventually(IntegrationPodImage(t, ctx, ns, kbindName)).Should(Equal(kitKbind.Status.Image)) - - // Check the Integration runs correctly - g.Eventually(IntegrationPodPhase(t, ctx, ns, name)).Should(Equal(corev1.PodRunning)) - g.Eventually(IntegrationPodPhase(t, ctx, ns, kbindName)).Should(Equal(corev1.PodRunning)) - g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutMedium). - Should(Equal(corev1.ConditionTrue)) - g.Eventually(IntegrationConditionStatus(t, ctx, ns, kbindName, v1.IntegrationConditionReady), TestTimeoutMedium). - Should(Equal(corev1.ConditionTrue)) - }) - }) -} diff --git a/e2e/install/upgrade/kustomize_upgrade_test.go b/e2e/install/upgrade/upgrade_test.go similarity index 70% rename from e2e/install/upgrade/kustomize_upgrade_test.go rename to e2e/install/upgrade/upgrade_test.go index 24aa400a7..236b53a20 100644 --- a/e2e/install/upgrade/kustomize_upgrade_test.go +++ b/e2e/install/upgrade/upgrade_test.go @@ -35,36 +35,53 @@ import ( corev1 "k8s.io/api/core/v1" . "github.com/apache/camel-k/v2/e2e/support" - testutil "github.com/apache/camel-k/v2/e2e/support/util" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/util/defaults" ) -// WARNING: this test is not OLM specific but needs certain setting we provide in OLM installation scenario func TestKustomizeUpgrade(t *testing.T) { WithNewTestNamespace(t, func(ctx context.Context, g *WithT, ns string) { - // ********* START - // TODO: we need to replace this CLI based installation with Kustomize installation after 2.4 release - // this is a workaround as Kustomize was not working properly pre 2.4 - version, ok := os.LookupEnv("KAMEL_K_TEST_RELEASE_VERSION") + // We start the test by installing previous version operator + lastVersion, ok := os.LookupEnv("LAST_RELEASED_VERSION") g.Expect(ok).To(BeTrue()) - image, ok := os.LookupEnv("KAMEL_K_TEST_OPERATOR_CURRENT_IMAGE") - g.Expect(ok).To(BeTrue()) - kamel, ok := os.LookupEnv("RELEASED_KAMEL_BIN") - g.Expect(ok).To(BeTrue()) - // Set KAMEL_BIN only for this test - don't override the ENV variable for all tests - g.Expect(os.Setenv("KAMEL_BIN", kamel)).To(Succeed()) - - // Should both install the CRDs and kamel in the given namespace - g.Expect(Kamel(t, ctx, "install", "-n", ns, "--global", "--olm=false", "--force").Execute()).To(Succeed()) + lastVersionDir := fmt.Sprintf("/tmp/camel-k-v-%s", lastVersion) + // We clone and install the previous installed operator + // from source with tag + ExpectExecSucceed(t, g, + exec.Command( + "rm", + "-rf", + lastVersionDir, + )) + ExpectExecSucceed(t, g, + exec.Command( + "git", + "clone", + "https://github.com/apache/camel-k.git", + lastVersionDir, + )) + checkoutCmd := exec.Command( + "git", + "checkout", + fmt.Sprintf("v%s", lastVersion), + ) + checkoutCmd.Dir = lastVersionDir + ExpectExecSucceed(t, g, checkoutCmd) + installPrevCmd := exec.Command( + "make", + "install-k8s-global", + fmt.Sprintf("NAMESPACE=%s", ns), + ) + installPrevCmd.Dir = lastVersionDir + ExpectExecSucceed(t, g, installPrevCmd) + + // Check the operator image is the previous one + g.Eventually(OperatorImage(t, ctx, ns)).Should(ContainSubstring(lastVersion)) // Check the operator pod is running g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) - // Refresh the test client to account for the newly installed CRDs - RefreshClient(t) // Check the IntegrationPlatform has been reconciled - g.Eventually(PlatformVersion(t, ctx, ns), TestTimeoutMedium).Should(Equal(version)) - // TODO: replace the code above - // ************* END + g.Eventually(PlatformPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + g.Eventually(PlatformVersion(t, ctx, ns), TestTimeoutMedium).Should(Equal(lastVersion)) // We need a different namespace from the global operator WithNewTestNamespace(t, func(ctx context.Context, g *WithT, nsIntegration string) { @@ -74,34 +91,19 @@ func TestKustomizeUpgrade(t *testing.T) { g.Eventually(IntegrationPodPhase(t, ctx, nsIntegration, name)).Should(Equal(corev1.PodRunning)) g.Eventually(IntegrationConditionStatus(t, ctx, nsIntegration, name, v1.IntegrationConditionReady)).Should(Equal(corev1.ConditionTrue)) // Check the Integration version - g.Eventually(IntegrationVersion(t, ctx, nsIntegration, name)).Should(Equal(version)) - - // Clear the KAMEL_BIN environment variable so that the current version is used from now on - g.Expect(os.Setenv("KAMEL_BIN", "")).To(Succeed()) + g.Eventually(IntegrationVersion(t, ctx, nsIntegration, name)).Should(Equal(lastVersion)) - // Upgrade the operator by installing the current version - registry := os.Getenv("KIND_REGISTRY") - g.Expect(registry).NotTo(Equal("")) - kustomizeDir := testutil.MakeTempCopyDir(t, "../../../install") - // We must change a few values in the Kustomize config + // Let's upgrade the operator with the newer installation ExpectExecSucceed(t, g, exec.Command( - "sed", - "-i", - fmt.Sprintf("s/namespace: .*/namespace: %s/", ns), - fmt.Sprintf("%s/overlays/kubernetes/descoped/kustomization.yaml", kustomizeDir), - )) - ExpectExecSucceed(t, g, Kubectl( - "apply", - "-k", - fmt.Sprintf("%s/overlays/kubernetes/descoped", kustomizeDir), - "--server-side", - "--wait", - "--force-conflicts", - )) + "make", + "install-k8s-global", + fmt.Sprintf("NAMESPACE=%s", ns), + ), + ) // Check the operator image is the current built one - g.Eventually(OperatorImage(t, ctx, ns)).Should(Equal(image)) + g.Eventually(OperatorImage(t, ctx, ns)).Should(ContainSubstring(defaults.Version)) // Check the operator pod is running g.Eventually(OperatorPodPhase(t, ctx, ns), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) // Check the IntegrationPlatform has been reconciled @@ -109,7 +111,7 @@ func TestKustomizeUpgrade(t *testing.T) { g.Eventually(PlatformVersion(t, ctx, ns), TestTimeoutMedium).Should(Equal(defaults.Version)) // Check the Integration hasn't been upgraded - g.Consistently(IntegrationVersion(t, ctx, nsIntegration, name), 15*time.Second, 3*time.Second).Should(Equal(version)) + g.Consistently(IntegrationVersion(t, ctx, nsIntegration, name), 15*time.Second, 3*time.Second).Should(Equal(lastVersion)) // Make sure that any Pod rollout is completing successfully // otherwise we are probably in front of a non breaking compatibility change g.Consistently(IntegrationConditionStatus(t, ctx, nsIntegration, name, v1.IntegrationConditionReady), @@ -124,7 +126,7 @@ func TestKustomizeUpgrade(t *testing.T) { g.Eventually(IntegrationVersion(t, ctx, nsIntegration, name), TestTimeoutMedium).Should(Equal(defaults.Version)) // Check the previous kit is not garbage collected - g.Eventually(Kits(t, ctx, ns, KitWithVersion(version))).Should(HaveLen(1)) + g.Eventually(Kits(t, ctx, ns, KitWithVersion(lastVersion))).Should(HaveLen(1)) // Check a new kit is created with the current version g.Eventually(Kits(t, ctx, ns, KitWithVersion(defaults.Version))).Should(HaveLen(1)) // Check the new kit is ready
