Skip to content

Commit

Permalink
Adding abstraction to code and enhance the codecov (#138)
Browse files Browse the repository at this point in the history
* Adding abstraction to code and enhancing the codecov

Signed-off-by: nagesh bansal <[email protected]>
  • Loading branch information
Nageshbansal authored Aug 25, 2023
1 parent 55700d7 commit 19f3788
Show file tree
Hide file tree
Showing 12 changed files with 562 additions and 58 deletions.
42 changes: 31 additions & 11 deletions controller/collect-data.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,23 @@ import (
clientTypes "k8s.io/apimachinery/pkg/types"
)

//go:generate mockgen -destination=mocks/mock_collect-data.go -package=mocks github.com/litmuschaos/chaos-exporter/controller ResultCollector

// ResultCollector interface for the both functions GetResultList and getExperimentMetricsFromResult
type ResultCollector interface {
GetResultList(clients clients.ClientSets, chaosNamespace string, monitoringEnabled *MonitoringEnabled) (litmuschaosv1alpha1.ChaosResultList, error)
GetExperimentMetricsFromResult(chaosResult *litmuschaosv1alpha1.ChaosResult, clients clients.ClientSets) (bool, error)
SetResultDetails()
GetResultDetails() ChaosResultDetails
}
type ResultDetails struct {
resultDetails ChaosResultDetails
}

// GetResultList return the result list correspond to the monitoring enabled chaosengine
func GetResultList(clients clients.ClientSets, chaosNamespace string, monitoringEnabled *MonitoringEnabled) (litmuschaosv1alpha1.ChaosResultList, error) {
func (r *ResultDetails) GetResultList(clients clients.ClientSets, chaosNamespace string, monitoringEnabled *MonitoringEnabled) (litmuschaosv1alpha1.ChaosResultList, error) {

chaosResultList, err := clients.LitmusClient.ChaosResults(chaosNamespace).List(context.Background(), metav1.ListOptions{})
chaosResultList, err := clients.LitmusClient.LitmuschaosV1alpha1().ChaosResults(chaosNamespace).List(context.Background(), metav1.ListOptions{})
if err != nil {
return litmuschaosv1alpha1.ChaosResultList{}, err
}
Expand All @@ -41,15 +54,14 @@ 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 (r *ResultDetails) GetExperimentMetricsFromResult(chaosResult *litmuschaosv1alpha1.ChaosResult, clients clients.ClientSets) (bool, error) {
verdict := strings.ToLower(string(chaosResult.Status.ExperimentStatus.Verdict))
probeSuccesPercentage, err := getProbeSuccessPercentage(chaosResult)
if err != nil {
return false, err
}

engine, err := clients.LitmusClient.ChaosEngines(chaosResult.Namespace).Get(context.Background(), chaosResult.Spec.EngineName, metav1.GetOptions{})
engine, err := clients.LitmusClient.LitmuschaosV1alpha1().ChaosEngines(chaosResult.Namespace).Get(context.Background(), chaosResult.Spec.EngineName, metav1.GetOptions{})
if err != nil {
// k8serrors.IsNotFound(err) checking k8s resource is found or not,
// It will skip this result if k8s resource is not found.
Expand All @@ -64,9 +76,8 @@ func (resultDetails *ChaosResultDetails) getExperimentMetricsFromResult(chaosRes
if err != nil {
return false, err
}

// setting all the values inside resultdetails struct
resultDetails.setName(chaosResult.Name).
r.resultDetails.setName(chaosResult.Name).
setUID(chaosResult.UID).
setNamespace(chaosResult.Namespace).
setProbeSuccessPercentage(probeSuccesPercentage).
Expand All @@ -89,19 +100,28 @@ func (resultDetails *ChaosResultDetails) getExperimentMetricsFromResult(chaosRes
// experiment's final verdict[passed,failed,stopped] is already exported/overridden
// and 'litmuschaos_experiment_verdict' metric was reset to 0
if engine.Status.EngineStatus == v1alpha1.EngineStatusCompleted {
result, ok := matchVerdict[string(resultDetails.UID)]
if !ok || (ok && result.Verdict == resultDetails.Verdict && result.VerdictReset) {
result, ok := matchVerdict[string(r.resultDetails.UID)]
if !ok || (ok && result.Verdict == r.resultDetails.Verdict && result.VerdictReset) {
return true, nil
}
}

return false, nil
}

func (r *ResultDetails) SetResultDetails() {
r.resultDetails.PassedExperiments = 0
r.resultDetails.AwaitedExperiments = 0
r.resultDetails.FailedExperiments = 0
}

func (r *ResultDetails) GetResultDetails() ChaosResultDetails {
return r.resultDetails
}

// initialiseResult create the new instance of the ChaosResultDetails struct
func initialiseResult() *ChaosResultDetails {
return &ChaosResultDetails{}

}

// setName sets name inside resultDetails struct
Expand Down
187 changes: 187 additions & 0 deletions controller/collect-data_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
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"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/fake"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
"testing"
)

func TestGetResultList(t *testing.T) {
FakeChaosNameSpace := "Fake Namespace"
FakeEngineName := "Fake Engine"

tests := []struct {
name string
execFunc func(client clients.ClientSets, chaosResult *v1alpha1.ChaosResult)
chaosResult *v1alpha1.ChaosResult
monitoring *controller.MonitoringEnabled
isErr bool
}{
{
name: "success:chaos result found",
execFunc: func(client clients.ClientSets, chaosResult *v1alpha1.ChaosResult) {
_, err := client.LitmusClient.LitmuschaosV1alpha1().ChaosResults(chaosResult.Namespace).Create(context.Background(), chaosResult, metav1.CreateOptions{})
if err != nil {
t.Fatalf("chaosresult not created")
}
},

chaosResult: &v1alpha1.ChaosResult{
ObjectMeta: metav1.ObjectMeta{
Name: FakeEngineName,
Namespace: FakeChaosNameSpace,
},
Spec: v1alpha1.ChaosResultSpec{
ExperimentName: "exp-1",
EngineName: FakeEngineName,
},
},

isErr: false,
monitoring: &controller.MonitoringEnabled{
IsChaosResultsAvailable: true,
},
},
{
name: "success:empty chaosResult",
chaosResult: &v1alpha1.ChaosResult{},
execFunc: func(client clients.ClientSets, chaosResult *v1alpha1.ChaosResult) {},
isErr: false,
monitoring: &controller.MonitoringEnabled{
IsChaosResultsAvailable: true,
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := CreateFakeClient(t)
tt.execFunc(client, tt.chaosResult)
resultDetails := &controller.ResultDetails{}
_, err := resultDetails.GetResultList(client, FakeChaosNameSpace, tt.monitoring)
if tt.isErr {
require.Error(t, err)
return
}
require.NoError(t, err)
})
}
}

func TestGetExperimentMetricsFromResult(t *testing.T) {
FakeEngineName := "Fake Engine"
FakeNamespace := "Fake Namespace"
fakeServiceAcc := "Fake Service Account"
fakeAppLabel := "Fake Label"
fakeAppKind := "Fake Kind"

tests := map[string]struct {
chaosengine *v1alpha1.ChaosEngine
chaosresult *v1alpha1.ChaosResult
expectedVerdict bool
isErr bool
verdict bool
execFunc func(client clients.ClientSets, engine *v1alpha1.ChaosEngine, result *v1alpha1.ChaosResult)
}{
"success": {
chaosengine: &v1alpha1.ChaosEngine{
ObjectMeta: metav1.ObjectMeta{
Name: FakeEngineName,
Namespace: FakeNamespace,
},
Spec: v1alpha1.ChaosEngineSpec{
ChaosServiceAccount: fakeServiceAcc,
Appinfo: v1alpha1.ApplicationParams{
Appns: FakeNamespace,
Applabel: fakeAppLabel,
AppKind: fakeAppKind,
},
Experiments: []v1alpha1.ExperimentList{
{
Name: "Fake-Exp-Name",
},
},
},
Status: v1alpha1.ChaosEngineStatus{
EngineStatus: v1alpha1.EngineStatusCompleted,
Experiments: []v1alpha1.ExperimentStatuses{
{
Name: "Fake-Exp-Name",
Status: v1alpha1.ExperimentStatusRunning,
},
},
},
},
chaosresult: &v1alpha1.ChaosResult{
ObjectMeta: metav1.ObjectMeta{
Name: FakeEngineName + "-" + "Fake-Exp-Name",
Namespace: FakeNamespace,
UID: "Fake-UID",
},
Spec: v1alpha1.ChaosResultSpec{
EngineName: FakeEngineName,
ExperimentName: "Fake-Exp-Name",
},
Status: v1alpha1.ChaosResultStatus{
ExperimentStatus: v1alpha1.TestStatus{
Phase: "Completed",
Verdict: "Pass",
},
History: &v1alpha1.HistoryDetails{},
},
},

execFunc: func(client clients.ClientSets, engine *v1alpha1.ChaosEngine, result *v1alpha1.ChaosResult) {
_, err := client.LitmusClient.LitmuschaosV1alpha1().ChaosEngines(engine.Namespace).Create(context.Background(), engine, metav1.CreateOptions{})
if err != nil {
t.Fatalf("engine not created for test, err: %v", err)
}

_, err = client.LitmusClient.LitmuschaosV1alpha1().ChaosResults(result.Namespace).Create(context.Background(), result, metav1.CreateOptions{})
if err != nil {
t.Fatalf("chaosresult not created fortest, err: %v", err)
}
},
isErr: false,
verdict: true,
},
"failure: No Chaos Engine": {
chaosresult: &v1alpha1.ChaosResult{},
isErr: false,
verdict: true,
execFunc: func(client clients.ClientSets, engine *v1alpha1.ChaosEngine, result *v1alpha1.ChaosResult) {
},
},
}

for name, tt := range tests {
t.Run(name, func(t *testing.T) {
client := CreateFakeClient(t)
resultDetails := controller.ResultDetails{}
tt.execFunc(client, tt.chaosengine, tt.chaosresult)
verdict, err := resultDetails.GetExperimentMetricsFromResult(tt.chaosresult, client)
assert.Equal(t, tt.verdict, verdict)
if tt.isErr {
require.Error(t, err)
return
}
require.NoError(t, err)
})
}
}

func CreateFakeClient(t *testing.T) clients.ClientSets {
cs := clients.ClientSets{}
cs.KubeClient = fake.NewSimpleClientset([]runtime.Object{}...)
cs.LitmusClient = litmusFakeClientSet.NewSimpleClientset([]runtime.Object{}...)
return cs
}
9 changes: 6 additions & 3 deletions controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@ func Exporter(clients clients.ClientSets) {
// Register the fixed (count) chaos metrics
log.Info("Registering Fixed Metrics")

gaugeMetrics := GaugeMetrics{}
r := MetricesCollecter{
ResultCollector: &ResultDetails{},
}
//gaugeMetrics := GaugeMetrics{}
overallChaosResults := litmuschaosv1alpha1.ChaosResultList{}

gaugeMetrics.InitializeGaugeMetrics().
r.GaugeMetrics.InitializeGaugeMetrics().
RegisterFixedMetrics()

monitoringEnabled := MonitoringEnabled{
Expand All @@ -43,7 +46,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)
Expand Down
Loading

0 comments on commit 19f3788

Please sign in to comment.