From 7dc245487a79d7aa5cf6af98bcc932d52be67514 Mon Sep 17 00:00:00 2001 From: Neil Shen Date: Thu, 23 May 2019 16:08:55 +0800 Subject: [PATCH] Add sequential test (#29) * tidb: add sequential test * pkg: allow none model checker * tidb: reneme request to seqRequest and response to seqResponse --- cmd/tidb/main.go | 19 ++- cmd/verifier/main.go | 2 + db/cluster/cluster.go | 45 ++++-- db/tidb/sequential.go | 292 +++++++++++++++++++++++++++++++++++++ db/tidb/sequential_test.go | 45 ++++++ go.sum | 62 ++++---- pkg/control/control.go | 2 + pkg/generator/gen.go | 19 +++ pkg/util/util.go | 3 - pkg/verify/suit.go | 14 +- 10 files changed, 447 insertions(+), 56 deletions(-) create mode 100644 db/tidb/sequential.go create mode 100644 db/tidb/sequential_test.go create mode 100644 pkg/generator/gen.go diff --git a/cmd/tidb/main.go b/cmd/tidb/main.go index 7f29ed4..aff6587 100644 --- a/cmd/tidb/main.go +++ b/cmd/tidb/main.go @@ -4,6 +4,8 @@ import ( "context" "flag" "log" + "net/http" + _ "net/http/pprof" "time" "github.com/pingcap/chaos/cmd/util" @@ -22,11 +24,16 @@ var ( historyFile = flag.String("history", "./history.log", "history file") nemesises = flag.String("nemesis", "", "nemesis, seperated by name, like random_kill,all_kill") checkerNames = flag.String("checker", "porcupine", "checker name, eg, porcupine, tidb_bank_tso") + pprofAddr = flag.String("pprof", "0.0.0.0:8080", "Pprof address") ) func main() { flag.Parse() + go func() { + http.ListenAndServe(*pprofAddr, nil) + }() + cfg := control.Config{ DB: "tidb", RequestCount: *requestCount, @@ -41,24 +48,32 @@ func main() { creator = tidb.BankClientCreator{} case "multi_bank": creator = tidb.MultiBankClientCreator{} + case "sequential": + creator = tidb.SequentialClientCreator{} default: log.Fatalf("invalid client test case %s", *clientCase) } + parser := tidb.BankParser() + model := tidb.BankModel() var checker core.Checker switch *checkerNames { case "porcupine": checker = porcupine.Checker{} case "tidb_bank_tso": checker = tidb.BankTsoChecker() + case "sequential_checker": + checker = tidb.NewSequentialChecker() + parser = tidb.NewSequentialParser() + model = nil default: log.Fatalf("invalid checker %s", *checkerNames) } verifySuit := verify.Suit{ - Model: tidb.BankModel(), + Model: model, Checker: checker, - Parser: tidb.BankParser(), + Parser: parser, } suit := util.Suit{ Config: &cfg, diff --git a/cmd/verifier/main.go b/cmd/verifier/main.go index f035365..e328af3 100644 --- a/cmd/verifier/main.go +++ b/cmd/verifier/main.go @@ -50,6 +50,8 @@ func main() { case "tidb_bank_tso": // Actually we can omit BankModel, since BankTsoChecker does not require a Model. s.Model, s.Parser, s.Checker = tidb.BankModel(), tidb.BankParser(), tidb.BankTsoChecker() + case "sequential": + s.Parser, s.Checker = tidb.NewSequentialParser(), tidb.NewSequentialChecker() case "register": s.Model, s.Parser, s.Checker = model.RegisterModel(), model.RegisterParser(), porcupine.Checker{} case "": diff --git a/db/cluster/cluster.go b/db/cluster/cluster.go index ebd4092..2493ae9 100644 --- a/db/cluster/cluster.go +++ b/db/cluster/cluster.go @@ -7,6 +7,7 @@ import ( "path" "strconv" "strings" + "sync" "time" "github.com/pingcap/chaos/pkg/util" @@ -27,6 +28,7 @@ var ( pdConfig = path.Join(deployDir, "./conf/pd.toml") tikvConfig = path.Join(deployDir, "./conf/tikv.toml") + tidbConfig = path.Join(deployDir, "./conf/tidb.toml") pdLog = path.Join(deployDir, "./log/pd.log") tikvLog = path.Join(deployDir, "./log/tikv.log") @@ -36,6 +38,7 @@ var ( // Cluster is the TiKV/TiDB database cluster. // Note: Cluster does not implement `core.DB` interface. type Cluster struct { + once sync.Once nodes []string installBlocker util.BlockRunner IncludeTidb bool @@ -50,15 +53,18 @@ func (cluster *Cluster) SetUp(ctx context.Context, nodes []string, node string) ssh.Exec(ctx, node, "killall", "-9", "tikv-server") ssh.Exec(ctx, node, "killall", "-9", "pd-server") - cluster.nodes = nodes - - cluster.installBlocker.Init(len(nodes)) + cluster.once.Do(func() { + cluster.nodes = nodes + cluster.installBlocker.Init(len(nodes)) + }) log.Printf("install archieve on node %s", node) var err error cluster.installBlocker.Run(func() { - err = util.InstallArchive(ctx, node, archiveURL, deployDir) + if !util.IsFileExist(ctx, node, deployDir) { + err = util.InstallArchive(ctx, node, archiveURL, deployDir) + } }) if err != nil { return err @@ -72,7 +78,7 @@ func (cluster *Cluster) SetUp(ctx context.Context, nodes []string, node string) "election-interval=\"500ms\"", "tso-save-interval=\"500ms\"", "[replication]", - "max-replicas=5", + "max-replicas=3", } if err := util.WriteFile(ctx, node, pdConfig, strconv.Quote(strings.Join(pdCfs, "\n"))); err != nil { @@ -80,19 +86,37 @@ func (cluster *Cluster) SetUp(ctx context.Context, nodes []string, node string) } tikvCfs := []string{ + "[server]", + "status-addr=\"0.0.0.0:20180\"", "[raftstore]", - "pd-heartbeat-tick-interval=\"500ms\"", - "pd-store-heartbeat-tick-interval=\"1s\"", - "raft_store_max_leader_lease=\"900ms\"", + "capacity =\"100G\"", + "pd-heartbeat-tick-interval=\"3s\"", + "raft_store_max_leader_lease=\"50ms\"", "raft_base_tick_interval=\"100ms\"", "raft_heartbeat_ticks=3", "raft_election_timeout_ticks=10", + "sync-log = true", + "[coprocessor]", + "region-max-keys = 5", + "region-split-keys = 2", } if err := util.WriteFile(ctx, node, tikvConfig, strconv.Quote(strings.Join(tikvCfs, "\n"))); err != nil { return err } + tidbCfs := []string{ + "lease = \"1s\"", + "split-table = true", + "[tikv-client]", + "commit-timeout = \"10ms\"", + "max-txn-time-use = 590", + } + + if err := util.WriteFile(ctx, node, tidbConfig, strconv.Quote(strings.Join(tidbCfs, "\n"))); err != nil { + return err + } + return cluster.start(ctx, node, true) } @@ -178,10 +202,6 @@ WAIT: return err } - if inSetUp { - time.Sleep(30 * time.Second) - } - if !util.IsDaemonRunning(ctx, node, tikvBinary, tikvPID) { return fmt.Errorf("fail to start tikv on node %s", node) } @@ -191,6 +211,7 @@ WAIT: "--store=tikv", fmt.Sprintf("--path=%s", strings.Join(pdEndpoints, ",")), fmt.Sprintf("--log-file=%s", tidbLog), + fmt.Sprintf("--config=%s", tidbConfig), } log.Printf("start tidb-server on node %s", node) diff --git a/db/tidb/sequential.go b/db/tidb/sequential.go new file mode 100644 index 0000000..f59c328 --- /dev/null +++ b/db/tidb/sequential.go @@ -0,0 +1,292 @@ +package tidb + +import ( + "context" + "database/sql" + "encoding/json" + "fmt" + "hash/fnv" + "log" + "math/rand" + "sync" + "time" + + "github.com/pingcap/chaos/pkg/generator" + "github.com/pingcap/chaos/pkg/history" + + "github.com/pingcap/chaos/pkg/core" +) + +const ( + tablePrefix = "seq_" + tpRead = "read" + tpWrite = "write" +) + +type seqRequest struct { + Tp string + K int +} + +type seqResponse struct { + Ok bool + K int + V []string + Unknown bool +} + +var ( + _ core.UnknownResponse = (*seqResponse)(nil) + + queue = struct { + mu sync.Mutex + q []int + count int + r *rand.Rand + }{ + mu: sync.Mutex{}, + q: make([]int, 0, 10), // TODO: make the cap configurable. + r: rand.New(rand.NewSource(time.Now().UnixNano())), + } +) + +// IsUnknown implements UnknownResponse interface +func (r seqResponse) IsUnknown() bool { + return r.Unknown +} + +type sequentialClient struct { + db *sql.DB + tableCount int + keyCount int + gen generator.Generator +} + +// SequentialClientCreator creates a bank test client for tidb. +type SequentialClientCreator struct { +} + +func genRequest() interface{} { + queue.mu.Lock() + defer queue.mu.Unlock() + c := cap(queue.q) + l := len(queue.q) + k := queue.count + // The first len(queue.q) requests are all write requests. + if k < c { + goto WRITE + } else if l == c { + // Read if the queue is full + goto READ + } else if l <= 3 { + // Write if the queue is empty + goto WRITE + } else if queue.r.Int()%2 == 1 { + goto READ + } else { + goto WRITE + } + +READ: + // Read + // Pop the front + k, queue.q = queue.q[0], append([]int{}, queue.q[1:]...) + return seqRequest{Tp: tpRead, K: k} +WRITE: + // Write + // Push the end + queue.count++ + queue.q = append(queue.q, k) + return seqRequest{Tp: tpWrite, K: k} +} + +// Create creates a new SequentialClient. +func (SequentialClientCreator) Create(node string) core.Client { + return &sequentialClient{ + tableCount: 3, + keyCount: 5, + gen: generator.Stagger(time.Millisecond*10, genRequest), + } +} + +func (c *sequentialClient) tableNames() []string { + names := make([]string, 0, c.tableCount) + for i := 0; i < c.tableCount; i++ { + names = append(names, fmt.Sprintf("%s%d", tablePrefix, i)) + } + return names +} + +func subkeys(keyCount int, k int) []string { + ks := make([]string, 0, keyCount) + for i := 0; i < keyCount; i++ { + ks = append(ks, fmt.Sprintf("%d_%d", k, i)) + } + return ks +} + +func hash(s string) int { + h := fnv.New32a() + h.Write([]byte(s)) + return int(h.Sum32()) +} + +func key2table(tableCount int, key string) string { + return fmt.Sprintf("%s%d", tablePrefix, hash(key)%tableCount) +} + +// SetUp sets up the client. +func (c *sequentialClient) SetUp(ctx context.Context, nodes []string, node string) error { + db, err := sql.Open("mysql", fmt.Sprintf("root@tcp(%s:4000)/test", node)) + if err != nil { + return err + } + c.db = db + + db.SetMaxIdleConns(1 + c.tableCount) + + // Do SetUp in the first node + if node != nodes[0] { + return nil + } + + tableNames := c.tableNames() + log.Printf("begin to create table %v on node %s", tableNames, node) + for _, tableName := range tableNames { + log.Printf("try to drop table %s", tableName) + if _, err = db.ExecContext(ctx, + fmt.Sprintf(" drop table if exists %s", tableName)); err != nil { + return err + } + sql := `create table if not exists %s (tkey varchar(255) primary key)` + if _, err = db.ExecContext(ctx, fmt.Sprintf(sql, tableName)); err != nil { + return err + } + log.Printf("created table %s", tableName) + } + + return nil +} + +// TearDown tears down the client. +func (c *sequentialClient) TearDown(ctx context.Context, nodes []string, node string) error { + return c.db.Close() +} + +// Invoke invokes a request to the database. +// Mostly, the return Response should implement UnknownResponse interface +func (c *sequentialClient) Invoke(ctx context.Context, node string, r interface{}) interface{} { + req := r.(seqRequest) + ks := subkeys(c.keyCount, req.K) + if req.Tp == tpWrite { + for _, k := range ks { + sql := fmt.Sprintf("insert into %s values (?)", key2table(c.tableCount, k)) + _, err := c.db.ExecContext(ctx, sql, k) + if err != nil { + // TODO: retry on conflict + log.Println(err) + return seqResponse{Ok: false} + } + } + return seqResponse{Ok: true} + } else if req.Tp == tpRead { + vs := make([]string, 0, len(ks)) + for i := len(ks) - 1; i >= 0; i-- { + k := ks[i] + sql := fmt.Sprintf("select tkey from %s where tkey = ?", key2table(c.tableCount, k)) + var v string + err := c.db.QueryRowContext(ctx, sql, k).Scan(&v) + if err != nil { + // TODO: retry on conflict + log.Println(err) + return seqResponse{Ok: false} + } + vs = append(vs, v) + } + resp := seqResponse{ + Ok: true, + K: req.K, + V: vs, + } + return resp + } else { + panic(fmt.Sprintf("unknown req %v", req)) + } +} + +// NextRequest generates a request for latter Invoke. +func (c *sequentialClient) NextRequest() interface{} { + return c.gen() +} + +// DumpState the database state(also the model's state) +func (c *sequentialClient) DumpState(ctx context.Context) (interface{}, error) { + return nil, nil +} + +// NewSequentialChecker returns a new sequentialChecker. +func NewSequentialChecker() core.Checker { + return sequentialChecker{} +} + +// sequentialChecker checks whether a history is sequential. +type sequentialChecker struct{} + +// Check checks the sequential history. +func (sequentialChecker) Check(_ core.Model, ops []core.Operation) (bool, error) { + for _, op := range ops { + if op.Action == core.ReturnOperation { + resp := op.Data.(seqResponse) + if !resp.Unknown && resp.Ok { + foundNoneEmpty := false + for _, s := range resp.V { + if !foundNoneEmpty { + foundNoneEmpty = s != "" + } else if s == "" { + log.Printf("Find no sequential op %+v", resp) + return false, nil + } + } + } + } + } + return true, nil +} + +// Name returns the name of the verifier. +func (sequentialChecker) Name() string { + return "sequential_checker" +} + +type parser struct{} + +// OnRequest impls history.RecordParser.OnRequest +func (p parser) OnRequest(data json.RawMessage) (interface{}, error) { + r := seqRequest{} + err := json.Unmarshal(data, &r) + return r, err +} + +// OnResponse impls history.RecordParser.OnRequest +func (p parser) OnResponse(data json.RawMessage) (interface{}, error) { + r := seqResponse{} + err := json.Unmarshal(data, &r) + if r.Unknown { + return nil, err + } + return r, err +} + +// OnNoopResponse impls history.RecordParser.OnRequest +func (p parser) OnNoopResponse() interface{} { + return seqResponse{Unknown: true} +} + +func (p parser) OnState(data json.RawMessage) (interface{}, error) { + return nil, nil +} + +// NewSequentialParser returns a parser parses a history of bank operations. +func NewSequentialParser() history.RecordParser { + return parser{} +} diff --git a/db/tidb/sequential_test.go b/db/tidb/sequential_test.go new file mode 100644 index 0000000..800399c --- /dev/null +++ b/db/tidb/sequential_test.go @@ -0,0 +1,45 @@ +package tidb + +import ( + "testing" + + "github.com/pingcap/chaos/pkg/core" +) + +func TestGenRequest(t *testing.T) { + for i := 0; i < 10000; i++ { + _ = genRequest().(seqRequest) + } +} + +func BenchmarkGenRequest(b *testing.B) { + _ = genRequest().(seqRequest) +} + +func TestCheckSequential(t *testing.T) { + good := []core.Operation{ + core.Operation{Action: core.InvokeOperation, Proc: 0, Data: seqRequest{}}, + core.Operation{Action: core.InvokeOperation, Proc: 1, Data: seqRequest{}}, + core.Operation{Action: core.InvokeOperation, Proc: 2, Data: seqRequest{}}, + core.Operation{Action: core.ReturnOperation, Proc: 1, Data: seqResponse{Ok: true, K: 1, V: []string{"", "1", "1"}}}, + core.Operation{Action: core.ReturnOperation, Proc: 0, Data: seqResponse{Ok: true, K: 0, V: []string{"", "", "0"}}}, + core.Operation{Action: core.ReturnOperation, Proc: 2, Data: seqResponse{Ok: true, K: 2, V: []string{"2", "2", "2"}}}, + } + bad := []core.Operation{ + core.Operation{Action: core.InvokeOperation, Proc: 0, Data: seqRequest{}}, + core.Operation{Action: core.InvokeOperation, Proc: 1, Data: seqRequest{}}, + core.Operation{Action: core.InvokeOperation, Proc: 2, Data: seqRequest{}}, + core.Operation{Action: core.ReturnOperation, Proc: 1, Data: seqResponse{Ok: true, K: 1, V: []string{"", "1", "1"}}}, + core.Operation{Action: core.ReturnOperation, Proc: 0, Data: seqResponse{Ok: true, K: 0, V: []string{"0", "", "0"}}}, + core.Operation{Action: core.ReturnOperation, Proc: 2, Data: seqResponse{Ok: true, K: 2, V: []string{"2", "2", "2"}}}, + } + checker := NewSequentialChecker() + ok, err := checker.Check(nil, good) + if !ok || err != nil { + t.Fatalf("good must pass check") + } + ok, err = checker.Check(nil, bad) + if ok { + t.Fatalf("bad must fail check") + } +} diff --git a/go.sum b/go.sum index 435e530..b5006cd 100644 --- a/go.sum +++ b/go.sum @@ -1,93 +1,85 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f h1:5ZfJxyXo8KyX8DgGXC5B7ILL8y51fci/qYz2B4j8iLY= github.com/StackExchange/wmi v0.0.0-20180725035823-b12b22c5341f/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/anishathalye/porcupine v0.0.0-20180912012540-c95d370e6abb h1:m7AZO1q3bHOBd8tr9ME99PLKC+37pKGvnj9npmiRwp4= github.com/anishathalye/porcupine v0.0.0-20180912012540-c95d370e6abb/go.mod h1:FTYUM6ZeF0TIVWODQgFV5mEwQLdfF2IiPICYgN+unJM= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/blacktear23/go-proxyprotocol v0.0.0-20171102103907-62e368e1c470/go.mod h1:VKt7CNAQxpFpSDz3sXyj9hY/GbVsQCr0sB3w59nE7lU= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= +github.com/coreos/etcd v3.3.10+incompatible h1:KjVWqrZ5U0wa3CxY2AxlH6/UcB+PK2td1DcsYhA+HRs= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142 h1:3jFq2xL4ZajGK4aZY8jz+DAF0FHjI51BXjjSwCzS1Dk= github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cznic/mathutil v0.0.0-20181021201202-eba54fb065b7/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= +github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 h1:iwZdTE0PVqJCos1vaoKsclOGD3ADKpshg3SRtYBbwso= github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= -github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65 h1:hxuZop6tSoOi0sxFzoGGYdRqNrPubyaIf9KoBG9tPiE= github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= -github.com/etcd-io/gofail v0.0.0-20180808172546-51ce9a71510a h1:QNEenQIsGDEEfFNSnN+h6hE1OwnHqTg7Dl9gEk1Cko4= github.com/etcd-io/gofail v0.0.0-20180808172546-51ce9a71510a/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-sql-driver/mysql v0.0.0-20170715192408-3955978caca4/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff h1:kOkM9whyQYodu09SJ6W3NCsHG7crFaJILQ22Gozp3lg= github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:BWIsLfhgKhV5g/oF34aRjniBHLTZe5DNekSjbAjIS6c= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.5.1 h1:3scN4iuXkNOyP98jF55Lv8a9j1o/IwvnDIZ0LHJK1nk= github.com/grpc-ecosystem/grpc-gateway v1.5.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/montanaflynn/stats v0.0.0-20180911141734-db72e6cae808 h1:pmpDGKLw4n82EtrNiLqB+xSz/JQwFOaZuMALYUHwX5s= github.com/montanaflynn/stats v0.0.0-20180911141734-db72e6cae808/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/myesui/uuid v1.0.0 h1:xCBmH4l5KuvLYc5L7AS7SZg9/jKdIFubM7OVoLqaQUI= github.com/myesui/uuid v1.0.0/go.mod h1:2CDfNgU0LR8mIdO8vdWd8i9gWWxLlcoIGGpSNgafq84= -github.com/ngaut/pools v0.0.0-20180318154953-b7bc8c42aac7 h1:7KAv7KMGTTqSmYZtNdcNTgsos+vFzULLwyElndwn+5c= github.com/ngaut/pools v0.0.0-20180318154953-b7bc8c42aac7/go.mod h1:iWMfgwqYW+e8n5lC/jjNEhwcjbRDpl5NT7n2h+4UNcI= -github.com/ngaut/sync2 v0.0.0-20141008032647-7a24ed77b2ef h1:K0Fn+DoFqNqktdZtdV3bPQ/0cuYh2H4rkg0tytX/07k= github.com/ngaut/sync2 v0.0.0-20141008032647-7a24ed77b2ef/go.mod h1:7WjlapSfwQyo6LNmIvEWzsW1hbBQfpUO4JWnuQRmva8= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/pingcap/check v0.0.0-20171206051426-1c287c953996 h1:ZBdiJCMan6GSo/aPAM7gywcUKa0z58gczVrnG6TQnAQ= github.com/pingcap/check v0.0.0-20171206051426-1c287c953996/go.mod h1:B1+S9LNcuMyLH/4HMTViQOJevkGiik3wW2AN9zb2fNQ= +github.com/pingcap/errors v0.11.0 h1:DCJQB8jrHbQ1VVlMFIrbj2ApScNNotVmkSNplu2yUt4= github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e h1:P73/4dPCL96rGrobssy1nVy2VaVpNCuLpCbr+FEaTA8= github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw= github.com/pingcap/kvproto v0.0.0-20181105061835-1b5d69cd1d26/go.mod h1:0gwbe1F2iBIjuQ9AH0DbQhL+Dpr5GofU8fgYyXk+ykk= github.com/pingcap/kvproto v0.0.0-20181130084342-6bbef21532da h1:fZHOC3Nzse+WSLtuetndHfAn97m4TKnnxy2/o/lU9qw= github.com/pingcap/kvproto v0.0.0-20181130084342-6bbef21532da/go.mod h1:0gwbe1F2iBIjuQ9AH0DbQhL+Dpr5GofU8fgYyXk+ykk= +github.com/pingcap/parser v0.0.0-20181126111651-a38036a60de7 h1:E/T5kIrtzipWJhN/YREI+f3PiP6Uw5boE4KRcD+zVvo= github.com/pingcap/parser v0.0.0-20181126111651-a38036a60de7/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA= github.com/pingcap/pd v2.1.0-rc.4+incompatible h1:/buwGk04aHO5odk/+O8ZOXGs4qkUjYTJ2UpCJXna8NE= github.com/pingcap/pd v2.1.0-rc.4+incompatible/go.mod h1:nD3+EoYes4+aNNODO99ES59V83MZSI+dFbhyr667a0E= @@ -96,7 +88,9 @@ github.com/pingcap/tidb v0.0.0-20181203021530-741adcee43e2/go.mod h1:xn+3XVdDK// github.com/pingcap/tidb-tools v0.0.0-20181112132202-4860a0d5de03 h1:xVuo5U+l6XAWHsb+xhkZ8zz3jerIwDfCHAO6kR2Kaog= github.com/pingcap/tidb-tools v0.0.0-20181112132202-4860a0d5de03/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM= github.com/pingcap/tipb v0.0.0-20181012112600-11e33c750323/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI= +github.com/pingcap/tipb v0.0.0-20181126132056-a7fd2aaa9719 h1:MEHhwNcWuuoJJvYxMaWIXFp+BvK/WORPiiwmSOS0cA4= github.com/pingcap/tipb v0.0.0-20181126132056-a7fd2aaa9719/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -110,11 +104,13 @@ github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7q github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181129180645-aa55a523dc0a h1:Z2GBQ7wAiTCixJhSGK4sMO/FHYlvFvUBBK0M0FSsxeU= github.com/prometheus/procfs v0.0.0-20181129180645-aa55a523dc0a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446 h1:/NRJ5vAYoqz+7sG51ubIDHXeWO8DlTSrToPu6q11ziA= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/shirou/gopsutil v2.18.10+incompatible h1:cy84jW6EVRPa5g9HAHrlbxMSIjBhDSX0OFYyMYminYs= github.com/shirou/gopsutil v2.18.10+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/vfsgen v0.0.0-20181020040650-a97a25d856ca/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= +github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= @@ -123,21 +119,20 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2/go.mod h1:2PfKggNGDuadAa0LElHrByyrz4JPZ9fFx6Gs7nx7ZZU= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/twinj/uuid v1.0.0 h1:fzz7COZnDrXGTAOHGuUGYd6sG+JMq+AoE7+Jlu0przk= github.com/twinj/uuid v1.0.0/go.mod h1:mMgcE1RHFUFqe5AfiwlINXisXfDGro23fWdPUfOMjRY= -github.com/uber-go/atomic v1.3.2 h1:Azu9lPBWRNKzYXSIwRfgRuDuS0YKsK4NFhiQv98gkxo= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/uber/jaeger-client-go v2.15.0+incompatible h1:NP3qsSqNxh8VYr956ur1N/1C1PjvOJnJykCzcD5QHbk= github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v1.5.0 h1:OHbgr8l656Ub3Fw5k9SWnBfIEwvoHQ+W2y+Aa9D1Uyo= github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go/codec v0.0.0-20181127175209-856da096dbdf h1:BLcwkDfQ8QPXNXBApZUATvuigovcYPXkHzez80QFGNg= github.com/ugorji/go/codec v0.0.0-20181127175209-856da096dbdf/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/unrolled/render v0.0.0-20180914162206-b9786414de4d h1:ggUgChAeyge4NZ4QUw6lhHsVymzwSDJOZcE0s2X8S20= github.com/unrolled/render v0.0.0-20180914162206-b9786414de4d/go.mod h1:tu82oB5W2ykJRVioYsB+IQKcft7ryBr7w12qMBUPyXg= github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -150,27 +145,24 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuArfcOvC4AoJmILihzhDg= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.16.0 h1:dz5IJGuC2BB7qXR5AyHNwAUBhZscK2xVez7mznh72sY= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/stretchr/testify.v1 v1.2.2 h1:yhQC6Uy5CqibAIlk1wlusa/MJ3iAN49/BsR/dCCKz3M= gopkg.in/stretchr/testify.v1 v1.2.2/go.mod h1:QI5V/q6UbPmuhtm10CaFZxED9NreB8PnFYN9JcR6TxU= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -sourcegraph.com/sourcegraph/appdash v0.0.0-20180531100431-4c381bd170b4 h1:VO9oZbbkvTwqLimlQt15QNdOOBArT2dw/bvzsMZBiqQ= sourcegraph.com/sourcegraph/appdash v0.0.0-20180531100431-4c381bd170b4/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k= diff --git a/pkg/control/control.go b/pkg/control/control.go index 5a95d08..6b2e8d6 100644 --- a/pkg/control/control.go +++ b/pkg/control/control.go @@ -241,7 +241,9 @@ func (c *Controller) onClientLoop( log.Fatalf("record request %v failed %v", request, err) } + log.Printf("%s: call %+v", node, request) response := client.Invoke(ctx, node, request) + log.Printf("%s: return %+v", node, response) isUnknown := true if v, ok := response.(core.UnknownResponse); ok { isUnknown = v.IsUnknown() diff --git a/pkg/generator/gen.go b/pkg/generator/gen.go new file mode 100644 index 0000000..5b7e10a --- /dev/null +++ b/pkg/generator/gen.go @@ -0,0 +1,19 @@ +package generator + +import ( + "math/rand" + "time" +) + +// Generator generates a series of operations +type Generator = func() interface{} + +// Stagger introduces uniform random timing noise with a mean delay of +// dt duration for every operation. Delays range from 0 to 2 * dt." +func Stagger(dt time.Duration, gen Generator) Generator { + r := rand.New(rand.NewSource(time.Now().UnixNano())) + return func() interface{} { + time.Sleep(time.Duration(r.Int63n(2 * int64(dt)))) + return gen() + } +} diff --git a/pkg/util/util.go b/pkg/util/util.go index 451f161..14764f2 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -38,9 +38,6 @@ func Wget(ctx context.Context, node string, rawURL string, dest string) (string, fileName := path.Base(u.Path) filePath := path.Join(dest, fileName) - if IsFileExist(ctx, node, filePath) { - return filePath, nil - } Mkdir(ctx, node, dest) err = ssh.Exec(ctx, node, "wget", "--tries", "20", "--waitretry", "60", diff --git a/pkg/verify/suit.go b/pkg/verify/suit.go index 5d5592c..e18a839 100644 --- a/pkg/verify/suit.go +++ b/pkg/verify/suit.go @@ -16,7 +16,11 @@ type Suit struct { // Verify creates the verifier from model name and verfies the history file. func (s Suit) Verify(historyFile string) { - log.Printf("begin to check %s with %s", s.Model.Name(), s.Checker.Name()) + if s.Model == nil { + log.Printf("begin to check %s", s.Checker.Name()) + } else { + log.Printf("begin to check %s with %s", s.Model.Name(), s.Checker.Name()) + } ops, state, err := history.ReadHistory(historyFile, s.Parser) if err != nil { log.Fatalf("verify failed: %v", err) @@ -27,15 +31,17 @@ func (s Suit) Verify(historyFile string) { log.Fatalf("verify failed: %v", err) } - s.Model.Prepare(state) + if s.Model != nil { + s.Model.Prepare(state) + } ok, err := s.Checker.Check(s.Model, ops) if err != nil { log.Fatalf("verify history failed %v", err) } if !ok { - log.Fatalf("%s: history %s is not linearizable", s.Model.Name(), historyFile) + log.Fatalf("history %s is not valid", historyFile) } else { - log.Printf("%s: history %s is linearizable", s.Model.Name(), historyFile) + log.Printf("history %s is valid", historyFile) } }