Skip to content

Commit

Permalink
format code
Browse files Browse the repository at this point in the history
  • Loading branch information
cnlh committed Mar 31, 2020
1 parent fd22286 commit a11e391
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 23 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ A simple benchmark testing tool implemented in golang, the basic functions refer
- simple code, easy to change
## Building

```
```shell script
git clone git://github.com/cnlh/benchmark.git
cd benchmark
go build
```
## Usage

basic usage is quite simple:
```
```shell script
benchmark [flags] url
```

with the flags being
```
```shell script
-b string
the body of request
-c int
Expand All @@ -40,7 +40,7 @@ with the flags being
proxy of request
```
for example
```
```shell script
benchmark -c 1100 -n 1000000 http://127.0.0.1/
```

Expand Down
21 changes: 13 additions & 8 deletions benchmark.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// Copyright 2020 The benchmark. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package main

import (
Expand All @@ -8,6 +12,7 @@ import (
"time"
)

// benchmark is used to manager connection and deal with the result
type benchmark struct {
connectionNum int
reqNum int64
Expand All @@ -23,6 +28,7 @@ type benchmark struct {
reqConnList []*ReqConn
}

// Start benchmark with the param has setting
func (pf *benchmark) Run() {
fmt.Printf("Running %d test @ %s by %d connections\n", pf.reqNum, pf.target, pf.connectionNum)
var err error
Expand Down Expand Up @@ -54,6 +60,7 @@ func (pf *benchmark) Run() {
return
}

// Print the result of benchmark on console
func (pf *benchmark) Print() {
readAll := 0
writeAll := 0
Expand All @@ -65,10 +72,10 @@ func (pf *benchmark) Print() {
allTimes = append(allTimes, v.reqTimes...)
allError += v.ErrorTimes
}
second := pf.endTime.Sub(pf.startTime).Seconds()
fmt.Printf("%d requests in %.2fs, %s read, %s write\n", pf.reqNum, second, formatFlow(float64(readAll)), formatFlow(float64(writeAll)))
fmt.Printf("Requests/sec: %.2f\n", float64(pf.reqNum)/second)
fmt.Printf("Transfer/sec: %s\n", formatFlow(float64(readAll+writeAll)/second))
runSecond := pf.endTime.Sub(pf.startTime).Seconds()
fmt.Printf("%d requests in %.2fs, %s read, %s write\n", pf.reqNum, runSecond, formatFlow(float64(readAll)), formatFlow(float64(writeAll)))
fmt.Printf("Requests/sec: %.2f\n", float64(pf.reqNum)/runSecond)
fmt.Printf("Transfer/sec: %s\n", formatFlow(float64(readAll+writeAll)/runSecond))
fmt.Printf("Error : %d\n", allError)
sort.Ints(allTimes)
rates := []int{50, 65, 75, 80, 90, 95, 98, 99, 100}
Expand All @@ -78,6 +85,7 @@ func (pf *benchmark) Print() {
}
}

// Format the flow data
func formatFlow(size float64) string {
var rt float64
var suffix string
Expand All @@ -87,7 +95,6 @@ func formatFlow(size float64) string {
MByte = KByte * 1024
GByte = MByte * 1024
)

if size > GByte {
rt = size / GByte
suffix = "GB"
Expand All @@ -101,7 +108,5 @@ func formatFlow(size float64) string {
rt = size
suffix = "bytes"
}

srt := fmt.Sprintf("%.2f%v", rt, suffix)
return srt
return fmt.Sprintf("%.2f%v", rt, suffix)
}
42 changes: 42 additions & 0 deletions benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package main

import (
"io"
"net/http"
"net/http/httputil"
"testing"
"time"
)

func TestMain(m *testing.M) {
// create a http server
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
io.WriteString(writer, "work well!")
})
go http.ListenAndServe(":15342", nil)
time.Sleep(time.Second)
m.Run()
}

func TestBenchmark_Run(t *testing.T) {
// create a request
r, err := http.NewRequest("GET", "http://127.0.0.0.1:15342", nil)
if err != nil {
t.Fatal(err)
}
writeBytes, err := httputil.DumpRequest(r, true)
if err != nil {
t.Fatal(err)
}
p := &benchmark{
connectionNum: 100,
reqNum: 20000,
requestBytes: writeBytes,
target: "127.0.0.1:15342",
schema: r.URL.Scheme,
timeout: 30000,
reqConnList: make([]*ReqConn, 0),
}
p.Run()
p.Print()
}
31 changes: 20 additions & 11 deletions connection.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// Copyright 2020 The benchmark. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package main

import (
Expand All @@ -17,12 +21,13 @@ import (
)

var (
rawBytes = []byte("\r\n\r\n")
rowBytes = []byte("\r\n")
lenBytes = []byte("Content-Length: ")
l = len(lenBytes)
bodyHeaderSepBytes = []byte{13, 10, 13, 10}
bodyHeaderSepBytesLen = 4
headerSepBytes = []byte{13, 10}
contentLengthBytes = []byte{67, 111, 110, 116, 101, 110, 116, 45, 76, 101, 110, 103, 116, 104, 58, 32}
contentLengthBytesLen = 16
)

// ReqConn is used to create a connection and record data
type ReqConn struct {
ErrorTimes int
Count int64
Expand All @@ -39,6 +44,8 @@ type ReqConn struct {
proxy string
}

// Connect to the server, http and socks5 proxy support
// If the target is https, convert connection to tls client
func (rc *ReqConn) dial() error {
if rc.conn != nil {
rc.conn.Close()
Expand Down Expand Up @@ -79,6 +86,7 @@ func (rc *ReqConn) dial() error {
return nil
}

// Start a connection, send request to server and read response from server
func (rc *ReqConn) Start() (err error) {
var contentLen string
var bodyHasRead int
Expand Down Expand Up @@ -110,16 +118,16 @@ re:
headerHasRead += n
rc.readLen += n
var bbArr [2][]byte
bodyPos := bytes.Index(rc.buf[:headerHasRead], rawBytes)
bodyPos := bytes.Index(rc.buf[:headerHasRead], bodyHeaderSepBytes)
if bodyPos > -1 {
bbArr[0] = rc.buf[:bodyPos]
bbArr[1] = rc.buf[bodyPos+len(rawBytes):]
bbArr[1] = rc.buf[bodyPos+bodyHeaderSepBytesLen:]
} else {
goto readHeader
}
n := bytes.Index(bbArr[0], lenBytes)
start := n + l
end := bytes.Index(bbArr[0][start:], rowBytes)
n := bytes.Index(bbArr[0], contentLengthBytes)
start := n + contentLengthBytesLen
end := bytes.Index(bbArr[0][start:], headerSepBytes)
if end == -1 {
contentLen = Bytes2str(bbArr[0][start:])
} else {
Expand All @@ -145,18 +153,19 @@ re:
}
}

// Convert bytes to strings
func Bytes2str(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}

// Create a connection by http proxy server
func NewHttpProxyConn(url *url.URL, remoteAddr string) (net.Conn, error) {
req, err := http.NewRequest("CONNECT", "http://"+remoteAddr, nil)
if err != nil {
return nil, err
}
password, _ := url.User.Password()
req.SetBasicAuth(url.User.Username(), password)
// we make a http proxy request
proxyConn, err := net.Dial("tcp", url.Host)
if err != nil {
return nil, err
Expand Down
9 changes: 9 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
// Copyright 2020 The benchmark. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package main

import (
"flag"
"fmt"
"net/http"
"net/http/httputil"
"net/url"
"runtime"
"strings"
)
Expand All @@ -23,6 +28,10 @@ var (

func main() {
flag.Parse()
if u, err := url.Parse(flag.Arg(0)); err != nil || u.Host == "" {
fmt.Printf("the request url %s is not correct \n", flag.Arg(0))
return
}
payload := strings.NewReader(*body)
req, err := http.NewRequest(*method, flag.Arg(0), payload)
if err != nil {
Expand Down

0 comments on commit a11e391

Please sign in to comment.