diff --git a/controller/collect-data.go b/controller/collect-data.go index 1a09a15..c5df7dc 100644 --- a/controller/collect-data.go +++ b/controller/collect-data.go @@ -16,10 +16,12 @@ import ( clientTypes "k8s.io/apimachinery/pkg/types" ) -// interface for the both functions GetResultList and getExperimentMetricsFromResult for being dependent on the clientsets +//go:generate mockgen -destination=mocks/mock_collect-data.go -package=mocks github.com/litmuschaos/chaos-exporter/controller CollectResult + +// CollectResult interface for the both functions GetResultList and getExperimentMetricsFromResult type CollectResult interface { - GetResultList(chaosNamespace string, monitoringEnabled *MonitoringEnabled) (litmuschaosv1alpha1.ChaosResultList, error) - getExperimentMetricsFromResult(chaosResult *litmuschaosv1alpha1.ChaosResult, clients clients.ClientSets) (bool, error) + GetResultList(clients clients.ClientSets, chaosNamespace string, monitoringEnabled *MonitoringEnabled) (litmuschaosv1alpha1.ChaosResultList, error) + GetExperimentMetricsFromResult(chaosResult *litmuschaosv1alpha1.ChaosResult, clients clients.ClientSets) (bool, error) } // GetResultList return the result list correspond to the monitoring enabled chaosengine @@ -47,8 +49,8 @@ func GetResultList(clients clients.ClientSets, chaosNamespace string, monitoring return *chaosResultList, nil } -// getExperimentMetricsFromResult derive all the metrics data from the chaosresult and set into resultDetails struct -func (resultDetails *ChaosResultDetails) getExperimentMetricsFromResult(chaosResult *litmuschaosv1alpha1.ChaosResult, clients clients.ClientSets) (bool, error) { +// GetExperimentMetricsFromResult derive all the metrics data from the chaosresult and set into resultDetails struct +func (resultDetails *ChaosResultDetails) GetExperimentMetricsFromResult(chaosResult *litmuschaosv1alpha1.ChaosResult, clients clients.ClientSets) (bool, error) { verdict := strings.ToLower(string(chaosResult.Status.ExperimentStatus.Verdict)) probeSuccesPercentage, err := getProbeSuccessPercentage(chaosResult) if err != nil { diff --git a/controller/controller.go b/controller/controller.go index 0c58103..d9863b2 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -31,10 +31,11 @@ func Exporter(clients clients.ClientSets) { // Register the fixed (count) chaos metrics log.Info("Registering Fixed Metrics") - gaugeMetrics := GaugeMetrics{} + r := ResultDetails{} + //gaugeMetrics := GaugeMetrics{} overallChaosResults := litmuschaosv1alpha1.ChaosResultList{} - gaugeMetrics.InitializeGaugeMetrics(). + r.GaugeMetrics.InitializeGaugeMetrics(). RegisterFixedMetrics() monitoringEnabled := MonitoringEnabled{ @@ -43,7 +44,7 @@ func Exporter(clients clients.ClientSets) { } for { - if err := gaugeMetrics.GetLitmusChaosMetrics(clients, &overallChaosResults, &monitoringEnabled); err != nil { + if err := r.GetLitmusChaosMetrics(clients, &overallChaosResults, &monitoringEnabled); err != nil { log.Errorf("err: %v", err) } time.Sleep(1000 * time.Millisecond) diff --git a/controller/mocks/mock_collect-data.go b/controller/mocks/mock_collect-data.go new file mode 100644 index 0000000..40ad581 --- /dev/null +++ b/controller/mocks/mock_collect-data.go @@ -0,0 +1,67 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/litmuschaos/chaos-exporter/controller (interfaces: CollectResult) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + controller "github.com/litmuschaos/chaos-exporter/controller" + clients "github.com/litmuschaos/chaos-exporter/pkg/clients" + v1alpha1 "github.com/litmuschaos/chaos-operator/api/litmuschaos/v1alpha1" +) + +// MockCollectResult is a mock of CollectResult interface. +type MockCollectResult struct { + ctrl *gomock.Controller + recorder *MockCollectResultMockRecorder +} + +// MockCollectResultMockRecorder is the mock recorder for MockCollectResult. +type MockCollectResultMockRecorder struct { + mock *MockCollectResult +} + +// NewMockCollectResult creates a new mock instance. +func NewMockCollectResult(ctrl *gomock.Controller) *MockCollectResult { + mock := &MockCollectResult{ctrl: ctrl} + mock.recorder = &MockCollectResultMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCollectResult) EXPECT() *MockCollectResultMockRecorder { + return m.recorder +} + +// GetExperimentMetricsFromResult mocks base method. +func (m *MockCollectResult) GetExperimentMetricsFromResult(arg0 *v1alpha1.ChaosResult, arg1 clients.ClientSets) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetExperimentMetricsFromResult", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetExperimentMetricsFromResult indicates an expected call of GetExperimentMetricsFromResult. +func (mr *MockCollectResultMockRecorder) GetExperimentMetricsFromResult(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExperimentMetricsFromResult", reflect.TypeOf((*MockCollectResult)(nil).GetExperimentMetricsFromResult), arg0, arg1) +} + +// GetResultList mocks base method. +func (m *MockCollectResult) GetResultList(arg0 clients.ClientSets, arg1 string, arg2 *controller.MonitoringEnabled) (v1alpha1.ChaosResultList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetResultList", arg0, arg1, arg2) + ret0, _ := ret[0].(v1alpha1.ChaosResultList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetResultList indicates an expected call of GetResultList. +func (mr *MockCollectResultMockRecorder) GetResultList(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetResultList", reflect.TypeOf((*MockCollectResult)(nil).GetResultList), arg0, arg1, arg2) +} diff --git a/controller/scrap_test.go b/controller/scrap_test.go deleted file mode 100644 index 79255af..0000000 --- a/controller/scrap_test.go +++ /dev/null @@ -1,71 +0,0 @@ -package controller - -import ( - "fmt" - "github.com/litmuschaos/chaos-exporter/pkg/clients" - v1alpha1 "github.com/litmuschaos/chaos-operator/api/litmuschaos/v1alpha1" - "github.com/stretchr/testify/mock" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "testing" -) - -type MockResult struct { - mock.Mock -} - -func (m *MockResult) GetResultList(clients clients.ClientSets, chaosNamespace string, monitoringEnabled *MonitoringEnabled) (litmuschaosv1alpha1.ChaosResultList, error) { - args := m.Called(clients, chaosNamespace, monitoringEnabled) - return args.Get(0).(v1alpha1.ChaosResultList), args.Error(1) -} - -func (m *MockResult) getExperimentDetails(clients clients.ClientSets, chaosNamespace string, chaosName string) (v1alpha1.ChaosExperiment, error) { - args := m.Called(clients, chaosNamespace, chaosName) - return args.Get(0).(v1alpha1.ChaosExperiment), args.Error(1) -} - -var mockResult = new(MockResult) - -func TestGetLitmusChaosMetrics(t *testing.T) { - - //mockCollectData := mock_controller.NewMockcollect_data(gomock.NewController(t)) - //mockCollectData.EXPECT().GetResultList(gomock.Any(), gomock.Any(), gomock.Any()).Return(v1alpha1.ChaosResultList{ - // Items: []v1alpha1.ChaosResult{ - // { - // ObjectMeta: metav1.ObjectMeta{ - // Name: "chaosresult-1", - // }, - // }, - // }, - //}, nil) - - tests := []struct { - name string - execFunc func() - }{ - { - name: "Test Positive-1", - execFunc: func() { - mockResult.On("GetResultList", mock.Anything, mock.Anything).Return(v1alpha1.ChaosResultList{ - Items: []v1alpha1.ChaosResult{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "chaosresult-1", - }, - }, - }, - }, nil).Once() - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tt.execFunc() - client := CreateFakeClient(t) - gaugeMetrics := &GaugeMetrics{} - overallChaosresult := &v1alpha1.ChaosResultList{} - err := gaugeMetrics.GetLitmusChaosMetrics(client, overallChaosresult, &MonitoringEnabled{}) - fmt.Print(err) - }) - } - -} diff --git a/controller/scrape.go b/controller/scrape.go index b1da15d..21d1494 100644 --- a/controller/scrape.go +++ b/controller/scrape.go @@ -34,7 +34,7 @@ import ( var err error // GetLitmusChaosMetrics derive and send the chaos metrics -func (gaugeMetrics *GaugeMetrics) GetLitmusChaosMetrics(clients clients.ClientSets, overallChaosResults *litmuschaosv1alpha1.ChaosResultList, monitoringEnabled *MonitoringEnabled) error { +func (r *ResultDetails) GetLitmusChaosMetrics(clients clients.ClientSets, overallChaosResults *litmuschaosv1alpha1.ChaosResultList, monitoringEnabled *MonitoringEnabled) error { engineCount := 0 // initialising the parameters for the namespaced scope metrics @@ -53,13 +53,13 @@ func (gaugeMetrics *GaugeMetrics) GetLitmusChaosMetrics(clients clients.ClientSe } watchNamespace := os.Getenv("WATCH_NAMESPACE") // Getting list of all the chaosresults for the monitoring - resultList, err := GetResultList(clients, watchNamespace, monitoringEnabled) + resultList, err := r.CollectResult.GetResultList(clients, watchNamespace, monitoringEnabled) if err != nil { return err } // unset the metrics correspond to deleted chaosresults - gaugeMetrics.unsetDeletedChaosResults(overallChaosResults, &resultList) + r.GaugeMetrics.unsetDeletedChaosResults(overallChaosResults, &resultList) // updating the overall chaosresults items to latest overallChaosResults.Items = resultList.Items @@ -75,7 +75,7 @@ func (gaugeMetrics *GaugeMetrics) GetLitmusChaosMetrics(clients clients.ClientSe } // deriving metrics data from the chaosresult - skip, err := resultDetails.getExperimentMetricsFromResult(&chaosresult, clients) + skip, err := r.CollectResult.GetExperimentMetricsFromResult(&chaosresult, clients) if err != nil { return err } @@ -110,8 +110,8 @@ func (gaugeMetrics *GaugeMetrics) GetLitmusChaosMetrics(clients clients.ClientSe }) // setting chaosresult metrics for the given chaosresult - verdictValue := gaugeMetrics.unsetOutdatedMetrics(resultDetails) - gaugeMetrics.setResultChaosMetrics(resultDetails, verdictValue) + verdictValue := r.GaugeMetrics.unsetOutdatedMetrics(resultDetails) + r.GaugeMetrics.setResultChaosMetrics(resultDetails, verdictValue) // setting chaosresult aws metrics for the given chaosresult, which can be used for cloudwatch if awsConfig.Namespace != "" && awsConfig.ClusterName != "" && awsConfig.Service != "" { awsConfig.setAwsResultChaosMetrics(resultDetails) @@ -128,7 +128,7 @@ func (gaugeMetrics *GaugeMetrics) GetLitmusChaosMetrics(clients clients.ClientSe } //setting aggregate metrics from the all chaosresults - gaugeMetrics.setNamespacedChaosMetrics(namespacedScopeMetrics, watchNamespace) + r.GaugeMetrics.setNamespacedChaosMetrics(namespacedScopeMetrics, watchNamespace) //setting aggregate aws metrics from the all chaosresults, which can be used for cloudwatch if awsConfig.Namespace != "" && awsConfig.ClusterName != "" && awsConfig.Service != "" { awsConfig.setAwsNamespacedChaosMetrics(namespacedScopeMetrics) diff --git a/controller/types.go b/controller/types.go index 3019164..f9e0d4b 100644 --- a/controller/types.go +++ b/controller/types.go @@ -280,6 +280,10 @@ type GaugeMetrics struct { ClusterScopedExperimentsInstalledCount *prometheus.GaugeVec ClusterScopedExperimentsRunCount *prometheus.GaugeVec } +type ResultDetails struct { + CollectResult CollectResult + GaugeMetrics GaugeMetrics +} // MonitoringEnabled contains existence/availability of chaosEngines and chaosResults type MonitoringEnabled struct { diff --git a/controller/collect-data_test.go b/tests/controller_test/collect-data_test.go similarity index 84% rename from controller/collect-data_test.go rename to tests/controller_test/collect-data_test.go index 417b950..2c8ce17 100644 --- a/controller/collect-data_test.go +++ b/tests/controller_test/collect-data_test.go @@ -1,7 +1,8 @@ -package controller +package controller_test import ( "context" + "github.com/litmuschaos/chaos-exporter/controller" "github.com/litmuschaos/chaos-exporter/pkg/clients" "github.com/litmuschaos/chaos-operator/api/litmuschaos/v1alpha1" litmusFakeClientSet "github.com/litmuschaos/chaos-operator/pkg/client/clientset/versioned/fake" @@ -18,7 +19,7 @@ func TestGetResultList(t *testing.T) { tests := map[string]struct { chaosresult *v1alpha1.ChaosResult - monitoring *MonitoringEnabled + monitoring *controller.MonitoringEnabled isErr bool }{ "Test Positive-1": { @@ -33,37 +34,36 @@ func TestGetResultList(t *testing.T) { }, }, isErr: false, - monitoring: &MonitoringEnabled{ + monitoring: &controller.MonitoringEnabled{ IsChaosResultsAvailable: true, }, }, "Test Negative-1": { chaosresult: &v1alpha1.ChaosResult{}, isErr: true, - monitoring: &MonitoringEnabled{ + monitoring: &controller.MonitoringEnabled{ IsChaosResultsAvailable: true, }, }, "Test Negative-2": { isErr: true, - monitoring: &MonitoringEnabled{}, + monitoring: &controller.MonitoringEnabled{}, }, } for name, mock := range tests { t.Run(name, func(t *testing.T) { - client := CreateFakeClient(t) if !mock.isErr { - _, err = client.LitmusClient.LitmuschaosV1alpha1().ChaosResults(mock.chaosresult.Namespace).Create(context.Background(), mock.chaosresult, metav1.CreateOptions{}) + _, err := client.LitmusClient.LitmuschaosV1alpha1().ChaosResults(mock.chaosresult.Namespace).Create(context.Background(), mock.chaosresult, metav1.CreateOptions{}) if err != nil { t.Fatalf("chaosresult not created for %v test, err: %v", name, err) } } - _, err = GetResultList(client, FakeChaosNameSpace, mock.monitoring) - //if !mock.isErr && err != nil && mock.chaosresultlist != resultList { - // t.Fatalf("test Failed as not able to get the Chaos result list") - //} + _, err := controller.GetResultList(client, FakeChaosNameSpace, mock.monitoring) + if !mock.isErr && err != nil { + t.Fatalf("test Failed as not able to get the Chaos result list") + } }) } @@ -141,7 +141,7 @@ func TestGetExperimentMetricsFromResult(t *testing.T) { t.Run(name, func(t *testing.T) { client := CreateFakeClient(t) - resultDetails := &ChaosResultDetails{} + resultDetails := &controller.ChaosResultDetails{} if !mock.isErr { _, err := client.LitmusClient.LitmuschaosV1alpha1().ChaosEngines(mock.chaosengine.Namespace).Create(context.Background(), mock.chaosengine, metav1.CreateOptions{}) if err != nil { @@ -153,7 +153,8 @@ func TestGetExperimentMetricsFromResult(t *testing.T) { t.Fatalf("chaosresult not created for %v test, err: %v", name, err) } } - _, err = resultDetails.getExperimentMetricsFromResult(mock.chaosresult, client) + var err error + _, err = resultDetails.GetExperimentMetricsFromResult(mock.chaosresult, client) if !mock.isErr && err != nil { t.Fatalf("Test %q failed: expected error to be nil", name) } diff --git a/tests/controller_test/scrap_test.go b/tests/controller_test/scrap_test.go new file mode 100644 index 0000000..f369ec0 --- /dev/null +++ b/tests/controller_test/scrap_test.go @@ -0,0 +1,107 @@ +package controller_test + +import ( + "context" + "fmt" + "github.com/golang/mock/gomock" + "github.com/litmuschaos/chaos-exporter/controller" + "github.com/litmuschaos/chaos-exporter/controller/mocks" + v1alpha1 "github.com/litmuschaos/chaos-operator/api/litmuschaos/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "os" + "testing" +) + +func TestGetLitmusChaosMetrics(t *testing.T) { + mockCtl := gomock.NewController(t) + defer mockCtl.Finish() + mockCollectData := mocks.NewMockCollectResult(mockCtl) + + FakeEngineName := "Fake Engine" + FakeNamespace := "Fake Namespace" + fakeServiceAcc := "Fake Service Account" + fakeAppLabel := "Fake Label" + fakeAppKind := "Fake Kind" + //FakeCluster_NAME := "Fake Cluster" + + tests := []struct { + name string + execFunc func() + chaosengine *v1alpha1.ChaosEngine + chaosresult *v1alpha1.ChaosResult + isErr bool + monitoring *controller.MonitoringEnabled + overallChaosResult *v1alpha1.ChaosResultList + }{ + { + name: "Test Positive-1", + execFunc: func() { + mockCollectData.EXPECT().GetResultList(gomock.Any(), gomock.Any(), gomock.Any()). + Return(v1alpha1.ChaosResultList{ + Items: []v1alpha1.ChaosResult{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "chaosresult-1", + }, + }, + }, + }, nil).Times(1) + mockCollectData.EXPECT().GetExperimentMetricsFromResult(gomock.Any(), gomock.Any()).Return(false, nil).Times(1) + }, + chaosengine: &v1alpha1.ChaosEngine{ + ObjectMeta: metav1.ObjectMeta{ + Name: FakeEngineName, + Namespace: FakeNamespace, + }, + Spec: v1alpha1.ChaosEngineSpec{ + ChaosServiceAccount: fakeServiceAcc, + Appinfo: v1alpha1.ApplicationParams{ + Appns: FakeNamespace, + Applabel: fakeAppLabel, + AppKind: fakeAppKind, + }, + }, + Status: v1alpha1.ChaosEngineStatus{ + EngineStatus: v1alpha1.EngineStatusStopped, + }, + }, + overallChaosResult: &v1alpha1.ChaosResultList{ + Items: []v1alpha1.ChaosResult{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "chaosresult-1", + }, + }, + }, + }, + monitoring: &controller.MonitoringEnabled{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.execFunc() + + os.Setenv("AWS_CLOUDWATCH_METRIC_NAMESPACE", "") + os.Setenv("CLUSTER_NAME", "") + os.Setenv("APP_NAME", "") + os.Setenv("WATCH_NAMESPACE", FakeNamespace) + + client := CreateFakeClient(t) + r := controller.ResultDetails{ + CollectResult: mockCollectData, + } + + if !tt.isErr { + _, err := client.LitmusClient.LitmuschaosV1alpha1().ChaosEngines(tt.chaosengine.Namespace).Create(context.Background(), tt.chaosengine, metav1.CreateOptions{}) + if err != nil { + t.Fatalf("engine not created for %v test, err: %v", tt.name, err) + } + + } + r.GaugeMetrics.InitializeGaugeMetrics().RegisterFixedMetrics() + err := r.GetLitmusChaosMetrics(client, tt.overallChaosResult, tt.monitoring) + fmt.Print(err) + }) + } + +}