Skip to content

Commit

Permalink
Fix apache#1107: add tests for kamelet binding and replicas
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolaferraro committed Jan 10, 2022
1 parent 37162bc commit ff5031b
Show file tree
Hide file tree
Showing 9 changed files with 196 additions and 19 deletions.
191 changes: 183 additions & 8 deletions addons/keda/keda_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ package keda

import (
"context"
"encoding/json"
"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/controller/kameletbinding"
"github.com/apache/camel-k/pkg/trait"
"github.com/apache/camel-k/pkg/util/camel"
"github.com/apache/camel-k/pkg/util/kubernetes"
Expand All @@ -33,6 +35,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)

var (
Expand Down Expand Up @@ -205,6 +208,156 @@ func TestKameletAutoDetection(t *testing.T) {
assert.Contains(t, secret.StringData, "cc")
}

func TestKameletBindingAutoDetection(t *testing.T) {
keda, _ := NewKedaTrait().(*kedaTrait)
keda.Enabled = &testingTrue
logEndpoint := "log:info"
klb := camelv1alpha1.KameletBinding{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "my-binding",
},
Spec: camelv1alpha1.KameletBindingSpec{
Source: camelv1alpha1.Endpoint{
Ref: &corev1.ObjectReference{
Kind: "Kamelet",
APIVersion: camelv1alpha1.SchemeGroupVersion.String(),
Name: "my-kamelet",
},
Properties: asEndpointProperties(map[string]string{
"a": "v1",
"b": "v2",
"c": "v3",
}),
},
Sink: camelv1alpha1.Endpoint{
URI: &logEndpoint,
},
},
}

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",
},
},
},
},
},
},
&klb,
&camelv1.IntegrationPlatform{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "camel-k",
},
Spec: camelv1.IntegrationPlatformSpec{
Cluster: camelv1.IntegrationPlatformClusterKubernetes,
Profile: camelv1.TraitProfileKubernetes,
},
Status: camelv1.IntegrationPlatformStatus{
Phase: camelv1.IntegrationPlatformPhaseReady,
},
})

it, err := kameletbinding.CreateIntegrationFor(env.Ctx, env.Client, &klb)
assert.NoError(t, err)
assert.NotNil(t, it)
env.Integration = it

it.Status.Phase = camelv1.IntegrationPhaseInitialization
init := trait.NewInitTrait()
ok, err := init.Configure(env)
assert.NoError(t, err)
assert.True(t, ok)
assert.NoError(t, init.Apply(env))

it.Status.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 TestHackReplicas(t *testing.T) {
keda, _ := NewKedaTrait().(*kedaTrait)
keda.Enabled = &testingTrue
keda.Auto = &testingFalse
keda.Triggers = append(keda.Triggers, kedaTrigger{
Type: "custom",
Metadata: map[string]string{
"a": "b",
},
})
keda.HackControllerReplicas = &testingTrue
env := createBasicTestEnvironment(
&camelv1.Integration{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "my-it",
},
Status: camelv1.IntegrationStatus{
Phase: camelv1.IntegrationPhaseInitialization,
},
},
)

res, err := keda.Configure(env)
assert.NoError(t, err)
assert.True(t, res)
assert.NoError(t, keda.Apply(env))
it := camelv1.Integration{}
key := client.ObjectKey{
Namespace: "test",
Name: "my-it",
}
assert.NoError(t, env.Client.Get(env.Ctx, key, &it))
assert.NotNil(t, it.Spec.Replicas)
assert.Equal(t, int32(1), *it.Spec.Replicas)
}

func getScaledObject(e *trait.Environment) *v1alpha1.ScaledObject {
var res *v1alpha1.ScaledObject
for _, o := range e.Resources.Items() {
Expand Down Expand Up @@ -268,6 +421,25 @@ func createBasicTestEnvironment(resources ...runtime.Object) *trait.Environment
}
}

var pl *camelv1.IntegrationPlatform
for _, res := range resources {
if platform, ok := res.(*camelv1.IntegrationPlatform); ok {
pl = platform
}
}
if pl == nil {
pl = &camelv1.IntegrationPlatform{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "camel-k",
},
Spec: camelv1.IntegrationPlatformSpec{
Cluster: camelv1.IntegrationPlatformClusterKubernetes,
Profile: camelv1.TraitProfileKubernetes,
},
}
}

return &trait.Environment{
Catalog: trait.NewCatalog(nil),
Ctx: context.Background(),
Expand All @@ -281,15 +453,18 @@ func createBasicTestEnvironment(resources ...runtime.Object) *trait.Environment
},
},
},
Platform: &camelv1.IntegrationPlatform{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
},
Spec: camelv1.IntegrationPlatformSpec{
Cluster: camelv1.IntegrationPlatformClusterKubernetes,
},
},
Platform: pl,
Resources: kubernetes.NewCollection(),
ApplicationProperties: make(map[string]string),
}
}

func asEndpointProperties(props map[string]string) *camelv1alpha1.EndpointProperties {
serialized, err := json.Marshal(props)
if err != nil {
panic(err)
}
return &camelv1alpha1.EndpointProperties{
RawMessage: serialized,
}
}
8 changes: 5 additions & 3 deletions config/manifests/bases/camel-k.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ metadata:
categories: Integration & Delivery
certified: "false"
containerImage: docker.io/apache/camel-k:1.8.0-SNAPSHOT
createdAt: 2021-05-03T07:48:00Z
description: Apache Camel K is a lightweight integration platform, born on Kubernetes, with serverless superpowers.
createdAt: 2021-12-20T16:11:27Z
description: Apache Camel K is a lightweight integration platform, born on Kubernetes,
with serverless superpowers.
operators.operatorframework.io/builder: operator-sdk-v1.3.0
operators.operatorframework.io/internal-objects: '["builds.camel.apache.org","integrationkits.camel.apache.org","camelcatalogs.camel.apache.org"]'
operators.operatorframework.io/project_layout: go.kubebuilder.io/v2
Expand All @@ -51,7 +52,8 @@ spec:
kind: IntegrationKit
name: integrationkits.camel.apache.org
version: v1
- description: IntegrationPlatform is the Schema for the integrationplatforms API
- description: IntegrationPlatform is the Schema for the integrationplatforms
API
displayName: Integration Platform
kind: IntegrationPlatform
name: integrationplatforms.camel.apache.org
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/kameletbinding/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var (
endpointTypeSinkContext = bindings.EndpointContext{Type: v1alpha1.EndpointTypeSink}
)

func createIntegrationFor(ctx context.Context, c client.Client, kameletbinding *v1alpha1.KameletBinding) (*v1.Integration, error) {
func CreateIntegrationFor(ctx context.Context, c client.Client, kameletbinding *v1alpha1.KameletBinding) (*v1.Integration, error) {
controller := true
blockOwnerDeletion := true
annotations := util.CopyMap(kameletbinding.Annotations)
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/kameletbinding/initialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (action *initializeAction) CanHandle(kameletbinding *v1alpha1.KameletBindin
}

func (action *initializeAction) Handle(ctx context.Context, kameletbinding *v1alpha1.KameletBinding) (*v1alpha1.KameletBinding, error) {
it, err := createIntegrationFor(ctx, action.client, kameletbinding)
it, err := CreateIntegrationFor(ctx, action.client, kameletbinding)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/kameletbinding/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (action *monitorAction) Handle(ctx context.Context, kameletbinding *v1alpha
}

// Check if the integration needs to be changed
expected, err := createIntegrationFor(ctx, action.client, kameletbinding)
expected, err := CreateIntegrationFor(ctx, action.client, kameletbinding)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/resources/resources.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pkg/trait/dependencies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ func TestIntegrationAutoGeneratedDeps(t *testing.T) {
},
}

for _, trait := range []Trait{newInitTrait(), newDependenciesTrait()} {
for _, trait := range []Trait{NewInitTrait(), newDependenciesTrait()} {
enabled, err := trait.Configure(e)
assert.Nil(t, err)
assert.True(t, enabled)
Expand Down
2 changes: 1 addition & 1 deletion pkg/trait/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type initTrait struct {
BaseTrait `property:",squash"`
}

func newInitTrait() Trait {
func NewInitTrait() Trait {
return &initTrait{
BaseTrait: NewBaseTrait("init", 1),
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/trait/trait_register.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func init() {
AddToTraits(newErrorHandlerTrait)
AddToTraits(newGarbageCollectorTrait)
AddToTraits(newHealthTrait)
AddToTraits(newInitTrait)
AddToTraits(NewInitTrait)
AddToTraits(newIngressTrait)
AddToTraits(newIstioTrait)
AddToTraits(newJolokiaTrait)
Expand Down

0 comments on commit ff5031b

Please sign in to comment.