Skip to content

Commit

Permalink
add fuzz test in chaos_experiment_run (litmuschaos#4834)
Browse files Browse the repository at this point in the history
* add handler_fuzz_test file

Signed-off-by: weeeeestern <[email protected]>

* add service_fuzz_test file

Signed-off-by: weeeeestern <[email protected]>

* test: add fuzz test

Signed-off-by: weeeeestern <[email protected]>

* test: add fuzz_test

Signed-off-by: weeeeestern <[email protected]>

* test: modify fuzz-test

Signed-off-by: weeeeestern <[email protected]>

* test: modify fuzz-test

Signed-off-by: weeeeestern <[email protected]>

---------

Signed-off-by: weeeeestern <[email protected]>
Co-authored-by: Namkyu Park <[email protected]>
Co-authored-by: Saranya Jena <[email protected]>
  • Loading branch information
3 people authored Sep 6, 2024
1 parent 4873194 commit 2bdec7e
Show file tree
Hide file tree
Showing 2 changed files with 387 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package fuzz_tests

import (
"context"
"testing"

"github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/chaos_experiment_run"
dbChaosExperiment "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/database/mongodb/chaos_experiment"
dbChaosExperimentRun "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/database/mongodb/chaos_experiment_run"
dbChaosInfra "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/database/mongodb/chaos_infrastructure"
dbMocks "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/database/mongodb/mocks"

fuzz "github.com/AdaLogics/go-fuzz-headers"
store "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/data-store"
"github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/database/mongodb"
"github.com/stretchr/testify/mock"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)

type MockServices struct {
ChaosExperimentOperator *dbChaosExperiment.Operator
ChaosExperimentRunOperator *dbChaosExperimentRun.Operator
ChaosInfrastructureOperator *dbChaosInfra.Operator
MongodbOperator *dbMocks.MongoOperator
ChaosExperimentRunService chaos_experiment_run.Service
}

func NewMockServices() *MockServices {
var (
mongodbMockOperator = new(dbMocks.MongoOperator)
chaosExperimentOperator = dbChaosExperiment.NewChaosExperimentOperator(mongodbMockOperator)
chaosExperimentRunOperator = dbChaosExperimentRun.NewChaosExperimentRunOperator(mongodbMockOperator)
chaosInfrastructureOperator = dbChaosInfra.NewInfrastructureOperator(mongodbMockOperator)
chaosExperimentRunService chaos_experiment_run.Service = chaos_experiment_run.NewChaosExperimentRunService(
chaosExperimentOperator,
chaosInfrastructureOperator,
chaosExperimentRunOperator,
)
)
return &MockServices{
ChaosExperimentOperator: chaosExperimentOperator,
ChaosExperimentRunOperator: chaosExperimentRunOperator,
ChaosInfrastructureOperator: chaosInfrastructureOperator,
MongodbOperator: mongodbMockOperator,
ChaosExperimentRunService: chaosExperimentRunService,
}
}

func FuzzProcessExperimentRunDelete(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzConsumer := fuzz.NewConsumer(data)
targetStruct := &struct {
Query bson.D
WorkflowRunID *string
ExperimentRun dbChaosExperimentRun.ChaosExperimentRun
Workflow dbChaosExperiment.ChaosExperimentRequest
Username string
StoreStateData *store.StateData
}{}
err := fuzzConsumer.GenerateStruct(targetStruct)
if err != nil {
return
}
mockServices := NewMockServices()
mockServices.MongodbOperator.On("Update", mock.Anything, mongodb.ChaosExperimentRunsCollection, mock.Anything, mock.Anything, mock.Anything).Return(&mongo.UpdateResult{}, nil).Once()

err = mockServices.ChaosExperimentRunService.ProcessExperimentRunDelete(
context.Background(),
targetStruct.Query,
targetStruct.WorkflowRunID,
targetStruct.ExperimentRun,
targetStruct.Workflow,
targetStruct.Username,
targetStruct.StoreStateData,
)
if err != nil {
t.Errorf("ProcessExperimentRunDelete() error = %v", err)
}
})
}

func FuzzProcessExperimentRunStop(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzConsumer := fuzz.NewConsumer(data)
targetStruct := &struct {
Query bson.D
ExperimentRunID *string
Experiment dbChaosExperiment.ChaosExperimentRequest
Username string
ProjectID string
StoreStateData *store.StateData
}{}
err := fuzzConsumer.GenerateStruct(targetStruct)
if err != nil {
return
}

mockServices := NewMockServices()
mockServices.MongodbOperator.On("Update", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&mongo.UpdateResult{}, nil).Once()
err = mockServices.ChaosExperimentRunService.ProcessExperimentRunStop(
context.Background(),
targetStruct.Query,
targetStruct.ExperimentRunID,
targetStruct.Experiment,
targetStruct.Username,
targetStruct.ProjectID,
targetStruct.StoreStateData,
)
if err != nil {
t.Errorf("ProcessExperimentRunStop() error = %v", err)
}
})
}

func FuzzProcessCompletedExperimentRun(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzConsumer := fuzz.NewConsumer(data)
targetStruct := &struct {
ExecData chaos_experiment_run.ExecutionData
WfID string
RunID string
}{}
err := fuzzConsumer.GenerateStruct(targetStruct)
if err != nil {
return
}

findResult := []interface{}{bson.D{
{Key: "experiment_id", Value: targetStruct.WfID},
}}
mockServices := NewMockServices()
singleResult := mongo.NewSingleResultFromDocument(findResult[0], nil, nil)
mockServices.MongodbOperator.On("Get", mock.Anything, mock.Anything, mock.Anything).Return(singleResult, nil).Once()

_, err = mockServices.ChaosExperimentRunService.ProcessCompletedExperimentRun(
targetStruct.ExecData,
targetStruct.WfID,
targetStruct.RunID,
)
if err != nil {
t.Errorf("ProcessCompletedExperimentRun() error = %v", err)
}
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
package fuzz_tests

import (
"context"
"strings"
"testing"
"time"

"github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/chaos_experiment_run/handler"
chaosInfraMocks "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/chaos_infrastructure/model/mocks"
dbChaosExperiment "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/database/mongodb/chaos_experiment"
dbChaosExperimentRun "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/database/mongodb/chaos_experiment_run"
dbMocks "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/database/mongodb/mocks"
dbGitOpsMocks "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/gitops/model/mocks"

fuzz "github.com/AdaLogics/go-fuzz-headers"

"github.com/google/uuid"
"github.com/litmuschaos/litmus/chaoscenter/graphql/server/graph/model"
typesMocks "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/chaos_experiment_run/model/mocks"
"github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/database/mongodb"
"github.com/stretchr/testify/mock"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)

type MockServices struct {
ChaosExperimentRunService *typesMocks.ChaosExperimentRunService
InfrastructureService *chaosInfraMocks.InfraService
GitOpsService *dbGitOpsMocks.GitOpsService
ChaosExperimentOperator *dbChaosExperiment.Operator
ChaosExperimentRunOperator *dbChaosExperimentRun.Operator
MongodbOperator *dbMocks.MongoOperator
ChaosExperimentRunHandler *handler.ChaosExperimentRunHandler
}

func NewMockServices() *MockServices {
var (
mongodbMockOperator = new(dbMocks.MongoOperator)
infrastructureService = new(chaosInfraMocks.InfraService)
gitOpsService = new(dbGitOpsMocks.GitOpsService)
chaosExperimentRunService = new(typesMocks.ChaosExperimentRunService)
chaosExperimentOperator = dbChaosExperiment.NewChaosExperimentOperator(mongodbMockOperator)
chaosExperimentRunOperator = dbChaosExperimentRun.NewChaosExperimentRunOperator(mongodbMockOperator)
)
var chaosExperimentRunHandler = handler.NewChaosExperimentRunHandler(
chaosExperimentRunService,
infrastructureService,
gitOpsService,
chaosExperimentOperator,
chaosExperimentRunOperator,
mongodbMockOperator,
)
return &MockServices{
ChaosExperimentRunService: chaosExperimentRunService,
InfrastructureService: infrastructureService,
GitOpsService: gitOpsService,
ChaosExperimentOperator: chaosExperimentOperator,
ChaosExperimentRunOperator: chaosExperimentRunOperator,
MongodbOperator: mongodbMockOperator,
ChaosExperimentRunHandler: chaosExperimentRunHandler,
}
}

func FuzzGetExperimentRun(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzConsumer := fuzz.NewConsumer(data)
targetStruct := &struct {
ProjectID string
ExperimentRunID string
NotifyID string
}{}

targetStruct.ProjectID = uuid.New().String()

err := fuzzConsumer.GenerateStruct(targetStruct)
if err != nil {
return
}

ctx := context.Background()
mockServices := NewMockServices()
findResult := []interface{}{bson.D{
{Key: "experiment_run_id", Value: targetStruct.ExperimentRunID},
{Key: "project_id", Value: targetStruct.ProjectID},
{Key: "infra_id", Value: "mockInfraID"},
{Key: "kubernetesInfraDetails", Value: bson.A{
bson.D{
{Key: "InfraID", Value: "mockInfraID"},
{Key: "Name", Value: "MockInfra"},
{Key: "EnvironmentID", Value: "mockEnvID"},
{Key: "Description", Value: "Mock Infrastructure"},
{Key: "PlatformName", Value: "Kubernetes"},
{Key: "IsActive", Value: true},
{Key: "UpdatedAt", Value: time.Now().Unix()},
{Key: "CreatedAt", Value: time.Now().Unix()},
},
}},
{Key: "experiment", Value: bson.A{
bson.D{
{Key: "ExperimentName", Value: "MockExperiment"},
{Key: "ExperimentType", Value: "MockType"},
{Key: "Revision", Value: bson.A{
bson.D{
{Key: "RevisionID", Value: uuid.NewString()},
{Key: "ExperimentManifest", Value: "mockManifest"},
{Key: "Weightages", Value: bson.A{
bson.D{{Key: "FaultName", Value: "fault1"}, {Key: "Weightage", Value: 10}},
bson.D{{Key: "FaultName", Value: "fault2"}, {Key: "Weightage", Value: 20}},
}},
},
}},
},
}},
}}

cursor, _ := mongo.NewCursorFromDocuments(findResult, nil, nil)
mockServices.MongodbOperator.On("Aggregate", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(cursor, nil).Once()

res, err := mockServices.ChaosExperimentRunHandler.GetExperimentRun(ctx, targetStruct.ProjectID, &targetStruct.ExperimentRunID, &targetStruct.NotifyID)
if err != nil {
t.Errorf("ChaosExperimentRunHandler.GetExperimentRun() error = %v", err)
return
}
if res == nil {
t.Errorf("Returned response is nil")
}
})
}

func FuzzListExperimentRun(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzConsumer := fuzz.NewConsumer(data)
targetStruct := &struct {
ProjectID string
Request model.ListExperimentRunRequest
}{}
err := fuzzConsumer.GenerateStruct(targetStruct)
if err != nil {
return
}

mockServices := NewMockServices()
findResult := []interface{}{bson.D{
{Key: "project_id", Value: targetStruct.ProjectID},
{Key: "infra_id", Value: "abc"},
{
Key: "revision", Value: []dbChaosExperiment.ExperimentRevision{
{
RevisionID: uuid.NewString(),
},
},
},
}}
cursor, _ := mongo.NewCursorFromDocuments(findResult, nil, nil)
mockServices.MongodbOperator.On("Aggregate", mock.Anything, mongodb.ChaosExperimentRunsCollection, mock.Anything, mock.Anything).Return(cursor, nil).Once()

res, err := mockServices.ChaosExperimentRunHandler.ListExperimentRun(targetStruct.ProjectID, targetStruct.Request)
if err != nil {
t.Errorf("ListExperimentRun() error = %v", err)
return
}
if res == nil {
t.Errorf("Returned response is nil")
}

})
}

func FuzzRunChaosWorkFlow(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzConsumer := fuzz.NewConsumer(data)
targetStruct := &struct {
ProjectID string
Workflow dbChaosExperiment.ChaosExperimentRequest
}{}
err := fuzzConsumer.GenerateStruct(targetStruct)
if err != nil {
return
}

mockServices := NewMockServices()
mockServices.MongodbOperator.On("StartSession").Return(mock.Anything, nil).Once()
mockServices.MongodbOperator.On("Update", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&mongo.UpdateResult{}, nil).Once()
mockServices.MongodbOperator.On("CommitTransaction", mock.Anything).Return(nil).Once()
mockServices.MongodbOperator.On("AbortTransaction", mock.Anything).Return(nil).Once()

findResult := []interface{}{bson.D{
{Key: "infra_id", Value: targetStruct.ProjectID},
}}
singleResult := mongo.NewSingleResultFromDocument(findResult[0], nil, nil)
mockServices.MongodbOperator.On("Get", mock.Anything, mock.Anything, mock.Anything).Return(singleResult, nil).Once()

res, err := mockServices.ChaosExperimentRunHandler.RunChaosWorkFlow(context.Background(), targetStruct.ProjectID, targetStruct.Workflow, nil)
if strings.Contains(err.Error(), "inactive infra") {
t.Log("Handled expected error due to inactive infrastructure: ", err)
return
}
if res == nil {
t.Errorf("Returned response is nil")
}
})
}

func FuzzGetExperimentRunStats(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
fuzzConsumer := fuzz.NewConsumer(data)
targetStruct := &struct {
ProjectID string
}{}
err := fuzzConsumer.GenerateStruct(targetStruct)
if err != nil {
return
}
targetStruct.ProjectID = uuid.New().String()

mockServices := NewMockServices()

findResult := []interface{}{bson.D{
{Key: "project_id", Value: targetStruct.ProjectID},
{Key: "infra_id", Value: "abc"},
{
Key: "revision", Value: []dbChaosExperiment.ExperimentRevision{
{
RevisionID: uuid.NewString(),
},
},
},
}}
cursor, _ := mongo.NewCursorFromDocuments(findResult, nil, nil)
mockServices.MongodbOperator.On("Aggregate", mock.Anything, mongodb.ChaosExperimentRunsCollection, mock.Anything, mock.Anything).Return(cursor, nil).Once()

res, err := mockServices.ChaosExperimentRunHandler.GetExperimentRunStats(context.Background(), targetStruct.ProjectID)
if err != nil {
t.Errorf("GetExperimentRunStats() error = %v", err)
return
}
if res == nil {
t.Errorf("Returned response is nil")
}
})
}

0 comments on commit 2bdec7e

Please sign in to comment.