fix: unittests for plugin

This commit is contained in:
debugtalk
2022-01-18 17:18:16 +08:00
parent 6874a2428c
commit 9db54544d9
11 changed files with 125 additions and 41 deletions

View File

@@ -8,6 +8,7 @@ import (
"github.com/httprunner/hrp/internal/boomer" "github.com/httprunner/hrp/internal/boomer"
"github.com/httprunner/hrp/internal/ga" "github.com/httprunner/hrp/internal/ga"
"github.com/httprunner/hrp/plugin/common"
) )
func NewBoomer(spawnCount int, spawnRate float64) *HRPBoomer { func NewBoomer(spawnCount int, spawnRate float64) *HRPBoomer {
@@ -20,7 +21,8 @@ func NewBoomer(spawnCount int, spawnRate float64) *HRPBoomer {
type HRPBoomer struct { type HRPBoomer struct {
*boomer.Boomer *boomer.Boomer
debug bool plugins []common.Plugin // each task has its own plugin process
debug bool
} }
// SetDebug configures whether to log HTTP request and response content. // SetDebug configures whether to log HTTP request and response content.
@@ -57,14 +59,29 @@ func (b *HRPBoomer) Run(testcases ...ITestCase) {
b.Boomer.Run(taskSlice...) b.Boomer.Run(taskSlice...)
} }
func (b *HRPBoomer) Quit() {
for _, plugin := range b.plugins {
plugin.Quit()
}
b.Boomer.Quit()
}
func (b *HRPBoomer) convertBoomerTask(testcase *TestCase) *boomer.Task { func (b *HRPBoomer) convertBoomerTask(testcase *TestCase) *boomer.Task {
hrpRunner := NewRunner(nil).SetDebug(b.debug) hrpRunner := NewRunner(nil).SetDebug(b.debug)
config := testcase.Config.ToStruct() config := testcase.Config.ToStruct()
// each testcase has its own plugin process
plugin, _ := initPlugin(config.Path)
if plugin != nil {
b.plugins = append(b.plugins, plugin)
}
return &boomer.Task{ return &boomer.Task{
Name: config.Name, Name: config.Name,
Weight: config.Weight, Weight: config.Weight,
Fn: func() { Fn: func() {
runner := hrpRunner.newCaseRunner(testcase) runner := hrpRunner.newCaseRunner(testcase)
runner.parser.plugin = plugin
testcaseSuccess := true // flag whole testcase result testcaseSuccess := true // flag whole testcase result
var transactionSuccess = true // flag current transaction result var transactionSuccess = true // flag current transaction result
@@ -74,6 +91,7 @@ func (b *HRPBoomer) convertBoomerTask(testcase *TestCase) *boomer.Task {
// copy config to avoid data racing // copy config to avoid data racing
if err := copier.Copy(caseConfig, cfg); err != nil { if err := copier.Copy(caseConfig, cfg); err != nil {
log.Error().Err(err).Msg("copy config data failed") log.Error().Err(err).Msg("copy config data failed")
return
} }
// iterate through all parameter iterators and update case variables // iterate through all parameter iterators and update case variables
for _, it := range caseConfig.ParametersSetting.Iterators { for _, it := range caseConfig.ParametersSetting.Iterators {
@@ -81,6 +99,13 @@ func (b *HRPBoomer) convertBoomerTask(testcase *TestCase) *boomer.Task {
caseConfig.Variables = mergeVariables(it.Next(), caseConfig.Variables) caseConfig.Variables = mergeVariables(it.Next(), caseConfig.Variables)
} }
} }
config := runner.TestCase.Config
if err := runner.parseConfig(config); err != nil {
log.Error().Err(err).Msg("parse config failed")
return
}
startTime := time.Now() startTime := time.Now()
for index, step := range testcase.TestSteps { for index, step := range testcase.TestSteps {
stepData, err := runner.runStep(index, caseConfig) stepData, err := runner.runStep(index, caseConfig)

View File

@@ -6,6 +6,9 @@ import (
) )
func TestBoomerStandaloneRun(t *testing.T) { func TestBoomerStandaloneRun(t *testing.T) {
buildHashicorpPlugin()
defer removeHashicorpPlugin()
testcase1 := &TestCase{ testcase1 := &TestCase{
Config: NewConfig("TestCase1").SetBaseURL("http://httpbin.org"), Config: NewConfig("TestCase1").SetBaseURL("http://httpbin.org"),
TestSteps: []IStep{ TestSteps: []IStep{

View File

@@ -33,4 +33,4 @@ Copyright 2021 debugtalk
* [hrp run](hrp_run.md) - run API test * [hrp run](hrp_run.md) - run API test
* [hrp startproject](hrp_startproject.md) - create a scaffold project * [hrp startproject](hrp_startproject.md) - create a scaffold project
###### Auto generated by spf13/cobra on 17-Jan-2022 ###### Auto generated by spf13/cobra on 18-Jan-2022

View File

@@ -39,4 +39,4 @@ hrp boom [flags]
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing. * [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
###### Auto generated by spf13/cobra on 17-Jan-2022 ###### Auto generated by spf13/cobra on 18-Jan-2022

View File

@@ -23,4 +23,4 @@ hrp har2case $har_path... [flags]
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing. * [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
###### Auto generated by spf13/cobra on 17-Jan-2022 ###### Auto generated by spf13/cobra on 18-Jan-2022

View File

@@ -31,4 +31,4 @@ hrp run $path... [flags]
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing. * [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
###### Auto generated by spf13/cobra on 17-Jan-2022 ###### Auto generated by spf13/cobra on 18-Jan-2022

View File

@@ -16,4 +16,4 @@ hrp startproject $project_name [flags]
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing. * [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
###### Auto generated by spf13/cobra on 17-Jan-2022 ###### Auto generated by spf13/cobra on 18-Jan-2022

View File

@@ -2,8 +2,12 @@ package scaffold
import ( import (
"fmt" "fmt"
"os"
"os/exec"
"testing" "testing"
"github.com/rs/zerolog/log"
"github.com/httprunner/hrp" "github.com/httprunner/hrp"
) )
@@ -12,6 +16,21 @@ var (
demoTestCaseYAMLPath = "../../examples/demo.yaml" demoTestCaseYAMLPath = "../../examples/demo.yaml"
) )
func buildHashicorpPlugin() {
log.Info().Msg("[init] build hashicorp go plugin")
cmd := exec.Command("go", "build",
"-o", "../../examples/debugtalk.bin",
"../../examples/plugin/hashicorp.go", "../../examples/plugin/debugtalk.go")
if err := cmd.Run(); err != nil {
panic(err)
}
}
func removeHashicorpPlugin() {
log.Info().Msg("[teardown] remove hashicorp plugin")
os.Remove("../../examples/debugtalk.bin")
}
func TestGenDemoTestCase(t *testing.T) { func TestGenDemoTestCase(t *testing.T) {
tCase, _ := demoTestCase.ToTCase() tCase, _ := demoTestCase.ToTCase()
err := tCase.Dump2JSON(demoTestCaseJSONPath) err := tCase.Dump2JSON(demoTestCaseJSONPath)
@@ -25,6 +44,9 @@ func TestGenDemoTestCase(t *testing.T) {
} }
func Example_demo() { func Example_demo() {
buildHashicorpPlugin()
defer removeHashicorpPlugin()
demoTestCase.Config.ToStruct().Path = "../../examples/debugtalk.bin" demoTestCase.Config.ToStruct().Path = "../../examples/debugtalk.bin"
err := hrp.NewRunner(nil).Run(demoTestCase) // hrp.Run(demoTestCase) err := hrp.NewRunner(nil).Run(demoTestCase) // hrp.Run(demoTestCase)
fmt.Println(err) fmt.Println(err)
@@ -33,6 +55,9 @@ func Example_demo() {
} }
func Example_jsonDemo() { func Example_jsonDemo() {
buildHashicorpPlugin()
defer removeHashicorpPlugin()
testCase := &hrp.TestCasePath{Path: demoTestCaseJSONPath} testCase := &hrp.TestCasePath{Path: demoTestCaseJSONPath}
err := hrp.NewRunner(nil).Run(testCase) // hrp.Run(testCase) err := hrp.NewRunner(nil).Run(testCase) // hrp.Run(testCase)
fmt.Println(err) fmt.Println(err)
@@ -41,6 +66,9 @@ func Example_jsonDemo() {
} }
func Example_yamlDemo() { func Example_yamlDemo() {
buildHashicorpPlugin()
defer removeHashicorpPlugin()
testCase := &hrp.TestCasePath{Path: demoTestCaseYAMLPath} testCase := &hrp.TestCasePath{Path: demoTestCaseYAMLPath}
err := hrp.NewRunner(nil).Run(testCase) // hrp.Run(testCase) err := hrp.NewRunner(nil).Run(testCase) // hrp.Run(testCase)
fmt.Println(err) fmt.Println(err)

View File

@@ -1,18 +1,18 @@
package common package common
import ( import (
"fmt"
"os" "os"
"os/exec" "os/exec"
"testing" "testing"
"github.com/rs/zerolog/log"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func buildHashicorpPlugin() { func buildHashicorpPlugin() {
fmt.Println("[init] build hashicorp go plugin") log.Info().Msg("[init] build hashicorp go plugin")
cmd := exec.Command("go", "build", cmd := exec.Command("go", "build",
"-o=debugtalk.bin", "-o", "../../examples/debugtalk.bin",
"../../examples/plugin/hashicorp.go", "../../examples/plugin/debugtalk.go") "../../examples/plugin/hashicorp.go", "../../examples/plugin/debugtalk.go")
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
panic(err) panic(err)
@@ -20,15 +20,15 @@ func buildHashicorpPlugin() {
} }
func removeHashicorpPlugin() { func removeHashicorpPlugin() {
fmt.Println("[teardown] remove hashicorp plugin") log.Info().Msg("[teardown] remove hashicorp plugin")
os.Remove("debugtalk.bin") os.Remove("../../examples/debugtalk.bin")
} }
func TestInitHashicorpPlugin(t *testing.T) { func TestInitHashicorpPlugin(t *testing.T) {
buildHashicorpPlugin() buildHashicorpPlugin()
defer removeHashicorpPlugin() defer removeHashicorpPlugin()
plugin, err := Init("debugtalk.bin") plugin, err := Init("../../examples/debugtalk.bin")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@@ -156,12 +156,19 @@ func (r *caseRunner) reset() *caseRunner {
} }
func (r *caseRunner) run() error { func (r *caseRunner) run() error {
config := r.TestCase.Config
// init plugin
var err error
if r.parser.plugin, err = initPlugin(config.ToStruct().Path); err != nil {
return err
}
defer func() { defer func() {
if r.parser.plugin != nil { if r.parser.plugin != nil {
r.parser.plugin.Quit() r.parser.plugin.Quit()
} }
}() }()
config := r.TestCase.Config
if err := r.parseConfig(config); err != nil { if err := r.parseConfig(config); err != nil {
return err return err
} }
@@ -182,6 +189,33 @@ func (r *caseRunner) run() error {
return nil return nil
} }
func initPlugin(path string) (plugin common.Plugin, err error) {
defer func() {
if plugin == nil {
return
}
var pluginType string
if _, ok := plugin.(*common.GoPlugin); ok {
pluginType = "go"
} else {
pluginType = "hashicorp"
}
// report event for initializing plugin
event := ga.EventTracking{
Category: "InitPlugin",
Action: fmt.Sprintf("Init %s plugin", pluginType),
}
if err != nil {
event.Value = 1 // failed
}
go ga.SendEvent(event)
}()
plugin, err = common.Init(path)
return
}
func (r *caseRunner) runStep(index int, caseConfig *TConfig) (stepResult *stepData, err error) { func (r *caseRunner) runStep(index int, caseConfig *TConfig) (stepResult *stepData, err error) {
step := r.TestCase.TestSteps[index] step := r.TestCase.TestSteps[index]
@@ -504,34 +538,6 @@ func (r *caseRunner) runStepTestCase(step *TStep) (stepResult *stepData, err err
func (r *caseRunner) parseConfig(config IConfig) error { func (r *caseRunner) parseConfig(config IConfig) error {
cfg := config.ToStruct() cfg := config.ToStruct()
// init plugin
var err error
defer func() {
if r.parser.plugin == nil {
return
}
var pluginType string
if _, ok := r.parser.plugin.(*common.GoPlugin); ok {
pluginType = "go"
} else {
pluginType = "hashicorp"
}
// report event for initializing plugin
event := ga.EventTracking{
Category: "InitPlugin",
Action: fmt.Sprintf("Init %s plugin", pluginType),
}
if err != nil {
event.Value = 1 // failed
}
go ga.SendEvent(event)
}()
r.parser.plugin, err = common.Init(cfg.Path)
if err != nil {
return err
}
// parse config variables // parse config variables
parsedVariables, err := r.parser.parseVariables(cfg.Variables) parsedVariables, err := r.parser.parseVariables(cfg.Variables)
if err != nil { if err != nil {

View File

@@ -1,10 +1,32 @@
package hrp package hrp
import ( import (
"os"
"os/exec"
"testing" "testing"
"github.com/rs/zerolog/log"
) )
func buildHashicorpPlugin() {
log.Info().Msg("[init] build hashicorp go plugin")
cmd := exec.Command("go", "build",
"-o", "examples/debugtalk.bin",
"examples/plugin/hashicorp.go", "examples/plugin/debugtalk.go")
if err := cmd.Run(); err != nil {
panic(err)
}
}
func removeHashicorpPlugin() {
log.Info().Msg("[teardown] remove hashicorp plugin")
os.Remove("examples/debugtalk.bin")
}
func TestHttpRunner(t *testing.T) { func TestHttpRunner(t *testing.T) {
buildHashicorpPlugin()
defer removeHashicorpPlugin()
testcase1 := &TestCase{ testcase1 := &TestCase{
Config: NewConfig("TestCase1"). Config: NewConfig("TestCase1").
SetBaseURL("http://httpbin.org"), SetBaseURL("http://httpbin.org"),