This is an automated email from the ASF dual-hosted git repository. astefanutti pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 95af8de2ff394df265995b50ea014ebc2bc9aeb3 Author: Antonin Stefanutti <[email protected]> AuthorDate: Tue Sep 7 12:44:46 2021 +0200 feat(native): Automatic rollout deployment to native kit e2e test --- .github/workflows/kubernetes.yml | 3 +- e2e/native/native_test.go | 90 ++++++++++++++++++++++++++++++++++++++++ e2e/native/yaml.yaml | 28 +++++++++++++ e2e/support/test_support.go | 62 ++++++++++++++++++++++----- e2e/upgrade/cli_upgrade_test.go | 16 ++----- e2e/upgrade/olm_upgrade_test.go | 8 ++-- script/Makefile | 28 +++++++------ 7 files changed, 195 insertions(+), 40 deletions(-) diff --git a/.github/workflows/kubernetes.yml b/.github/workflows/kubernetes.yml index 6677360..33f7f01 100644 --- a/.github/workflows/kubernetes.yml +++ b/.github/workflows/kubernetes.yml @@ -131,4 +131,5 @@ jobs: # Then run integration tests make test-integration - make test-service-binding \ No newline at end of file + make test-service-binding + make test-quarkus-native diff --git a/e2e/native/native_test.go b/e2e/native/native_test.go new file mode 100644 index 0000000..e3fd7ca --- /dev/null +++ b/e2e/native/native_test.go @@ -0,0 +1,90 @@ +// +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 native + +import ( + "testing" + + . "github.com/onsi/gomega" + + corev1 "k8s.io/api/core/v1" + + . "github.com/apache/camel-k/e2e/support" + v1 "github.com/apache/camel-k/pkg/apis/camel/v1" +) + +var ( + withFastJarLayout = KitWithLabels(map[string]string{v1.IntegrationKitLayoutLabel: v1.IntegrationKitLayoutFastJar}) + withNativeLayout = KitWithLabels(map[string]string{v1.IntegrationKitLayoutLabel: v1.IntegrationKitLayoutNative}) +) + +func TestAutomaticRolloutDeploymentFromFastJarToNativeKit(t *testing.T) { + WithNewTestNamespace(t, func(ns string) { + Expect(Kamel("install", "-n", ns, "--build-timeout", "15m0s").Execute()).To(Succeed()) + Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + name := "jvm-to-native" + Expect(Kamel("run", "-n", ns, "yaml.yaml", "--name", name, + "-t", "quarkus.package-type=fast-jar", + "-t", "quarkus.package-type=native", + ).Execute()).To(Succeed()) + + // Check that two Kits are created with distinct layout + Eventually(Kits(ns, withFastJarLayout)).Should(HaveLen(1)) + Eventually(Kits(ns, withNativeLayout)).Should(HaveLen(1)) + + // Check the fast-jar Kit is ready + Eventually(Kits(ns, withFastJarLayout, KitWithPhase(v1.IntegrationKitPhaseReady)), + TestTimeoutMedium).Should(HaveLen(1)) + + fastJarKit := Kits(ns, withFastJarLayout, KitWithPhase(v1.IntegrationKitPhaseReady))()[0] + // Check the Integration uses the fast-jar Kit + Eventually(IntegrationKit(ns, name), TestTimeoutShort).Should(Equal(fastJarKit.Name)) + // Check the Integration Pod uses the fast-jar Kit + Eventually(IntegrationPodImage(ns, name)).Should(Equal(fastJarKit.Status.Image)) + + // Check the Integration is ready + Eventually(IntegrationPodPhase(ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + + Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + // Check the native Kit is ready + Eventually(Kits(ns, withNativeLayout, KitWithPhase(v1.IntegrationKitPhaseReady)), + TestTimeoutLong).Should(HaveLen(1)) + + nativeKit := Kits(ns, withNativeLayout, KitWithPhase(v1.IntegrationKitPhaseReady))()[0] + // Check the Integration uses the native Kit + Eventually(IntegrationKit(ns, name), TestTimeoutShort).Should(Equal(nativeKit.Name)) + // Check the Integration Pod uses the native Kit + Eventually(IntegrationPodImage(ns, name)).Should(Equal(nativeKit.Status.Image)) + + // Check the Integration is still ready + Eventually(IntegrationPodPhase(ns, name), TestTimeoutMedium).Should(Equal(corev1.PodRunning)) + Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + + Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + // Clean up + Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) +} diff --git a/e2e/native/yaml.yaml b/e2e/native/yaml.yaml new file mode 100644 index 0000000..9ccf652 --- /dev/null +++ b/e2e/native/yaml.yaml @@ -0,0 +1,28 @@ +# --------------------------------------------------------------------------- +# 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. +# --------------------------------------------------------------------------- + +- from: + uri: "timer:yaml" + parameters: + period: "5000" + steps: + - set-header: + name: "m" + constant: "string!" + - set-body: + simple: "Magic${header.m}" + - to: "log:info" diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go index 6f29b22..096a1e9 100644 --- a/e2e/support/test_support.go +++ b/e2e/support/test_support.go @@ -46,6 +46,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" "k8s.io/utils/pointer" @@ -678,26 +679,65 @@ func ScaleKameletBinding(ns string, name string, replicas int32) error { }) } -func Kits(ns string, filters ...func(*v1.IntegrationKit) bool) func() []v1.IntegrationKit { +type KitFilter interface { + Match(*v1.IntegrationKit) bool +} + +func KitWithPhase(phase v1.IntegrationKitPhase) KitFilter { + return &kitFilter{ + filter: func(kit *v1.IntegrationKit) bool { + return kit.Status.Phase == phase + }, + } +} + +func KitWithVersion(version string) KitFilter { + return &kitFilter{ + filter: func(kit *v1.IntegrationKit) bool { + return kit.Status.Version == version + }, + } +} + +func KitWithLabels(kitLabels map[string]string) ctrl.ListOption { + return ctrl.MatchingLabelsSelector{ + Selector: labels.Set(kitLabels).AsSelector(), + } +} + +type kitFilter struct { + filter func(*v1.IntegrationKit) bool +} + +func (f *kitFilter) Match(kit *v1.IntegrationKit) bool { + return f.filter(kit) +} + +func Kits(ns string, options ...interface{}) func() []v1.IntegrationKit { + filters := make([]KitFilter, 0) + listOptions := []ctrl.ListOption{ctrl.InNamespace(ns)} + for _, option := range options { + switch o := option.(type) { + case KitFilter: + filters = append(filters, o) + case ctrl.ListOption: + listOptions = append(listOptions, o) + default: + panic(fmt.Errorf("unsupported kits option %q", o)) + } + } + return func() []v1.IntegrationKit { list := v1.NewIntegrationKitList() - if err := TestClient().List(TestContext, &list, ctrl.InNamespace(ns)); err != nil { + if err := TestClient().List(TestContext, &list, listOptions...); err != nil { panic(err) } - if len(filters) == 0 { - filters = []func(*v1.IntegrationKit) bool{ - func(kit *v1.IntegrationKit) bool { - return true - }, - } - } - var kits []v1.IntegrationKit kits: for _, kit := range list.Items { for _, filter := range filters { - if !filter(&kit) { + if !filter.Match(&kit) { continue kits } } diff --git a/e2e/upgrade/cli_upgrade_test.go b/e2e/upgrade/cli_upgrade_test.go index b324633..313b18e 100644 --- a/e2e/upgrade/cli_upgrade_test.go +++ b/e2e/upgrade/cli_upgrade_test.go @@ -94,14 +94,14 @@ func TestOperatorUpgrade(t *testing.T) { Eventually(IntegrationVersion(ns, name)).Should(Equal(defaults.Version)) // Check the previous kit is not garbage collected - Eventually(Kits(ns, kitWithVersion(version))).Should(HaveLen(1)) + Eventually(Kits(ns, KitWithVersion(version))).Should(HaveLen(1)) // Check a new kit is created with the current version - Eventually(Kits(ns, kitWithVersion(defaults.Version))).Should(HaveLen(1)) + Eventually(Kits(ns, KitWithVersion(defaults.Version))).Should(HaveLen(1)) // Check the new kit is ready - Eventually(Kits(ns, kitWithVersion(defaults.Version), kitWithPhase(v1.IntegrationKitPhaseReady)), + Eventually(Kits(ns, KitWithVersion(defaults.Version), KitWithPhase(v1.IntegrationKitPhaseReady)), TestTimeoutMedium).Should(HaveLen(1)) - kit := Kits(ns, kitWithVersion(defaults.Version))()[0] + kit := Kits(ns, KitWithVersion(defaults.Version))()[0] // Check the Integration uses the new image Eventually(IntegrationKit(ns, name), TestTimeoutMedium).Should(Equal(kit.Name)) @@ -117,11 +117,3 @@ func TestOperatorUpgrade(t *testing.T) { Expect(Kamel("uninstall", "--all", "--olm=false").Execute()).To(Succeed()) }) } - -func kitWithVersion(version string) func(kit *v1.IntegrationKit) bool { - return func(kit *v1.IntegrationKit) bool { return kit.Status.Version == version } -} - -func kitWithPhase(phase v1.IntegrationKitPhase) func(kit *v1.IntegrationKit) bool { - return func(kit *v1.IntegrationKit) bool { return kit.Status.Phase == phase } -} diff --git a/e2e/upgrade/olm_upgrade_test.go b/e2e/upgrade/olm_upgrade_test.go index 5641959..7977c74 100644 --- a/e2e/upgrade/olm_upgrade_test.go +++ b/e2e/upgrade/olm_upgrade_test.go @@ -141,14 +141,14 @@ func TestOLMAutomaticUpgrade(t *testing.T) { Eventually(IntegrationVersion(ns, name)).Should(ContainSubstring(newIPVersionPrefix)) // Check the previous kit is not garbage collected - Eventually(Kits(ns, kitWithVersion(prevCSVVersion.String()))).Should(HaveLen(1)) + Eventually(Kits(ns, KitWithVersion(prevCSVVersion.String()))).Should(HaveLen(1)) // Check a new kit is created with the current version - Eventually(Kits(ns, kitWithVersion(defaults.Version))).Should(HaveLen(1)) + Eventually(Kits(ns, KitWithVersion(defaults.Version))).Should(HaveLen(1)) // Check the new kit is ready - Eventually(Kits(ns, kitWithVersion(defaults.Version), kitWithPhase(v1.IntegrationKitPhaseReady)), + Eventually(Kits(ns, KitWithVersion(defaults.Version), KitWithPhase(v1.IntegrationKitPhaseReady)), TestTimeoutMedium).Should(HaveLen(1)) - kit := Kits(ns, kitWithVersion(defaults.Version))()[0] + kit := Kits(ns, KitWithVersion(defaults.Version))()[0] // Check the Integration uses the new kit Eventually(IntegrationKit(ns, name), TestTimeoutMedium).Should(Equal(kit.Name)) diff --git a/script/Makefile b/script/Makefile index e5fe4c6..4a74b79 100644 --- a/script/Makefile +++ b/script/Makefile @@ -161,28 +161,32 @@ test-integration: build go test -timeout 60m -v ./e2e/common/traits -tags=integration test-knative: build - STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" go test -timeout 60m -v ./e2e/knative -tags=integration - #go test -timeout 60m -v ./e2e/knative -tags=integration + STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \ + go test -timeout 60m -v ./e2e/knative -tags=integration test-builder: build - STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" go test -timeout 60m -v ./e2e/builder -tags=integration - #go test -timeout 60m -v ./e2e/builder -tags=integration + STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \ + go test -timeout 60m -v ./e2e/builder -tags=integration test-local: build - STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" go test -timeout 60m -v ./e2e/local -tags=integration - #go test -timeout 60m -v ./e2e/local -tags=integration + STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \ + go test -timeout 60m -v ./e2e/local -tags=integration test-kamel-cli: build - STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" go test -timeout 60m -v ./e2e/common/cli -tags=integration - #go test -timeout 60m -v ./e2e/common/cli -tags=integration + STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \ + go test -timeout 60m -v ./e2e/common/cli -tags=integration -test-upgrade: build +test-quarkus-native: build STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \ - go test -timeout 60m -v ./e2e/upgrade -tags=integration + go test -timeout 60m -v ./e2e/native -tags=integration test-service-binding: build - STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" go test -timeout 60m -v ./e2e/service-binding -tags=integration - #go test -timeout 60m -v ./e2e/service-binding -tags=integration + STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \ + go test -timeout 60m -v ./e2e/service-binding -tags=integration + +test-upgrade: build + STAGING_RUNTIME_REPO="$(STAGING_RUNTIME_REPO)" \ + go test -timeout 60m -v ./e2e/upgrade -tags=integration build-kamel: # Ensure the binary is statically linked when building on Linux due to ABI changes in newer glibc 2.32, otherwise
