From 43547cc681467f1977a97f1d165cec398b24c9de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Tue, 7 Mar 2023 11:37:14 +0100 Subject: [PATCH] Benchmark options (#5684) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * make benchmark clients remember cookies Signed-off-by: Jörn Friedrich Dreyer * add --rate option for benchmark clients Signed-off-by: Jörn Friedrich Dreyer * create a new request on every request to fix vanishing data Signed-off-by: Jörn Friedrich Dreyer * use corret minute unit Co-authored-by: Florian Schade --------- Signed-off-by: Jörn Friedrich Dreyer Co-authored-by: Florian Schade --- ocis/pkg/command/benchmark.go | 67 +++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/ocis/pkg/command/benchmark.go b/ocis/pkg/command/benchmark.go index 247667f425..3439619c92 100644 --- a/ocis/pkg/command/benchmark.go +++ b/ocis/pkg/command/benchmark.go @@ -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) }