Benchmark options (#5684)

* make benchmark clients remember cookies

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>

* add --rate option for benchmark clients

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>

* create a new request on every request to fix vanishing data

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>

* use corret minute unit

Co-authored-by: Florian Schade <f.schade@icloud.com>

---------

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
Co-authored-by: Florian Schade <f.schade@icloud.com>
This commit is contained in:
Jörn Friedrich Dreyer
2023-03-07 11:37:14 +01:00
committed by GitHub
parent 7750492de4
commit 43547cc681

View File

@@ -71,6 +71,11 @@ func BenchmarkClientCommand(cfg *config.Config) *cli.Command {
Aliases: []string{"H"},
Usage: "Extra header to include in information sent.",
},
&cli.StringFlag{
Name: "rate",
Usage: `Specify the maximum transfer frequency you allow a client to use - in number of transfer starts per time unit (sometimes called request rate).
The request rate is provided as "N/U" where N is an integer number and U is a time unit. Supported units are 's' (second), 'm' (minute), 'h' (hour) and 'd' /(day, as in a 24 hour unit). The default time unit, if no "/U" is provided, is number of transfers per hour.`,
},
/*
&cli.StringFlag{
Name: "oauth2-bearer",
@@ -121,6 +126,29 @@ func BenchmarkClientCommand(cfg *config.Config) *cli.Command {
opt.headers[parts[0]] = strings.TrimSpace(parts[1])
}
rate := c.String("rate")
if rate != "" {
parts := strings.SplitN(rate, "/", 2)
num, err := strconv.Atoi(parts[0])
if err != nil {
fmt.Println(err)
}
unit := time.Hour // default
if len(parts) == 2 {
switch parts[1] {
case "s":
unit = time.Second
case "m":
unit = time.Minute
case "d":
unit = time.Hour * 24
default:
log.Fatal(errors.New("unsupported rate unit. Use s, m, h or d"))
}
}
opt.rateDelay = unit / time.Duration(num)
}
user := c.String("user")
opt.auth = func() string {
return "Basic " + base64.StdEncoding.EncodeToString([]byte(user))
@@ -157,14 +185,15 @@ func BenchmarkClientCommand(cfg *config.Config) *cli.Command {
}
type clientOptions struct {
request string
url string
auth func() string
insecure bool
headers map[string]string
data []byte
ticker *time.Ticker
jobs int
request string
url string
auth func() string
insecure bool
headers map[string]string
rateDelay time.Duration
data []byte
ticker *time.Ticker
jobs int
}
func client(o clientOptions) error {
@@ -182,20 +211,24 @@ func client(o clientOptions) error {
}
client := &http.Client{Transport: tr}
req, err := http.NewRequest(o.request, o.url, bytes.NewReader(o.data))
if err != nil {
log.Printf("client %d: could not create request: %s\n", i, err)
return
}
cookies := map[string]*http.Cookie{}
for {
req, err := http.NewRequest(o.request, o.url, bytes.NewReader(o.data))
if err != nil {
log.Printf("client %d: could not create request: %s\n", i, err)
return
}
req.Header.Set("Authorization", strings.TrimSpace(o.auth()))
for k, v := range o.headers {
req.Header.Set(k, v)
}
for _, cookie := range cookies {
req.AddCookie(cookie)
}
start := time.Now()
res, err := client.Do(req)
duration := -time.Until(start)
if err != nil {
log.Printf("client %d: could not create request: %s\n", i, err)
time.Sleep(time.Second)
@@ -203,10 +236,14 @@ func client(o clientOptions) error {
res.Body.Close()
stats <- stat{
job: i,
duration: -time.Until(start),
duration: duration,
status: res.StatusCode,
}
for _, c := range res.Cookies() {
cookies[c.Name] = c
}
}
time.Sleep(o.rateDelay - duration)
}
}(i)
}