blob: dc320d6ae1c87cce252bf1f275dab4812d866b7c [file] [log] [blame]
// Copyright (C) 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Program to benchmark Gerrit. Creates pending changes in a loop,
// which tests performance of BatchRefUpdate and Lucene indexing
package main
import (
"bytes"
"encoding/base64"
"flag"
"fmt"
"io"
"log"
"net/http"
"net/url"
"os"
"sort"
"time"
)
func main() {
user := flag.String("user", "admin", "username for basic auth")
pw := flag.String("password", "secret", "HTTP password for basic auth")
project := flag.String("project", "", "project to create changes in")
gerritURL := flag.String("url", "http://localhost:8080/", "URL to gerrit instance")
numChanges := flag.Int("n", 100, "number of changes to create")
flag.Parse()
if *gerritURL == "" {
log.Fatal("provide --url")
}
if *project == "" {
log.Fatal("provide --project")
}
u, err := url.Parse(*gerritURL)
if err != nil {
log.Fatal(err)
}
basicAuth := fmt.Sprintf("%s:%s", *user, *pw)
authHeader := base64.StdEncoding.EncodeToString([]byte(basicAuth))
client := &http.Client{}
var dts []time.Duration
startAll := time.Now()
var lastSec int
for i := 0; i < *numChanges; i++ {
body := fmt.Sprintf(`{
"project" : "%s",
"subject" : "change %d",
"branch" : "master",
"status" : "NEW"
}`, *project, i)
start := time.Now()
thisSec := int(start.Sub(startAll) / time.Second)
if thisSec != lastSec {
log.Printf("change %d", i)
}
lastSec = thisSec
u.Path = "/a/changes/"
req, err := http.NewRequest("POST", u.String(), bytes.NewBufferString(body))
if err != nil {
log.Fatal(err)
}
req.Header.Add("Authorization", "Basic "+authHeader)
req.Header.Add("Content-Type", "application/json; charset=UTF-8")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
dt := time.Now().Sub(start)
dts = append(dts, dt)
if resp.StatusCode/100 == 2 {
continue
}
log.Println("code", resp.StatusCode)
io.Copy(os.Stdout, resp.Body)
}
sort.Slice(dts, func(i, j int) bool { return dts[i] < dts[j] })
var total time.Duration
for _, dt := range dts {
total += dt
}
log.Printf("min %v max %v median %v avg %v", dts[0], dts[len(dts)-1], dts[len(dts)/2], total/time.Duration(len(dts)))
}