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) +}
