From 34f204155a3053ffe6d112a1725cff34cd8720af Mon Sep 17 00:00:00 2001 From: shivamsouravjha Date: Thu, 18 Apr 2024 14:06:47 +0000 Subject: [PATCH 1/6] add: support of custom mock name Signed-off-by: shivamsouravjha --- pkg/platform/yaml/mockdb/db.go | 6 ++++-- pkg/service/replay/replay.go | 19 +++++++++++++------ pkg/service/replay/service.go | 6 ++++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/pkg/platform/yaml/mockdb/db.go b/pkg/platform/yaml/mockdb/db.go index 6b0f15420..80bb626ed 100644 --- a/pkg/platform/yaml/mockdb/db.go +++ b/pkg/platform/yaml/mockdb/db.go @@ -36,6 +36,10 @@ func New(Logger *zap.Logger, mockPath string, mockName string) *MockYaml { } } +func (ys *MockYaml) SetMockFileName(mockName string) { + ys.MockName = mockName +} + // UpdateMocks deletes the mocks from the mock file with given names // // mockNames is a map which contains the name of the mocks as key and a isConfig boolean as value @@ -144,7 +148,6 @@ func (ys *MockYaml) GetFilteredMocks(ctx context.Context, testSetID string, afte var tcsMocks = make([]*models.Mock, 0) var filteredTcsMocks = make([]*models.Mock, 0) - mockFileName := "mocks" if ys.MockName != "" { mockFileName = ys.MockName @@ -196,7 +199,6 @@ func (ys *MockYaml) GetFilteredMocks(ctx context.Context, testSetID string, afte } } } - filteredTcsMocks, _ = ys.filterByTimeStamp(ctx, tcsMocks, afterTime, beforeTime, ys.Logger) sort.SliceStable(filteredTcsMocks, func(i, j int) bool { diff --git a/pkg/service/replay/replay.go b/pkg/service/replay/replay.go index 4877ca9fe..1f16a86ba 100644 --- a/pkg/service/replay/replay.go +++ b/pkg/service/replay/replay.go @@ -29,11 +29,16 @@ var totalTestFailed int // emulator contains the struct instance that implements RequestEmulator interface. This is done for // attaching the objects dynamically as plugins. var emulator RequestEmulator +var runTestSetResult TestResult func SetTestUtilInstance(instance RequestEmulator) { emulator = instance } +func SetRunTestSet(instance TestResult) { + runTestSetResult = instance +} + type Replayer struct { logger *zap.Logger testDB TestDB @@ -49,6 +54,9 @@ func NewReplayer(logger *zap.Logger, testDB TestDB, mockDB MockDB, reportDB Repo if emulator == nil { SetTestUtilInstance(NewTestUtils(config.Test.APITimeout, logger)) } + if runTestSetResult == nil { + SetRunTestSet(NewTestStatusUtil(logger, config.Path, "mocks")) + } return &Replayer{ logger: logger, @@ -121,13 +129,11 @@ func (r *Replayer) Start(ctx context.Context) error { testSetResult := false testRunResult := true abortTestRun := false - for _, testSetID := range testSetIDs { - if _, ok := r.config.Test.SelectedTests[testSetID]; !ok && len(r.config.Test.SelectedTests) != 0 { continue } - + runTestSetResult.MockFile(testSetID) testSetStatus, err := r.RunTestSet(ctx, testSetID, testRunID, appID, false) if err != nil { stopReason = fmt.Sprintf("failed to run test set: %v", err) @@ -153,6 +159,7 @@ func (r *Replayer) Start(ctx context.Context) error { testSetResult = false case models.TestSetStatusPassed: testSetResult = true + runTestSetResult.TestRunStatus(testSetResult, testSetID) } testRunResult = testRunResult && testSetResult if abortTestRun { @@ -225,7 +232,6 @@ func (r *Replayer) GetAllTestSetIDs(ctx context.Context) ([]string, error) { } func (r *Replayer) RunTestSet(ctx context.Context, testSetID string, testRunID string, appID uint64, serveTest bool) (models.TestSetStatus, error) { - // creating error group to manage proper shutdown of all the go routines and to propagate the error to the caller runTestSetErrGrp, runTestSetCtx := errgroup.WithContext(ctx) runTestSetCtx = context.WithValue(runTestSetCtx, models.ErrGroupKey, runTestSetErrGrp) @@ -242,6 +248,8 @@ func (r *Replayer) RunTestSet(ctx context.Context, testSetID string, testRunID s close(exitLoopChan) }() + r.mockDB.SetMockFileName(runTestSetResult.MockName()) + var appErrChan = make(chan models.AppError, 1) var appErr models.AppError var success int @@ -438,7 +446,6 @@ func (r *Replayer) RunTestSet(ctx context.Context, testSetID string, testRunID s totalConsumedMocks[mockName] = true } } - testPass, testResult = r.compareResp(testCase, resp, testSetID) if !testPass { // log the consumed mocks during the test run of the test case for test set @@ -477,7 +484,7 @@ func (r *Replayer) RunTestSet(ctx context.Context, testSetID string, testRunID s }, Res: *resp, TestCasePath: filepath.Join(r.config.Path, testSetID), - MockPath: filepath.Join(r.config.Path, testSetID, "mocks.yaml"), + MockPath: filepath.Join(r.config.Path, testSetID, runTestSetResult.MockName()), Noise: testCase.Noise, Result: *testResult, } diff --git a/pkg/service/replay/service.go b/pkg/service/replay/service.go index fa272e0bb..74caf7926 100644 --- a/pkg/service/replay/service.go +++ b/pkg/service/replay/service.go @@ -44,6 +44,7 @@ type MockDB interface { GetFilteredMocks(ctx context.Context, testSetID string, afterTime time.Time, beforeTime time.Time) ([]*models.Mock, error) GetUnFilteredMocks(ctx context.Context, testSetID string, afterTime time.Time, beforeTime time.Time) ([]*models.Mock, error) UpdateMocks(ctx context.Context, testSetID string, mockNames map[string]bool) error + SetMockFileName(mockName string) } type ReportDB interface { @@ -66,3 +67,8 @@ type RequestEmulator interface { SimulateRequest(ctx context.Context, appID uint64, tc *models.TestCase, testSetID string) (*models.HTTPResp, error) AfterTestHook(ctx context.Context, testRunID, testSetID string, totalTestSets int) (*models.TestReport, error) } +type TestResult interface { + TestRunStatus(status bool, testSetID string) + MockName() string + MockFile(testSetID string) +} From b990f8acbee848c9767cd69341402d65dba91b93 Mon Sep 17 00:00:00 2001 From: shivamsouravjha Date: Thu, 18 Apr 2024 19:47:46 +0000 Subject: [PATCH 2/6] add:context timeout --- pkg/service/replay/replay.go | 4 ++-- pkg/service/replay/service.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/service/replay/replay.go b/pkg/service/replay/replay.go index 1f16a86ba..69e8ba546 100644 --- a/pkg/service/replay/replay.go +++ b/pkg/service/replay/replay.go @@ -133,7 +133,7 @@ func (r *Replayer) Start(ctx context.Context) error { if _, ok := r.config.Test.SelectedTests[testSetID]; !ok && len(r.config.Test.SelectedTests) != 0 { continue } - runTestSetResult.MockFile(testSetID) + runTestSetResult.MockFile(ctx, testSetID) testSetStatus, err := r.RunTestSet(ctx, testSetID, testRunID, appID, false) if err != nil { stopReason = fmt.Sprintf("failed to run test set: %v", err) @@ -159,7 +159,7 @@ func (r *Replayer) Start(ctx context.Context) error { testSetResult = false case models.TestSetStatusPassed: testSetResult = true - runTestSetResult.TestRunStatus(testSetResult, testSetID) + runTestSetResult.TestRunStatus(ctx, testSetResult, testSetID) } testRunResult = testRunResult && testSetResult if abortTestRun { diff --git a/pkg/service/replay/service.go b/pkg/service/replay/service.go index 74caf7926..b14ee4ef3 100644 --- a/pkg/service/replay/service.go +++ b/pkg/service/replay/service.go @@ -68,7 +68,7 @@ type RequestEmulator interface { AfterTestHook(ctx context.Context, testRunID, testSetID string, totalTestSets int) (*models.TestReport, error) } type TestResult interface { - TestRunStatus(status bool, testSetID string) + TestRunStatus(ctx context.Context, status bool, testSetID string) MockName() string - MockFile(testSetID string) + MockFile(ctx context.Context, testSetID string) } From c63bbecf2ef3d28cc5fc6a81198dc9f54903e79c Mon Sep 17 00:00:00 2001 From: shivamsouravjha <2019145@iiitdmj.ac.in> Date: Tue, 23 Apr 2024 10:44:04 +0000 Subject: [PATCH 3/6] remove: mock file setter --- pkg/platform/yaml/mockdb/db.go | 4 ---- pkg/service/replay/replay.go | 2 -- pkg/service/replay/service.go | 1 - 3 files changed, 7 deletions(-) diff --git a/pkg/platform/yaml/mockdb/db.go b/pkg/platform/yaml/mockdb/db.go index 80bb626ed..9e150bf6f 100644 --- a/pkg/platform/yaml/mockdb/db.go +++ b/pkg/platform/yaml/mockdb/db.go @@ -36,10 +36,6 @@ func New(Logger *zap.Logger, mockPath string, mockName string) *MockYaml { } } -func (ys *MockYaml) SetMockFileName(mockName string) { - ys.MockName = mockName -} - // UpdateMocks deletes the mocks from the mock file with given names // // mockNames is a map which contains the name of the mocks as key and a isConfig boolean as value diff --git a/pkg/service/replay/replay.go b/pkg/service/replay/replay.go index 69e8ba546..0cd870662 100644 --- a/pkg/service/replay/replay.go +++ b/pkg/service/replay/replay.go @@ -248,8 +248,6 @@ func (r *Replayer) RunTestSet(ctx context.Context, testSetID string, testRunID s close(exitLoopChan) }() - r.mockDB.SetMockFileName(runTestSetResult.MockName()) - var appErrChan = make(chan models.AppError, 1) var appErr models.AppError var success int diff --git a/pkg/service/replay/service.go b/pkg/service/replay/service.go index b14ee4ef3..86f8c9c2d 100644 --- a/pkg/service/replay/service.go +++ b/pkg/service/replay/service.go @@ -44,7 +44,6 @@ type MockDB interface { GetFilteredMocks(ctx context.Context, testSetID string, afterTime time.Time, beforeTime time.Time) ([]*models.Mock, error) GetUnFilteredMocks(ctx context.Context, testSetID string, afterTime time.Time, beforeTime time.Time) ([]*models.Mock, error) UpdateMocks(ctx context.Context, testSetID string, mockNames map[string]bool) error - SetMockFileName(mockName string) } type ReportDB interface { From cf4eaa4cf7f4bb5fd2a1d24ebba85cb3c421fef9 Mon Sep 17 00:00:00 2001 From: shivamsouravjha Date: Tue, 21 May 2024 12:10:12 +0530 Subject: [PATCH 4/6] refactor: function rename and merge --- pkg/service/replay/replay.go | 28 +++++++++---------------- pkg/service/replay/service.go | 10 ++++----- pkg/service/replay/utils.go | 39 +++++++++++++++++++++++++++++------ 3 files changed, 47 insertions(+), 30 deletions(-) diff --git a/pkg/service/replay/replay.go b/pkg/service/replay/replay.go index 0cd870662..6b7f20f68 100644 --- a/pkg/service/replay/replay.go +++ b/pkg/service/replay/replay.go @@ -28,15 +28,10 @@ var totalTestFailed int // emulator contains the struct instance that implements RequestEmulator interface. This is done for // attaching the objects dynamically as plugins. -var emulator RequestEmulator -var runTestSetResult TestResult +var requestMockemulator RequestMockHandler -func SetTestUtilInstance(instance RequestEmulator) { - emulator = instance -} - -func SetRunTestSet(instance TestResult) { - runTestSetResult = instance +func SetTestUtilInstance(emulatorInstance RequestMockHandler) { + requestMockemulator = emulatorInstance } type Replayer struct { @@ -51,13 +46,10 @@ type Replayer struct { func NewReplayer(logger *zap.Logger, testDB TestDB, mockDB MockDB, reportDB ReportDB, telemetry Telemetry, instrumentation Instrumentation, config config.Config) Service { // set the request emulator for simulating test case requests, if not set - if emulator == nil { - SetTestUtilInstance(NewTestUtils(config.Test.APITimeout, logger)) + if requestMockemulator == nil { + // SetTestUtilInstance() + requestMockemulator = NewRequestMockUtil(logger, config.Path, "mocks", config.Test.APITimeout) } - if runTestSetResult == nil { - SetRunTestSet(NewTestStatusUtil(logger, config.Path, "mocks")) - } - return &Replayer{ logger: logger, testDB: testDB, @@ -133,7 +125,7 @@ func (r *Replayer) Start(ctx context.Context) error { if _, ok := r.config.Test.SelectedTests[testSetID]; !ok && len(r.config.Test.SelectedTests) != 0 { continue } - runTestSetResult.MockFile(ctx, testSetID) + requestMockemulator.ProcessMockFile(ctx, testSetID) testSetStatus, err := r.RunTestSet(ctx, testSetID, testRunID, appID, false) if err != nil { stopReason = fmt.Sprintf("failed to run test set: %v", err) @@ -159,7 +151,7 @@ func (r *Replayer) Start(ctx context.Context) error { testSetResult = false case models.TestSetStatusPassed: testSetResult = true - runTestSetResult.TestRunStatus(ctx, testSetResult, testSetID) + requestMockemulator.ProcessTestRunStatus(ctx, testSetResult, testSetID) } testRunResult = testRunResult && testSetResult if abortTestRun { @@ -429,7 +421,7 @@ func (r *Replayer) RunTestSet(ctx context.Context, testSetID string, testRunID s r.logger.Debug("", zap.Any("replaced URL in case of docker env", testCase.HTTPReq.URL)) } - resp, loopErr := emulator.SimulateRequest(runTestSetCtx, appID, testCase, testSetID) + resp, loopErr := requestMockemulator.SimulateRequest(runTestSetCtx, appID, testCase, testSetID) if loopErr != nil { utils.LogError(r.logger, err, "failed to simulate request") break @@ -482,7 +474,7 @@ func (r *Replayer) RunTestSet(ctx context.Context, testSetID string, testRunID s }, Res: *resp, TestCasePath: filepath.Join(r.config.Path, testSetID), - MockPath: filepath.Join(r.config.Path, testSetID, runTestSetResult.MockName()), + MockPath: filepath.Join(r.config.Path, testSetID, requestMockemulator.FetchMockName()), Noise: testCase.Noise, Result: *testResult, } diff --git a/pkg/service/replay/service.go b/pkg/service/replay/service.go index 86f8c9c2d..63d0ac428 100644 --- a/pkg/service/replay/service.go +++ b/pkg/service/replay/service.go @@ -62,12 +62,10 @@ type Telemetry interface { // RequestEmulator is used to simulate the API requests to the user API. The requests are read from // the recorded test case of the user app. -type RequestEmulator interface { +type RequestMockHandler interface { SimulateRequest(ctx context.Context, appID uint64, tc *models.TestCase, testSetID string) (*models.HTTPResp, error) + ProcessTestRunStatus(ctx context.Context, status bool, testSetID string) + FetchMockName() string + ProcessMockFile(ctx context.Context, testSetID string) AfterTestHook(ctx context.Context, testRunID, testSetID string, totalTestSets int) (*models.TestReport, error) } -type TestResult interface { - TestRunStatus(ctx context.Context, status bool, testSetID string) - MockName() string - MockFile(ctx context.Context, testSetID string) -} diff --git a/pkg/service/replay/utils.go b/pkg/service/replay/utils.go index 1f7525476..14931460b 100644 --- a/pkg/service/replay/utils.go +++ b/pkg/service/replay/utils.go @@ -41,19 +41,22 @@ func LeftJoinNoise(globalNoise config.GlobalNoise, tsNoise config.GlobalNoise) c return noise } -type testUtils struct { +type requestMockUtil struct { logger *zap.Logger + path string + mockName string apiTimeout uint64 } -func NewTestUtils(apiTimeout uint64, logger *zap.Logger) RequestEmulator { - return &testUtils{ +func NewRequestMockUtil(logger *zap.Logger, path, mockName string, apiTimeout uint64) RequestMockHandler { + return &requestMockUtil{ + path: path, logger: logger, + mockName: mockName, apiTimeout: apiTimeout, } } - -func (t *testUtils) SimulateRequest(ctx context.Context, _ uint64, tc *models.TestCase, testSetID string) (*models.HTTPResp, error) { +func (t *requestMockUtil) SimulateRequest(ctx context.Context, _ uint64, tc *models.TestCase, testSetID string) (*models.HTTPResp, error) { switch tc.Kind { case models.HTTP: t.logger.Debug("Before simulating the request", zap.Any("Test case", tc)) @@ -66,7 +69,31 @@ func (t *testUtils) SimulateRequest(ctx context.Context, _ uint64, tc *models.Te return nil, nil } -func (t *testUtils) AfterTestHook(_ context.Context, testRunID, testSetID string, tsCnt int) (*models.TestReport, error) { +func (t *requestMockUtil) AfterTestHook(_ context.Context, testRunID, testSetID string, tsCnt int) (*models.TestReport, error) { t.logger.Debug("AfterTestHook", zap.Any("testRunID", testRunID), zap.Any("testSetID", testSetID), zap.Any("totTestSetCount", tsCnt)) return nil, nil } + +func (t *requestMockUtil) ProcessTestRunStatus(ctx context.Context, status bool, testSetID string) { + if err := ctx.Err(); err != nil { + t.logger.Debug("Operation cancelled or timed out", zap.Error(err)) + return + } + if status { + t.logger.Debug("Test case passed for", zap.String("testSetID", testSetID)) + } else { + t.logger.Debug("Test case failed for", zap.String("testSetID", testSetID)) + } +} + +func (t *requestMockUtil) FetchMockName() string { + return t.mockName +} + +func (t *requestMockUtil) ProcessMockFile(ctx context.Context, testSetID string) { + if err := ctx.Err(); err != nil { + t.logger.Debug("Operation cancelled or timed out", zap.Error(err)) + return + } + t.logger.Debug("Mock file for test set", zap.String("testSetID", testSetID)) +} From 071363a5a58a6b08a036e0731f165b1587160375 Mon Sep 17 00:00:00 2001 From: shivamsouravjha Date: Tue, 21 May 2024 12:13:33 +0530 Subject: [PATCH 5/6] refactor:function name --- pkg/service/replay/replay.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/service/replay/replay.go b/pkg/service/replay/replay.go index 6b7f20f68..dacff7ace 100644 --- a/pkg/service/replay/replay.go +++ b/pkg/service/replay/replay.go @@ -158,7 +158,7 @@ func (r *Replayer) Start(ctx context.Context) error { break } - _, err = emulator.AfterTestHook(ctx, testRunID, testSetID, len(testSetIDs)) + _, err = requestMockemulator.AfterTestHook(ctx, testRunID, testSetID, len(testSetIDs)) if err != nil { utils.LogError(r.logger, err, "failed to get after test hook") } From a945e0cf672f10858a9c87da9db52156eeb16a4d Mon Sep 17 00:00:00 2001 From: shivamsouravjha Date: Tue, 21 May 2024 12:31:17 +0530 Subject: [PATCH 6/6] refactor:using set util and removing un-needed contexts --- pkg/service/replay/replay.go | 3 +-- pkg/service/replay/utils.go | 12 ++---------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/pkg/service/replay/replay.go b/pkg/service/replay/replay.go index dacff7ace..f40c2f711 100644 --- a/pkg/service/replay/replay.go +++ b/pkg/service/replay/replay.go @@ -47,8 +47,7 @@ type Replayer struct { func NewReplayer(logger *zap.Logger, testDB TestDB, mockDB MockDB, reportDB ReportDB, telemetry Telemetry, instrumentation Instrumentation, config config.Config) Service { // set the request emulator for simulating test case requests, if not set if requestMockemulator == nil { - // SetTestUtilInstance() - requestMockemulator = NewRequestMockUtil(logger, config.Path, "mocks", config.Test.APITimeout) + SetTestUtilInstance(NewRequestMockUtil(logger, config.Path, "mocks", config.Test.APITimeout)) } return &Replayer{ logger: logger, diff --git a/pkg/service/replay/utils.go b/pkg/service/replay/utils.go index 14931460b..8b7ed36d6 100644 --- a/pkg/service/replay/utils.go +++ b/pkg/service/replay/utils.go @@ -74,11 +74,7 @@ func (t *requestMockUtil) AfterTestHook(_ context.Context, testRunID, testSetID return nil, nil } -func (t *requestMockUtil) ProcessTestRunStatus(ctx context.Context, status bool, testSetID string) { - if err := ctx.Err(); err != nil { - t.logger.Debug("Operation cancelled or timed out", zap.Error(err)) - return - } +func (t *requestMockUtil) ProcessTestRunStatus(_ context.Context, status bool, testSetID string) { if status { t.logger.Debug("Test case passed for", zap.String("testSetID", testSetID)) } else { @@ -90,10 +86,6 @@ func (t *requestMockUtil) FetchMockName() string { return t.mockName } -func (t *requestMockUtil) ProcessMockFile(ctx context.Context, testSetID string) { - if err := ctx.Err(); err != nil { - t.logger.Debug("Operation cancelled or timed out", zap.Error(err)) - return - } +func (t *requestMockUtil) ProcessMockFile(_ context.Context, testSetID string) { t.logger.Debug("Mock file for test set", zap.String("testSetID", testSetID)) }