From 99fa8df08b2e25f060ebab939ad656f2e7d04a50 Mon Sep 17 00:00:00 2001 From: Amit Arora Date: Wed, 21 Aug 2024 21:30:54 +0530 Subject: [PATCH] Metrics for SyncSet and SelectorSyncSets --- pkg/monitor/cluster/syncsetstatus.go | 65 +++++---- pkg/monitor/cluster/syncsetstatus_test.go | 165 ++++++++++++++++++++++ 2 files changed, 203 insertions(+), 27 deletions(-) create mode 100644 pkg/monitor/cluster/syncsetstatus_test.go diff --git a/pkg/monitor/cluster/syncsetstatus.go b/pkg/monitor/cluster/syncsetstatus.go index 29ec0f9fc63..6a478478a6d 100644 --- a/pkg/monitor/cluster/syncsetstatus.go +++ b/pkg/monitor/cluster/syncsetstatus.go @@ -1,43 +1,54 @@ package cluster -// Copyright (c) Microsoft Corporation. -// Licensed under the Apache License 2.0. - import ( "context" ) func (mon *Monitor) emitSyncSetStatus(ctx context.Context) error { - cs, error := mon.hiveClusterManager.GetSyncSetResources(ctx, mon.doc) - if error != nil { - return nil + clusterSync, err := mon.hiveClusterManager.GetSyncSetResources(ctx, mon.doc) + if err != nil { + return err } - if cs.Status.SyncSets != nil { - mon.emitGauge("syncsets.count", int64(len(cs.Status.SyncSets)), nil) - for _, s := range cs.Status.SyncSets { - mon.emitGauge("hive.syncsets", 1, map[string]string{ - "name": s.Name, - "result": string(s.Result), - "firstSuccessTime": s.FirstSuccessTime.String(), - "lastTransitionTime": s.LastTransitionTime.String(), - "failureMessage": s.FailureMessage, - }) + if clusterSync != nil { + clustersyncLabels := make(map[string]string) + + if clusterSync.Status.SyncSets != nil { + for _, s := range clusterSync.Status.SyncSets { + labels := map[string]string{ + "name": s.Name, + "result": string(s.Result), + "firstSuccessTime": s.FirstSuccessTime.String(), + "lastTransitionTime": s.LastTransitionTime.String(), + "failureMessage": s.FailureMessage, + } + mon.emitGauge("hive.syncsets", 1, labels) + for k, v := range labels { + clustersyncLabels[k] = v + } + } } - } - if cs.Status.SelectorSyncSets != nil { - mon.emitGauge("selectorsyncsets.count", int64(len(cs.Status.SelectorSyncSets)), nil) + if clusterSync.Status.SelectorSyncSets != nil { + for _, s := range clusterSync.Status.SelectorSyncSets { + labels := map[string]string{ + "name": s.Name, + "result": string(s.Result), + "firstSuccessTime": s.FirstSuccessTime.String(), + "lastTransitionTime": s.LastTransitionTime.String(), + "failureMessage": s.FailureMessage, + } + mon.emitGauge("hive.selectorsyncsets", 1, labels) + for k, v := range labels { + clustersyncLabels[k] = v + } + } + } - for _, s := range cs.Status.SelectorSyncSets { - mon.emitGauge("hive.selectorsyncsets", 1, map[string]string{ - "name": s.Name, - "result": string(s.Result), - "firstSuccessTime": s.FirstSuccessTime.String(), - "lastTransitionTime": s.LastTransitionTime.String(), - "failureMessage": s.FailureMessage, - }) + if len(clustersyncLabels) > 0 { + mon.emitGauge("hive.clustersync", 1, clustersyncLabels) } } + return nil } diff --git a/pkg/monitor/cluster/syncsetstatus_test.go b/pkg/monitor/cluster/syncsetstatus_test.go new file mode 100644 index 00000000000..fb64f2f077b --- /dev/null +++ b/pkg/monitor/cluster/syncsetstatus_test.go @@ -0,0 +1,165 @@ +package cluster + +import ( + "context" + "errors" + "testing" + "time" + + mock_hive "github.com/Azure/ARO-RP/pkg/util/mocks/hive" + mock_metrics "github.com/Azure/ARO-RP/pkg/util/mocks/metrics" + "github.com/golang/mock/gomock" + hivev1alpha1 "github.com/openshift/hive/apis/hiveinternal/v1alpha1" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/scheme" +) + +func init() { + // Register the ClusterSync type with the scheme + hivev1alpha1.AddToScheme(scheme.Scheme) +} + +func TestEmitSyncSetStatus(t *testing.T) { + for _, tt := range []struct { + name string + clusterSync *hivev1alpha1.ClusterSync + getClusterSyncErr error + expectedError error + expectedGauges []struct { + name string + value int64 + labels map[string]string + } + }{ + { + name: "SyncSets and SelectorSyncSets have elements", + clusterSync: &hivev1alpha1.ClusterSync{ + Status: hivev1alpha1.ClusterSyncStatus{ + SyncSets: []hivev1alpha1.SyncStatus{ + { + Name: "syncset1", + Result: "Success", + FirstSuccessTime: &metav1.Time{Time: time.Now()}, + LastTransitionTime: metav1.Time{Time: time.Now()}, + FailureMessage: "", + }, + }, + SelectorSyncSets: []hivev1alpha1.SyncStatus{ + { + Name: "selectorsyncset1", + Result: "Success", + FirstSuccessTime: &metav1.Time{Time: time.Now()}, + LastTransitionTime: metav1.Time{Time: time.Now()}, + FailureMessage: "", + }, + }, + }, + }, + expectedError: nil, + expectedGauges: []struct { + name string + value int64 + labels map[string]string + }{ + { + name: "hive.syncsets", + value: 1, + labels: map[string]string{ + "name": "syncset1", + "result": "Success", + "firstSuccessTime": time.Now().Format(time.RFC3339), + "lastTransitionTime": time.Now().Format(time.RFC3339), + "failureMessage": "", + }, + }, + { + name: "hive.selectorsyncsets", + value: 1, + labels: map[string]string{ + "name": "selectorsyncset1", + "result": "Success", + "firstSuccessTime": time.Now().Format(time.RFC3339), + "lastTransitionTime": time.Now().Format(time.RFC3339), + "failureMessage": "", + }, + }, + { + name: "hive.clustersync", + value: 1, + labels: map[string]string{ + "name": "selectorsyncset1", + "result": "Success", + "firstSuccessTime": time.Now().Format(time.RFC3339), + "lastTransitionTime": time.Now().Format(time.RFC3339), + "failureMessage": "", + }, + }, + }, + }, + { + name: "SyncSets and SelectorSyncSets are nil", + clusterSync: &hivev1alpha1.ClusterSync{ + Status: hivev1alpha1.ClusterSyncStatus{ + SyncSets: nil, + SelectorSyncSets: nil, + }, + }, + expectedError: nil, + expectedGauges: []struct { + name string + value int64 + labels map[string]string + }{ + { + name: "hive.syncsets", + value: 0, + labels: map[string]string{}, + }, + { + name: "hive.selectorsyncsets", + value: 0, + labels: map[string]string{}, + }, + { + name: "hive.clustersync", + value: 0, + labels: map[string]string{}, + }, + }, + }, + { + name: "GetClusterSyncforClusterDeployment returns error", + getClusterSyncErr: errors.New("some error"), + expectedError: nil, + expectedGauges: []struct { + name string + value int64 + labels map[string]string + }{}, + }, + } { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockHiveClusterManager := mock_hive.NewMockClusterManager(ctrl) + m := mock_metrics.NewMockEmitter(ctrl) + mockMonitor := &Monitor{ + hiveClusterManager: mockHiveClusterManager, + m: m, + } + + ctx := context.Background() + + mockHiveClusterManager.EXPECT().GetSyncSetResources(ctx, mockMonitor.doc).Return(tt.clusterSync, tt.getClusterSyncErr).AnyTimes() + + for _, gauge := range tt.expectedGauges { + m.EXPECT().EmitGauge(gauge.name, gauge.value, gauge.labels).Times(1) + } + + err := mockMonitor.emitSyncSetStatus(ctx) + assert.Equal(t, tt.expectedError, err) + }) + } +}