152 lines
4.2 KiB
Go
152 lines
4.2 KiB
Go
/*
|
|
*
|
|
* Copyright 2015 gRPC authors.
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
// Package main implements a gRPC test client for lightwalletd.
|
|
// This file adapted from:
|
|
// https://github.com/grpc/grpc-go/blob/master/examples/helloworld/greeter_client/main.go
|
|
// For now at least, all it does is generate a load for performance and stress testing.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"io"
|
|
"log"
|
|
"strconv"
|
|
"sync"
|
|
"time"
|
|
|
|
pb "github.com/zcash/lightwalletd/walletrpc"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
const (
|
|
address = "localhost:9067"
|
|
)
|
|
|
|
type Options struct {
|
|
concurrency int `json:"concurrency"`
|
|
iterations int `json:"iterations"`
|
|
op string `json:"op"`
|
|
verbose *bool `json:"v"`
|
|
}
|
|
|
|
func main() {
|
|
opts := &Options{}
|
|
flag.IntVar(&opts.concurrency, "concurrency", 1, "number of threads")
|
|
flag.IntVar(&opts.iterations, "iterations", 1, "number of iterations")
|
|
flag.StringVar(&opts.op, "op", "ping", "operation(ping|getlightdinfo|getblock|getblockrange)")
|
|
opts.verbose = flag.Bool("v", false, "verbose (print operation results)")
|
|
flag.Parse()
|
|
|
|
// Remaining args are all integers (at least for now)
|
|
args := make([]int64, flag.NArg())
|
|
for i := 0; i < flag.NArg(); i++ {
|
|
var err error
|
|
if args[i], err = strconv.ParseInt(flag.Arg(i), 10, 64); err != nil {
|
|
log.Fatalf("argument %v is not an int64: %v", flag.Arg(i), err)
|
|
}
|
|
}
|
|
|
|
// Set up a connection to the server.
|
|
conn, err := grpc.Dial(address, grpc.WithInsecure(),
|
|
grpc.WithConnectParams(grpc.ConnectParams{MinConnectTimeout: 30 * time.Second}))
|
|
if err != nil {
|
|
log.Fatalf("did not connect: %v", err)
|
|
}
|
|
defer conn.Close()
|
|
c := pb.NewCompactTxStreamerClient(conn)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 100000*time.Second)
|
|
defer cancel()
|
|
var wg sync.WaitGroup
|
|
wg.Add(opts.concurrency)
|
|
for i := 0; i < opts.concurrency; i++ {
|
|
go func(i int) {
|
|
for j := 0; j < opts.iterations; j++ {
|
|
switch opts.op {
|
|
case "ping":
|
|
var a pb.Duration
|
|
a.IntervalUs = 8 * 1000 * 1000 // default 8 seconds
|
|
if len(args) > 0 {
|
|
a.IntervalUs = args[0]
|
|
}
|
|
r, err := c.Ping(ctx, &a)
|
|
if err != nil {
|
|
log.Fatalf("Ping failed: %v", err)
|
|
}
|
|
if *opts.verbose {
|
|
log.Println("thr:", i, "entry:", r.Entry, "exit:", r.Exit)
|
|
}
|
|
case "getlightdinfo":
|
|
r, err := c.GetLightdInfo(ctx, &pb.Empty{})
|
|
if err != nil {
|
|
log.Fatalf("GetLightwalletdInfo failed: %v", err)
|
|
}
|
|
if *opts.verbose {
|
|
log.Println("thr:", i, r)
|
|
}
|
|
case "getblock":
|
|
blockid := &pb.BlockID{Height: 748400} // default (arbitrary)
|
|
if len(args) > 0 {
|
|
blockid.Height = uint64(args[0])
|
|
}
|
|
r, err := c.GetBlock(ctx, blockid)
|
|
if err != nil {
|
|
log.Fatalf("GetLightwalletdInfo failed: %v", err)
|
|
}
|
|
// Height is enough to see if it's working
|
|
if *opts.verbose {
|
|
log.Println("thr:", i, r.Height)
|
|
}
|
|
case "getblockrange":
|
|
blockrange := &pb.BlockRange{ // defaults (arbitrary)
|
|
Start: &pb.BlockID{Height: 738100},
|
|
End: &pb.BlockID{Height: 738199},
|
|
}
|
|
if len(args) > 0 {
|
|
blockrange.Start.Height = uint64(args[0])
|
|
blockrange.End.Height = uint64(args[1])
|
|
}
|
|
stream, err := c.GetBlockRange(ctx, blockrange)
|
|
if err != nil {
|
|
log.Fatalf("GetLightwalletdInfo failed: %v", err)
|
|
}
|
|
for {
|
|
// each call to Recv returns a compact block
|
|
r, err := stream.Recv()
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
// Height is enough to see if it's working
|
|
if *opts.verbose {
|
|
log.Println("thr:", i, r.Height)
|
|
}
|
|
}
|
|
default:
|
|
log.Fatalf("unknown op %s", opts.op)
|
|
}
|
|
}
|
|
wg.Done()
|
|
}(i)
|
|
}
|
|
wg.Wait()
|
|
}
|