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

nferraro pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 8b5cc0b171497c95f4877613e707b25db55b58d7
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Tue May 18 15:03:34 2021 +0200

    fix(trait): some error when comparing trait properties
    
    * The operator panicked because some equality on slices.
    * Checking if the kit has no traits which was always having the comparison 
succesful
---
 pkg/controller/integration/util.go      | 37 +++++++++++++-
 pkg/controller/integration/util_test.go | 86 +++++++++++++++++++++++++++++++++
 2 files changed, 122 insertions(+), 1 deletion(-)

diff --git a/pkg/controller/integration/util.go 
b/pkg/controller/integration/util.go
index 986b499..2087bd6 100644
--- a/pkg/controller/integration/util.go
+++ b/pkg/controller/integration/util.go
@@ -122,6 +122,10 @@ func LookupKitForIntegration(ctx context.Context, c 
k8sclient.Reader, integratio
 
 // HasMatchingTraits compare traits defined on kit against those defined on 
integration.
 func HasMatchingTraits(kit *v1.IntegrationKit, integration *v1.Integration) 
(bool, error) {
+       // The kit has no trait, but the integration need some
+       if len(kit.Spec.Traits) == 0 && len(integration.Spec.Traits) > 0 {
+               return false, nil
+       }
        for name, kitTrait := range kit.Spec.Traits {
                intTrait, ok := integration.Spec.Traits[name]
                if !ok {
@@ -153,7 +157,7 @@ func HasMatchingTraits(kit *v1.IntegrationKit, integration 
*v1.Integration) (boo
                                // in integration trait
                                return false, nil
                        }
-                       if iv != cv {
+                       if !equal(iv, cv) {
                                // skip it because trait configured on kit has 
a value that differs from
                                // the one configured on integration
                                return false, nil
@@ -163,3 +167,34 @@ func HasMatchingTraits(kit *v1.IntegrationKit, integration 
*v1.Integration) (boo
 
        return true, nil
 }
+
+// We need to try to perform a slice equality in order to prevent a runtime 
panic
+func equal(a, b interface{}) bool {
+       aSlice, aOk := a.([]interface{})
+       bSlice, bOk := b.([]interface{})
+
+       if aOk && bOk {
+               // Both are slices
+               return sliceEqual(aSlice, bSlice)
+       }
+
+       if aOk || bOk {
+               // One of the 2 is a slice
+               return false
+       }
+
+       // None is a slice
+       return a == b
+}
+
+func sliceEqual(a, b []interface{}) bool {
+       if len(a) != len(b) {
+               return false
+       }
+       for i, v := range a {
+               if v != b[i] {
+                       return false
+               }
+       }
+       return true
+}
diff --git a/pkg/controller/integration/util_test.go 
b/pkg/controller/integration/util_test.go
index d6b813b..0ec0846 100644
--- a/pkg/controller/integration/util_test.go
+++ b/pkg/controller/integration/util_test.go
@@ -271,3 +271,89 @@ func 
TestLookupKitForIntegration_DiscardKitsWithIncompatibleTraits(t *testing.T)
        assert.NotNil(t, i)
        assert.Equal(t, "my-kit-4", i.Name)
 }
+
+func TestHasMatchingTraits_KitNoTraitShouldNotBePicked(t *testing.T) {
+       integration := &v1.Integration{
+               TypeMeta: metav1.TypeMeta{
+                       APIVersion: v1.SchemeGroupVersion.String(),
+                       Kind:       v1.IntegrationKind,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "ns",
+                       Name:      "my-integration",
+               },
+               Spec: v1.IntegrationSpec{
+                       Traits: map[string]v1.TraitSpec{
+                               "builder": test.TraitSpecFromMap(t, 
map[string]interface{}{
+                                       "enabled": "true",
+                               }),
+                       },
+               },
+       }
+
+       integrationKitSpec := &v1.IntegrationKit{
+               TypeMeta: metav1.TypeMeta{
+                       APIVersion: v1.SchemeGroupVersion.String(),
+                       Kind:       v1.IntegrationKitKind,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "ns",
+                       Name:      "my-kit",
+               },
+               Spec: v1.IntegrationKitSpec{
+                       Traits: map[string]v1.TraitSpec{},
+               },
+       }
+
+       ok, err := HasMatchingTraits(integrationKitSpec, integration)
+       assert.Nil(t, err)
+       assert.False(t, ok)
+}
+
+func TestHasMatchingTraits_KitSameTraitShouldBePicked(t *testing.T) {
+       integration := &v1.Integration{
+               TypeMeta: metav1.TypeMeta{
+                       APIVersion: v1.SchemeGroupVersion.String(),
+                       Kind:       v1.IntegrationKind,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "ns",
+                       Name:      "my-integration",
+               },
+               Spec: v1.IntegrationSpec{
+                       Traits: map[string]v1.TraitSpec{
+                               "builder": test.TraitSpecFromMap(t, 
map[string]interface{}{
+                                       "enabled": "true",
+                                       "buildTimeProperties": []string{
+                                               "build-key1=build-value1",
+                                       },
+                               }),
+                       },
+               },
+       }
+
+       integrationKitSpec := &v1.IntegrationKit{
+               TypeMeta: metav1.TypeMeta{
+                       APIVersion: v1.SchemeGroupVersion.String(),
+                       Kind:       v1.IntegrationKitKind,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "ns",
+                       Name:      "my-kit",
+               },
+               Spec: v1.IntegrationKitSpec{
+                       Traits: map[string]v1.TraitSpec{
+                               "builder": test.TraitSpecFromMap(t, 
map[string]interface{}{
+                                       "enabled": "true",
+                                       "buildTimeProperties": []string{
+                                               "build-key1=build-value1",
+                                       },
+                               }),
+                       },
+               },
+       }
+
+       ok, err := HasMatchingTraits(integrationKitSpec, integration)
+       assert.Nil(t, err)
+       assert.True(t, ok)
+}

Reply via email to