From 259dd1759f41e7ec302b9607d8a88e6ac0f03e9d Mon Sep 17 00:00:00 2001 From: Lucas Hinderberger Date: Fri, 7 Jun 2024 14:31:25 +0200 Subject: [PATCH] Adding parallel_run_idx template function --- api_testsuite.go | 42 ++++++++++++-------- pkg/lib/template/template_loader.go | 8 ++++ test/parallel/check_collected_responses.json | 4 +- test/parallel/parallel.json | 25 +----------- test/parallel/parallel_case.json | 24 +++++++++++ 5 files changed, 61 insertions(+), 42 deletions(-) create mode 100644 test/parallel/parallel_case.json diff --git a/api_testsuite.go b/api_testsuite.go index 70ad671..3cfca05 100644 --- a/api_testsuite.go +++ b/api_testsuite.go @@ -47,7 +47,7 @@ type Suite struct { manifestPath string reporterRoot *report.ReportElement index int - serverURL string + serverURL *url.URL httpServer http.Server httpServerProxy *httpproxy.Proxy httpServerDir string @@ -151,6 +151,12 @@ func NewTestSuite(config TestToolConfig, manifestPath string, manifestDir string //Append suite manifest path to name, so we know in an automatic setup where the test is loaded from suite.Name = fmt.Sprintf("%s (%s)", suite.Name, manifestPath) + // Parse serverURL + suite.serverURL, err = url.Parse(suite.Config.ServerURL) + if err != nil { + return nil, fmt.Errorf("can not load server url : %s", err) + } + // init store err = suite.datastore.SetMap(suite.Store) if err != nil { @@ -187,7 +193,7 @@ func (ats *Suite) Run() bool { ats.manifestDir, ats.manifestPath, child, - ats.loader, + ats.buildLoader(ats.loader, -1), true, // parallel exec allowed for top-level tests ) @@ -225,23 +231,21 @@ type TestContainer struct { Path string } -func (ats *Suite) parseAndRunTest( - v any, manifestDir, testFilePath string, r *report.ReportElement, - rootLoader template.Loader, allowParallelExec bool, -) bool { - //Init variables - // logrus.Warnf("Test %s, Prev delimiters: %#v", testFilePath, rootLoader.Delimiters) +func (ats *Suite) buildLoader(rootLoader template.Loader, parallelRunIdx int) template.Loader { loader := template.NewLoader(ats.datastore) loader.Delimiters = rootLoader.Delimiters loader.HTTPServerHost = ats.HTTPServerHost - serverURL, err := url.Parse(ats.Config.ServerURL) - if err != nil { - logrus.Error(fmt.Errorf("can not load server url into test (%s): %s", testFilePath, err)) - return false - } - loader.ServerURL = serverURL + loader.ServerURL = ats.serverURL loader.OAuthClient = ats.Config.OAuthClient + loader.ParallelRunIdx = parallelRunIdx + return loader +} + +func (ats *Suite) parseAndRunTest( + v any, manifestDir, testFilePath string, r *report.ReportElement, + loader template.Loader, allowParallelExec bool, +) bool { // Parse PathSpec (if any) and determine number of parallel runs parallelRuns := 1 if vStr, ok := v.(string); ok { @@ -307,12 +311,16 @@ func (ats *Suite) parseAndRunTest( waitGroup.Add(parallelRuns) for runIdx := range parallelRuns { + runIdxCapture := runIdx + go func() { defer waitGroup.Done() for testIdx, testCase := range testCases { var success bool + caseLoader := ats.buildLoader(loader, runIdxCapture) + // If testCase can be unmarshalled as string, we may have a // reference to another test using @ notation at hand var testCaseStr string @@ -324,7 +332,7 @@ func (ats *Suite) parseAndRunTest( filepath.Join(manifestDir, dir), testFilePath, r, - loader, + caseLoader, false, // no parallel exec allowed in nested tests ) } else { @@ -336,8 +344,8 @@ func (ats *Suite) parseAndRunTest( }, r, testFilePath, - loader, - runIdx*len(testCases)+testIdx, + caseLoader, + runIdxCapture*len(testCases)+testIdx, ) } diff --git a/pkg/lib/template/template_loader.go b/pkg/lib/template/template_loader.go index 8f31b0a..0b376a8 100644 --- a/pkg/lib/template/template_loader.go +++ b/pkg/lib/template/template_loader.go @@ -49,6 +49,9 @@ type Loader struct { ServerURL *url.URL OAuthClient util.OAuthClientsConfig Delimiters delimiters + + // ParallelRunIdx is the index of the Parallel Run that this Loader is used in + ParallelRunIdx int } func NewLoader(datastore *datastore.Datastore) Loader { @@ -489,6 +492,11 @@ func (loader *Loader) Render( q := u.Query() return q.Get(qKey) }, + // parallel_run_idx returns the index of the Parallel Run that the current template + // is rendered in. + "parallel_run_idx": func() int { + return loader.ParallelRunIdx + }, } tmpl, err := template. New("tmpl"). diff --git a/test/parallel/check_collected_responses.json b/test/parallel/check_collected_responses.json index 1eceb32..7b2b624 100644 --- a/test/parallel/check_collected_responses.json +++ b/test/parallel/check_collected_responses.json @@ -16,11 +16,11 @@ "responses": [ {{ range $idx, $n := N (datastore "n_parallel") }} {{ if gt $idx 0 }}, {{ end }} - 1 + {{ $idx }} {{ end }} ] } } } } -] \ No newline at end of file +] diff --git a/test/parallel/parallel.json b/test/parallel/parallel.json index d07a68f..ed5ad4d 100644 --- a/test/parallel/parallel.json +++ b/test/parallel/parallel.json @@ -1,24 +1,3 @@ [ - { - "name": "bounce-json: bounce n=1", - "request": { - "server_url": "http://localhost{{ datastore `local_port` }}", - "endpoint": "bounce-json", - "method": "POST", - "body": { - "n": 1 - } - }, - "response": { - "statuscode": 200, - "body": { - "body": { - "n": 1 - } - } - }, - "store_response_qjson": { - "responses[]": "body.body.n" - } - } -] \ No newline at end of file + "@parallel_case.json" +] diff --git a/test/parallel/parallel_case.json b/test/parallel/parallel_case.json new file mode 100644 index 0000000..9f00e47 --- /dev/null +++ b/test/parallel/parallel_case.json @@ -0,0 +1,24 @@ +[ + { + "name": "bounce-json: bounce n=1", + "request": { + "server_url": "http://localhost{{ datastore `local_port` }}", + "endpoint": "bounce-json", + "method": "POST", + "body": { + "n": {{ parallel_run_idx }} + } + }, + "response": { + "statuscode": 200, + "body": { + "body": { + "n": {{ parallel_run_idx }} + } + } + }, + "store_response_qjson": { + "responses[]": "body.body.n" + } + } +]