Help Center/
CodeArts PerfTest/
User Guide/
PerfTest Case Management/
Plug-in Management/
Custom Examples
Updated on 2023-07-13 GMT+08:00
Custom Examples
Custom Request Example
Example of a custom Go request:
package main
import (
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/http/cookiejar"
"strings"
"sync"
)
var (
trs = sync.Map{}
jars = sync.Map{}
)
func getTr(addr string) *http.Transport {
if v, ok := trs.Load(addr); ok {
return v.(*http.Transport)
} else {
tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
MaxConnsPerHost: 5000,
MaxIdleConnsPerHost: 5000,
}
v, _ = trs.LoadOrStore(addr, tr)
return v.(*http.Transport)
}
}
func getJar(goroutineId string) *cookiejar.Jar {
if v, ok := jars.Load(goroutineId); ok {
return v.(*cookiejar.Jar)
} else {
jar, _ := cookiejar.New(nil)
v, _ = jars.LoadOrStore(goroutineId, jar)
return v.(*cookiejar.Jar)
}
}
func outgoingLength(req *http.Request) int64 {
if req.Body == nil || req.Body == http.NoBody {
return 0
}
if req.ContentLength != 0 {
return req.ContentLength
}
return -1
}
func redirectBehavior(reqMethod string, resp *http.Response, req *http.Request) (redirectMethod string, shouldRedirect, includeBody bool) {
switch resp.StatusCode {
case 301, 302, 303:
redirectMethod = reqMethod
shouldRedirect = true
includeBody = false
if reqMethod != "GET" && reqMethod != "HEAD" {
redirectMethod = "GET"
}
case 307, 308:
redirectMethod = reqMethod
shouldRedirect = true
includeBody = true
if resp.Header.Get("Location") == "" {
shouldRedirect = false
break
}
if req.GetBody == nil && outgoingLength(req) != 0 {
shouldRedirect = false
}
}
return redirectMethod, shouldRedirect, includeBody
}
func Do(params map[string]string) interface{} {
parent := acquireResult(params[InnerVarName])
sub := parent
var (
err error
redirectCount int
req *http.Request
res *http.Response
)
defer func() {
if p := recover(); p != nil {
sub.ResponseCode = 500
sub.Success = false
sub.FailureMessage = fmt.Sprintf("%v", sub)
} else if err != nil {
sub.ResponseCode = 500
sub.Success = false
sub.FailureMessage = err.Error()
}
}()
redirect := params["redirect"]
for {
// process params
url, method, body := params["url"], params["method"], params["body"]
sub.Url, sub.Method, sub.RequestBody = url, method, body
sub.SentBytes = len(body)
// create request
req, err = http.NewRequest(method, url, strings.NewReader(body))
if err != nil {
return parent
}
// load cookies
jar := getJar(params[InnerVarGoroutineId])
cookies := jar.Cookies(req.URL)
for _, c := range cookies {
req.AddCookie(c)
}
// write headers
if params["headers"] != "" {
headers := map[string][]string{}
if err = json.Unmarshal([]byte(params["headers"]), &headers); err != nil {
return parent
}
for k, vs := range headers {
for _, v := range vs {
req.Header.Add(k, v)
}
}
}
for k, v := range req.Header {
sub.RequestHeader[k] = strings.Join(v, ",")
}
// do request
sub.begin()
res, err = getTr(fmt.Sprintf("%s://%s", req.URL.Scheme, req.URL.Host)).RoundTrip(req)
sub.end()
if err != nil {
return parent
}
var b []byte
b, err = ioutil.ReadAll(res.Body)
if err != nil {
_ = res.Body.Close()
return parent
}
// store cookies
jar.SetCookies(req.URL, res.Cookies())
for k, v := range res.Header {
sub.ResponseHeader[k] = strings.Join(v, ",")
}
sub.ResponseBody = string(b)
sub.ReceivedBytes = len(b)
sub.ResponseCode = res.StatusCode
_ = res.Body.Close()
if redirect != "on" {
break
}
if redirectMethod, shouldRedirect, includeBody := redirectBehavior(method, res, req); shouldRedirect {
redirectCount++
if redirectCount > 10 {
err = errors.New("stopped after 10 redirects")
return parent
}
params["url"] = res.Header.Get("Location")
params["method"] = redirectMethod
if !includeBody {
params["body"] = ""
}
parent = acquireResult(params[InnerVarName])
sub = parent
continue
}
break
}
return parent
}
Example of a custom request in JSON format:
{
"name": "Http 1.0",
"plugin": "http.so",
"desc": "Http plugin supports http 1.0 test.",
"funcs": [
{
"name": "Do",
"type": "req",
"desc": "This is the entry of http request.",
"params": [
{
"name": "url",
"default": "",
"range": [],
"desc": "The url of http request",
"required": true
},
{
"name": "headers",
"default": "{\"Content-Type\": [\"text/plain;utf-8\"]}",
"range": [],
"desc": "The headers of http request",
"required": true
},
{
"name": "method",
"default": "GET",
"range": [
"GET",
"HEAD",
"POST",
"PUT",
"PATCH",
"DELETE",
"CONNECT",
"OPTIONS",
"TRACE"
],
"desc": "The method of http request",
"required": true
},
{
"name": "body",
"default": "",
"range": [],
"desc": "The body of http request",
"required": true
},
{
"name": "redirect",
"default": "on",
"range": [
"on",
"off"
],
"desc": "If enable auto redirect",
"required": true
}
]
}
]
}
Example of a Custom Function
Example of a custom Go function:
package main
import (
"fmt"
"math/rand"
"strconv"
)
func RandomNum(params map[string]string) (s string) {
var err error
defer func() {
if r := recover(); r != nil {
s = fmt.Sprintf("%v", r)
} else if err != nil {
s = err.Error()
}
}()
min, err := strconv.ParseInt(params["min"], 10, 64)
if err != nil {
return
}
max, err := strconv.ParseInt(params["max"], 10, 64)
if err != nil {
return
}
if min > max {
min, max = max, min
}
return strconv.FormatInt(min+rand.Int63n(max-min+1), 10)
}
var (
charSet = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
)
func RandomText(params map[string]string) (s string) {
var err error
defer func() {
if r := recover(); r != nil {
s = fmt.Sprintf("%v", r)
} else if err != nil {
s = err.Error()
}
}()
length, err := strconv.ParseInt(params["length"], 10, 64)
if err != nil {
return
}
if length == 0 {
return ""
}
set := []rune(params["charset"])
if len(set) == 0 {
set = charSet
}
n := len(set)
rs := make([]rune, length)
for i := int64(0); i < length; i++ {
rs[i] = set[rand.Intn(n)]
}
return string(rs)
}
Example of a custom JSON function:
{
"name": "Random",
"plugin": "random.so",
"desc": "Random plugin supports generating random value.",
"funcs": [
{
"name": "RandomNum",
"type": "func",
"desc": "RandomNum generates random number.",
"params": [
{
"name": "min",
"default": "0",
"range": [],
"desc": "The maximum of random number.",
"required": true
},
{
"name": "max",
"default": "100",
"range": [],
"desc": "The maximum of random number.",
"required": true
}
]
},
{
"name": "RandomText",
"type": "func",
"desc": "RandomText generates random text of a specified length.",
"params": [
{
"name": "length",
"default": "32",
"range": [],
"desc": "The length of random text.",
"required": true
},
{
"name": "charset",
"default": "",
"range": [],
"desc": "Random text is generated randomly from the specified character set. if empty, default char set is 0-9 a-z A-Z",
"required": false
}
]
}
]
}
Parent topic: Plug-in Management
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.See the reply and handling status in My Cloud VOC.
The system is busy. Please try again later.
For any further questions, feel free to contact us through the chatbot.
Chatbot