From 55fcc8eac4bbea0e7ae14dff17db8b78046a87ac Mon Sep 17 00:00:00 2001 From: Wahab Ali Date: Thu, 31 Oct 2024 10:31:29 -0400 Subject: [PATCH] Added unit tests for sveltos status transformation --- internal/sveltos/profile.go | 55 ------------- internal/sveltos/status.go | 72 +++++++++++++++++ internal/sveltos/status_test.go | 132 ++++++++++++++++++++++++++++++++ 3 files changed, 204 insertions(+), 55 deletions(-) create mode 100644 internal/sveltos/status.go create mode 100644 internal/sveltos/status_test.go diff --git a/internal/sveltos/profile.go b/internal/sveltos/profile.go index 6e47811fb..2c3dc79d3 100644 --- a/internal/sveltos/profile.go +++ b/internal/sveltos/profile.go @@ -16,7 +16,6 @@ package sveltos import ( "context" - "errors" "fmt" "math" "unsafe" @@ -24,7 +23,6 @@ import ( sveltosv1beta1 "github.com/projectsveltos/addon-controller/api/v1beta1" libsveltosv1beta1 "github.com/projectsveltos/libsveltos/api/v1beta1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -227,56 +225,3 @@ func priorityToTier(priority int32) (int32, error) { return 0, fmt.Errorf("invalid value %d, priority has to be between %d and %d", priority, mini, maxi) } - -// SetStatusConditions transforms status from Sveltos ClusterSummary -// object and sets it into the provided list of conditions. -func SetStatusConditions(summary *sveltosv1beta1.ClusterSummary, conditions *[]metav1.Condition) error { - if summary == nil { - return errors.New("nil summary provided") - } - - for _, x := range summary.Status.FeatureSummaries { - msg := "" - status := metav1.ConditionTrue - if x.FailureMessage != nil && *x.FailureMessage != "" { - msg = *x.FailureMessage - status = metav1.ConditionFalse - } - - apimeta.SetStatusCondition(conditions, metav1.Condition{ - Message: msg, - Reason: string(x.Status), - Status: status, - Type: string(x.FeatureID), - }) - } - - for _, x := range summary.Status.HelmReleaseSummaries { - msg := "Release " + x.ReleaseNamespace + "/" + x.ReleaseName - status := metav1.ConditionTrue - if x.ConflictMessage != "" { - msg += ": " + x.ConflictMessage - status = metav1.ConditionFalse - } - - apimeta.SetStatusCondition(conditions, metav1.Condition{ - Message: msg, - Reason: string(x.Status), - Status: status, - Type: HelmReleaseReadyConditionType(x.ReleaseNamespace, x.ReleaseName), - }) - } - - return nil -} - -// HelmReleaseReadyConditionType returns a SveltosHelmReleaseReady -// type per service to be used in status conditions. -func HelmReleaseReadyConditionType(releaseNamespace, releaseName string) string { - return fmt.Sprintf( - "%s.%s/%s", - releaseNamespace, - releaseName, - hmc.SveltosHelmReleaseReadyCondition, - ) -} diff --git a/internal/sveltos/status.go b/internal/sveltos/status.go new file mode 100644 index 000000000..60b466ef7 --- /dev/null +++ b/internal/sveltos/status.go @@ -0,0 +1,72 @@ +package sveltos + +import ( + "errors" + "fmt" + + sveltosv1beta1 "github.com/projectsveltos/addon-controller/api/v1beta1" + apimeta "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + hmc "github.com/Mirantis/hmc/api/v1alpha1" +) + +// SetStatusConditions transforms status from Sveltos ClusterSummary +// object and sets it into the provided list of conditions. +func SetStatusConditions(summary *sveltosv1beta1.ClusterSummary, conditions *[]metav1.Condition) error { + if summary == nil { + return errors.New("nil summary provided") + } + + for _, x := range summary.Status.FeatureSummaries { + msg := "" + status := metav1.ConditionTrue + if x.FailureMessage != nil && *x.FailureMessage != "" { + msg = *x.FailureMessage + status = metav1.ConditionFalse + } + + apimeta.SetStatusCondition(conditions, metav1.Condition{ + Message: msg, + Reason: string(x.Status), + Status: status, + Type: string(x.FeatureID), + }) + } + + for _, x := range summary.Status.HelmReleaseSummaries { + status := metav1.ConditionTrue + if x.ConflictMessage != "" { + status = metav1.ConditionFalse + } + + apimeta.SetStatusCondition(conditions, metav1.Condition{ + Message: helmReleaseConditionMessage(x.ReleaseNamespace, x.ReleaseName, x.ConflictMessage), + Reason: string(x.Status), + Status: status, + Type: HelmReleaseReadyConditionType(x.ReleaseNamespace, x.ReleaseName), + }) + } + + return nil +} + +// HelmReleaseReadyConditionType returns a SveltosHelmReleaseReady +// type per service to be used in status conditions. +func HelmReleaseReadyConditionType(releaseNamespace, releaseName string) string { + return fmt.Sprintf( + "%s.%s/%s", + releaseNamespace, + releaseName, + hmc.SveltosHelmReleaseReadyCondition, + ) +} + +func helmReleaseConditionMessage(releaseNamespace, releaseName, conflictMsg string) string { + msg := "Release " + releaseNamespace + "/" + releaseName + if conflictMsg != "" { + msg += ": " + conflictMsg + } + + return msg +} diff --git a/internal/sveltos/status_test.go b/internal/sveltos/status_test.go new file mode 100644 index 000000000..a2194d4e0 --- /dev/null +++ b/internal/sveltos/status_test.go @@ -0,0 +1,132 @@ +package sveltos + +import ( + "testing" + + sveltosv1beta1 "github.com/projectsveltos/addon-controller/api/v1beta1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestSetStatusConditions(t *testing.T) { + releaseNamespace := "testnamespace" + releaseName := "testname" + conflictMsg := "some conflict message" + failureMesg := "some failure message" + + for _, tc := range []struct { + err error + expectCondition metav1.Condition + name string + summary sveltosv1beta1.ClusterSummary + }{ + { + name: "sveltos featuresummary provisioning", + summary: sveltosv1beta1.ClusterSummary{ + Status: sveltosv1beta1.ClusterSummaryStatus{ + FeatureSummaries: []sveltosv1beta1.FeatureSummary{ + { + FeatureID: sveltosv1beta1.FeatureHelm, + Status: sveltosv1beta1.FeatureStatusProvisioning, + }, + }, + }, + }, + expectCondition: metav1.Condition{ + Type: string(sveltosv1beta1.FeatureHelm), + Status: metav1.ConditionTrue, + Reason: string(sveltosv1beta1.FeatureStatusProvisioning), + }, + }, + { + name: "sveltos featuresummary provisioned", + summary: sveltosv1beta1.ClusterSummary{ + Status: sveltosv1beta1.ClusterSummaryStatus{ + FeatureSummaries: []sveltosv1beta1.FeatureSummary{ + { + FeatureID: sveltosv1beta1.FeatureHelm, + Status: sveltosv1beta1.FeatureStatusProvisioned, + }, + }, + }, + }, + expectCondition: metav1.Condition{ + Type: string(sveltosv1beta1.FeatureHelm), + Status: metav1.ConditionTrue, + Reason: string(sveltosv1beta1.FeatureStatusProvisioned), + }, + }, + { + name: "sveltos featuresummary failed", + summary: sveltosv1beta1.ClusterSummary{ + Status: sveltosv1beta1.ClusterSummaryStatus{ + FeatureSummaries: []sveltosv1beta1.FeatureSummary{ + { + FeatureID: sveltosv1beta1.FeatureHelm, + Status: sveltosv1beta1.FeatureStatusFailed, + FailureMessage: &failureMesg, + }, + }, + }, + }, + expectCondition: metav1.Condition{ + Type: string(sveltosv1beta1.FeatureHelm), + Status: metav1.ConditionFalse, + Reason: string(sveltosv1beta1.FeatureStatusFailed), + Message: failureMesg, + }, + }, + { + name: "sveltos helmreleasesummary managing", + summary: sveltosv1beta1.ClusterSummary{ + Status: sveltosv1beta1.ClusterSummaryStatus{ + HelmReleaseSummaries: []sveltosv1beta1.HelmChartSummary{ + { + ReleaseNamespace: releaseNamespace, + ReleaseName: releaseName, + Status: sveltosv1beta1.HelmChartStatusManaging, + }, + }, + }, + }, + expectCondition: metav1.Condition{ + Type: HelmReleaseReadyConditionType(releaseNamespace, releaseName), + Status: metav1.ConditionTrue, + Reason: string(sveltosv1beta1.HelmChartStatusManaging), + Message: helmReleaseConditionMessage(releaseNamespace, releaseName, ""), + }, + }, + { + name: "sveltos helmreleasesummary conflict", + summary: sveltosv1beta1.ClusterSummary{ + Status: sveltosv1beta1.ClusterSummaryStatus{ + HelmReleaseSummaries: []sveltosv1beta1.HelmChartSummary{ + { + ReleaseNamespace: releaseNamespace, + ReleaseName: releaseName, + Status: sveltosv1beta1.HelmChartStatusConflict, + ConflictMessage: conflictMsg, + }, + }, + }, + }, + expectCondition: metav1.Condition{ + Type: HelmReleaseReadyConditionType(releaseNamespace, releaseName), + Status: metav1.ConditionFalse, + Reason: string(sveltosv1beta1.HelmChartStatusConflict), + Message: helmReleaseConditionMessage(releaseNamespace, releaseName, conflictMsg), + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + conditions := []metav1.Condition{} + require.NoError(t, SetStatusConditions(&tc.summary, &conditions)) + assert.Len(t, conditions, 1) + assert.Equal(t, tc.expectCondition.Type, conditions[0].Type) + assert.Equal(t, tc.expectCondition.Status, conditions[0].Status) + assert.Equal(t, tc.expectCondition.Reason, conditions[0].Reason) + assert.Equal(t, tc.expectCondition.Message, conditions[0].Message) + }) + } +}