mirror of
https://github.com/versity/versitygw.git
synced 2026-01-30 15:02:02 +00:00
Compare commits
1 Commits
ben/plugin
...
proxy-test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27a8aa66d9 |
@@ -2,6 +2,9 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
"text/tabwriter"
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"github.com/versity/versitygw/integration"
|
"github.com/versity/versitygw/integration"
|
||||||
@@ -13,6 +16,7 @@ var (
|
|||||||
endpoint string
|
endpoint string
|
||||||
prefix string
|
prefix string
|
||||||
dstBucket string
|
dstBucket string
|
||||||
|
proxyURL string
|
||||||
partSize int64
|
partSize int64
|
||||||
objSize int64
|
objSize int64
|
||||||
concurrency int
|
concurrency int
|
||||||
@@ -118,6 +122,7 @@ func initTestCommands() []*cli.Command {
|
|||||||
Name: "bucket",
|
Name: "bucket",
|
||||||
Usage: "Destination bucket name to read/write data",
|
Usage: "Destination bucket name to read/write data",
|
||||||
Destination: &dstBucket,
|
Destination: &dstBucket,
|
||||||
|
Required: true,
|
||||||
},
|
},
|
||||||
&cli.Int64Flag{
|
&cli.Int64Flag{
|
||||||
Name: "partSize",
|
Name: "partSize",
|
||||||
@@ -143,6 +148,11 @@ func initTestCommands() []*cli.Command {
|
|||||||
Value: false,
|
Value: false,
|
||||||
Destination: &checksumDisable,
|
Destination: &checksumDisable,
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "proxy-url",
|
||||||
|
Usage: "S3 proxy server url to compare",
|
||||||
|
Destination: &proxyURL,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: func(ctx *cli.Context) error {
|
Action: func(ctx *cli.Context) error {
|
||||||
if upload && download {
|
if upload && download {
|
||||||
@@ -152,10 +162,6 @@ func initTestCommands() []*cli.Command {
|
|||||||
return fmt.Errorf("must specify one of upload or download")
|
return fmt.Errorf("must specify one of upload or download")
|
||||||
}
|
}
|
||||||
|
|
||||||
if dstBucket == "" {
|
|
||||||
return fmt.Errorf("must specify bucket")
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := []integration.Option{
|
opts := []integration.Option{
|
||||||
integration.WithAccess(awsID),
|
integration.WithAccess(awsID),
|
||||||
integration.WithSecret(awsSecret),
|
integration.WithSecret(awsSecret),
|
||||||
@@ -177,9 +183,47 @@ func initTestCommands() []*cli.Command {
|
|||||||
s3conf := integration.NewS3Conf(opts...)
|
s3conf := integration.NewS3Conf(opts...)
|
||||||
|
|
||||||
if upload {
|
if upload {
|
||||||
return integration.TestUpload(s3conf, files, objSize, dstBucket, prefix)
|
if proxyURL == "" {
|
||||||
|
integration.TestUpload(s3conf, files, objSize, dstBucket, prefix)
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
size, elapsed, err := integration.TestUpload(s3conf, files, objSize, dstBucket, prefix)
|
||||||
|
opts = append(opts, integration.WithEndpoint(proxyURL))
|
||||||
|
proxyS3Conf := integration.NewS3Conf(opts...)
|
||||||
|
proxySize, proxyElapsed, proxyErr := integration.TestUpload(proxyS3Conf, files, objSize, dstBucket, prefix)
|
||||||
|
if err != nil || proxyErr != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
printProxyResultsTable([][4]string{
|
||||||
|
{" # ", "Total Size", "Time Taken", "Speed(MB/S)"},
|
||||||
|
{"---------", "----------", "----------", "-----------"},
|
||||||
|
{"S3 Server", fmt.Sprint(size), fmt.Sprintf("%v", elapsed), fmt.Sprint(int(math.Ceil(float64(size)/elapsed.Seconds()) / 1048576))},
|
||||||
|
{"S3 Proxy", fmt.Sprint(proxySize), fmt.Sprintf("%v", proxyElapsed), fmt.Sprint(int(math.Ceil(float64(proxySize)/proxyElapsed.Seconds()) / 1048576))},
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return integration.TestDownload(s3conf, files, objSize, dstBucket, prefix)
|
if proxyURL == "" {
|
||||||
|
integration.TestDownload(s3conf, files, objSize, dstBucket, prefix)
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
size, elapsed, err := integration.TestDownload(s3conf, files, objSize, dstBucket, prefix)
|
||||||
|
opts = append(opts, integration.WithEndpoint(proxyURL))
|
||||||
|
proxyS3Conf := integration.NewS3Conf(opts...)
|
||||||
|
proxySize, proxyElapsed, proxyErr := integration.TestDownload(proxyS3Conf, files, objSize, dstBucket, prefix)
|
||||||
|
if err != nil || proxyErr != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
printProxyResultsTable([][4]string{
|
||||||
|
{" # ", "Total Size", "Time Taken", "Speed(MB/S)"},
|
||||||
|
{"---------", "----------", "----------", "-----------"},
|
||||||
|
{"S3 server", fmt.Sprint(size), fmt.Sprintf("%v", elapsed), fmt.Sprint(int(math.Ceil(float64(size)/elapsed.Seconds()) / 1048576))},
|
||||||
|
{"S3 proxy", fmt.Sprint(proxySize), fmt.Sprintf("%v", proxyElapsed), fmt.Sprint(int(math.Ceil(float64(proxySize)/proxyElapsed.Seconds()) / 1048576))},
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -211,12 +255,13 @@ func initTestCommands() []*cli.Command {
|
|||||||
Value: false,
|
Value: false,
|
||||||
Destination: &checksumDisable,
|
Destination: &checksumDisable,
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "proxy-url",
|
||||||
|
Usage: "S3 proxy server url to compare",
|
||||||
|
Destination: &proxyURL,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: func(ctx *cli.Context) error {
|
Action: func(ctx *cli.Context) error {
|
||||||
if dstBucket == "" {
|
|
||||||
return fmt.Errorf("must specify the destination bucket")
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := []integration.Option{
|
opts := []integration.Option{
|
||||||
integration.WithAccess(awsID),
|
integration.WithAccess(awsID),
|
||||||
integration.WithSecret(awsSecret),
|
integration.WithSecret(awsSecret),
|
||||||
@@ -233,7 +278,27 @@ func initTestCommands() []*cli.Command {
|
|||||||
|
|
||||||
s3conf := integration.NewS3Conf(opts...)
|
s3conf := integration.NewS3Conf(opts...)
|
||||||
|
|
||||||
return integration.TestReqPerSec(s3conf, totalReqs, dstBucket)
|
if proxyURL == "" {
|
||||||
|
_, _, err := integration.TestReqPerSec(s3conf, totalReqs, dstBucket)
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
elapsed, rps, err := integration.TestReqPerSec(s3conf, totalReqs, dstBucket)
|
||||||
|
opts = append(opts, integration.WithEndpoint(proxyURL))
|
||||||
|
s3proxy := integration.NewS3Conf(opts...)
|
||||||
|
proxyElapsed, proxyRPS, proxyErr := integration.TestReqPerSec(s3proxy, totalReqs, dstBucket)
|
||||||
|
if err != nil || proxyErr != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
printProxyResultsTable([][4]string{
|
||||||
|
{" # ", "Total Requests", "Time Taken", "Requests Per Second(Req/Sec)"},
|
||||||
|
{"---------", "--------------", "----------", "----------------------------"},
|
||||||
|
{"S3 Server", fmt.Sprint(totalReqs), fmt.Sprintf("%v", elapsed), fmt.Sprint(rps)},
|
||||||
|
{"S3 Proxy", fmt.Sprint(totalReqs), fmt.Sprintf("%v", proxyElapsed), fmt.Sprint(proxyRPS)},
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -264,3 +329,13 @@ func getAction(tf testFunc) func(*cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func printProxyResultsTable(stats [][4]string) {
|
||||||
|
w := new(tabwriter.Writer)
|
||||||
|
w.Init(os.Stdout, minwidth, tabwidth, padding, padchar, flags)
|
||||||
|
for _, elem := range stats {
|
||||||
|
fmt.Fprintf(w, "%v\t%v\t%v\t%v\n", elem[0], elem[1], elem[2], elem[3])
|
||||||
|
}
|
||||||
|
fmt.Fprintln(w)
|
||||||
|
w.Flush()
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,16 +17,16 @@ type prefResult struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpload(s *S3Conf, files int, objSize int64, bucket, prefix string) error {
|
func TestUpload(s *S3Conf, files int, objSize int64, bucket, prefix string) (size int64, elapsed time.Duration, err error) {
|
||||||
var sg sync.WaitGroup
|
var sg sync.WaitGroup
|
||||||
results := make([]prefResult, files)
|
results := make([]prefResult, files)
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
if objSize == 0 {
|
if objSize == 0 {
|
||||||
return fmt.Errorf("must specify object size for upload")
|
return 0, time.Since(start), fmt.Errorf("must specify object size for upload")
|
||||||
}
|
}
|
||||||
|
|
||||||
if objSize > (int64(10000) * s.PartSize) {
|
if objSize > (int64(10000) * s.PartSize) {
|
||||||
return fmt.Errorf("object size can not exceed 10000 * chunksize")
|
return 0, time.Since(start), fmt.Errorf("object size can not exceed 10000 * chunksize")
|
||||||
}
|
}
|
||||||
|
|
||||||
runF("performance test: upload objects")
|
runF("performance test: upload objects")
|
||||||
@@ -45,13 +45,13 @@ func TestUpload(s *S3Conf, files int, objSize int64, bucket, prefix string) erro
|
|||||||
}(i)
|
}(i)
|
||||||
}
|
}
|
||||||
sg.Wait()
|
sg.Wait()
|
||||||
elapsed := time.Since(start)
|
elapsed = time.Since(start)
|
||||||
|
|
||||||
var tot int64
|
var tot int64
|
||||||
for i, res := range results {
|
for i, res := range results {
|
||||||
if res.err != nil {
|
if res.err != nil {
|
||||||
failF("%v: %v\n", i, res.err)
|
failF("%v: %v\n", i, res.err)
|
||||||
break
|
return 0, time.Since(start), res.err
|
||||||
}
|
}
|
||||||
tot += res.size
|
tot += res.size
|
||||||
fmt.Printf("%v: %v in %v (%v MB/s)\n",
|
fmt.Printf("%v: %v in %v (%v MB/s)\n",
|
||||||
@@ -63,10 +63,10 @@ func TestUpload(s *S3Conf, files int, objSize int64, bucket, prefix string) erro
|
|||||||
passF("run upload: %v in %v (%v MB/s)\n",
|
passF("run upload: %v in %v (%v MB/s)\n",
|
||||||
tot, elapsed, int(math.Ceil(float64(tot)/elapsed.Seconds())/1048576))
|
tot, elapsed, int(math.Ceil(float64(tot)/elapsed.Seconds())/1048576))
|
||||||
|
|
||||||
return nil
|
return tot, time.Since(start), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDownload(s *S3Conf, files int, objSize int64, bucket, prefix string) error {
|
func TestDownload(s *S3Conf, files int, objSize int64, bucket, prefix string) (size int64, elapsed time.Duration, err error) {
|
||||||
var sg sync.WaitGroup
|
var sg sync.WaitGroup
|
||||||
results := make([]prefResult, files)
|
results := make([]prefResult, files)
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
@@ -86,13 +86,13 @@ func TestDownload(s *S3Conf, files int, objSize int64, bucket, prefix string) er
|
|||||||
}(i)
|
}(i)
|
||||||
}
|
}
|
||||||
sg.Wait()
|
sg.Wait()
|
||||||
elapsed := time.Since(start)
|
elapsed = time.Since(start)
|
||||||
|
|
||||||
var tot int64
|
var tot int64
|
||||||
for i, res := range results {
|
for i, res := range results {
|
||||||
if res.err != nil {
|
if res.err != nil {
|
||||||
failF("%v: %v\n", i, res.err)
|
failF("%v: %v\n", i, res.err)
|
||||||
break
|
return 0, elapsed, err
|
||||||
}
|
}
|
||||||
tot += res.size
|
tot += res.size
|
||||||
fmt.Printf("%v: %v in %v (%v MB/s)\n",
|
fmt.Printf("%v: %v in %v (%v MB/s)\n",
|
||||||
@@ -104,10 +104,10 @@ func TestDownload(s *S3Conf, files int, objSize int64, bucket, prefix string) er
|
|||||||
passF("run download: %v in %v (%v MB/s)\n",
|
passF("run download: %v in %v (%v MB/s)\n",
|
||||||
tot, elapsed, int(math.Ceil(float64(tot)/elapsed.Seconds())/1048576))
|
tot, elapsed, int(math.Ceil(float64(tot)/elapsed.Seconds())/1048576))
|
||||||
|
|
||||||
return nil
|
return tot, elapsed, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReqPerSec(s *S3Conf, totalReqs int, bucket string) error {
|
func TestReqPerSec(s *S3Conf, totalReqs int, bucket string) (time.Duration, int, error) {
|
||||||
client := s3.NewFromConfig(s.Config())
|
client := s3.NewFromConfig(s.Config())
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var resErr error
|
var resErr error
|
||||||
@@ -132,11 +132,11 @@ func TestReqPerSec(s *S3Conf, totalReqs int, bucket string) error {
|
|||||||
wg.Wait()
|
wg.Wait()
|
||||||
if resErr != nil {
|
if resErr != nil {
|
||||||
failF("performance test failed with error: %w", resErr)
|
failF("performance test failed with error: %w", resErr)
|
||||||
return nil
|
return time.Since(startTime), 0, resErr
|
||||||
}
|
}
|
||||||
elapsedTime := time.Since(startTime)
|
elapsedTime := time.Since(startTime)
|
||||||
rps := int(float64(totalReqs) / elapsedTime.Seconds())
|
rps := int(float64(totalReqs) / elapsedTime.Seconds())
|
||||||
|
|
||||||
passF("Success\nTotal Requests: %d,\nConcurrency Level: %d,\nTime Taken: %s,\nRequests Per Second: %dreq/sec", totalReqs, s.Concurrency, elapsedTime, rps)
|
passF("Success\nTotal Requests: %d,\nConcurrency Level: %d,\nTime Taken: %s,\nRequests Per Second: %dreq/sec", totalReqs, s.Concurrency, elapsedTime, rps)
|
||||||
return nil
|
return elapsedTime, rps, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user