Skip to content

Commit 26239a9

Browse files
author
poolqa
committed
first commit
0 parents  commit 26239a9

File tree

11 files changed

+769
-0
lines changed

11 files changed

+769
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/.idea

LICENSE

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2020, Hank Chen
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Transactions Request Pressure Test
2+
This is a simple tool for Http Pressure test.
3+
4+
You can use it on Windows system, and don't be afraid to encounter run out the port.
5+
6+
It can reuse the connection.
7+
8+
If this tool can help you, please don't forget to star me. :)
9+
10+
### TODO
11+
This tool is a semifinished product, if you want add some features, you can clone and fix it, or tall me.
12+
13+
### get it
14+
```bash
15+
go get github.com/poolqa/request_test
16+
```
17+
or
18+
```bash
19+
git clone https://github.com/poolqa/request_test
20+
```
21+
### build it
22+
```bash
23+
go build
24+
```
25+
### Run it
26+
27+
```bash
28+
request_test -c 3 -n 5 -u https://www.google.com -w
29+
30+
Thread count: 3
31+
Starting at: 2020/08/03 22:20:40.711046
32+
Finished at: 2020/08/03 22:20:41.067851
33+
34+
performance statistics :
35+
LE 1 Sec: count: 15
36+
-----------------------
37+
Total Count: 15
38+
39+
Use times: 356.8042ms
40+
Tps: 42.040 per/sec
41+
Availability: 100.00%
42+
Failed: 0
43+
Connection Times
44+
min max avg
45+
Response time: 47.0104ms 116.3257ms 7.755046ms
46+
Transaction time: 47.0104ms 116.3257ms 7.755046ms
47+
Build cli time: 0s 0s 0s
48+
49+
```
50+
### Usage
51+
```bash
52+
request_test -h
53+
Transactions Request Pressure Test/ v0.0.1
54+
Usage: pressure -c concurrency -n requests -t timeLimit -m method -u url -[dh]
55+
56+
Options:
57+
-c concurrency
58+
go routine(concurrency) count at same time. (default 1)
59+
-d show debug log
60+
-h this help
61+
-i int
62+
print interval for process request count time. (default 1)
63+
-m method
64+
http method name. (default "GET")
65+
-n requests
66+
requests at every concurrency
67+
-r show those routine's requests detail at report log,
68+
but it wall use more and more memory.
69+
-t timeLimit
70+
timeLimit Seconds to max. to spend on benchmarking, timer is start at all routine wake up.
71+
-u url
72+
target url
73+
-w waiting all routines stand-by.
74+
75+
```
76+
77+
### Copyright
78+
request_test is completely free. Please mark the source of request_test in your commercial product if possible.

bot/bot.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package bot
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"github.com/valyala/fasthttp"
7+
"request_test/flagArg"
8+
"request_test/performance"
9+
"runtime"
10+
"strings"
11+
"sync"
12+
"time"
13+
)
14+
15+
type OrderBot struct {
16+
ID int64
17+
Client *fasthttp.Client
18+
procCnt int64
19+
gId string
20+
}
21+
22+
func (bot *OrderBot) GetRoutineId() string {
23+
var (
24+
buf [64]byte
25+
n = runtime.Stack(buf[:], false)
26+
stk = strings.TrimPrefix(string(buf[:n]), "goroutine ")
27+
)
28+
29+
idField := strings.Fields(stk)[0]
30+
return idField
31+
}
32+
33+
func (bot *OrderBot) GetRunCount() int64 {
34+
return bot.procCnt
35+
}
36+
37+
func (bot *OrderBot) StandBy(ctx context.Context, wg *sync.WaitGroup, runCnt int64) {
38+
bot.gId = bot.GetRoutineId()
39+
if flagArg.FlagArgs.DebugLog {
40+
fmt.Printf("routine:%v start %v...\n", bot.gId, time.Now().Format("2006/01/02 15:04:05.999999"))
41+
}
42+
<- ctx.Done()
43+
44+
for bot.procCnt = int64(1); bot.procCnt <= runCnt; bot.procCnt++ {
45+
tps := &performance.Tps{
46+
ID: bot.ID,
47+
STime: time.Now(),
48+
}
49+
// send msg
50+
req := fasthttp.AcquireRequest()
51+
resp := fasthttp.AcquireResponse()
52+
53+
req.Header.SetMethod(flagArg.FlagArgs.Method)
54+
req.SetRequestURI(flagArg.FlagArgs.Url)
55+
56+
tps.SendTime = time.Now()
57+
err := bot.Client.Do(req, resp)
58+
tps.ETime = time.Now()
59+
if err != nil {
60+
tps.RespStatus = fasthttp.StatusBadRequest
61+
} else {
62+
tps.RespStatus = resp.StatusCode()
63+
}
64+
fasthttp.ReleaseResponse(resp)
65+
fasthttp.ReleaseRequest(req)
66+
67+
performance.Push(tps)
68+
}
69+
wg.Done()
70+
}

flagArg/flag.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package flagArg
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"math"
7+
"net/http"
8+
"os"
9+
"strings"
10+
)
11+
12+
var FlagArgs *FlagArg
13+
14+
func InitFlag(f *FlagArg) {
15+
16+
flag.Int64Var(&f.RoutineCount, "c", 1, "go routine(`concurrency`) count at same time.")
17+
flag.Int64Var(&f.RunCount, "n", 0, "`requests` at every concurrency")
18+
flag.Int64Var(&f.RunTimeSec, "t", 0, "`timeLimit` Seconds to max. to spend on benchmarking, timer is start at all routine wake up.")
19+
20+
flag.StringVar(&f.Method, "m", "GET", "http `method` name.")
21+
flag.StringVar(&f.Url, "u", "", "target `url`")
22+
23+
flag.BoolVar(&f.DebugLog, "d", false, "show debug log")
24+
flag.BoolVar(&f.ReportDetail, "r", false, "show those routine's requests detail at report log,\nbut it wall use more and more memory.")
25+
flag.BoolVar(&f.PreHeat, "w", false, "waiting all routines stand-by.")
26+
flag.Int64Var(&f.PrintInterval, "i", 1, "print interval for process request count time.")
27+
flag.BoolVar(&f.Help, "h", false, "this help")
28+
29+
flag.Usage = f.Usage
30+
}
31+
32+
type FlagArg struct {
33+
RoutineCount int64
34+
RunCount int64
35+
RunTimeSec int64
36+
Method string
37+
Url string
38+
TempFile string
39+
PreHeat bool
40+
DebugLog bool
41+
ReportDetail bool
42+
PrintInterval int64
43+
Help bool
44+
}
45+
46+
func (f *FlagArg) Usage() {
47+
_, _ = fmt.Fprintf(os.Stderr, `Transactions Request Pressure Test/ v0.0.1
48+
Usage: pressure -c concurrency -n requests -t timeLimit -m method -u url -[dh]
49+
50+
Options:
51+
`)
52+
flag.PrintDefaults()
53+
}
54+
55+
func (f *FlagArg) CheckFlag() bool {
56+
if f.Url == "" {
57+
fmt.Printf("You need to set url.\n")
58+
return false
59+
}
60+
if f.RoutineCount < 1 {
61+
fmt.Printf("You need to set concurrency >= 1.\n")
62+
return false
63+
}
64+
65+
if f.RunCount == 0 && f.RunTimeSec == 0 {
66+
fmt.Printf("You need to set request count or time limit.\n")
67+
return false
68+
}
69+
method := strings.ToUpper(f.Method)
70+
switch method {
71+
case http.MethodGet:
72+
case http.MethodHead:
73+
case http.MethodPost:
74+
case http.MethodPut:
75+
case http.MethodPatch:
76+
case http.MethodDelete:
77+
case http.MethodConnect:
78+
case http.MethodOptions:
79+
case http.MethodTrace:
80+
default:
81+
fmt.Printf("the method [%v] is wrong\n", f.Method)
82+
return false
83+
}
84+
if f.RunTimeSec > 0 {
85+
f.RunCount = math.MaxInt64
86+
}
87+
if f.PrintInterval < 1 {
88+
f.PrintInterval = 1
89+
}
90+
return true
91+
}
92+
93+

go.mod

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module request_test
2+
3+
go 1.14
4+
5+
require (
6+
github.com/shopspring/decimal v1.2.0
7+
github.com/valyala/fasthttp v1.15.1
8+
go.uber.org/atomic v1.6.0
9+
golang.org/x/text v0.3.3
10+
)

go.sum

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
2+
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
3+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6+
github.com/klauspost/compress v1.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqybrAg=
7+
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
8+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
9+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
10+
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
11+
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
12+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
13+
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
14+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
15+
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
16+
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
17+
github.com/valyala/fasthttp v1.15.1 h1:eRb5jzWhbCn/cGu3gNJMcOfPUfXgXCcQIOHjh9ajAS8=
18+
github.com/valyala/fasthttp v1.15.1/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA=
19+
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
20+
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
21+
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
22+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
23+
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
24+
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
25+
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
26+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
27+
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
28+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
29+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
30+
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
31+
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
32+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
33+
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
34+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
35+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
36+
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
37+
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c h1:IGkKhmfzcztjm6gYkykvu/NiS8kaqbCWAEWWAyf8J5U=
38+
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
39+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

0 commit comments

Comments
 (0)