This is an automated email from the ASF dual-hosted git repository.

pcongiusti pushed a commit to branch release-1.12.x
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit a654320ead27a4f17689314323a1fb1a89e6a789
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Thu Mar 23 12:03:54 2023 +0100

    fix(builder): native from source should rebuild
    
    Closes #4126
---
 e2e/namespace/native/files/Java2.java            | 28 ++++++++++++++++
 e2e/namespace/native/files/yaml2.yaml            | 28 ++++++++++++++++
 e2e/namespace/native/native_test.go              | 37 ++++++++++-----------
 e2e/namespace/native/native_with_sources_test.go | 29 ++++++++++++++++
 pkg/controller/integration/kits.go               | 20 +++++++++++
 pkg/controller/integration/kits_test.go          | 42 ++++++++++++++++++++++++
 pkg/resources/resources.go                       | 17 ++++++++++
 7 files changed, 181 insertions(+), 20 deletions(-)

diff --git a/e2e/namespace/native/files/Java2.java 
b/e2e/namespace/native/files/Java2.java
new file mode 100644
index 000000000..73b29ab99
--- /dev/null
+++ b/e2e/namespace/native/files/Java2.java
@@ -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.
+ */
+
+ import org.apache.camel.builder.RouteBuilder;
+
+ public class Java extends RouteBuilder {
+   @Override
+   public void configure() throws Exception {
+     from("timer:tick")
+       .setHeader("m").constant("string!")
+       .setBody().simple("Magic2${header.m}")
+       .log("Java ${body}");
+   }
+ }
diff --git a/e2e/namespace/native/files/yaml2.yaml 
b/e2e/namespace/native/files/yaml2.yaml
new file mode 100644
index 000000000..d717e5da6
--- /dev/null
+++ b/e2e/namespace/native/files/yaml2.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}2"
+      - to: "log:info"
diff --git a/e2e/namespace/native/native_test.go 
b/e2e/namespace/native/native_test.go
index f1686f737..e1cf1995a 100644
--- a/e2e/namespace/native/native_test.go
+++ b/e2e/namespace/native/native_test.go
@@ -75,24 +75,8 @@ func TestNativeIntegrations(t *testing.T) {
                        Expect(Kamel("delete", name, "-n", 
ns).Execute()).To(Succeed())
                })
 
-               t.Run("warm up before native build testing", func(t *testing.T) 
{
-                       // The following native build test is under tight time 
constraints, so here it runs
-                       // a warm up testing to make sure necessary jars are 
already downloaded.
-                       name := "warm-up-yaml"
-                       Expect(KamelRunWithID(operatorID, ns, 
"files/yaml.yaml", "--name", name).Execute()).To(Succeed())
-
-                       Eventually(IntegrationPodPhase(ns, name), 
TestTimeoutLong).Should(Equal(corev1.PodRunning))
-                       Eventually(IntegrationConditionStatus(ns, name, 
v1.IntegrationConditionReady), TestTimeoutShort).
-                               Should(Equal(corev1.ConditionTrue))
-                       Eventually(IntegrationLogs(ns, name), 
TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-                       // Clean up
-                       Expect(Kamel("delete", name, "-n", 
ns).Execute()).To(Succeed())
-                       Expect(DeleteKits(ns)).To(Succeed())
-               })
-
                t.Run("automatic rollout deployment from fast-jar to native 
kit", func(t *testing.T) {
-                       name := "jvm-to-native"
+                       name := "yaml-native"
                        Expect(KamelRunWithID(operatorID, ns, 
"files/yaml.yaml", "--name", name,
                                "-t", "quarkus.package-type=fast-jar",
                                "-t", "quarkus.package-type=native",
@@ -143,11 +127,24 @@ func TestNativeIntegrations(t *testing.T) {
 
                        Eventually(IntegrationLogs(ns, name), 
TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
 
+                       t.Run("yaml native should not rebuild", func(t 
*testing.T) {
+                               name := "yaml-native-2"
+                               Expect(KamelRunWithID(operatorID, ns, 
"files/yaml2.yaml", "--name", name,
+                                       "-t", "quarkus.package-type=native",
+                               ).Execute()).To(Succeed())
+
+                               // This one should run quickly as it suppose to 
reuse an IntegrationKit
+                               Eventually(IntegrationPodPhase(ns, name), 
TestTimeoutShort).Should(Equal(corev1.PodRunning))
+                               Eventually(IntegrationPod(ns, name), 
TestTimeoutShort).
+                                       
Should(WithTransform(getContainerCommand(), 
MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*")))
+                               Eventually(IntegrationConditionStatus(ns, name, 
v1.IntegrationConditionReady), TestTimeoutShort).
+                                       Should(Equal(corev1.ConditionTrue))
+                               Eventually(IntegrationLogs(ns, name), 
TestTimeoutShort).Should(ContainSubstring("Magicstring!2"))
+                               Expect(IntegrationKit(ns, 
"yaml-native")).Should(Equal(IntegrationKit(ns, "yaml-native-2")))
+                       })
+
                        // Clean up
                        Expect(Kamel("delete", name, "-n", 
ns).Execute()).To(Succeed())
                })
-
-               // Clean up
-               Expect(Kamel("delete", "--all", "-n", 
ns).Execute()).To(Succeed())
        })
 }
diff --git a/e2e/namespace/native/native_with_sources_test.go 
b/e2e/namespace/native/native_with_sources_test.go
index fc39ace54..fc3c73242 100644
--- a/e2e/namespace/native/native_with_sources_test.go
+++ b/e2e/namespace/native/native_with_sources_test.go
@@ -54,9 +54,38 @@ func TestNativeHighMemoryIntegrations(t *testing.T) {
                                Should(WithTransform(getContainerCommand(), 
MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*")))
                        Eventually(IntegrationConditionStatus(ns, name, 
v1.IntegrationConditionReady), TestTimeoutShort).
                                Should(Equal(corev1.ConditionTrue))
+                       Eventually(IntegrationLogs(ns, name), 
TestTimeoutShort).Should(ContainSubstring("Java Magicstring!"))
+               })
+
+               t.Run("java native same should not rebuild", func(t *testing.T) 
{
+                       name := "java-native-clone"
+                       Expect(KamelRunWithID(operatorID, ns, 
"files/Java.java", "--name", name,
+                               "-t", "quarkus.package-type=native",
+                       ).Execute()).To(Succeed())
 
+                       // This one should run quickly as it suppose to reuse 
an IntegrationKit
+                       Eventually(IntegrationPodPhase(ns, name), 
TestTimeoutShort).Should(Equal(corev1.PodRunning))
+                       Eventually(IntegrationPod(ns, name), TestTimeoutShort).
+                               Should(WithTransform(getContainerCommand(), 
MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*")))
+                       Eventually(IntegrationConditionStatus(ns, name, 
v1.IntegrationConditionReady), TestTimeoutShort).
+                               Should(Equal(corev1.ConditionTrue))
                        Eventually(IntegrationLogs(ns, name), 
TestTimeoutShort).Should(ContainSubstring("Java Magicstring!"))
+                       Expect(IntegrationKit(ns, 
"java-native")).Should(Equal(IntegrationKit(ns, "java-native-clone")))
+               })
 
+               t.Run("java native should rebuild", func(t *testing.T) {
+                       name := "java-native-2"
+                       Expect(KamelRunWithID(operatorID, ns, 
"files/Java2.java", "--name", name,
+                               "-t", "quarkus.package-type=native",
+                       ).Execute()).To(Succeed())
+
+                       Eventually(IntegrationPodPhase(ns, name), 
TestTimeoutVeryLong).Should(Equal(corev1.PodRunning))
+                       Eventually(IntegrationPod(ns, name), TestTimeoutShort).
+                               Should(WithTransform(getContainerCommand(), 
MatchRegexp(".*camel-k-integration-\\d+\\.\\d+\\.\\d+[-A-Za-z]*-runner.*")))
+                       Eventually(IntegrationConditionStatus(ns, name, 
v1.IntegrationConditionReady), TestTimeoutShort).
+                               Should(Equal(corev1.ConditionTrue))
+                       Eventually(IntegrationLogs(ns, name), 
TestTimeoutShort).Should(ContainSubstring("Java Magic2string!"))
+                       Expect(IntegrationKit(ns, 
"java-native-2")).ShouldNot(Equal(IntegrationKit(ns, "java-native")))
                        // Clean up
                        Expect(Kamel("delete", name, "-n", 
ns).Execute()).To(Succeed())
                })
diff --git a/pkg/controller/integration/kits.go 
b/pkg/controller/integration/kits.go
index 433d96180..4dfc4c74d 100644
--- a/pkg/controller/integration/kits.go
+++ b/pkg/controller/integration/kits.go
@@ -131,6 +131,12 @@ func integrationMatches(integration *v1.Integration, kit 
*v1.IntegrationKit) (bo
                ilog.Debug("Integration and integration-kit dependencies do not 
match", "integration", integration.Name, "integration-kit", kit.Name, 
"namespace", integration.Namespace)
                return false, nil
        }
+       // If IntegrationKit has any source, we must verify that it corresponds 
with the one in the Integration.
+       // This is important in case of Native builds as we need to rebuild 
when language requires a source during build.
+       if (kit.Spec.Sources != nil && len(kit.Spec.Sources) > 0) && 
!hasMatchingSources(integration, kit) {
+               ilog.Debug("Integration and integration-kit sources do not 
match", "integration", integration.Name, "integration-kit", kit.Name, 
"namespace", integration.Namespace)
+               return false, nil
+       }
 
        ilog.Debug("Matched Integration and integration-kit", "integration", 
integration.Name, "integration-kit", kit.Name, "namespace", 
integration.Namespace)
        return true, nil
@@ -250,3 +256,17 @@ func matchesTrait(it map[string]interface{}, kt 
map[string]interface{}) bool {
        // perform exact match on the two trait maps
        return reflect.DeepEqual(it, kt)
 }
+
+func hasMatchingSources(it *v1.Integration, kit *v1.IntegrationKit) bool {
+       for _, itSource := range it.Sources() {
+               for _, ikSource := range kit.Spec.Sources {
+                       if itSource.Content == ikSource.Content {
+                               // found, let's move to the next one
+                               break
+                       }
+                       return false
+               }
+
+       }
+       return true
+}
diff --git a/pkg/controller/integration/kits_test.go 
b/pkg/controller/integration/kits_test.go
index 694be1521..3abc0ef47 100644
--- a/pkg/controller/integration/kits_test.go
+++ b/pkg/controller/integration/kits_test.go
@@ -338,3 +338,45 @@ func TestHasMatchingTraits_KitSameTraitShouldBePicked(t 
*testing.T) {
        assert.Nil(t, err)
        assert.True(t, ok)
 }
+
+func TestHasMatchingSources(t *testing.T) {
+       integration := &v1.Integration{
+               Spec: v1.IntegrationSpec{
+                       Sources: []v1.SourceSpec{
+                               v1.NewSourceSpec("test", "some content", 
v1.LanguageJavaShell),
+                       },
+               },
+       }
+
+       kit := &v1.IntegrationKit{
+               Spec: v1.IntegrationKitSpec{
+                       Sources: []v1.SourceSpec{
+                               v1.NewSourceSpec("test", "some content", 
v1.LanguageJavaShell),
+                       },
+               },
+       }
+
+       hasMatchingSources := hasMatchingSources(integration, kit)
+       assert.True(t, hasMatchingSources)
+}
+
+func TestHasNotMatchingSources(t *testing.T) {
+       integration := &v1.Integration{
+               Spec: v1.IntegrationSpec{
+                       Sources: []v1.SourceSpec{
+                               v1.NewSourceSpec("test", "some content", 
v1.LanguageJavaShell),
+                       },
+               },
+       }
+
+       kit := &v1.IntegrationKit{
+               Spec: v1.IntegrationKitSpec{
+                       Sources: []v1.SourceSpec{
+                               v1.NewSourceSpec("test", "some content 2", 
v1.LanguageJavaShell),
+                       },
+               },
+       }
+
+       hasMatchingSources := hasMatchingSources(integration, kit)
+       assert.False(t, hasMatchingSources)
+}
diff --git a/pkg/resources/resources.go b/pkg/resources/resources.go
index 23b682afd..0511f9dd1 100644
--- a/pkg/resources/resources.go
+++ b/pkg/resources/resources.go
@@ -167,6 +167,18 @@ var assets = func() http.FileSystem {
                        name:    "manager",
                        modTime: time.Time{},
                },
+               "/manager/bundle": &vfsgen۰DirInfo{
+                       name:    "bundle",
+                       modTime: time.Time{},
+               },
+               "/manager/bundle/manifests": &vfsgen۰DirInfo{
+                       name:    "manifests",
+                       modTime: time.Time{},
+               },
+               "/manager/bundle/metadata": &vfsgen۰DirInfo{
+                       name:    "metadata",
+                       modTime: time.Time{},
+               },
                "/manager/operator-deployment.yaml": &vfsgen۰CompressedFileInfo{
                        name:             "operator-deployment.yaml",
                        modTime:          time.Time{},
@@ -657,6 +669,7 @@ var assets = func() http.FileSystem {
                fs["/crd/bases/camel.apache.org_kamelets.yaml"].(os.FileInfo),
        }
        fs["/manager"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
+               fs["/manager/bundle"].(os.FileInfo),
                fs["/manager/operator-deployment.yaml"].(os.FileInfo),
                fs["/manager/operator-service-account.yaml"].(os.FileInfo),
                
fs["/manager/patch-image-pull-policy-always.yaml"].(os.FileInfo),
@@ -668,6 +681,10 @@ var assets = func() http.FileSystem {
                fs["/manager/patch-toleration.yaml"].(os.FileInfo),
                fs["/manager/patch-watch-namespace-global.yaml"].(os.FileInfo),
        }
+       fs["/manager/bundle"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
+               fs["/manager/bundle/manifests"].(os.FileInfo),
+               fs["/manager/bundle/metadata"].(os.FileInfo),
+       }
        fs["/prometheus"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
                fs["/prometheus/operator-pod-monitor.yaml"].(os.FileInfo),
                fs["/prometheus/operator-prometheus-rule.yaml"].(os.FileInfo),

Reply via email to