mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-12 02:21:29 +08:00
refactor: hashicorp tests
This commit is contained in:
@@ -9,26 +9,49 @@ func init() {
|
||||
log.Println("plugin init function called")
|
||||
}
|
||||
|
||||
func SumInt(args ...interface{}) (interface{}, error) {
|
||||
func SumTwoInt(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
func SumInts(args ...int) int {
|
||||
var sum int
|
||||
for _, arg := range args {
|
||||
v, ok := arg.(int)
|
||||
if !ok {
|
||||
sum += arg
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func Sum(args ...interface{}) (interface{}, error) {
|
||||
var sum float64
|
||||
for _, arg := range args {
|
||||
switch v := arg.(type) {
|
||||
case int:
|
||||
sum += float64(v)
|
||||
case float64:
|
||||
sum += v
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected type: %T", arg)
|
||||
}
|
||||
sum += v
|
||||
}
|
||||
return sum, nil
|
||||
}
|
||||
|
||||
func ConcatenateString(args ...interface{}) (interface{}, error) {
|
||||
func SumTwoString(a, b string) string {
|
||||
return a + b
|
||||
}
|
||||
|
||||
func SumStrings(s ...string) string {
|
||||
var sum string
|
||||
for _, arg := range s {
|
||||
sum += arg
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func Concatenate(args ...interface{}) (interface{}, error) {
|
||||
var result string
|
||||
for _, arg := range args {
|
||||
v, ok := arg.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type: %T", arg)
|
||||
}
|
||||
result += v
|
||||
result += fmt.Sprintf("%v", arg)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
14
examples/plugin/hashicorp.go
Normal file
14
examples/plugin/hashicorp.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import "github.com/httprunner/hrp/plugin"
|
||||
|
||||
// register functions and build to plugin binary
|
||||
func main() {
|
||||
plugin.Register("sum_ints", SumInts)
|
||||
plugin.Register("sum_two_int", SumTwoInt)
|
||||
plugin.Register("sum", Sum)
|
||||
plugin.Register("sum_two_string", SumTwoString)
|
||||
plugin.Register("sum_strings", SumStrings)
|
||||
plugin.Register("concatenate", Concatenate)
|
||||
plugin.Serve()
|
||||
}
|
||||
@@ -15,7 +15,8 @@ import (
|
||||
func buildGoPlugin() {
|
||||
fmt.Println("[setup] build go plugin")
|
||||
// flag -race is necessary in order to be consistent with go test
|
||||
cmd := exec.Command("go", "build", "-buildmode=plugin", "-race", "-o=examples/debugtalk.so", "examples/plugin/debugtalk.go")
|
||||
cmd := exec.Command("go", "build", "-buildmode=plugin", "-race",
|
||||
"-o=examples/debugtalk.so", "examples/plugin/debugtalk.go")
|
||||
if err := cmd.Run(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -78,10 +79,13 @@ func TestCallPluginFunction(t *testing.T) {
|
||||
defer removeGoPlugin()
|
||||
|
||||
parser := newParser()
|
||||
parser.initPlugin("examples/debugtalk.so")
|
||||
err := parser.initPlugin("examples/debugtalk.so")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// call function without arguments
|
||||
result, err := parser.callFunc("ConcatenateString", "1", "2", "3.14")
|
||||
result, err := parser.callFunc("Concatenate", "1", 2, "3.14")
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package hrp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -6,22 +6,30 @@ import (
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/httprunner/hrp/plugin/host"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
fmt.Println("[TestMain] build go plugin")
|
||||
cmd := exec.Command("go", "build", "-o=debugtalk.bin", "./debugtalk.go")
|
||||
func buildHashicorpPlugin() {
|
||||
fmt.Println("[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)
|
||||
}
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func removeHashicorpPlugin() {
|
||||
fmt.Println("[teardown] remove hashicorp plugin")
|
||||
os.Remove("examples/debugtalk.bin")
|
||||
}
|
||||
|
||||
func TestInitHashicorpPlugin(t *testing.T) {
|
||||
f, err := host.Init("./debugtalk.bin")
|
||||
buildHashicorpPlugin()
|
||||
defer removeHashicorpPlugin()
|
||||
|
||||
f, err := host.Init("examples/debugtalk.bin")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/httprunner/hrp/plugin"
|
||||
)
|
||||
|
||||
func SumTwoInt(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
|
||||
func SumInts(args ...int) int {
|
||||
var sum int
|
||||
for _, arg := range args {
|
||||
sum += arg
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func Sum(args ...interface{}) (interface{}, error) {
|
||||
var sum float64
|
||||
for _, arg := range args {
|
||||
switch v := arg.(type) {
|
||||
case int:
|
||||
sum += float64(v)
|
||||
case float64:
|
||||
sum += v
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected type: %T", arg)
|
||||
}
|
||||
}
|
||||
return sum, nil
|
||||
}
|
||||
|
||||
func SumTwoString(a, b string) string {
|
||||
return a + b
|
||||
}
|
||||
|
||||
func SumStrings(s ...string) string {
|
||||
var sum string
|
||||
for _, arg := range s {
|
||||
sum += arg
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func Concatenate(args ...interface{}) (interface{}, error) {
|
||||
var result string
|
||||
for _, arg := range args {
|
||||
result += fmt.Sprintf("%v", arg)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// register functions and build to plugin binary
|
||||
func main() {
|
||||
plugin.Register("sum_ints", SumInts)
|
||||
plugin.Register("sum_two_int", SumTwoInt)
|
||||
plugin.Register("sum", Sum)
|
||||
plugin.Register("sum_two_string", SumTwoString)
|
||||
plugin.Register("sum_strings", SumStrings)
|
||||
plugin.Register("concatenate", Concatenate)
|
||||
plugin.Serve()
|
||||
}
|
||||
@@ -23,9 +23,28 @@ func CallFunc(fn reflect.Value, args ...interface{}) (interface{}, error) {
|
||||
for index, argument := range args {
|
||||
if argument == nil {
|
||||
argumentsValue[index] = reflect.Zero(fn.Type().In(index))
|
||||
} else {
|
||||
argumentsValue[index] = reflect.ValueOf(args[index])
|
||||
continue
|
||||
}
|
||||
|
||||
argumentValue := reflect.ValueOf(argument)
|
||||
expectArgumentType := fn.Type().In(index)
|
||||
actualArgumentType := reflect.TypeOf(argument)
|
||||
|
||||
// type match
|
||||
if expectArgumentType == actualArgumentType {
|
||||
argumentsValue[index] = argumentValue
|
||||
continue
|
||||
}
|
||||
|
||||
// type not match, check if convertible
|
||||
if !actualArgumentType.ConvertibleTo(expectArgumentType) {
|
||||
// function argument type not match and not convertible
|
||||
err := fmt.Errorf("function argument %d's type is neither match nor convertible, expect %v, actual %v",
|
||||
index, expectArgumentType, actualArgumentType)
|
||||
return nil, err
|
||||
}
|
||||
// convert argument to expect type
|
||||
argumentsValue[index] = argumentValue.Convert(expectArgumentType)
|
||||
}
|
||||
|
||||
resultValues := fn.Call(argumentsValue)
|
||||
@@ -40,8 +59,14 @@ func CallFunc(fn reflect.Value, args ...interface{}) (interface{}, error) {
|
||||
return resultValues[0].Interface(), nil
|
||||
}
|
||||
} else if len(resultValues) == 1 {
|
||||
// return one arguments: interface{}
|
||||
return resultValues[0].Interface(), nil
|
||||
// return one argument
|
||||
if err, ok := resultValues[0].Interface().(error); ok {
|
||||
// return error
|
||||
return nil, err
|
||||
} else {
|
||||
// return interface{}
|
||||
return resultValues[0].Interface(), nil
|
||||
}
|
||||
} else {
|
||||
// return more than 2 arguments, unexpected
|
||||
err := fmt.Errorf("function should return at most 2 arguments")
|
||||
62
plugin/shared/call_test.go
Normal file
62
plugin/shared/call_test.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package shared
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCallFunc(t *testing.T) {
|
||||
type data struct {
|
||||
f interface{}
|
||||
args []interface{}
|
||||
expVal interface{}
|
||||
expErr error
|
||||
}
|
||||
params := []data{
|
||||
// zero argument, zero return
|
||||
{f: func() {}, args: []interface{}{}, expVal: nil, expErr: nil},
|
||||
// zero argument, return one value
|
||||
{f: func() int { return 1 }, args: []interface{}{}, expVal: 1, expErr: nil},
|
||||
{f: func() string { return "a" }, args: []interface{}{}, expVal: "a", expErr: nil},
|
||||
{f: func() interface{} { return 1.23 }, args: []interface{}{}, expVal: 1.23, expErr: nil},
|
||||
// zero argument, return error
|
||||
{f: func() error { return errors.New("xxx") }, args: []interface{}{}, expVal: nil, expErr: errors.New("xxx")},
|
||||
// zero argument, return one value and error
|
||||
{f: func() (int, error) { return 1, errors.New("xxx") }, args: []interface{}{}, expVal: 1, expErr: errors.New("xxx")},
|
||||
{f: func() (interface{}, error) { return 1.23, errors.New("xxx") }, args: []interface{}{}, expVal: 1.23, expErr: errors.New("xxx")},
|
||||
// one argument, return one value
|
||||
{f: func(n int) int { return n * n }, args: []interface{}{2}, expVal: 4},
|
||||
{f: func(c string) string { return c + c }, args: []interface{}{"p"}, expVal: "pp"},
|
||||
{f: func(arg interface{}) interface{} { return fmt.Sprintf("%v", arg) }, args: []interface{}{1.23}, expVal: "1.23"},
|
||||
// two arguments in same type
|
||||
{f: func(a, b int) int { return a * b }, args: []interface{}{2, 3}, expVal: 6},
|
||||
// two arguments in different type
|
||||
{
|
||||
f: func(n int, c string) string {
|
||||
var s string
|
||||
for i := 0; i < n; i++ {
|
||||
s += c
|
||||
}
|
||||
return s
|
||||
},
|
||||
args: []interface{}{3, "p"},
|
||||
expVal: "ppp",
|
||||
},
|
||||
}
|
||||
|
||||
for _, p := range params {
|
||||
fn := reflect.ValueOf(p.f)
|
||||
val, err := CallFunc(fn, p.args...)
|
||||
if !assert.Equal(t, p.expErr, err) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !assert.Equal(t, p.expVal, val) {
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user