From 1a6d3ea2443914e628f30069ba337b429b293e77 Mon Sep 17 00:00:00 2001 From: Florian Bacher Date: Thu, 10 Nov 2022 11:40:45 +0100 Subject: [PATCH 1/5] fix(operator): Do no proceed with WLI of no AppVersion containing it is available Signed-off-by: Florian Bacher --- .../keptnworkloadinstance/controller.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/operator/controllers/keptnworkloadinstance/controller.go b/operator/controllers/keptnworkloadinstance/controller.go index 918f0443bf..8c87700beb 100644 --- a/operator/controllers/keptnworkloadinstance/controller.go +++ b/operator/controllers/keptnworkloadinstance/controller.go @@ -19,7 +19,6 @@ package keptnworkloadinstance import ( "context" "fmt" - "reflect" "time" "go.opentelemetry.io/otel" @@ -274,18 +273,22 @@ func (r *KeptnWorkloadInstanceReconciler) getAppVersion(ctx context.Context, app func (r *KeptnWorkloadInstanceReconciler) getAppVersionForWorkloadInstance(ctx context.Context, wli *klcv1alpha1.KeptnWorkloadInstance) (bool, klcv1alpha1.KeptnAppVersion, error) { apps := &klcv1alpha1.KeptnAppVersionList{} + // TODO add label selector for looking up by name? if err := r.Client.List(ctx, apps, client.InNamespace(wli.Namespace)); err != nil { return false, klcv1alpha1.KeptnAppVersion{}, err } latestVersion := klcv1alpha1.KeptnAppVersion{} + oldVersion, err := version.NewVersion("0.0.0") + if err != nil { + return false, latestVersion, err + } + workloadFound := false for _, app := range apps.Items { if app.Spec.AppName == wli.Spec.AppName { - for _, appWorkload := range app.Spec.Workloads { - if !reflect.DeepEqual(latestVersion, app) { - latestVersion = app - } else if appWorkload.Version == wli.Spec.Version && fmt.Sprintf("%s-%s", app.Spec.AppName, appWorkload.Name) == wli.Spec.WorkloadName { - oldVersion, err := version.NewVersion(app.Spec.Version) + if appWorkload.Version == wli.Spec.Version && fmt.Sprintf("%s-%s", app.Spec.AppName, appWorkload.Name) == wli.Spec.WorkloadName { + workloadFound = true + oldVersion, err = version.NewVersion(app.Spec.Version) if err != nil { r.Log.Error(err, "could not parse version") } @@ -301,7 +304,7 @@ func (r *KeptnWorkloadInstanceReconciler) getAppVersionForWorkloadInstance(ctx c } } - if latestVersion.Spec.Version == "" { + if latestVersion.Spec.Version == "" || !workloadFound { return false, klcv1alpha1.KeptnAppVersion{}, nil } return true, latestVersion, nil From 978b58f02954fe4f071b0e9995461cec2d3dcafd Mon Sep 17 00:00:00 2001 From: Florian Bacher Date: Thu, 10 Nov 2022 16:34:02 +0100 Subject: [PATCH 2/5] added component tests Signed-off-by: Florian Bacher --- .../keptnworkloadinstance/controller.go | 10 +- operator/test/component/common.go | 33 ++++ .../workloadinstancecontroller_test.go | 148 ++++++++++++++++++ 3 files changed, 185 insertions(+), 6 deletions(-) create mode 100644 operator/test/component/common.go create mode 100644 operator/test/component/workloadinstancecontroller_test.go diff --git a/operator/controllers/keptnworkloadinstance/controller.go b/operator/controllers/keptnworkloadinstance/controller.go index 8c87700beb..223b28571c 100644 --- a/operator/controllers/keptnworkloadinstance/controller.go +++ b/operator/controllers/keptnworkloadinstance/controller.go @@ -288,16 +288,14 @@ func (r *KeptnWorkloadInstanceReconciler) getAppVersionForWorkloadInstance(ctx c for _, appWorkload := range app.Spec.Workloads { if appWorkload.Version == wli.Spec.Version && fmt.Sprintf("%s-%s", app.Spec.AppName, appWorkload.Name) == wli.Spec.WorkloadName { workloadFound = true - oldVersion, err = version.NewVersion(app.Spec.Version) + newVersion, err := version.NewVersion(app.Spec.Version) if err != nil { r.Log.Error(err, "could not parse version") + return false, latestVersion, err } - newVersion, err := version.NewVersion(latestVersion.Spec.Version) - if err != nil { - r.Log.Error(err, "could not parse version") - } - if oldVersion.LessThan(newVersion) { + if newVersion.GreaterThan(oldVersion) { latestVersion = app + oldVersion = newVersion } } } diff --git a/operator/test/component/common.go b/operator/test/component/common.go new file mode 100644 index 0000000000..b1a4addef1 --- /dev/null +++ b/operator/test/component/common.go @@ -0,0 +1,33 @@ +package component + +import ( + "github.com/keptn/lifecycle-toolkit/operator/api/v1alpha1/common" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/metric/unit" + "go.opentelemetry.io/otel/sdk/metric" +) + +func initKeptnMeters() common.KeptnMeters { + provider := metric.NewMeterProvider() + meter := provider.Meter("keptn/task") + deploymentCount, _ := meter.SyncInt64().Counter("keptn.deployment.count", instrument.WithDescription("a simple counter for Keptn Deployments")) + deploymentDuration, _ := meter.SyncFloat64().Histogram("keptn.deployment.duration", instrument.WithDescription("a histogram of duration for Keptn Deployments"), instrument.WithUnit(unit.Unit("s"))) + taskCount, _ := meter.SyncInt64().Counter("keptn.task.count", instrument.WithDescription("a simple counter for Keptn Tasks")) + taskDuration, _ := meter.SyncFloat64().Histogram("keptn.task.duration", instrument.WithDescription("a histogram of duration for Keptn Tasks"), instrument.WithUnit(unit.Unit("s"))) + appCount, _ := meter.SyncInt64().Counter("keptn.app.count", instrument.WithDescription("a simple counter for Keptn Apps")) + appDuration, _ := meter.SyncFloat64().Histogram("keptn.app.duration", instrument.WithDescription("a histogram of duration for Keptn Apps"), instrument.WithUnit(unit.Unit("s"))) + evaluationCount, _ := meter.SyncInt64().Counter("keptn.evaluation.count", instrument.WithDescription("a simple counter for Keptn Evaluations")) + evaluationDuration, _ := meter.SyncFloat64().Histogram("keptn.evaluation.duration", instrument.WithDescription("a histogram of duration for Keptn Evaluations"), instrument.WithUnit(unit.Unit("s"))) + + meters := common.KeptnMeters{ + TaskCount: taskCount, + TaskDuration: taskDuration, + DeploymentCount: deploymentCount, + DeploymentDuration: deploymentDuration, + AppCount: appCount, + AppDuration: appDuration, + EvaluationCount: evaluationCount, + EvaluationDuration: evaluationDuration, + } + return meters +} diff --git a/operator/test/component/workloadinstancecontroller_test.go b/operator/test/component/workloadinstancecontroller_test.go new file mode 100644 index 0000000000..a752e92fd3 --- /dev/null +++ b/operator/test/component/workloadinstancecontroller_test.go @@ -0,0 +1,148 @@ +package component + +import ( + "context" + klcv1alpha1 "github.com/keptn/lifecycle-toolkit/operator/api/v1alpha1" + keptncontroller "github.com/keptn/lifecycle-toolkit/operator/controllers/common" + "github.com/keptn/lifecycle-toolkit/operator/controllers/keptnworkloadinstance" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + otelsdk "go.opentelemetry.io/otel/sdk/trace" + sdktest "go.opentelemetry.io/otel/sdk/trace/tracetest" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// clean example of component test (E2E test/ integration test can be achieved adding a real cluster) +// App controller creates AppVersion when a new App CRD is added +// span for creation and reconcile are correct +// container must be ordered to have the before all setup +// this way the container spec check is not randomized, so we can make +// assertions on spans number and traces +var _ = Describe("KeptnWorkloadInstanceController", Ordered, func() { + var ( + name string + namespace string + version string + spanRecorder *sdktest.SpanRecorder + tracer *otelsdk.TracerProvider + ) + + BeforeAll(func() { + //setup once + By("Waiting for Manager") + Eventually(func() bool { + return k8sManager != nil + }).Should(Equal(true)) + + By("Creating the Controller") + + spanRecorder = sdktest.NewSpanRecorder() + tracer = otelsdk.NewTracerProvider(otelsdk.WithSpanProcessor(spanRecorder)) + + ////setup controllers here + controllers := []keptncontroller.Controller{&keptnworkloadinstance.KeptnWorkloadInstanceReconciler{ + Client: k8sManager.GetClient(), + Scheme: k8sManager.GetScheme(), + Recorder: k8sManager.GetEventRecorderFor("test-app-controller"), + Log: GinkgoLogr, + Meters: initKeptnMeters(), + Tracer: tracer.Tracer("test-app-tracer"), + }} + setupManager(controllers) // we can register multiple time the same controller + // so that they have a different span/trace + + //for a fake controller you can also use + //controller, err := controller.New("app-controller", cm, controller.Options{ + // Reconciler: reconcile.Func( + // func(_ context.Context, request reconcile.Request) (reconcile.Result, error) { + // reconciled <- request + // return reconcile.Result{}, nil + // }), + //}) + //Expect(err).NotTo(HaveOccurred()) + }) + + BeforeEach(func() { // list var here they will be copied for every spec + name = "test-app" + namespace = "default" // namespaces are not deleted in the api so be careful + // when creating you can use ignoreAlreadyExists(err error) + version = "1.0.0" + }) + Describe("Creation of WorkloadInstance", func() { + var ( + appVersion *klcv1alpha1.KeptnAppVersion + wi *klcv1alpha1.KeptnWorkloadInstance + ) + Context("with a new AppVersions CRD", func() { + + BeforeEach(func() { + appVersion = createAppVersionInCluster(name, namespace, version) + }) + + It("should fail if Workload not found in AppVersion", func() { + wiName := "not-found" + wi = &klcv1alpha1.KeptnWorkloadInstance{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: klcv1alpha1.KeptnWorkloadInstanceSpec{ + KeptnWorkloadSpec: klcv1alpha1.KeptnWorkloadSpec{}, + WorkloadName: "app-wname-" + wiName, + TraceId: map[string]string{"traceparent": "00-0f89f15e562489e2e171eca1cf9ba958-d2fa6dbbcbf7e29a-01"}, + }, + } + By("Creating WorkloadInstance") + err := k8sClient.Create(context.TODO(), wi) + Expect(err).To(BeNil()) + + By("Ensuring WorkloadInstance ends up in a failed state") + wiNameObj := types.NamespacedName{ + Namespace: wi.Namespace, + Name: wi.Name, + } + Consistently(func(g Gomega) { + wi := &klcv1alpha1.KeptnWorkloadInstance{} + err := k8sClient.Get(ctx, wiNameObj, wi) + g.Expect(err).To(BeNil()) + g.Expect(wi).To(Not(BeNil())) + g.Expect(wi.Status.CurrentPhase).To(BeEmpty()) + }, "10s").Should(Succeed()) + }) + AfterEach(func() { + // Remember to clean up the cluster after each test + k8sClient.Delete(ctx, appVersion) + k8sClient.Delete(ctx, wi) + // Reset span recorder after each spec + resetSpanRecords(tracer, spanRecorder) + }) + + }) + + }) +}) + +func createAppVersionInCluster(name string, namespace string, version string) *klcv1alpha1.KeptnAppVersion { + instance := &klcv1alpha1.KeptnAppVersion{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: klcv1alpha1.KeptnAppVersionSpec{ + KeptnAppSpec: klcv1alpha1.KeptnAppSpec{ + Version: version, + Workloads: []klcv1alpha1.KeptnWorkloadRef{ + { + Name: "app-wname", + Version: "2.0", + }, + }, + }, + }, + } + By("Invoking Reconciling for Create") + + Expect(ignoreAlreadyExists(k8sClient.Create(ctx, instance))).Should(Succeed()) + return instance +} From a2f68fc2e2f0a0fe51c234ecf2b2fe68c422c5b3 Mon Sep 17 00:00:00 2001 From: Florian Bacher Date: Fri, 11 Nov 2022 08:38:40 +0100 Subject: [PATCH 3/5] added unit tests, adapted component tests Signed-off-by: Florian Bacher --- .../keptnworkloadinstance/controller.go | 26 ++- .../keptnworkloadinstance/controller_test.go | 221 +++++++++++++++++- .../workloadinstancecontroller_test.go | 6 +- 3 files changed, 236 insertions(+), 17 deletions(-) diff --git a/operator/controllers/keptnworkloadinstance/controller.go b/operator/controllers/keptnworkloadinstance/controller.go index 223b28571c..251a08fb1a 100644 --- a/operator/controllers/keptnworkloadinstance/controller.go +++ b/operator/controllers/keptnworkloadinstance/controller.go @@ -277,11 +277,24 @@ func (r *KeptnWorkloadInstanceReconciler) getAppVersionForWorkloadInstance(ctx c if err := r.Client.List(ctx, apps, client.InNamespace(wli.Namespace)); err != nil { return false, klcv1alpha1.KeptnAppVersion{}, err } - latestVersion := klcv1alpha1.KeptnAppVersion{} - oldVersion, err := version.NewVersion("0.0.0") + + workloadFound, latestVersion, err := getLatestAppVersion(apps, wli) if err != nil { + r.Log.Error(err, "could not look up KeptnAppVersion for WorkloadInstance") return false, latestVersion, err } + + if latestVersion.Spec.Version == "" || !workloadFound { + return false, klcv1alpha1.KeptnAppVersion{}, nil + } + return true, latestVersion, nil +} + +func getLatestAppVersion(apps *klcv1alpha1.KeptnAppVersionList, wli *klcv1alpha1.KeptnWorkloadInstance) (bool, klcv1alpha1.KeptnAppVersion, error) { + latestVersion := klcv1alpha1.KeptnAppVersion{} + // ignore the potential error since this can not return an error with 0.0.0 + oldVersion, _ := version.NewVersion("0.0.0") + workloadFound := false for _, app := range apps.Items { if app.Spec.AppName == wli.Spec.AppName { @@ -290,8 +303,7 @@ func (r *KeptnWorkloadInstanceReconciler) getAppVersionForWorkloadInstance(ctx c workloadFound = true newVersion, err := version.NewVersion(app.Spec.Version) if err != nil { - r.Log.Error(err, "could not parse version") - return false, latestVersion, err + return false, klcv1alpha1.KeptnAppVersion{}, err } if newVersion.GreaterThan(oldVersion) { latestVersion = app @@ -301,9 +313,5 @@ func (r *KeptnWorkloadInstanceReconciler) getAppVersionForWorkloadInstance(ctx c } } } - - if latestVersion.Spec.Version == "" || !workloadFound { - return false, klcv1alpha1.KeptnAppVersion{}, nil - } - return true, latestVersion, nil + return workloadFound, latestVersion, nil } diff --git a/operator/controllers/keptnworkloadinstance/controller_test.go b/operator/controllers/keptnworkloadinstance/controller_test.go index 375b7a34da..7b1206b66c 100644 --- a/operator/controllers/keptnworkloadinstance/controller_test.go +++ b/operator/controllers/keptnworkloadinstance/controller_test.go @@ -2,14 +2,14 @@ package keptnworkloadinstance import ( "context" - "testing" - - "github.com/keptn/lifecycle-toolkit/operator/api/v1alpha1" + klcv1alpha1 "github.com/keptn/lifecycle-toolkit/operator/api/v1alpha1" + "github.com/stretchr/testify/require" testrequire "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client/fake" + "testing" ) func TestKeptnWorkloadInstanceReconciler_IsPodRunning(t *testing.T) { @@ -20,7 +20,7 @@ func TestKeptnWorkloadInstanceReconciler_IsPodRunning(t *testing.T) { r := &KeptnWorkloadInstanceReconciler{ Client: fake.NewClientBuilder().WithLists(podList).Build(), } - isPodRunning, err := r.isPodRunning(context.TODO(), v1alpha1.ResourceReference{UID: types.UID("pod1")}, "node1") + isPodRunning, err := r.isPodRunning(context.TODO(), klcv1alpha1.ResourceReference{UID: types.UID("pod1")}, "node1") testrequire.Nil(t, err) if !isPodRunning { t.Errorf("Wrong!") @@ -29,7 +29,7 @@ func TestKeptnWorkloadInstanceReconciler_IsPodRunning(t *testing.T) { r2 := &KeptnWorkloadInstanceReconciler{ Client: fake.NewClientBuilder().WithLists(podList2).Build(), } - isPodRunning, err = r2.isPodRunning(context.TODO(), v1alpha1.ResourceReference{UID: types.UID("pod1")}, "node1") + isPodRunning, err = r2.isPodRunning(context.TODO(), klcv1alpha1.ResourceReference{UID: types.UID("pod1")}, "node1") testrequire.Nil(t, err) if isPodRunning { t.Errorf("Wrong!") @@ -50,3 +50,214 @@ func makeNominatedPod(podName string, nodeName string, phase v1.PodPhase) v1.Pod }, } } + +func Test_getLatestAppVersion(t *testing.T) { + type args struct { + apps *klcv1alpha1.KeptnAppVersionList + wli *klcv1alpha1.KeptnWorkloadInstance + } + tests := []struct { + name string + args args + wantFound bool + wantAppVersion klcv1alpha1.KeptnAppVersion + wantErr bool + }{ + { + name: "app version found", + args: args{ + apps: &klcv1alpha1.KeptnAppVersionList{ + Items: []klcv1alpha1.KeptnAppVersion{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-app", + Namespace: "default", + }, + Spec: klcv1alpha1.KeptnAppVersionSpec{ + KeptnAppSpec: klcv1alpha1.KeptnAppSpec{ + Version: "1.0", + Workloads: []klcv1alpha1.KeptnWorkloadRef{ + { + Name: "my-workload", + Version: "1.0", + }, + }, + }, + AppName: "my-app", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-app", + Namespace: "default", + }, + Spec: klcv1alpha1.KeptnAppVersionSpec{ + KeptnAppSpec: klcv1alpha1.KeptnAppSpec{ + Version: "2.0", + Workloads: []klcv1alpha1.KeptnWorkloadRef{ + { + Name: "my-workload", + Version: "1.0", + }, + }, + }, + AppName: "my-app", + }, + }, + }, + }, + wli: &klcv1alpha1.KeptnWorkloadInstance{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-workloadinstance", + Namespace: "default", + }, + Spec: klcv1alpha1.KeptnWorkloadInstanceSpec{ + KeptnWorkloadSpec: klcv1alpha1.KeptnWorkloadSpec{ + AppName: "my-app", + Version: "1.0", + }, + WorkloadName: "my-app-my-workload", + }, + }, + }, + wantFound: true, + wantAppVersion: klcv1alpha1.KeptnAppVersion{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-app", + Namespace: "default", + }, + Spec: klcv1alpha1.KeptnAppVersionSpec{ + KeptnAppSpec: klcv1alpha1.KeptnAppSpec{ + Version: "2.0", + Workloads: []klcv1alpha1.KeptnWorkloadRef{ + { + Name: "my-workload", + Version: "1.0", + }, + }, + }, + AppName: "my-app", + }, + }, + wantErr: false, + }, + { + name: "app version not found", + args: args{ + apps: &klcv1alpha1.KeptnAppVersionList{ + Items: []klcv1alpha1.KeptnAppVersion{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-app", + Namespace: "default", + }, + Spec: klcv1alpha1.KeptnAppVersionSpec{ + KeptnAppSpec: klcv1alpha1.KeptnAppSpec{ + Version: "1.0", + Workloads: []klcv1alpha1.KeptnWorkloadRef{ + { + Name: "my-other-workload", + Version: "1.0", + }, + }, + }, + AppName: "my-app", + }, + }, + }, + }, + wli: &klcv1alpha1.KeptnWorkloadInstance{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-workloadinstance", + Namespace: "default", + }, + Spec: klcv1alpha1.KeptnWorkloadInstanceSpec{ + KeptnWorkloadSpec: klcv1alpha1.KeptnWorkloadSpec{ + AppName: "my-app", + Version: "1.0", + }, + WorkloadName: "my-app-my-workload", + }, + }, + }, + wantFound: false, + wantAppVersion: klcv1alpha1.KeptnAppVersion{}, + wantErr: false, + }, + { + name: "app version with invalid version", + args: args{ + apps: &klcv1alpha1.KeptnAppVersionList{ + Items: []klcv1alpha1.KeptnAppVersion{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "my-app", + Namespace: "default", + }, + Spec: klcv1alpha1.KeptnAppVersionSpec{ + KeptnAppSpec: klcv1alpha1.KeptnAppSpec{ + Version: "", + Workloads: []klcv1alpha1.KeptnWorkloadRef{ + { + Name: "my-workload", + Version: "1.0", + }, + }, + }, + AppName: "my-app", + }, + }, + }, + }, + wli: &klcv1alpha1.KeptnWorkloadInstance{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-workloadinstance", + Namespace: "default", + }, + Spec: klcv1alpha1.KeptnWorkloadInstanceSpec{ + KeptnWorkloadSpec: klcv1alpha1.KeptnWorkloadSpec{ + AppName: "my-app", + Version: "1.0", + }, + WorkloadName: "my-app-my-workload", + }, + }, + }, + wantFound: false, + wantAppVersion: klcv1alpha1.KeptnAppVersion{}, + wantErr: true, + }, + { + name: "app version list empty", + args: args{ + apps: &klcv1alpha1.KeptnAppVersionList{ + Items: []klcv1alpha1.KeptnAppVersion{}, + }, + wli: &klcv1alpha1.KeptnWorkloadInstance{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-workloadinstance", + Namespace: "default", + }, + Spec: klcv1alpha1.KeptnWorkloadInstanceSpec{ + KeptnWorkloadSpec: klcv1alpha1.KeptnWorkloadSpec{ + AppName: "my-app", + Version: "1.0", + }, + WorkloadName: "my-app-my-workload", + }, + }, + }, + wantFound: false, + wantAppVersion: klcv1alpha1.KeptnAppVersion{}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + found, gotAppVersion, err := getLatestAppVersion(tt.args.apps, tt.args.wli) + require.Equal(t, tt.wantErr, err != nil) + require.Equal(t, tt.wantFound, found) + require.Equal(t, tt.wantAppVersion, gotAppVersion) + }) + } +} diff --git a/operator/test/component/workloadinstancecontroller_test.go b/operator/test/component/workloadinstancecontroller_test.go index a752e92fd3..7d2cfdcb07 100644 --- a/operator/test/component/workloadinstancecontroller_test.go +++ b/operator/test/component/workloadinstancecontroller_test.go @@ -89,7 +89,7 @@ var _ = Describe("KeptnWorkloadInstanceController", Ordered, func() { }, Spec: klcv1alpha1.KeptnWorkloadInstanceSpec{ KeptnWorkloadSpec: klcv1alpha1.KeptnWorkloadSpec{}, - WorkloadName: "app-wname-" + wiName, + WorkloadName: "wi-test-app-wname-" + wiName, TraceId: map[string]string{"traceparent": "00-0f89f15e562489e2e171eca1cf9ba958-d2fa6dbbcbf7e29a-01"}, }, } @@ -97,7 +97,7 @@ var _ = Describe("KeptnWorkloadInstanceController", Ordered, func() { err := k8sClient.Create(context.TODO(), wi) Expect(err).To(BeNil()) - By("Ensuring WorkloadInstance ends up in a failed state") + By("Ensuring WorkloadInstance does not progress to next phase") wiNameObj := types.NamespacedName{ Namespace: wi.Namespace, Name: wi.Name, @@ -134,7 +134,7 @@ func createAppVersionInCluster(name string, namespace string, version string) *k Version: version, Workloads: []klcv1alpha1.KeptnWorkloadRef{ { - Name: "app-wname", + Name: "wi-test-app-wname", Version: "2.0", }, }, From 3d000718dd5faa22c5be2801a37e06fda681e6c6 Mon Sep 17 00:00:00 2001 From: Florian Bacher Date: Fri, 11 Nov 2022 08:41:29 +0100 Subject: [PATCH 4/5] reduce test time Signed-off-by: Florian Bacher --- operator/test/component/workloadinstancecontroller_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operator/test/component/workloadinstancecontroller_test.go b/operator/test/component/workloadinstancecontroller_test.go index 7d2cfdcb07..ec4ac39576 100644 --- a/operator/test/component/workloadinstancecontroller_test.go +++ b/operator/test/component/workloadinstancecontroller_test.go @@ -108,7 +108,7 @@ var _ = Describe("KeptnWorkloadInstanceController", Ordered, func() { g.Expect(err).To(BeNil()) g.Expect(wi).To(Not(BeNil())) g.Expect(wi.Status.CurrentPhase).To(BeEmpty()) - }, "10s").Should(Succeed()) + }, "3s").Should(Succeed()) }) AfterEach(func() { // Remember to clean up the cluster after each test From 2aee04e3f8387dc8cfd3c201fd91d03081980c8d Mon Sep 17 00:00:00 2001 From: Florian Bacher Date: Mon, 14 Nov 2022 10:52:39 +0100 Subject: [PATCH 5/5] pr review: added function for generating name of workload of an app Signed-off-by: Florian Bacher --- .../api/v1alpha1/keptnappversion_types.go | 4 ++ .../v1alpha1/keptnappversion_types_test.go | 41 +++++++++++++++++++ .../keptnworkloadinstance/controller.go | 2 +- 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 operator/api/v1alpha1/keptnappversion_types_test.go diff --git a/operator/api/v1alpha1/keptnappversion_types.go b/operator/api/v1alpha1/keptnappversion_types.go index a7e21a7ae0..0695dbb9f0 100644 --- a/operator/api/v1alpha1/keptnappversion_types.go +++ b/operator/api/v1alpha1/keptnappversion_types.go @@ -355,3 +355,7 @@ func (a KeptnAppVersion) GetSpanAttributes() []attribute.KeyValue { common.AppNamespace.String(a.Namespace), } } + +func (v KeptnAppVersion) GetWorkloadNameOfApp(workloadName string) string { + return fmt.Sprintf("%s-%s", v.Spec.AppName, workloadName) +} diff --git a/operator/api/v1alpha1/keptnappversion_types_test.go b/operator/api/v1alpha1/keptnappversion_types_test.go new file mode 100644 index 0000000000..68f4c47396 --- /dev/null +++ b/operator/api/v1alpha1/keptnappversion_types_test.go @@ -0,0 +1,41 @@ +package v1alpha1 + +import ( + "testing" +) + +func TestKeptnAppVersion_GetWorkloadNameOfApp(t *testing.T) { + type fields struct { + Spec KeptnAppVersionSpec + } + type args struct { + workloadName string + } + tests := []struct { + name string + fields fields + args args + want string + }{ + { + name: "", + fields: fields{ + Spec: KeptnAppVersionSpec{AppName: "my-app"}, + }, + args: args{ + workloadName: "my-workload", + }, + want: "my-app-my-workload", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + v := KeptnAppVersion{ + Spec: tt.fields.Spec, + } + if got := v.GetWorkloadNameOfApp(tt.args.workloadName); got != tt.want { + t.Errorf("GetWorkloadNameOfApp() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/operator/controllers/keptnworkloadinstance/controller.go b/operator/controllers/keptnworkloadinstance/controller.go index 251a08fb1a..9f7dbe773e 100644 --- a/operator/controllers/keptnworkloadinstance/controller.go +++ b/operator/controllers/keptnworkloadinstance/controller.go @@ -299,7 +299,7 @@ func getLatestAppVersion(apps *klcv1alpha1.KeptnAppVersionList, wli *klcv1alpha1 for _, app := range apps.Items { if app.Spec.AppName == wli.Spec.AppName { for _, appWorkload := range app.Spec.Workloads { - if appWorkload.Version == wli.Spec.Version && fmt.Sprintf("%s-%s", app.Spec.AppName, appWorkload.Name) == wli.Spec.WorkloadName { + if appWorkload.Version == wli.Spec.Version && app.GetWorkloadNameOfApp(appWorkload.Name) == wli.Spec.WorkloadName { workloadFound = true newVersion, err := version.NewVersion(app.Spec.Version) if err != nil {