You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2024/01/09 14:21:52 UTC
(camel-k) 04/08: chore: syntethic Integration unit testing
This is an automated email from the ASF dual-hosted git repository.
pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit ece9fb46b2d27f3f0f5273b5bdadfff09cc6a512
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Mon Dec 4 15:30:55 2023 +0100
chore: syntethic Integration unit testing
---
pkg/controller/integration/initialize_test.go | 189 ++++++++
.../integration/monitor_synthetic_test.go | 489 +++++++++++++++++++++
pkg/controller/synthetic/synthetic.go | 4 +-
pkg/controller/synthetic/synthetic_test.go | 221 ++++++++++
pkg/util/test/client.go | 15 +-
5 files changed, 915 insertions(+), 3 deletions(-)
diff --git a/pkg/controller/integration/initialize_test.go b/pkg/controller/integration/initialize_test.go
new file mode 100644
index 000000000..2beaaa798
--- /dev/null
+++ b/pkg/controller/integration/initialize_test.go
@@ -0,0 +1,189 @@
+/*
+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 integration
+
+import (
+ "context"
+ "testing"
+
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+ v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
+
+ "github.com/apache/camel-k/v2/pkg/util/log"
+ "github.com/apache/camel-k/v2/pkg/util/test"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestCamelImportDeployment(t *testing.T) {
+ importedIt := &v1.Integration{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: v1.SchemeGroupVersion.String(),
+ Kind: v1.IntegrationKind,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-imported-it",
+ Annotations: map[string]string{
+ v1.IntegrationImportedNameLabel: "my-deploy",
+ v1.IntegrationSyntheticLabel: "true",
+ v1.IntegrationImportedKindLabel: "Deployment",
+ },
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseInitialization,
+ },
+ }
+ c, err := test.NewFakeClient(importedIt)
+ assert.Nil(t, err)
+
+ a := initializeAction{}
+ a.InjectLogger(log.Log)
+ a.InjectClient(c)
+ assert.Equal(t, "initialize", a.Name())
+ assert.True(t, a.CanHandle(importedIt))
+ handledIt, err := a.Handle(context.TODO(), importedIt)
+ assert.Nil(t, err)
+ assert.Equal(t, v1.IntegrationPhaseRunning, handledIt.Status.Phase)
+ // Ready condition
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status)
+ assert.Equal(t, v1.IntegrationConditionDeploymentReadyReason, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Reason)
+ assert.Equal(t, "imported from my-deploy Deployment", handledIt.Status.GetCondition(v1.IntegrationConditionReady).Message)
+ // Deployment condition
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionDeploymentAvailable).Status)
+ assert.Equal(t, v1.IntegrationConditionDeploymentAvailableReason, handledIt.Status.GetCondition(v1.IntegrationConditionDeploymentAvailable).Reason)
+ assert.Equal(t, "imported from my-deploy Deployment", handledIt.Status.GetCondition(v1.IntegrationConditionDeploymentAvailable).Message)
+}
+
+func TestCamelImportCronJob(t *testing.T) {
+ importedIt := &v1.Integration{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: v1.SchemeGroupVersion.String(),
+ Kind: v1.IntegrationKind,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-imported-it",
+ Annotations: map[string]string{
+ v1.IntegrationImportedNameLabel: "my-cron",
+ v1.IntegrationSyntheticLabel: "true",
+ v1.IntegrationImportedKindLabel: "CronJob",
+ },
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseInitialization,
+ },
+ }
+ c, err := test.NewFakeClient(importedIt)
+ assert.Nil(t, err)
+
+ a := initializeAction{}
+ a.InjectLogger(log.Log)
+ a.InjectClient(c)
+ assert.Equal(t, "initialize", a.Name())
+ assert.True(t, a.CanHandle(importedIt))
+ handledIt, err := a.Handle(context.TODO(), importedIt)
+ assert.Nil(t, err)
+ assert.Equal(t, v1.IntegrationPhaseRunning, handledIt.Status.Phase)
+ // Ready condition
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status)
+ assert.Equal(t, v1.IntegrationConditionDeploymentReadyReason, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Reason)
+ assert.Equal(t, "imported from my-cron CronJob", handledIt.Status.GetCondition(v1.IntegrationConditionReady).Message)
+ // CronJob condition
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionCronJobAvailable).Status)
+ assert.Equal(t, v1.IntegrationConditionCronJobCreatedReason, handledIt.Status.GetCondition(v1.IntegrationConditionCronJobAvailable).Reason)
+ assert.Equal(t, "imported from my-cron CronJob", handledIt.Status.GetCondition(v1.IntegrationConditionCronJobAvailable).Message)
+}
+
+func TestCamelImportKnativeService(t *testing.T) {
+ importedIt := &v1.Integration{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: v1.SchemeGroupVersion.String(),
+ Kind: v1.IntegrationKind,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-imported-it",
+ Annotations: map[string]string{
+ v1.IntegrationImportedNameLabel: "my-ksvc",
+ v1.IntegrationSyntheticLabel: "true",
+ v1.IntegrationImportedKindLabel: "KnativeService",
+ },
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseInitialization,
+ },
+ }
+ c, err := test.NewFakeClient(importedIt)
+ assert.Nil(t, err)
+
+ a := initializeAction{}
+ a.InjectLogger(log.Log)
+ a.InjectClient(c)
+ assert.Equal(t, "initialize", a.Name())
+ assert.True(t, a.CanHandle(importedIt))
+ handledIt, err := a.Handle(context.TODO(), importedIt)
+ assert.Nil(t, err)
+ assert.Equal(t, v1.IntegrationPhaseRunning, handledIt.Status.Phase)
+ // Ready condition
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status)
+ assert.Equal(t, v1.IntegrationConditionKnativeServiceReadyReason, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Reason)
+ assert.Equal(t, "imported from my-ksvc KnativeService", handledIt.Status.GetCondition(v1.IntegrationConditionReady).Message)
+ // Knative Service condition
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionKnativeServiceAvailable).Status)
+ assert.Equal(t, v1.IntegrationConditionKnativeServiceAvailableReason, handledIt.Status.GetCondition(v1.IntegrationConditionKnativeServiceAvailable).Reason)
+ assert.Equal(t, "imported from my-ksvc KnativeService", handledIt.Status.GetCondition(v1.IntegrationConditionKnativeServiceAvailable).Message)
+}
+
+func TestCamelImportUnsupportedKind(t *testing.T) {
+ importedIt := &v1.Integration{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: v1.SchemeGroupVersion.String(),
+ Kind: v1.IntegrationKind,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-imported-it",
+ Annotations: map[string]string{
+ v1.IntegrationImportedNameLabel: "my-kind",
+ v1.IntegrationSyntheticLabel: "true",
+ v1.IntegrationImportedKindLabel: "SomeKind",
+ },
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseInitialization,
+ },
+ }
+ c, err := test.NewFakeClient(importedIt)
+ assert.Nil(t, err)
+
+ a := initializeAction{}
+ a.InjectLogger(log.Log)
+ a.InjectClient(c)
+ assert.Equal(t, "initialize", a.Name())
+ assert.True(t, a.CanHandle(importedIt))
+ handledIt, err := a.Handle(context.TODO(), importedIt)
+ assert.Nil(t, err)
+ assert.Equal(t, v1.IntegrationPhaseError, handledIt.Status.Phase)
+ // Ready condition
+ assert.Equal(t, corev1.ConditionFalse, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status)
+ assert.Equal(t, v1.IntegrationConditionImportingKindAvailableReason, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Reason)
+ assert.Equal(t, "Unsupported SomeKind import kind", handledIt.Status.GetCondition(v1.IntegrationConditionReady).Message)
+}
diff --git a/pkg/controller/integration/monitor_synthetic_test.go b/pkg/controller/integration/monitor_synthetic_test.go
new file mode 100644
index 000000000..c2217218a
--- /dev/null
+++ b/pkg/controller/integration/monitor_synthetic_test.go
@@ -0,0 +1,489 @@
+/*
+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 integration
+
+import (
+ "context"
+ "testing"
+
+ appsv1 "k8s.io/api/apps/v1"
+ batchv1 "k8s.io/api/batch/v1"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ servingv1 "knative.dev/serving/pkg/apis/serving/v1"
+
+ v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
+ "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
+
+ "github.com/apache/camel-k/v2/pkg/util/log"
+ "github.com/apache/camel-k/v2/pkg/util/test"
+
+ "github.com/stretchr/testify/assert"
+ "knative.dev/pkg/apis"
+ duckv1 "knative.dev/pkg/apis/duck/v1"
+)
+
+func TestMonitorSyntheticIntegrationImportingKindUnavailable(t *testing.T) {
+ importedIt := &v1.Integration{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: v1.SchemeGroupVersion.String(),
+ Kind: v1.IntegrationKind,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-imported-it",
+ Annotations: map[string]string{
+ v1.IntegrationImportedNameLabel: "my-deploy",
+ v1.IntegrationSyntheticLabel: "true",
+ v1.IntegrationImportedKindLabel: "SomeKind",
+ },
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseRunning,
+ },
+ }
+ c, err := test.NewFakeClient(importedIt)
+ assert.Nil(t, err)
+
+ a := monitorSyntheticAction{}
+ a.InjectLogger(log.Log)
+ a.InjectClient(c)
+ assert.Equal(t, "monitor-synthetic", a.Name())
+ assert.True(t, a.CanHandle(importedIt))
+ handledIt, err := a.Handle(context.TODO(), importedIt)
+ assert.NotNil(t, err)
+ assert.Equal(t, v1.IntegrationPhaseError, handledIt.Status.Phase)
+ assert.Equal(t, corev1.ConditionFalse, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status)
+ assert.Equal(t, v1.IntegrationConditionImportingKindAvailableReason, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Reason)
+ assert.Equal(t, "cannot create a synthetic environment for SomeKind kind", handledIt.Status.GetCondition(v1.IntegrationConditionReady).Message)
+}
+
+func TestMonitorSyntheticIntegrationCannotMonitorPods(t *testing.T) {
+ importedIt := &v1.Integration{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: v1.SchemeGroupVersion.String(),
+ Kind: v1.IntegrationKind,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-imported-it",
+ Annotations: map[string]string{
+ v1.IntegrationImportedNameLabel: "my-deploy",
+ v1.IntegrationSyntheticLabel: "true",
+ v1.IntegrationImportedKindLabel: "Deployment",
+ },
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseRunning,
+ Conditions: []v1.IntegrationCondition{
+ {
+ Type: v1.IntegrationConditionDeploymentAvailable,
+ Status: corev1.ConditionTrue,
+ },
+ {
+ Type: v1.IntegrationConditionReady,
+ Status: corev1.ConditionTrue,
+ },
+ },
+ },
+ }
+ deploy := &appsv1.Deployment{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: appsv1.SchemeGroupVersion.String(),
+ Kind: "Deployment",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-deploy",
+ Annotations: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ }
+ c, err := test.NewFakeClient(importedIt, deploy)
+ assert.Nil(t, err)
+
+ a := monitorSyntheticAction{}
+ a.InjectLogger(log.Log)
+ a.InjectClient(c)
+ assert.Equal(t, "monitor-synthetic", a.Name())
+ assert.True(t, a.CanHandle(importedIt))
+ handledIt, err := a.Handle(context.TODO(), importedIt)
+ assert.Nil(t, err)
+ assert.Equal(t, v1.IntegrationPhaseCannotMonitor, handledIt.Status.Phase)
+ // Ready condition should be still true
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status)
+ // Check monitoring pods condition
+ assert.Equal(t, corev1.ConditionFalse, handledIt.Status.GetCondition(v1.IntegrationConditionMonitoringPodsAvailable).Status)
+ assert.Equal(t, v1.IntegrationConditionMonitoringPodsAvailableReason, handledIt.Status.GetCondition(v1.IntegrationConditionMonitoringPodsAvailable).Reason)
+ assert.Equal(t, "Could not find `camel.apache.org/integration: my-imported-it` label in the Deployment/my-deploy template. Make sure to include this label in the template for Pod monitoring purposes.", handledIt.Status.GetCondition(v1.IntegrationConditionMonitoringPodsAvailable).Message)
+}
+
+func TestMonitorSyntheticIntegrationDeployment(t *testing.T) {
+ importedIt := &v1.Integration{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: v1.SchemeGroupVersion.String(),
+ Kind: v1.IntegrationKind,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-imported-it",
+ Annotations: map[string]string{
+ v1.IntegrationImportedNameLabel: "my-deploy",
+ v1.IntegrationSyntheticLabel: "true",
+ v1.IntegrationImportedKindLabel: "Deployment",
+ },
+ },
+ Spec: v1.IntegrationSpec{
+ Traits: v1.Traits{
+ Container: &trait.ContainerTrait{
+ Name: "my-cnt",
+ },
+ },
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseRunning,
+ Conditions: []v1.IntegrationCondition{
+ {
+ Type: v1.IntegrationConditionDeploymentAvailable,
+ Status: corev1.ConditionTrue,
+ },
+ {
+ Type: v1.IntegrationConditionReady,
+ Status: corev1.ConditionTrue,
+ },
+ },
+ },
+ }
+ deploy := &appsv1.Deployment{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: appsv1.SchemeGroupVersion.String(),
+ Kind: "Deployment",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-deploy",
+ Annotations: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: appsv1.DeploymentSpec{
+ Template: corev1.PodTemplateSpec{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "my-cnt",
+ Image: "my-img",
+ },
+ },
+ },
+ },
+ },
+ }
+ pod := &corev1.Pod{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: appsv1.SchemeGroupVersion.String(),
+ Kind: "Pod",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-pod",
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "my-cnt",
+ Image: "my-img",
+ },
+ },
+ },
+ Status: corev1.PodStatus{
+ Phase: corev1.PodRunning,
+ Conditions: []corev1.PodCondition{
+ {
+ Type: corev1.PodReady,
+ Status: corev1.ConditionTrue,
+ },
+ },
+ },
+ }
+ c, err := test.NewFakeClient(importedIt, deploy, pod)
+ assert.Nil(t, err)
+
+ a := monitorSyntheticAction{}
+ a.InjectLogger(log.Log)
+ a.InjectClient(c)
+ assert.Equal(t, "monitor-synthetic", a.Name())
+ assert.True(t, a.CanHandle(importedIt))
+ handledIt, err := a.Handle(context.TODO(), importedIt)
+ assert.Nil(t, err)
+ assert.Equal(t, v1.IntegrationPhaseRunning, handledIt.Status.Phase)
+ assert.Equal(t, int32(1), *handledIt.Status.Replicas)
+ // Ready condition
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status)
+ assert.Equal(t, v1.IntegrationConditionDeploymentReadyReason, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Reason)
+ assert.Equal(t, "1/1 ready replicas", handledIt.Status.GetCondition(v1.IntegrationConditionReady).Message)
+ // Check monitoring pods condition
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionMonitoringPodsAvailable).Status)
+ assert.Equal(t, v1.IntegrationConditionMonitoringPodsAvailableReason, handledIt.Status.GetCondition(v1.IntegrationConditionMonitoringPodsAvailable).Reason)
+}
+
+func TestMonitorSyntheticIntegrationCronJob(t *testing.T) {
+ importedIt := &v1.Integration{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: v1.SchemeGroupVersion.String(),
+ Kind: v1.IntegrationKind,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-imported-it",
+ Annotations: map[string]string{
+ v1.IntegrationImportedNameLabel: "my-cron",
+ v1.IntegrationSyntheticLabel: "true",
+ v1.IntegrationImportedKindLabel: "CronJob",
+ },
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseRunning,
+ Conditions: []v1.IntegrationCondition{
+ {
+ Type: v1.IntegrationConditionCronJobAvailable,
+ Status: corev1.ConditionTrue,
+ },
+ {
+ Type: v1.IntegrationConditionReady,
+ Status: corev1.ConditionTrue,
+ },
+ },
+ },
+ }
+ cron := &batchv1.CronJob{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: appsv1.SchemeGroupVersion.String(),
+ Kind: "CronJob",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-cron",
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: batchv1.CronJobSpec{
+ JobTemplate: batchv1.JobTemplateSpec{
+ Spec: batchv1.JobSpec{
+ Template: corev1.PodTemplateSpec{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "my-cnt",
+ Image: "my-img",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+ pod := &corev1.Pod{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: appsv1.SchemeGroupVersion.String(),
+ Kind: "Pod",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-pod",
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "my-cnt",
+ Image: "my-img",
+ },
+ },
+ },
+ Status: corev1.PodStatus{
+ Phase: corev1.PodRunning,
+ Conditions: []corev1.PodCondition{
+ {
+ Type: corev1.PodReady,
+ Status: corev1.ConditionTrue,
+ },
+ },
+ },
+ }
+ c, err := test.NewFakeClient(importedIt, cron, pod)
+ assert.Nil(t, err)
+
+ a := monitorSyntheticAction{}
+ a.InjectLogger(log.Log)
+ a.InjectClient(c)
+ assert.Equal(t, "monitor-synthetic", a.Name())
+ assert.True(t, a.CanHandle(importedIt))
+ handledIt, err := a.Handle(context.TODO(), importedIt)
+ assert.Nil(t, err)
+ assert.Equal(t, v1.IntegrationPhaseRunning, handledIt.Status.Phase)
+ assert.Equal(t, int32(1), *handledIt.Status.Replicas)
+ // Ready condition
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status)
+ assert.Equal(t, v1.IntegrationConditionCronJobCreatedReason, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Reason)
+ assert.Equal(t, "cronjob created", handledIt.Status.GetCondition(v1.IntegrationConditionReady).Message)
+ // Check monitoring pods condition
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionMonitoringPodsAvailable).Status)
+ assert.Equal(t, v1.IntegrationConditionMonitoringPodsAvailableReason, handledIt.Status.GetCondition(v1.IntegrationConditionMonitoringPodsAvailable).Reason)
+}
+
+func TestMonitorSyntheticIntegrationKnativeService(t *testing.T) {
+ importedIt := &v1.Integration{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: v1.SchemeGroupVersion.String(),
+ Kind: v1.IntegrationKind,
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-imported-it",
+ Annotations: map[string]string{
+ v1.IntegrationImportedNameLabel: "my-ksvc",
+ v1.IntegrationSyntheticLabel: "true",
+ v1.IntegrationImportedKindLabel: "KnativeService",
+ },
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseRunning,
+ Conditions: []v1.IntegrationCondition{
+ {
+ Type: v1.IntegrationConditionKnativeServiceAvailable,
+ Status: corev1.ConditionTrue,
+ },
+ {
+ Type: v1.IntegrationConditionReady,
+ Status: corev1.ConditionTrue,
+ },
+ },
+ },
+ }
+ ksvc := &servingv1.Service{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: appsv1.SchemeGroupVersion.String(),
+ Kind: "Service",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-ksvc",
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: servingv1.ServiceSpec{
+ ConfigurationSpec: servingv1.ConfigurationSpec{
+ Template: servingv1.RevisionTemplateSpec{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: servingv1.RevisionSpec{
+ PodSpec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "my-cnt",
+ Image: "my-img",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Status: servingv1.ServiceStatus{
+ Status: duckv1.Status{
+ Conditions: duckv1.Conditions{
+ apis.Condition{
+ Type: servingv1.ServiceConditionReady,
+ Status: corev1.ConditionTrue,
+ },
+ },
+ },
+ },
+ }
+ pod := &corev1.Pod{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: appsv1.SchemeGroupVersion.String(),
+ Kind: "Pod",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-pod",
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "my-cnt",
+ Image: "my-img",
+ },
+ },
+ },
+ Status: corev1.PodStatus{
+ Phase: corev1.PodRunning,
+ Conditions: []corev1.PodCondition{
+ {
+ Type: corev1.PodReady,
+ Status: corev1.ConditionTrue,
+ },
+ },
+ },
+ }
+ c, err := test.NewFakeClient(importedIt, ksvc, pod)
+ assert.Nil(t, err)
+
+ a := monitorSyntheticAction{}
+ a.InjectLogger(log.Log)
+ a.InjectClient(c)
+ assert.Equal(t, "monitor-synthetic", a.Name())
+ assert.True(t, a.CanHandle(importedIt))
+ handledIt, err := a.Handle(context.TODO(), importedIt)
+ assert.Nil(t, err)
+ assert.Equal(t, v1.IntegrationPhaseRunning, handledIt.Status.Phase)
+ assert.Equal(t, int32(1), *handledIt.Status.Replicas)
+ // Ready condition
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Status)
+ assert.Equal(t, v1.IntegrationConditionKnativeServiceReadyReason, handledIt.Status.GetCondition(v1.IntegrationConditionReady).Reason)
+ // Check monitoring pods condition
+ assert.Equal(t, corev1.ConditionTrue, handledIt.Status.GetCondition(v1.IntegrationConditionMonitoringPodsAvailable).Status)
+ assert.Equal(t, v1.IntegrationConditionMonitoringPodsAvailableReason, handledIt.Status.GetCondition(v1.IntegrationConditionMonitoringPodsAvailable).Reason)
+}
diff --git a/pkg/controller/synthetic/synthetic.go b/pkg/controller/synthetic/synthetic.go
index bd785d318..c5f7bbb34 100644
--- a/pkg/controller/synthetic/synthetic.go
+++ b/pkg/controller/synthetic/synthetic.go
@@ -220,7 +220,7 @@ func nonManagedCamelApplicationFactory(obj ctrl.Object) (nonManagedCamelApplicat
if ok {
return &NonManagedCamelKnativeService{ksvc: ksvc}, nil
}
- return nil, fmt.Errorf("unsupported %s object kind", obj)
+ return nil, fmt.Errorf("unsupported %s object kind", obj.GetName())
}
// NonManagedCamelDeployment represents a regular Camel application built and deployed outside the operator lifecycle.
@@ -252,7 +252,7 @@ func (app *nonManagedCamelDeployment) getContainerNameFromDeployment() string {
for _, ct := range app.deploy.Spec.Template.Spec.Containers {
// set as fallback if no container is named as the deployment
if firstContainerName == "" {
- firstContainerName = app.deploy.Name
+ firstContainerName = ct.Name
}
if ct.Name == app.deploy.Name {
return app.deploy.Name
diff --git a/pkg/controller/synthetic/synthetic_test.go b/pkg/controller/synthetic/synthetic_test.go
new file mode 100644
index 000000000..c600f6d3e
--- /dev/null
+++ b/pkg/controller/synthetic/synthetic_test.go
@@ -0,0 +1,221 @@
+/*
+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 synthetic
+
+import (
+ "testing"
+
+ appsv1 "k8s.io/api/apps/v1"
+ batchv1 "k8s.io/api/batch/v1"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ servingv1 "knative.dev/serving/pkg/apis/serving/v1"
+
+ v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
+ "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestNonManagedUnsupported(t *testing.T) {
+ pod := &corev1.Pod{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: corev1.SchemeGroupVersion.String(),
+ Kind: "Pod",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-pod",
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "my-cnt",
+ Image: "my-img",
+ },
+ },
+ },
+ Status: corev1.PodStatus{
+ Phase: corev1.PodRunning,
+ Conditions: []corev1.PodCondition{
+ {
+ Type: corev1.PodReady,
+ Status: corev1.ConditionTrue,
+ },
+ },
+ },
+ }
+
+ nilAdapter, err := nonManagedCamelApplicationFactory(pod)
+ assert.NotNil(t, err)
+ assert.Equal(t, "unsupported my-pod object kind", err.Error())
+ assert.Nil(t, nilAdapter)
+}
+
+func TestNonManagedDeployment(t *testing.T) {
+ deploy := &appsv1.Deployment{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: appsv1.SchemeGroupVersion.String(),
+ Kind: "Deployment",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-deploy",
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: appsv1.DeploymentSpec{
+ Template: corev1.PodTemplateSpec{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "my-cnt",
+ Image: "my-img",
+ },
+ },
+ },
+ },
+ },
+ }
+
+ expectedIt := v1.NewIntegration("ns", "my-imported-it")
+ expectedIt.SetAnnotations(map[string]string{
+ v1.IntegrationImportedNameLabel: "my-deploy",
+ v1.IntegrationImportedKindLabel: "Deployment",
+ v1.IntegrationSyntheticLabel: "true",
+ })
+ expectedIt.Spec = v1.IntegrationSpec{
+ Traits: v1.Traits{
+ Container: &trait.ContainerTrait{
+ Name: "my-cnt",
+ },
+ },
+ }
+
+ deploymentAdapter, err := nonManagedCamelApplicationFactory(deploy)
+ assert.Nil(t, err)
+ assert.NotNil(t, deploymentAdapter)
+ assert.Equal(t, expectedIt, *deploymentAdapter.Integration())
+}
+
+func TestNonManagedCronJob(t *testing.T) {
+ cron := &batchv1.CronJob{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: batchv1.SchemeGroupVersion.String(),
+ Kind: "CronJob",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-cron",
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: batchv1.CronJobSpec{
+ JobTemplate: batchv1.JobTemplateSpec{
+ Spec: batchv1.JobSpec{
+ Template: corev1.PodTemplateSpec{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "my-cnt",
+ Image: "my-img",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+
+ expectedIt := v1.NewIntegration("ns", "my-imported-it")
+ expectedIt.SetAnnotations(map[string]string{
+ v1.IntegrationImportedNameLabel: "my-cron",
+ v1.IntegrationImportedKindLabel: "CronJob",
+ v1.IntegrationSyntheticLabel: "true",
+ })
+
+ cronJobAdapter, err := nonManagedCamelApplicationFactory(cron)
+ assert.Nil(t, err)
+ assert.NotNil(t, cronJobAdapter)
+ assert.Equal(t, expectedIt, *cronJobAdapter.Integration())
+}
+
+func TestNonManagedKnativeService(t *testing.T) {
+ ksvc := &servingv1.Service{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: appsv1.SchemeGroupVersion.String(),
+ Kind: "Service",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: "ns",
+ Name: "my-ksvc",
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: servingv1.ServiceSpec{
+ ConfigurationSpec: servingv1.ConfigurationSpec{
+ Template: servingv1.RevisionTemplateSpec{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: map[string]string{
+ v1.IntegrationLabel: "my-imported-it",
+ },
+ },
+ Spec: servingv1.RevisionSpec{
+ PodSpec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "my-cnt",
+ Image: "my-img",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+
+ expectedIt := v1.NewIntegration("ns", "my-imported-it")
+ expectedIt.SetAnnotations(map[string]string{
+ v1.IntegrationImportedNameLabel: "my-ksvc",
+ v1.IntegrationImportedKindLabel: "KnativeService",
+ v1.IntegrationSyntheticLabel: "true",
+ })
+
+ knativeServiceAdapter, err := nonManagedCamelApplicationFactory(ksvc)
+ assert.Nil(t, err)
+ assert.NotNil(t, knativeServiceAdapter)
+ assert.Equal(t, expectedIt, *knativeServiceAdapter.Integration())
+}
diff --git a/pkg/util/test/client.go b/pkg/util/test/client.go
index fef78d2b6..9105719eb 100644
--- a/pkg/util/test/client.go
+++ b/pkg/util/test/client.go
@@ -30,6 +30,7 @@ import (
camelv1alpha1 "github.com/apache/camel-k/v2/pkg/client/camel/clientset/versioned/typed/camel/v1alpha1"
"github.com/apache/camel-k/v2/pkg/util"
autoscalingv1 "k8s.io/api/autoscaling/v1"
+ corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@@ -55,7 +56,19 @@ func NewFakeClient(initObjs ...runtime.Object) (client.Client, error) {
return nil, err
}
- c := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(initObjs...).Build()
+ c := fake.
+ NewClientBuilder().
+ WithScheme(scheme).
+ WithIndex(
+ &corev1.Pod{},
+ "status.phase",
+ func(obj controller.Object) []string {
+ pod, _ := obj.(*corev1.Pod)
+ return []string{string(pod.Status.Phase)}
+ },
+ ).
+ WithRuntimeObjects(initObjs...).
+ Build()
camelClientset := fakecamelclientset.NewSimpleClientset(filterObjects(scheme, initObjs, func(gvk schema.GroupVersionKind) bool {
return strings.Contains(gvk.Group, "camel")