diff --git a/boomer.go b/boomer.go index 48593fbd..7096aee9 100644 --- a/boomer.go +++ b/boomer.go @@ -1,6 +1,7 @@ package hrp import ( + "github.com/jinzhu/copier" "time" "github.com/rs/zerolog/log" @@ -69,12 +70,17 @@ func (b *hrpBoomer) convertBoomerTask(testcase *TestCase) *boomer.Task { var transactionSuccess = true // flag current transaction result cfg := testcase.Config.ToStruct() + testCaseVariables := &TConfig{} + // copy config to avoid data racing + if err := copier.Copy(testCaseVariables, cfg); err != nil { + log.Error().Err(err).Msg("copy config data failed") + } if it := cfg.ParametersSetting.Iterator; it.HasNext() { - cfg.Variables = mergeVariables(it.Next(), cfg.Variables) + testCaseVariables.Variables = mergeVariables(it.Next(), cfg.Variables) } startTime := time.Now() for index, step := range testcase.TestSteps { - stepData, err := runner.runStep(index) + stepData, err := runner.runStep(index, testCaseVariables) if err != nil { // step failed var elapsed int64 diff --git a/runner.go b/runner.go index c227064a..df33b966 100644 --- a/runner.go +++ b/runner.go @@ -147,7 +147,7 @@ func (r *caseRunner) run() error { cfg.Variables = mergeVariables(it.Next(), cfg.Variables) r.startTime = time.Now() for index := range r.TestCase.TestSteps { - _, err := r.runStep(index) + _, err := r.runStep(index, cfg) if err != nil { if r.hrpRunner.failfast { return errors.Wrap(err, "abort running due to failfast setting") @@ -160,8 +160,7 @@ func (r *caseRunner) run() error { return nil } -func (r *caseRunner) runStep(index int) (stepResult *stepData, err error) { - config := r.TestCase.Config +func (r *caseRunner) runStep(index int, caseConfig *TConfig) (stepResult *stepData, err error) { step := r.TestCase.TestSteps[index] // step type priority order: transaction > rendezvous > testcase > request @@ -181,23 +180,18 @@ func (r *caseRunner) runStep(index int) (stepResult *stepData, err error) { log.Error().Err(err).Msg("copy step data failed") return nil, err } - copiedConfig := &TConfig{} - if err = copier.Copy(copiedConfig, config.ToStruct()); err != nil { - log.Error().Err(err).Msg("copy config data failed") - return nil, err - } stepVariables := copiedStep.Variables // override variables // step variables > session variables (extracted variables from previous steps) stepVariables = mergeVariables(stepVariables, r.sessionVariables) // step variables > testcase config variables - stepVariables = mergeVariables(stepVariables, copiedConfig.Variables) + stepVariables = mergeVariables(stepVariables, caseConfig.Variables) // parse step variables parsedVariables, err := parseVariables(stepVariables) if err != nil { - log.Error().Interface("variables", copiedConfig.Variables).Err(err).Msg("parse step variables failed") + log.Error().Interface("variables", caseConfig.Variables).Err(err).Msg("parse step variables failed") return nil, err } copiedStep.Variables = parsedVariables // avoid data racing @@ -214,7 +208,7 @@ func (r *caseRunner) runStep(index int) (stepResult *stepData, err error) { } } else { // run request - copiedStep.Request.URL = buildURL(copiedConfig.BaseURL, copiedStep.Request.URL) // avoid data racing + copiedStep.Request.URL = buildURL(caseConfig.BaseURL, copiedStep.Request.URL) // avoid data racing stepResult, err = r.runStepRequest(copiedStep) if err != nil { log.Error().Err(err).Msg("run request step failed") diff --git a/step_test.go b/step_test.go index 5fdd3c02..d7e3ee17 100644 --- a/step_test.go +++ b/step_test.go @@ -79,10 +79,10 @@ func TestRunRequestRun(t *testing.T) { TestSteps: []IStep{stepGET, stepPOSTData}, } runner := NewRunner(t).SetDebug(true).newCaseRunner(testcase) - if _, err := runner.runStep(0); err != nil { + if _, err := runner.runStep(0, testcase.Config.ToStruct()); err != nil { t.Fatalf("tStep.Run() error: %s", err) } - if _, err := runner.runStep(1); err != nil { + if _, err := runner.runStep(1, testcase.Config.ToStruct()); err != nil { t.Fatalf("tStepPOSTData.Run() error: %s", err) } }