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


The following commit(s) were added to refs/heads/main by this push:
     new 43326394a fix(ctrl): report error on traits failure
43326394a is described below

commit 43326394a2453d0d0bc1f5a22137812bc0267dd9
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Tue Mar 26 15:59:57 2024 +0100

    fix(ctrl): report error on traits failure
    
    Closes #5084
---
 pkg/controller/integration/monitor.go      |   5 +-
 pkg/controller/integration/monitor_test.go | 153 +++++++++++++++++++++++++++++
 2 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/pkg/controller/integration/monitor.go 
b/pkg/controller/integration/monitor.go
index 2c526be94..063eedcb4 100644
--- a/pkg/controller/integration/monitor.go
+++ b/pkg/controller/integration/monitor.go
@@ -125,7 +125,10 @@ func (action *monitorAction) Handle(ctx context.Context, 
integration *v1.Integra
        // Run traits that are enabled for the phase
        environment, err := trait.Apply(ctx, action.client, integration, kit)
        if err != nil {
-               return nil, err
+               integration.Status.Phase = v1.IntegrationPhaseError
+               integration.SetReadyCondition(corev1.ConditionFalse,
+                       v1.IntegrationConditionInitializationFailedReason, 
err.Error())
+               return integration, err
        }
 
        return action.monitorPods(ctx, environment, integration)
diff --git a/pkg/controller/integration/monitor_test.go 
b/pkg/controller/integration/monitor_test.go
index fcd3423d8..5d444bf3d 100644
--- a/pkg/controller/integration/monitor_test.go
+++ b/pkg/controller/integration/monitor_test.go
@@ -21,17 +21,23 @@ import (
        "context"
        "testing"
 
+       appsv1 "k8s.io/api/apps/v1"
        corev1 "k8s.io/api/core/v1"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/utils/pointer"
 
        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/client"
 
+       "github.com/apache/camel-k/v2/pkg/util/defaults"
+       "github.com/apache/camel-k/v2/pkg/util/digest"
        "github.com/apache/camel-k/v2/pkg/util/kubernetes"
+       "github.com/apache/camel-k/v2/pkg/util/log"
        "github.com/apache/camel-k/v2/pkg/util/test"
 
        "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
 )
 
 func TestGetIntegrationSecretAndConfigmapResourceVersions(t *testing.T) {
@@ -83,3 +89,150 @@ func TestGetIntegrationSecretAndConfigmapResourceVersions(t 
*testing.T) {
        assert.NotEqual(t, "", configmaps[0])
        assert.NotEqual(t, "", secrets[0])
 }
+
+func TestMonitorIntegration(t *testing.T) {
+       c, it, err := nominalEnvironment()
+       require.NoError(t, err)
+
+       a := monitorAction{}
+       a.InjectLogger(log.Log)
+       a.InjectClient(c)
+       assert.Equal(t, "monitor", a.Name())
+       assert.True(t, a.CanHandle(it))
+       handledIt, err := a.Handle(context.TODO(), it)
+       require.NoError(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)
+}
+
+func TestMonitorFailureIntegration(t *testing.T) {
+       c, it, err := nominalEnvironment()
+       require.NoError(t, err)
+
+       // simulate a trait execution failure
+       it.Status.RuntimeVersion = "0.0.0"
+
+       a := monitorAction{}
+       a.InjectLogger(log.Log)
+       a.InjectClient(c)
+       assert.Equal(t, "monitor", a.Name())
+       assert.True(t, a.CanHandle(it))
+       handledIt, err := a.Handle(context.TODO(), it)
+       require.Error(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.IntegrationConditionInitializationFailedReason, 
handledIt.Status.GetCondition(v1.IntegrationConditionReady).Reason)
+}
+
+func nominalEnvironment() (client.Client, *v1.Integration, error) {
+       catalog := &v1.CamelCatalog{
+               TypeMeta: metav1.TypeMeta{
+                       APIVersion: v1.SchemeGroupVersion.String(),
+                       Kind:       v1.CamelCatalogKind,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "ns",
+                       Name:      "camel-k-catalog",
+               },
+               Spec: v1.CamelCatalogSpec{
+                       Runtime: v1.RuntimeSpec{
+                               Provider: v1.RuntimeProviderQuarkus,
+                               Version:  defaults.DefaultRuntimeVersion,
+                       },
+               },
+       }
+       platform := &v1.IntegrationPlatform{
+               TypeMeta: metav1.TypeMeta{
+                       APIVersion: v1.SchemeGroupVersion.String(),
+                       Kind:       v1.IntegrationPlatformKind,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "ns",
+                       Name:      "camel-k",
+               },
+               Status: v1.IntegrationPlatformStatus{
+                       Phase: v1.IntegrationPlatformPhaseReady,
+               },
+       }
+       kit := &v1.IntegrationKit{
+               TypeMeta: metav1.TypeMeta{
+                       APIVersion: v1.SchemeGroupVersion.String(),
+                       Kind:       v1.IntegrationKitKind,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "ns",
+                       Name:      "my-kit",
+               },
+               Status: v1.IntegrationKitStatus{
+                       Phase: v1.IntegrationKitPhaseReady,
+               },
+       }
+       it := &v1.Integration{
+               TypeMeta: metav1.TypeMeta{
+                       APIVersion: v1.SchemeGroupVersion.String(),
+                       Kind:       v1.IntegrationKind,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Namespace: "ns",
+                       Name:      "my-it",
+               },
+               Status: v1.IntegrationStatus{
+                       RuntimeVersion: defaults.DefaultRuntimeVersion,
+                       Phase:          v1.IntegrationPhaseRunning,
+                       IntegrationKit: &corev1.ObjectReference{
+                               Name:       kit.Name,
+                               Namespace:  kit.Namespace,
+                               Kind:       kit.Kind,
+                               APIVersion: kit.APIVersion,
+                       },
+                       Conditions: []v1.IntegrationCondition{
+                               {
+                                       Type:   
v1.IntegrationConditionDeploymentAvailable,
+                                       Status: corev1.ConditionTrue,
+                               },
+                               {
+                                       Type:   v1.IntegrationConditionReady,
+                                       Status: corev1.ConditionTrue,
+                               },
+                       },
+               },
+       }
+       hash, _ := digest.ComputeForIntegration(it, nil, nil)
+       it.Status.Digest = hash
+       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-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(catalog, platform, it, kit, pod)
+       return c, it, err
+}

Reply via email to