blob: bbe00a2f81864f6ffbe97ec0ddd4731e61fc51fb [file] [log] [blame]
// Copyright 2023 Red Hat, Inc. and/or its affiliates
//
// Licensed 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 profiles
import (
"context"
"testing"
"time"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/rest"
"github.com/stretchr/testify/assert"
appsv1 "k8s.io/api/apps/v1"
clientruntime "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/kiegroup/kogito-serverless-operator/api"
operatorapi "github.com/kiegroup/kogito-serverless-operator/api/v1alpha08"
"github.com/kiegroup/kogito-serverless-operator/test"
)
func Test_reconcilerProdBuildConditions(t *testing.T) {
workflow := test.GetBaseSonataFlow(t.Name())
platform := test.GetBasePlatformInReadyPhase(t.Name())
client := test.NewKogitoClientBuilder().
WithRuntimeObjects(workflow, platform).
WithStatusSubresource(workflow, platform, &operatorapi.SonataFlowBuild{}).Build()
config := &rest.Config{}
result, err := NewReconciler(client, config, workflow).Reconcile(context.TODO(), workflow)
assert.NoError(t, err)
assert.NotNil(t, result.RequeueAfter)
assert.True(t, workflow.Status.IsBuildRunningOrUnknown())
assert.False(t, workflow.Status.IsReady())
// still building
result, err = NewReconciler(client, config, workflow).Reconcile(context.TODO(), workflow)
assert.NoError(t, err)
assert.Equal(t, requeueWhileWaitForBuild, result.RequeueAfter)
assert.True(t, workflow.Status.IsBuildRunningOrUnknown())
assert.False(t, workflow.Status.IsReady())
// let's finish this build
build := &operatorapi.SonataFlowBuild{}
assert.NoError(t, client.Get(context.TODO(), clientruntime.ObjectKeyFromObject(workflow), build))
build.Status.BuildPhase = operatorapi.BuildPhaseSucceeded
assert.NoError(t, client.Status().Update(context.TODO(), build))
// last reconciliation cycle waiting for build
result, err = NewReconciler(client, config, workflow).Reconcile(context.TODO(), workflow)
assert.NoError(t, err)
assert.Equal(t, requeueWhileWaitForBuild, result.RequeueAfter)
assert.False(t, workflow.Status.IsBuildRunningOrUnknown())
assert.False(t, workflow.Status.IsReady())
assert.Equal(t, api.WaitingForBuildReason, workflow.Status.GetTopLevelCondition().Reason)
// now we create the objects
result, err = NewReconciler(client, config, workflow).Reconcile(context.TODO(), workflow)
assert.NoError(t, err)
assert.False(t, workflow.Status.IsBuildRunningOrUnknown())
assert.False(t, workflow.Status.IsReady())
assert.Equal(t, api.WaitingForDeploymentReason, workflow.Status.GetTopLevelCondition().Reason)
// now with the objects created, it should be running
// let's update the deployment status to available == true
deployment := &appsv1.Deployment{}
err = client.Get(context.TODO(), clientruntime.ObjectKeyFromObject(workflow), deployment)
assert.NoError(t, err)
deployment.Status.Conditions = append(deployment.Status.Conditions, appsv1.DeploymentCondition{
Type: appsv1.DeploymentAvailable,
Status: corev1.ConditionTrue,
})
err = client.Status().Update(context.TODO(), deployment)
assert.NoError(t, err)
result, err = NewReconciler(client, config, workflow).Reconcile(context.TODO(), workflow)
assert.NoError(t, err)
assert.False(t, workflow.Status.IsBuildRunningOrUnknown())
assert.True(t, workflow.Status.IsReady())
}
func Test_deployWorkflowReconciliationHandler_handleObjects(t *testing.T) {
workflow := test.GetBaseSonataFlow(t.Name())
platform := test.GetBasePlatformInReadyPhase(t.Name())
build := test.GetLocalSucceedSonataFlowBuild(workflow.Name, workflow.Namespace)
client := test.NewKogitoClientBuilder().
WithRuntimeObjects(workflow, platform, build).
WithStatusSubresource(workflow, platform, build).
Build()
handler := &deployWorkflowReconciliationState{
stateSupport: fakeReconcilerSupport(client),
ensurers: newProdObjectEnsurers(&stateSupport{client: client}),
}
result, objects, err := handler.Do(context.TODO(), workflow)
assert.Greater(t, result.RequeueAfter, int64(0))
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Len(t, objects, 3)
deployment := &appsv1.Deployment{}
err = client.Get(context.TODO(), clientruntime.ObjectKeyFromObject(workflow), deployment)
assert.NoError(t, err)
assert.NotEmpty(t, deployment.Spec.Template.Spec.Containers[0].Image)
err = client.Get(context.TODO(), clientruntime.ObjectKeyFromObject(workflow), workflow)
assert.NoError(t, err)
assert.False(t, workflow.Status.IsReady())
assert.Equal(t, api.WaitingForDeploymentReason, workflow.Status.GetTopLevelCondition().Reason)
// let's mess with the deployment
/* TODO the state should be able to enforce: https://issues.redhat.com/browse/KOGITO-8524
deployment.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort = 9090
err = client.Update(context.TODO(), deployment)
assert.NoError(t, err)
result, objects, err = handler.Do(context.TODO(), workflow)
assert.True(t, result.Requeue)
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Len(t, objects, 2)
// the reconciliation state should guarantee our port
deployment = &appsv1.Deployment{}
err = client.Get(context.TODO(), clientruntime.ObjectKeyFromObject(workflow), deployment)
assert.NoError(t, err)
assert.Equal(t, int32(8080), deployment.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort)
*/
}
func Test_GenerationAnnotationCheck(t *testing.T) {
// we load a workflow with metadata.generation to 0
workflow := test.GetBaseSonataFlow(t.Name())
platform := test.GetBasePlatformInReadyPhase(t.Name())
client := test.NewKogitoClientBuilder().
WithRuntimeObjects(workflow, platform).
WithStatusSubresource(workflow, platform, &operatorapi.SonataFlowBuild{}).Build()
handler := &deployWorkflowReconciliationState{
stateSupport: fakeReconcilerSupport(client),
ensurers: newProdObjectEnsurers(&stateSupport{client: client}),
}
result, objects, err := handler.Do(context.TODO(), workflow)
assert.Greater(t, result.RequeueAfter, int64(time.Second))
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Len(t, objects, 3)
// then we load a workflow with metadata.generation set to 1
workflowChanged := &operatorapi.SonataFlow{}
err = client.Get(context.TODO(), clientruntime.ObjectKeyFromObject(workflow), workflowChanged)
assert.NoError(t, err)
//we set the generation to 1
workflowChanged.Generation = int64(1)
err = client.Update(context.TODO(), workflowChanged)
assert.NoError(t, err)
// reconcile
handler = &deployWorkflowReconciliationState{
stateSupport: fakeReconcilerSupport(client),
ensurers: newProdObjectEnsurers(&stateSupport{client: client}),
}
result, objects, err = handler.Do(context.TODO(), workflowChanged)
assert.NoError(t, err)
// no requeue, no objects since the workflow has changed
assert.Equal(t, time.Duration(0), result.RequeueAfter)
assert.False(t, result.Requeue)
assert.Len(t, objects, 0)
}