You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2022/01/12 08:15:11 UTC

[camel-k] 11/22: Fix #1107: added tests

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 1fde2b53666f30414d0a79521d0206dc023b68fc
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Mon Dec 20 16:35:39 2021 +0100

    Fix #1107: added tests
---
 addons/keda/keda.go      |   6 +-
 addons/keda/keda_test.go | 295 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 298 insertions(+), 3 deletions(-)

diff --git a/addons/keda/keda.go b/addons/keda/keda.go
index 3637153..3a54896 100644
--- a/addons/keda/keda.go
+++ b/addons/keda/keda.go
@@ -42,7 +42,7 @@ import (
 	scase "github.com/stoewer/go-strcase"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"sigs.k8s.io/controller-runtime/pkg/client"
+	ctrl "sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 const (
@@ -222,7 +222,7 @@ func (t *kedaTrait) addScalingResources(e *trait.Environment) error {
 			}
 		} else if trigger.AuthenticationSecret != "" {
 			s := v1.Secret{}
-			key := client.ObjectKey{
+			key := ctrl.ObjectKey{
 				Namespace: e.Integration.Namespace,
 				Name:      trigger.AuthenticationSecret,
 			}
@@ -273,7 +273,7 @@ func (t *kedaTrait) hackControllerReplicas(e *trait.Environment) error {
 	ctrlRef := t.getTopControllerReference(e)
 	if ctrlRef.Kind == camelv1alpha1.KameletBindingKind {
 		// Update the KameletBinding directly (do not add it to env resources, it's the integration parent)
-		key := client.ObjectKey{
+		key := ctrl.ObjectKey{
 			Namespace: e.Integration.Namespace,
 			Name:      ctrlRef.Name,
 		}
diff --git a/addons/keda/keda_test.go b/addons/keda/keda_test.go
new file mode 100644
index 0000000..083a231
--- /dev/null
+++ b/addons/keda/keda_test.go
@@ -0,0 +1,295 @@
+/*
+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 keda
+
+import (
+	"context"
+	"testing"
+
+	"github.com/apache/camel-k/addons/keda/duck/v1alpha1"
+	camelv1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	camelv1alpha1 "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/trait"
+	"github.com/apache/camel-k/pkg/util/camel"
+	"github.com/apache/camel-k/pkg/util/kubernetes"
+	"github.com/apache/camel-k/pkg/util/test"
+	"github.com/pkg/errors"
+	"github.com/stretchr/testify/assert"
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+)
+
+var (
+	testingTrue  = true
+	testingFalse = false
+)
+
+func TestManualConfig(t *testing.T) {
+	keda, _ := NewKedaTrait().(*kedaTrait)
+	keda.Enabled = &testingTrue
+	keda.Auto = &testingFalse
+	meta := map[string]string{
+		"prop":      "val",
+		"camelCase": "VAL",
+	}
+	keda.Triggers = append(keda.Triggers, kedaTrigger{
+		Type:     "mytype",
+		Metadata: meta,
+	})
+	env := createBasicTestEnvironment()
+
+	res, err := keda.Configure(env)
+	assert.NoError(t, err)
+	assert.True(t, res)
+	assert.NoError(t, keda.Apply(env))
+	so := getScaledObject(env)
+	assert.NotNil(t, so)
+	assert.Len(t, so.Spec.Triggers, 1)
+	assert.Equal(t, "mytype", so.Spec.Triggers[0].Type)
+	assert.Equal(t, meta, so.Spec.Triggers[0].Metadata)
+	assert.Nil(t, so.Spec.Triggers[0].AuthenticationRef)
+	assert.Nil(t, getTriggerAuthentication(env))
+	assert.Nil(t, getSecret(env))
+}
+
+func TestConfigFromSecret(t *testing.T) {
+	keda, _ := NewKedaTrait().(*kedaTrait)
+	keda.Enabled = &testingTrue
+	keda.Auto = &testingFalse
+	meta := map[string]string{
+		"prop":      "val",
+		"camelCase": "VAL",
+	}
+	keda.Triggers = append(keda.Triggers, kedaTrigger{
+		Type:                 "mytype",
+		Metadata:             meta,
+		AuthenticationSecret: "my-secret",
+	})
+	env := createBasicTestEnvironment(&corev1.Secret{
+		ObjectMeta: metav1.ObjectMeta{
+			Namespace: "test",
+			Name:      "my-secret",
+		},
+		Data: map[string][]byte{
+			"bbb": []byte("val1"),
+			"aaa": []byte("val2"),
+		},
+	})
+
+	res, err := keda.Configure(env)
+	assert.NoError(t, err)
+	assert.True(t, res)
+	assert.NoError(t, keda.Apply(env))
+	so := getScaledObject(env)
+	assert.NotNil(t, so)
+	assert.Len(t, so.Spec.Triggers, 1)
+	assert.Equal(t, "mytype", so.Spec.Triggers[0].Type)
+	assert.Equal(t, meta, so.Spec.Triggers[0].Metadata)
+	triggerAuth := getTriggerAuthentication(env)
+	assert.NotNil(t, triggerAuth)
+	assert.Equal(t, so.Spec.Triggers[0].AuthenticationRef.Name, triggerAuth.Name)
+	assert.NotEqual(t, "my-secret", triggerAuth.Name)
+	assert.Len(t, triggerAuth.Spec.SecretTargetRef, 2)
+	assert.Equal(t, "aaa", triggerAuth.Spec.SecretTargetRef[0].Key)
+	assert.Equal(t, "aaa", triggerAuth.Spec.SecretTargetRef[0].Parameter)
+	assert.Equal(t, "my-secret", triggerAuth.Spec.SecretTargetRef[0].Name)
+	assert.Equal(t, "bbb", triggerAuth.Spec.SecretTargetRef[1].Key)
+	assert.Equal(t, "bbb", triggerAuth.Spec.SecretTargetRef[1].Parameter)
+	assert.Equal(t, "my-secret", triggerAuth.Spec.SecretTargetRef[1].Name)
+	assert.Nil(t, getSecret(env)) // Secret is already present, not generated
+}
+
+func TestKameletAutoDetection(t *testing.T) {
+	keda, _ := NewKedaTrait().(*kedaTrait)
+	keda.Enabled = &testingTrue
+	env := createBasicTestEnvironment(
+		&camelv1alpha1.Kamelet{
+			ObjectMeta: metav1.ObjectMeta{
+				Namespace: "test",
+				Name:      "my-kamelet",
+				Annotations: map[string]string{
+					"camel.apache.org/keda.type": "my-scaler",
+				},
+			},
+			Spec: camelv1alpha1.KameletSpec{
+				Definition: &camelv1alpha1.JSONSchemaProps{
+					Properties: map[string]camelv1alpha1.JSONSchemaProp{
+						"a": camelv1alpha1.JSONSchemaProp{
+							XDescriptors: []string{
+								"urn:keda:metadata:a",
+							},
+						},
+						"b": camelv1alpha1.JSONSchemaProp{
+							XDescriptors: []string{
+								"urn:keda:metadata:bb",
+							},
+						},
+						"c": camelv1alpha1.JSONSchemaProp{
+							XDescriptors: []string{
+								"urn:keda:authentication:cc",
+							},
+						},
+					},
+				},
+			},
+		},
+		&camelv1.Integration{
+			ObjectMeta: metav1.ObjectMeta{
+				Namespace: "test",
+				Name:      "my-it",
+			},
+			Spec: camelv1.IntegrationSpec{
+				Sources: []camelv1.SourceSpec{
+					{
+						DataSpec: camelv1.DataSpec{
+							Name: "my-it.yaml",
+							Content: "" +
+								"- route:\n" +
+								"    from:\n" +
+								"      uri: kamelet:my-kamelet\n" +
+								"      parameters:\n" +
+								"        a: v1\n" +
+								"        b: v2\n" +
+								"        c: v3\n" +
+								"    steps:\n" +
+								"    - to: log:sink\n",
+						},
+						Language: camelv1.LanguageYaml,
+					},
+				},
+			},
+			Status: camelv1.IntegrationStatus{
+				Phase: camelv1.IntegrationPhaseDeploying,
+			},
+		})
+
+	res, err := keda.Configure(env)
+	assert.NoError(t, err)
+	assert.True(t, res)
+	assert.NoError(t, keda.Apply(env))
+	so := getScaledObject(env)
+	assert.NotNil(t, so)
+	assert.Len(t, so.Spec.Triggers, 1)
+	assert.Equal(t, "my-scaler", so.Spec.Triggers[0].Type)
+	assert.Equal(t, map[string]string{
+		"a":  "v1",
+		"bb": "v2",
+	}, so.Spec.Triggers[0].Metadata)
+	triggerAuth := getTriggerAuthentication(env)
+	assert.NotNil(t, triggerAuth)
+	assert.Equal(t, so.Spec.Triggers[0].AuthenticationRef.Name, triggerAuth.Name)
+	assert.Len(t, triggerAuth.Spec.SecretTargetRef, 1)
+	assert.Equal(t, "cc", triggerAuth.Spec.SecretTargetRef[0].Key)
+	assert.Equal(t, "cc", triggerAuth.Spec.SecretTargetRef[0].Parameter)
+	secretName := triggerAuth.Spec.SecretTargetRef[0].Name
+	secret := getSecret(env)
+	assert.NotNil(t, secret)
+	assert.Equal(t, secretName, secret.Name)
+	assert.Len(t, secret.StringData, 1)
+	assert.Contains(t, secret.StringData, "cc")
+}
+
+func getScaledObject(e *trait.Environment) *v1alpha1.ScaledObject {
+	var res *v1alpha1.ScaledObject
+	for _, o := range e.Resources.Items() {
+		if so, ok := o.(*v1alpha1.ScaledObject); ok {
+			if res != nil {
+				panic("multiple ScaledObjects found in env")
+			}
+			res = so
+		}
+	}
+	return res
+}
+
+func getTriggerAuthentication(e *trait.Environment) *v1alpha1.TriggerAuthentication {
+	var res *v1alpha1.TriggerAuthentication
+	for _, o := range e.Resources.Items() {
+		if so, ok := o.(*v1alpha1.TriggerAuthentication); ok {
+			if res != nil {
+				panic("multiple TriggerAuthentication found in env")
+			}
+			res = so
+		}
+	}
+	return res
+}
+
+func getSecret(e *trait.Environment) *corev1.Secret {
+	var res *corev1.Secret
+	for _, o := range e.Resources.Items() {
+		if so, ok := o.(*corev1.Secret); ok {
+			if res != nil {
+				panic("multiple Secret found in env")
+			}
+			res = so
+		}
+	}
+	return res
+}
+
+func createBasicTestEnvironment(resources ...runtime.Object) *trait.Environment {
+	fakeClient, err := test.NewFakeClient(resources...)
+	if err != nil {
+		panic(errors.Wrap(err, "could not create fake client"))
+	}
+
+	var it *camelv1.Integration
+	for _, res := range resources {
+		if integration, ok := res.(*camelv1.Integration); ok {
+			it = integration
+		}
+	}
+	if it == nil {
+		it = &camelv1.Integration{
+			ObjectMeta: metav1.ObjectMeta{
+				Namespace: "test",
+				Name:      "integration-name",
+			},
+			Status: camelv1.IntegrationStatus{
+				Phase: camelv1.IntegrationPhaseDeploying,
+			},
+		}
+	}
+
+	return &trait.Environment{
+		Catalog:     trait.NewCatalog(nil),
+		Ctx:         context.Background(),
+		Client:      fakeClient,
+		Integration: it,
+		CamelCatalog: &camel.RuntimeCatalog{
+			CamelCatalogSpec: camelv1.CamelCatalogSpec{
+				Runtime: camelv1.RuntimeSpec{
+					Version:  "0.0.1",
+					Provider: camelv1.RuntimeProviderQuarkus,
+				},
+			},
+		},
+		Platform: &camelv1.IntegrationPlatform{
+			ObjectMeta: metav1.ObjectMeta{
+				Namespace: "test",
+			},
+			Spec: camelv1.IntegrationPlatformSpec{
+				Cluster: camelv1.IntegrationPlatformClusterKubernetes,
+			},
+		},
+		Resources:             kubernetes.NewCollection(),
+		ApplicationProperties: make(map[string]string),
+	}
+}