Skip to content

Commit 40e2f66

Browse files
committed
Fix bug where passing existing name into UpdateChaosExperiment causes error
Modified tests: - Mock the fetch for the existing experiment - Rename tests to use `success` and `failure` like other tests in file - Add test to ensure that passing a duplicate experiment name throws an error Signed-off-by: Luke Zhan <luke.zhan@uwaterloo.ca>
1 parent 563ecb4 commit 40e2f66

File tree

3 files changed

+95
-11
lines changed

3 files changed

+95
-11
lines changed

chaoscenter/graphql/server/pkg/chaos_experiment/handler/fuzz_tests/handler_fuzz_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ func FuzzUpdateChaosExperiment(f *testing.F) {
158158
experimentType := dbChaosExperiment.NonCronExperiment
159159
ctx := context.Background()
160160
mockServices := NewMockServices()
161-
mockServices.MongodbOperator.On("CountDocuments", ctx, mongodb.ChaosExperimentCollection, mock.Anything, mock.Anything).Return(int64(0), nil).Once()
161+
// Mock the List call to check for duplicate experiment names
162+
cursor, _ := mongo.NewCursorFromDocuments(nil, nil, nil)
163+
mockServices.MongodbOperator.On("List", mock.Anything, mongodb.ChaosExperimentCollection, mock.Anything).Return(cursor, nil).Once()
162164
mockServices.ChaosExperimentService.On("ProcessExperiment", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(&model.ChaosExperimentRequest{
163165
ExperimentID: new(string),
164166
InfraID: "abc",

chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,19 @@ func (c *ChaosExperimentHandler) UpdateChaosExperiment(ctx context.Context, requ
283283
revID = uuid.New().String()
284284
)
285285

286-
// Check if the experiment_name exists under same project
287-
err := c.validateDuplicateExperimentName(ctx, projectID, request.ExperimentName)
286+
// Check if the experiment name exists under same project
287+
experiments, err := c.chaosExperimentOperator.GetExperiments(bson.D{
288+
{"project_id", projectID},
289+
{"name", request.ExperimentName},
290+
})
288291
if err != nil {
289292
return nil, err
290293
}
294+
for _, exp := range experiments {
295+
if exp.ExperimentID != *request.ExperimentID {
296+
return nil, errors.New("experiment name should be unique, duplicate experiment found with name: " + request.ExperimentName)
297+
}
298+
}
291299

292300
newRequest, wfType, err := c.chaosExperimentService.ProcessExperiment(ctx, &request, projectID, revID)
293301
if err != nil {

chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler_test.go

Lines changed: 82 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,8 @@ func TestChaosExperimentHandler_UpdateChaosExperiment(t *testing.T) {
355355
infraId := uuid.New().String()
356356
experimentId := uuid.New().String()
357357
experimentType := dbChaosExperiment.NonCronExperiment
358+
existingExperimentName := "existing-experiment"
359+
newExperimentName := "new-experiment"
358360

359361
store := store.NewStore()
360362
tests := []struct {
@@ -364,54 +366,126 @@ func TestChaosExperimentHandler_UpdateChaosExperiment(t *testing.T) {
364366
wantErr bool
365367
}{
366368
{
367-
name: "Update Chaos Experiment",
369+
name: "success: provided experiment name is the same as the existing experiment name",
370+
args: args{
371+
projectID: projectId,
372+
request: &model.ChaosExperimentRequest{
373+
ExperimentID: &experimentId,
374+
InfraID: infraId,
375+
ExperimentType: &model.AllExperimentType[0],
376+
ExperimentName: existingExperimentName,
377+
},
378+
},
379+
given: func(request *model.ChaosExperimentRequest, mockServices *MockServices) {
380+
// Mock GetExperiments to return an experiment with the same name and ID
381+
findResult := []interface{}{bson.D{
382+
{Key: "experiment_id", Value: experimentId},
383+
{Key: "name", Value: existingExperimentName},
384+
}}
385+
cursor, _ := mongo.NewCursorFromDocuments(findResult, nil, nil)
386+
mockServices.MongodbOperator.On("List", mock.Anything, mongodb.ChaosExperimentCollection, mock.Anything).Return(cursor, nil).Once()
368387

388+
mockServices.ChaosExperimentService.On("ProcessExperiment", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(request, &experimentType, nil).Once()
389+
mockServices.ChaosExperimentService.On("ProcessExperimentUpdate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
390+
mockServices.GitOpsService.On("UpsertExperimentToGit", mock.Anything, mock.Anything, request).Return(nil).Once()
391+
},
392+
wantErr: false,
393+
},
394+
{
395+
name: "success: provided experiment name is different from the existing experiment name",
369396
args: args{
370397
projectID: projectId,
371398
request: &model.ChaosExperimentRequest{
372399
ExperimentID: &experimentId,
373400
InfraID: infraId,
374401
ExperimentType: &model.AllExperimentType[0],
402+
ExperimentName: newExperimentName,
375403
},
376404
},
377405
given: func(request *model.ChaosExperimentRequest, mockServices *MockServices) {
378-
mockServices.MongodbOperator.On("CountDocuments", mock.Anything, mongodb.ChaosExperimentCollection, mock.Anything, mock.Anything).Return(int64(0), nil).Once()
406+
// Mock GetExperiments to return no experiments for the new name
407+
cursor, _ := mongo.NewCursorFromDocuments(nil, nil, nil)
408+
mockServices.MongodbOperator.On("List", mock.Anything, mongodb.ChaosExperimentCollection, mock.Anything).Return(cursor, nil).Once()
379409
mockServices.ChaosExperimentService.On("ProcessExperiment", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(request, &experimentType, nil).Once()
380410
mockServices.ChaosExperimentService.On("ProcessExperimentUpdate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Once()
381411
mockServices.GitOpsService.On("UpsertExperimentToGit", mock.Anything, mock.Anything, request).Return(nil).Once()
382-
383412
},
384413
wantErr: false,
385414
},
386415
{
387-
name: "Failed to process experiment",
416+
name: "failure: provided experiment name is a duplicate name",
417+
args: args{
418+
projectID: projectId,
419+
request: &model.ChaosExperimentRequest{
420+
ExperimentID: &experimentId,
421+
InfraID: infraId,
422+
ExperimentType: &model.AllExperimentType[0],
423+
ExperimentName: newExperimentName,
424+
},
425+
},
426+
given: func(request *model.ChaosExperimentRequest, mockServices *MockServices) {
427+
// Mock GetExperiments to return an experiment with a different ID
428+
otherFind := []interface{}{bson.D{
429+
{Key: "experiment_id", Value: uuid.New().String()},
430+
{Key: "name", Value: newExperimentName},
431+
}}
432+
cursor, _ := mongo.NewCursorFromDocuments(otherFind, nil, nil)
433+
mockServices.MongodbOperator.On("List", mock.Anything, mongodb.ChaosExperimentCollection, mock.Anything).Return(cursor, nil).Once()
434+
},
435+
wantErr: true,
436+
},
437+
{
438+
name: "failure: failed to get existing experiment",
388439
args: args{
389440
projectID: projectId,
390441
request: &model.ChaosExperimentRequest{
391442
ExperimentID: &experimentId,
392443
InfraID: infraId,
393444
ExperimentType: &model.AllExperimentType[0],
445+
ExperimentName: newExperimentName,
394446
},
395447
},
396448
given: func(request *model.ChaosExperimentRequest, mockServices *MockServices) {
397-
mockServices.MongodbOperator.On("CountDocuments", ctx, mongodb.ChaosExperimentCollection, mock.Anything, mock.Anything).Return(int64(0), nil).Once()
449+
// Simulate GetExperiments failing while checking for duplicate names
450+
cursor, _ := mongo.NewCursorFromDocuments(nil, nil, nil)
451+
mockServices.MongodbOperator.On("List", mock.Anything, mongodb.ChaosExperimentCollection, mock.Anything).Return(cursor, errors.New("experiment not found")).Once()
452+
},
453+
wantErr: true,
454+
},
455+
{
456+
name: "failure: failed to process experiment",
457+
args: args{
458+
projectID: projectId,
459+
request: &model.ChaosExperimentRequest{
460+
ExperimentID: &experimentId,
461+
InfraID: infraId,
462+
ExperimentType: &model.AllExperimentType[0],
463+
ExperimentName: newExperimentName,
464+
},
465+
},
466+
given: func(request *model.ChaosExperimentRequest, mockServices *MockServices) {
467+
// List returns empty (no duplicates) but ProcessExperiment fails
468+
cursor, _ := mongo.NewCursorFromDocuments(nil, nil, nil)
469+
mockServices.MongodbOperator.On("List", mock.Anything, mongodb.ChaosExperimentCollection, mock.Anything).Return(cursor, nil).Once()
398470
mockServices.ChaosExperimentService.On("ProcessExperiment", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(request, &experimentType, errors.New("Incorrect request format")).Once()
399471
},
400472
wantErr: true,
401473
},
402474
{
403-
name: "Update failed",
475+
name: "failure: failed to update experiment",
404476
args: args{
405477
projectID: projectId,
406478
request: &model.ChaosExperimentRequest{
407479
ExperimentID: &experimentId,
408480
InfraID: infraId,
409481
ExperimentType: &model.AllExperimentType[0],
482+
ExperimentName: newExperimentName,
410483
},
411484
},
412485
given: func(request *model.ChaosExperimentRequest, mockServices *MockServices) {
413-
mockServices.MongodbOperator.On("CountDocuments", ctx, mongodb.ChaosExperimentCollection, mock.Anything, mock.Anything).Return(int64(0), nil).Once()
414-
486+
// List returns no duplicates and ProcessExperiment succeeds but ProcessExperimentUpdate fails
487+
cursor, _ := mongo.NewCursorFromDocuments(nil, nil, nil)
488+
mockServices.MongodbOperator.On("List", mock.Anything, mongodb.ChaosExperimentCollection, mock.Anything).Return(cursor, nil).Once()
415489
mockServices.ChaosExperimentService.On("ProcessExperiment", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(request, &experimentType, nil).Once()
416490

417491
mockServices.ChaosExperimentService.On("ProcessExperimentUpdate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(errors.New("experiment update failed")).Once()

0 commit comments

Comments
 (0)