305 lines
7.4 KiB
Go
305 lines
7.4 KiB
Go
package hrp
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/httprunner/httprunner/v5/code"
|
|
)
|
|
|
|
func buildHashicorpGoPlugin() {
|
|
log.Info().Msg("[init] build hashicorp go plugin")
|
|
err := BuildPlugin(tmpl("plugin/debugtalk.go"), tmpl("debugtalk.bin"))
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("build hashicorp go plugin failed")
|
|
os.Exit(code.GetErrorCode(err))
|
|
}
|
|
}
|
|
|
|
func removeHashicorpGoPlugin() {
|
|
log.Info().Msg("[teardown] remove hashicorp go plugin")
|
|
os.Remove(tmpl("debugtalk.bin"))
|
|
pluginPath, _ := filepath.Abs(tmpl("debugtalk.bin"))
|
|
pluginMap.Delete(pluginPath)
|
|
}
|
|
|
|
func buildHashicorpPyPlugin() {
|
|
log.Info().Msg("[init] prepare hashicorp python plugin")
|
|
src, _ := os.ReadFile(tmpl("plugin/debugtalk.py"))
|
|
err := os.WriteFile(tmpl("debugtalk.py"), src, 0o644)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("copy hashicorp python plugin failed")
|
|
os.Exit(code.GetErrorCode(err))
|
|
}
|
|
}
|
|
|
|
func removeHashicorpPyPlugin() {
|
|
log.Info().Msg("[teardown] remove hashicorp python plugin")
|
|
// on v4.1^, running case will generate .debugtalk_gen.py used by python plugin
|
|
os.Remove(tmpl(PluginPySourceFile))
|
|
os.Remove(tmpl(PluginPySourceGenFile))
|
|
}
|
|
|
|
func TestRunCaseWithGoPlugin(t *testing.T) {
|
|
buildHashicorpGoPlugin()
|
|
defer removeHashicorpGoPlugin()
|
|
|
|
assertRunTestCases(t)
|
|
}
|
|
|
|
func TestRunCaseWithPythonPlugin(t *testing.T) {
|
|
buildHashicorpPyPlugin()
|
|
defer removeHashicorpPyPlugin()
|
|
|
|
assertRunTestCases(t)
|
|
}
|
|
|
|
func assertRunTestCases(t *testing.T) {
|
|
refCase := TestCasePath(demoTestCaseWithPluginJSONPath)
|
|
testcase1 := &TestCase{
|
|
Config: NewConfig("TestCase1").
|
|
SetBaseURL("https://postman-echo.com"),
|
|
TestSteps: []IStep{
|
|
NewStep("testcase1-step1").
|
|
GET("/headers").
|
|
Validate().
|
|
AssertEqual("status_code", 200, "check status code").
|
|
AssertEqual("headers.\"Content-Type\"", "application/json; charset=utf-8", "check http response Content-Type"),
|
|
NewStep("testcase1-step2").CallRefCase(
|
|
&TestCase{
|
|
Config: NewConfig("testcase1-step3-ref-case").SetBaseURL("https://postman-echo.com"),
|
|
TestSteps: []IStep{
|
|
NewStep("ip").
|
|
GET("/ip").
|
|
Validate().
|
|
AssertEqual("status_code", 200, "check status code").
|
|
AssertEqual("headers.\"Content-Type\"", "application/json; charset=utf-8", "check http response Content-Type"),
|
|
},
|
|
},
|
|
),
|
|
NewStep("testcase1-step3").CallRefCase(&refCase),
|
|
},
|
|
}
|
|
testcase2 := &TestCase{
|
|
Config: NewConfig("TestCase2").SetWeight(3),
|
|
}
|
|
|
|
r := NewRunner(t)
|
|
r.SetPluginLogOn()
|
|
err := r.Run(testcase1, testcase2)
|
|
if err != nil {
|
|
t.Fatalf("run testcase error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestRunCaseWithThinkTime(t *testing.T) {
|
|
buildHashicorpGoPlugin()
|
|
defer removeHashicorpGoPlugin()
|
|
|
|
testcases := []*TestCase{
|
|
{
|
|
Config: NewConfig("TestCase1"),
|
|
TestSteps: []IStep{
|
|
NewStep("thinkTime").SetThinkTime(2),
|
|
},
|
|
},
|
|
{
|
|
Config: NewConfig("TestCase2").
|
|
SetThinkTime(thinkTimeIgnore, nil, 0),
|
|
TestSteps: []IStep{
|
|
NewStep("thinkTime").SetThinkTime(0.5),
|
|
},
|
|
},
|
|
{
|
|
Config: NewConfig("TestCase3").
|
|
SetThinkTime(thinkTimeRandomPercentage, nil, 0),
|
|
TestSteps: []IStep{
|
|
NewStep("thinkTime").SetThinkTime(1),
|
|
},
|
|
},
|
|
{
|
|
Config: NewConfig("TestCase4").
|
|
SetThinkTime(thinkTimeRandomPercentage, map[string]interface{}{"min_percentage": 2, "max_percentage": 3}, 2.5),
|
|
TestSteps: []IStep{
|
|
NewStep("thinkTime").SetThinkTime(1),
|
|
},
|
|
},
|
|
{
|
|
Config: NewConfig("TestCase5"),
|
|
TestSteps: []IStep{
|
|
// think time: 3s, random pct: {"min_percentage":1, "max_percentage":1.5}, limit: 4s
|
|
NewStep("thinkTime").CallRefCase(&demoTestCaseWithThinkTimePath),
|
|
},
|
|
},
|
|
}
|
|
expectedMinValue := []float64{2, 0, 0.5, 2, 3}
|
|
expectedMaxValue := []float64{2.5, 0.5, 2, 3, 10}
|
|
for idx, testcase := range testcases {
|
|
r := NewRunner(t)
|
|
startTime := time.Now()
|
|
err := r.Run(testcase)
|
|
if err != nil {
|
|
t.Fatalf("run testcase error: %v", err)
|
|
}
|
|
duration := time.Since(startTime)
|
|
minValue := time.Duration(expectedMinValue[idx]*1000) * time.Millisecond
|
|
maxValue := time.Duration(expectedMaxValue[idx]*1000) * time.Millisecond
|
|
if duration < minValue || duration > maxValue {
|
|
t.Fatalf("failed to test think time, expect value: [%v, %v], actual value: %v", minValue, maxValue, duration)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRunCaseWithShell(t *testing.T) {
|
|
testcase1 := &TestCase{
|
|
Config: NewConfig("complex shell with env variables").
|
|
WithVariables(map[string]interface{}{
|
|
"SS": "12345",
|
|
"ABC": "$SS",
|
|
}),
|
|
TestSteps: []IStep{
|
|
NewStep("shell21").Shell("echo hello world"),
|
|
// NewStep("shell21").Shell("echo $ABC"),
|
|
// NewStep("shell21").Shell("which hrp"),
|
|
},
|
|
}
|
|
|
|
r := NewRunner(t)
|
|
err := r.Run(testcase1)
|
|
if err != nil {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
func TestRunCaseWithFunction(t *testing.T) {
|
|
fn1 := func() {
|
|
fmt.Println("call function1 without return")
|
|
}
|
|
num := 0
|
|
fn2 := func() {
|
|
num++
|
|
fmt.Println("call function2 with return value")
|
|
}
|
|
var err3 error
|
|
fn3 := func() {
|
|
num++
|
|
err3 = errors.New("func3 error")
|
|
fmt.Println("call function3 with return value and error")
|
|
}
|
|
testcase1 := &TestCase{
|
|
Config: NewConfig("call function"),
|
|
TestSteps: []IStep{
|
|
NewStep("fn1").Function(fn1),
|
|
NewStep("fn2").Function(fn2),
|
|
NewStep("fn3").Function(fn3),
|
|
},
|
|
}
|
|
|
|
r := NewRunner(t)
|
|
err := r.Run(testcase1)
|
|
if err != nil {
|
|
t.Fatal()
|
|
}
|
|
|
|
if !assert.Equal(t, num, 2) {
|
|
t.Fatal()
|
|
}
|
|
if !assert.NotNil(t, err3) {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
func TestRunCaseWithPluginJSON(t *testing.T) {
|
|
buildHashicorpGoPlugin()
|
|
defer removeHashicorpGoPlugin()
|
|
|
|
testCase := TestCasePath(demoTestCaseWithPluginJSONPath)
|
|
err := NewRunner(nil).Run(&testCase) // hrp.Run(testCase)
|
|
if err != nil {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
// TODO: FIXME
|
|
// func TestRunCaseWithPluginYAML(t *testing.T) {
|
|
// buildHashicorpGoPlugin()
|
|
// defer removeHashicorpGoPlugin()
|
|
|
|
// testCase := TestCasePath(demoTestCaseWithPluginYAMLPath)
|
|
// err := NewRunner(nil).Run(&testCase) // hrp.Run(testCase)
|
|
// if err != nil {
|
|
// t.Fatal()
|
|
// }
|
|
// }
|
|
|
|
func TestRunCaseWithRefAPI(t *testing.T) {
|
|
buildHashicorpGoPlugin()
|
|
defer removeHashicorpGoPlugin()
|
|
|
|
testCase := TestCasePath(demoTestCaseWithRefAPIPath)
|
|
err := NewRunner(nil).Run(&testCase)
|
|
if err != nil {
|
|
t.Fatal()
|
|
}
|
|
|
|
refAPI := APIPath(demoAPIGETPath)
|
|
testcase := &TestCase{
|
|
Config: NewConfig("TestCase").
|
|
SetBaseURL("https://postman-echo.com"),
|
|
TestSteps: []IStep{
|
|
NewStep("run referenced api").CallRefAPI(&refAPI),
|
|
},
|
|
}
|
|
|
|
r := NewRunner(t)
|
|
err = r.Run(testcase)
|
|
if err != nil {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
|
|
func TestSessionRunner(t *testing.T) {
|
|
testcase := TestCase{
|
|
Config: NewConfig("TestCase").
|
|
WithVariables(map[string]interface{}{
|
|
"a": 12.3,
|
|
"b": 3.45,
|
|
"varFoo": "${max($a, $b)}",
|
|
}),
|
|
TestSteps: []IStep{
|
|
NewStep("check variables").
|
|
WithVariables(map[string]interface{}{
|
|
"a": 12.3,
|
|
"b": 34.5,
|
|
"varFoo": "${max($a, $b)}",
|
|
}).
|
|
GET("/hello").
|
|
Validate().
|
|
AssertEqual("status_code", 200, "check status code"),
|
|
// AssertEqual("$varFoo", "$b", "check varFoo value"),
|
|
},
|
|
}
|
|
|
|
caseRunner, _ := NewRunner(t).NewCaseRunner(testcase)
|
|
sessionRunner := caseRunner.NewSession()
|
|
step := testcase.TestSteps[0]
|
|
if !assert.Equal(t, step.Config().Variables["varFoo"], "${max($a, $b)}") {
|
|
t.Fatal()
|
|
}
|
|
|
|
err := sessionRunner.ParseStep(step)
|
|
if err != nil {
|
|
t.Fatal()
|
|
}
|
|
if !assert.Equal(t, step.Config().Variables["varFoo"], 34.5) {
|
|
t.Fatal()
|
|
}
|
|
}
|