+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
// Testing tool for Keep services.
//
// keepexercise helps measure throughput and test reliability under
"crypto/rand"
"encoding/binary"
"flag"
+ "fmt"
"io"
"io/ioutil"
"log"
"net/http"
+ "os"
"time"
- "git.curoverse.com/arvados.git/sdk/go/arvadosclient"
- "git.curoverse.com/arvados.git/sdk/go/keepclient"
+ "git.arvados.org/arvados.git/sdk/go/arvadosclient"
+ "git.arvados.org/arvados.git/sdk/go/keepclient"
)
+var version = "dev"
+
// Command line config knobs
var (
BlockSize = flag.Int("block-size", keepclient.BLOCKSIZE, "bytes per read/write op")
StatsInterval = flag.Duration("stats-interval", time.Second, "time interval between IO stats reports, or 0 to disable")
ServiceURL = flag.String("url", "", "specify scheme://host of a single keep service to exercise (instead of using all advertised services like normal clients)")
ServiceUUID = flag.String("uuid", "", "specify UUID of a single advertised keep service to exercise")
+ getVersion = flag.Bool("version", false, "Print version information and exit.")
+ RunTime = flag.Duration("run-time", 0, "time to run (e.g. 60s), or 0 to run indefinitely (default)")
)
func main() {
flag.Parse()
+ // Print version information if requested
+ if *getVersion {
+ fmt.Printf("keep-exercise %s\n", version)
+ os.Exit(0)
+ }
+
+ log.Printf("keep-exercise %s started", version)
+
arv, err := arvadosclient.MakeArvadosClient()
if err != nil {
log.Fatal(err)
func countBeans(nextLocator chan string) {
t0 := time.Now()
var tickChan <-chan time.Time
+ var endChan <-chan time.Time
if *StatsInterval > 0 {
tickChan = time.NewTicker(*StatsInterval).C
}
+ if *RunTime > 0 {
+ endChan = time.NewTicker(*RunTime).C
+ }
var bytesIn uint64
var bytesOut uint64
var errors uint64
+ var maxRateIn, maxRateOut float64
for {
select {
case <-tickChan:
elapsed := time.Since(t0)
+ if float64(bytesIn)/elapsed.Seconds()/1048576 > maxRateIn {
+ maxRateIn = float64(bytesIn) / elapsed.Seconds() / 1048576
+ }
+ if float64(bytesOut)/elapsed.Seconds()/1048576 > maxRateOut {
+ maxRateOut = float64(bytesOut) / elapsed.Seconds() / 1048576
+ }
log.Printf("%v elapsed: read %v bytes (%.1f MiB/s), wrote %v bytes (%.1f MiB/s), errors %d",
elapsed,
bytesIn, (float64(bytesIn) / elapsed.Seconds() / 1048576),
bytesOut, (float64(bytesOut) / elapsed.Seconds() / 1048576),
errors,
)
+ case <-endChan:
+ elapsed := time.Since(t0)
+ log.Println("\nSummary:")
+ log.Println("Elapsed,Read (bytes),Avg Read Speed (MiB/s),Peak Read Speed (MiB/s),Written (bytes),Avg Write Speed (MiB/s),Peak Write Speed (MiB/s),Errors,ReadThreads,WriteThreads,VaryRequest,VaryThread,BlockSize,Replicas,StatsInterval,ServiceURL,ServiceUUID,RunTime\n")
+ log.Printf("%v,%v,%.1f,%.1f,%v,%.1f,%.1f,%d,%d,%d,%t,%t,%d,%d,%s,%s,%s,%s",
+ elapsed,
+ bytesIn, (float64(bytesIn) / elapsed.Seconds() / 1048576), maxRateIn,
+ bytesOut, (float64(bytesOut) / elapsed.Seconds() / 1048576), maxRateOut,
+ errors,
+ *ReadThreads,
+ *WriteThreads,
+ *VaryRequest,
+ *VaryThread,
+ *BlockSize,
+ *Replicas,
+ *StatsInterval,
+ *ServiceURL,
+ *ServiceUUID,
+ *RunTime,
+ )
+ os.Exit(0)
case i := <-bytesInChan:
bytesIn += i
case o := <-bytesOutChan: