From 203935511e2333fb6f5f90fd4c8ee152f90756e8 Mon Sep 17 00:00:00 2001 From: Matheus Nogueira Date: Fri, 13 May 2022 16:59:09 -0300 Subject: [PATCH 1/3] feat: endpoint to rerun test assertions on result --- api/openapi.yaml | 29 ++++++++++++++++++++ server/app/app.go | 2 +- server/executor/assertion_runner.go | 23 +++++++++++++--- server/executor/trace_poller.go | 23 +--------------- server/http/controller.go | 41 ++++++++++++++++++++++++----- server/openapi/api.go | 2 ++ server/openapi/api_api.go | 24 +++++++++++++++++ 7 files changed, 111 insertions(+), 33 deletions(-) diff --git a/api/openapi.yaml b/api/openapi.yaml index 03b567cda8..4087913cc6 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -211,6 +211,7 @@ paths: application/json: schema: $ref: "#/components/schemas/TestRunResult" + /tests/{testId}/results/{resultId}/select: get: tags: @@ -245,6 +246,34 @@ paths: items: type: string + /tests/{testId}/results/{resultId}/rerun: + post: + tags: + - api + parameters: + - in: path + name: testId + schema: + type: string + format: uuid + required: true + - in: path + name: resultId + schema: + type: string + format: uuid + required: true + summary: "rerun a test result" + description: "rerun a test result" + operationId: rerunTestResult + responses: + 200: + description: successful operation + content: + application/json: + schema: + $ref: "#/components/schemas/TestRunResult" + /tests/{testId}/results: get: tags: diff --git a/server/app/app.go b/server/app/app.go index bfc0ae458f..3aa87eb4f2 100644 --- a/server/app/app.go +++ b/server/app/app.go @@ -82,7 +82,7 @@ func (a *App) Start() error { runner.Start(5) // worker count. should be configurable defer runner.Stop() - controller := httpServer.NewController(a.traceDB, a.db, runner) + controller := httpServer.NewController(a.traceDB, a.db, runner, assertionRunner) apiApiController := openapi.NewApiApiController(controller) router := openapi.NewRouter(apiApiController) diff --git a/server/executor/assertion_runner.go b/server/executor/assertion_runner.go index 271143e65a..57bfd0d78a 100644 --- a/server/executor/assertion_runner.go +++ b/server/executor/assertion_runner.go @@ -20,7 +20,7 @@ type AssertionRequest struct { } type AssertionRunner interface { - RunAssertions(request AssertionRequest) + RunAssertions(ctx context.Context, result openapi.TestRunResult) error WorkerPool } @@ -160,6 +160,23 @@ func (e *defaultAssertionRunner) setResults(result *openapi.TestRunResult, testR result.AssertionResultState = allTestsPassed } -func (e *defaultAssertionRunner) RunAssertions(request AssertionRequest) { - e.inputChannel <- request +func (e *defaultAssertionRunner) RunAssertions(ctx context.Context, result openapi.TestRunResult) error { + test, err := e.db.GetTest(ctx, result.TestId) + if err != nil { + return err + } + + testDefinition, err := ConvertAssertionsIntoTestDefinition(test.Assertions) + if err != nil { + return err + } + + assertionRequest := AssertionRequest{ + TestDefinition: testDefinition, + Result: result, + } + + e.inputChannel <- assertionRequest + + return nil } diff --git a/server/executor/trace_poller.go b/server/executor/trace_poller.go index 543275317b..f5011cb26d 100644 --- a/server/executor/trace_poller.go +++ b/server/executor/trace_poller.go @@ -158,33 +158,12 @@ func (tp tracePoller) processJob(job tracePollReq) { Content: res, }) - err = tp.runAssertions(job.ctx, res) + err = tp.assertionRunner.RunAssertions(job.ctx, res) if err != nil { fmt.Printf("could not run assertions: %s\n", err.Error()) } } -func (tp tracePoller) runAssertions(ctx context.Context, result openapi.TestRunResult) error { - test, err := tp.testDB.GetTest(ctx, result.TestId) - if err != nil { - return err - } - - testDefinition, err := ConvertAssertionsIntoTestDefinition(test.Assertions) - if err != nil { - return err - } - - assertionRequest := AssertionRequest{ - TestDefinition: testDefinition, - Result: result, - } - - tp.assertionRunner.RunAssertions(assertionRequest) - - return nil -} - // to compare trace we count the number of resourceSpans + InstrumentationLibrarySpans + spans. func numSpans(trace openapi.ApiV3SpansResponseChunk) int { num := 0 diff --git a/server/http/controller.go b/server/http/controller.go index ebbfd890df..6994256e8d 100644 --- a/server/http/controller.go +++ b/server/http/controller.go @@ -16,16 +16,23 @@ import ( ) type controller struct { - traceDB tracedb.TraceDB - testDB testdb.Repository - runner executor.Runner + traceDB tracedb.TraceDB + testDB testdb.Repository + runner executor.Runner + assertionRunner executor.AssertionRunner } -func NewController(traceDB tracedb.TraceDB, testDB testdb.Repository, runner executor.Runner) openapi.ApiApiServicer { +func NewController( + traceDB tracedb.TraceDB, + testDB testdb.Repository, + runner executor.Runner, + assertionRunner executor.AssertionRunner, +) openapi.ApiApiServicer { return &controller{ - traceDB: traceDB, - testDB: testDB, - runner: runner, + traceDB: traceDB, + testDB: testDB, + runner: runner, + assertionRunner: assertionRunner, } } @@ -292,3 +299,23 @@ func (s *controller) GetTestResultSelectedSpans(ctx context.Context, testID stri return openapi.Response(http.StatusOK, selectedSpanIds), nil } + +func (s *controller) RerunTestResult(ctx context.Context, testID string, resultID string) (openapi.ImplResponse, error) { + result, err := s.testDB.GetResult(ctx, resultID) + if err != nil { + return openapi.Response(http.StatusInternalServerError, err.Error()), err + } + + result.State = executor.TestRunStateAwaitingTestResults + err = s.testDB.UpdateResult(ctx, result) + if err != nil { + return openapi.Response(http.StatusInternalServerError, err.Error()), err + } + + err = s.assertionRunner.RunAssertions(ctx, *result) + if err != nil { + return openapi.Response(http.StatusInternalServerError, err.Error()), err + } + + return openapi.Response(http.StatusOK, result), nil +} diff --git a/server/openapi/api.go b/server/openapi/api.go index f5f728bd83..c227831c73 100644 --- a/server/openapi/api.go +++ b/server/openapi/api.go @@ -28,6 +28,7 @@ type ApiApiRouter interface { GetTestResultSelectedSpans(http.ResponseWriter, *http.Request) GetTestResults(http.ResponseWriter, *http.Request) GetTests(http.ResponseWriter, *http.Request) + RerunTestResult(http.ResponseWriter, *http.Request) RunTest(http.ResponseWriter, *http.Request) UpdateAssertion(http.ResponseWriter, *http.Request) UpdateTest(http.ResponseWriter, *http.Request) @@ -49,6 +50,7 @@ type ApiApiServicer interface { GetTestResultSelectedSpans(context.Context, string, string, string) (ImplResponse, error) GetTestResults(context.Context, string, int32, int32) (ImplResponse, error) GetTests(context.Context, int32, int32) (ImplResponse, error) + RerunTestResult(context.Context, string, string) (ImplResponse, error) RunTest(context.Context, string) (ImplResponse, error) UpdateAssertion(context.Context, string, string, Assertion) (ImplResponse, error) UpdateTest(context.Context, string, Test) (ImplResponse, error) diff --git a/server/openapi/api_api.go b/server/openapi/api_api.go index fa6832d3b1..e140d9fad3 100644 --- a/server/openapi/api_api.go +++ b/server/openapi/api_api.go @@ -110,6 +110,12 @@ func (c *ApiApiController) Routes() Routes { "/api/tests", c.GetTests, }, + { + "RerunTestResult", + strings.ToUpper("Post"), + "/api/tests/{testId}/results/{resultId}/rerun", + c.RerunTestResult, + }, { "RunTest", strings.ToUpper("Post"), @@ -343,6 +349,24 @@ func (c *ApiApiController) GetTests(w http.ResponseWriter, r *http.Request) { } +// RerunTestResult - rerun a test result +func (c *ApiApiController) RerunTestResult(w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + testIdParam := params["testId"] + + resultIdParam := params["resultId"] + + result, err := c.service.RerunTestResult(r.Context(), testIdParam, resultIdParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) + +} + // RunTest - run test func (c *ApiApiController) RunTest(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) From 76fbc69d950119fa98fd80601488cbd4c3b7a3f7 Mon Sep 17 00:00:00 2001 From: Matheus Nogueira Date: Fri, 13 May 2022 17:02:32 -0300 Subject: [PATCH 2/3] fix tests --- server/executor/assertion_runner_test.go | 10 +--------- server/executor/trace_poller_test.go | 6 ++++-- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/server/executor/assertion_runner_test.go b/server/executor/assertion_runner_test.go index 7a3c3917e4..9780b1b0ee 100644 --- a/server/executor/assertion_runner_test.go +++ b/server/executor/assertion_runner_test.go @@ -57,16 +57,8 @@ func TestExecutorSuccessfulExecution(t *testing.T) { err = postgresRepository.CreateResult(ctx, test.TestId, &result) require.NoError(t, err) - testDefinition, err := executor.ConvertAssertionsIntoTestDefinition(test.Assertions) - assert.NoError(t, err) - - assertionRequest := executor.AssertionRequest{ - TestDefinition: testDefinition, - Result: result, - } - assertionExecutor.Start(1) - assertionExecutor.RunAssertions(assertionRequest) + assertionExecutor.RunAssertions(ctx, result) assertionExecutor.Stop() dbResult, err := postgresRepository.GetResult(ctx, result.ResultId) diff --git a/server/executor/trace_poller_test.go b/server/executor/trace_poller_test.go index 4a154c865c..d2c16d1550 100644 --- a/server/executor/trace_poller_test.go +++ b/server/executor/trace_poller_test.go @@ -111,8 +111,10 @@ type mockAssertionRunner struct { var _ executor.AssertionRunner = &mockAssertionRunner{} -func (m *mockAssertionRunner) RunAssertions(request executor.AssertionRequest) { - m.Called(request) +func (m *mockAssertionRunner) RunAssertions(ctx context.Context, result openapi.TestRunResult) error { + args := m.Called(ctx, result) + + return args.Error(0) } func (m *mockAssertionRunner) Start(workers int) { From 86945a14812b60b7ec5d3306dc441897ad91a571 Mon Sep 17 00:00:00 2001 From: Matheus Nogueira Date: Fri, 13 May 2022 17:35:45 -0300 Subject: [PATCH 3/3] PR changes --- server/executor/assertion_runner.go | 23 +++-------------------- server/executor/assertion_runner_test.go | 10 +++++++++- server/executor/trace_poller.go | 23 ++++++++++++++++++++++- server/executor/trace_poller_test.go | 6 ++---- server/http/controller.go | 14 +++++++++++++- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/server/executor/assertion_runner.go b/server/executor/assertion_runner.go index 57bfd0d78a..271143e65a 100644 --- a/server/executor/assertion_runner.go +++ b/server/executor/assertion_runner.go @@ -20,7 +20,7 @@ type AssertionRequest struct { } type AssertionRunner interface { - RunAssertions(ctx context.Context, result openapi.TestRunResult) error + RunAssertions(request AssertionRequest) WorkerPool } @@ -160,23 +160,6 @@ func (e *defaultAssertionRunner) setResults(result *openapi.TestRunResult, testR result.AssertionResultState = allTestsPassed } -func (e *defaultAssertionRunner) RunAssertions(ctx context.Context, result openapi.TestRunResult) error { - test, err := e.db.GetTest(ctx, result.TestId) - if err != nil { - return err - } - - testDefinition, err := ConvertAssertionsIntoTestDefinition(test.Assertions) - if err != nil { - return err - } - - assertionRequest := AssertionRequest{ - TestDefinition: testDefinition, - Result: result, - } - - e.inputChannel <- assertionRequest - - return nil +func (e *defaultAssertionRunner) RunAssertions(request AssertionRequest) { + e.inputChannel <- request } diff --git a/server/executor/assertion_runner_test.go b/server/executor/assertion_runner_test.go index 9780b1b0ee..7a3c3917e4 100644 --- a/server/executor/assertion_runner_test.go +++ b/server/executor/assertion_runner_test.go @@ -57,8 +57,16 @@ func TestExecutorSuccessfulExecution(t *testing.T) { err = postgresRepository.CreateResult(ctx, test.TestId, &result) require.NoError(t, err) + testDefinition, err := executor.ConvertAssertionsIntoTestDefinition(test.Assertions) + assert.NoError(t, err) + + assertionRequest := executor.AssertionRequest{ + TestDefinition: testDefinition, + Result: result, + } + assertionExecutor.Start(1) - assertionExecutor.RunAssertions(ctx, result) + assertionExecutor.RunAssertions(assertionRequest) assertionExecutor.Stop() dbResult, err := postgresRepository.GetResult(ctx, result.ResultId) diff --git a/server/executor/trace_poller.go b/server/executor/trace_poller.go index f5011cb26d..543275317b 100644 --- a/server/executor/trace_poller.go +++ b/server/executor/trace_poller.go @@ -158,12 +158,33 @@ func (tp tracePoller) processJob(job tracePollReq) { Content: res, }) - err = tp.assertionRunner.RunAssertions(job.ctx, res) + err = tp.runAssertions(job.ctx, res) if err != nil { fmt.Printf("could not run assertions: %s\n", err.Error()) } } +func (tp tracePoller) runAssertions(ctx context.Context, result openapi.TestRunResult) error { + test, err := tp.testDB.GetTest(ctx, result.TestId) + if err != nil { + return err + } + + testDefinition, err := ConvertAssertionsIntoTestDefinition(test.Assertions) + if err != nil { + return err + } + + assertionRequest := AssertionRequest{ + TestDefinition: testDefinition, + Result: result, + } + + tp.assertionRunner.RunAssertions(assertionRequest) + + return nil +} + // to compare trace we count the number of resourceSpans + InstrumentationLibrarySpans + spans. func numSpans(trace openapi.ApiV3SpansResponseChunk) int { num := 0 diff --git a/server/executor/trace_poller_test.go b/server/executor/trace_poller_test.go index d2c16d1550..4a154c865c 100644 --- a/server/executor/trace_poller_test.go +++ b/server/executor/trace_poller_test.go @@ -111,10 +111,8 @@ type mockAssertionRunner struct { var _ executor.AssertionRunner = &mockAssertionRunner{} -func (m *mockAssertionRunner) RunAssertions(ctx context.Context, result openapi.TestRunResult) error { - args := m.Called(ctx, result) - - return args.Error(0) +func (m *mockAssertionRunner) RunAssertions(request executor.AssertionRequest) { + m.Called(request) } func (m *mockAssertionRunner) Start(workers int) { diff --git a/server/http/controller.go b/server/http/controller.go index 6994256e8d..8c211a7ac0 100644 --- a/server/http/controller.go +++ b/server/http/controller.go @@ -301,6 +301,11 @@ func (s *controller) GetTestResultSelectedSpans(ctx context.Context, testID stri } func (s *controller) RerunTestResult(ctx context.Context, testID string, resultID string) (openapi.ImplResponse, error) { + test, err := s.testDB.GetTest(ctx, testID) + if err != nil { + return openapi.Response(http.StatusInternalServerError, err.Error()), err + } + result, err := s.testDB.GetResult(ctx, resultID) if err != nil { return openapi.Response(http.StatusInternalServerError, err.Error()), err @@ -312,10 +317,17 @@ func (s *controller) RerunTestResult(ctx context.Context, testID string, resultI return openapi.Response(http.StatusInternalServerError, err.Error()), err } - err = s.assertionRunner.RunAssertions(ctx, *result) + testDefinition, err := executor.ConvertAssertionsIntoTestDefinition(test.Assertions) if err != nil { return openapi.Response(http.StatusInternalServerError, err.Error()), err } + assertionRequest := executor.AssertionRequest{ + TestDefinition: testDefinition, + Result: *result, + } + + s.assertionRunner.RunAssertions(assertionRequest) + return openapi.Response(http.StatusOK, result), nil }