From eec52738d85b62b6883309d692f9fdeb8d3b04f2 Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Wed, 4 Mar 2015 22:13:00 -0800 Subject: [PATCH 1/2] etcd-tester: initial stresser --- .../functional-tester/etcd-tester/stresser.go | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 tools/functional-tester/etcd-tester/stresser.go diff --git a/tools/functional-tester/etcd-tester/stresser.go b/tools/functional-tester/etcd-tester/stresser.go new file mode 100644 index 000000000..2aef38961 --- /dev/null +++ b/tools/functional-tester/etcd-tester/stresser.go @@ -0,0 +1,74 @@ +package main + +import ( + "sync" + "time" + + "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" + "github.com/coreos/etcd/client" +) + +type Stresser interface { + // Stress starts to stress the etcd cluster + Stress() error + // Cancel cancels the stress test on the etcd cluster + Cancel() + // Report reports the success and failure of the stress test + Report() (success int, failure int) +} + +type stresser struct { + Endpoint string + SuffexRange int + + N int + Interval time.Duration + + mu sync.Mutex + failure int + success int + + cancel func() +} + +func (s *stresser) Stress() error { + cfg := client.Config{Endpoints: []string{s.Endpoint}} + c, err := client.New(cfg) + if err != nil { + return err + } + + kv := client.NewKeysAPI(c) + ctx, cancel := context.WithCancel(context.Background()) + s.cancel = cancel + + for i := 0; i < s.N; i++ { + go func() { + for { + _, err := kv.Set(ctx, "foo", "bar", nil) + if err == context.Canceled { + return + } + s.mu.Lock() + if err != nil { + s.failure++ + } + s.success++ + s.mu.Unlock() + } + }() + } + + <-ctx.Done() + return nil +} + +func (s *stresser) Cancel() { + s.cancel() +} + +func (s *stresser) Report() (success int, failure int) { + s.mu.Lock() + defer s.mu.Unlock() + return s.success, s.failure +} From 3cffc910de5da3d8b9ced73add479ea32e782250 Mon Sep 17 00:00:00 2001 From: Yicheng Qin Date: Thu, 5 Mar 2015 12:46:31 -0800 Subject: [PATCH 2/2] tools/etcd-tester: use stresser --- tools/functional-tester/etcd-tester/main.go | 14 +++++++++++++ .../functional-tester/etcd-tester/stresser.go | 21 +++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/tools/functional-tester/etcd-tester/main.go b/tools/functional-tester/etcd-tester/main.go index 708b221d5..f0854de46 100644 --- a/tools/functional-tester/etcd-tester/main.go +++ b/tools/functional-tester/etcd-tester/main.go @@ -33,10 +33,24 @@ func main() { } defer c.Terminate() + stressers := make([]Stresser, len(c.ClientURLs)) + for i, u := range c.ClientURLs { + s := &stresser{ + Endpoint: u, + N: 200, + } + go s.Stress() + stressers[i] = s + } + t := &tester{ failures: []failure{newFailureBase(), newFailureKillAll()}, cluster: c, limit: *limit, } t.runLoop() + + for _, s := range stressers { + s.Cancel() + } } diff --git a/tools/functional-tester/etcd-tester/stresser.go b/tools/functional-tester/etcd-tester/stresser.go index 2aef38961..680d47337 100644 --- a/tools/functional-tester/etcd-tester/stresser.go +++ b/tools/functional-tester/etcd-tester/stresser.go @@ -1,6 +1,8 @@ package main import ( + "net" + "net/http" "sync" "time" @@ -18,10 +20,12 @@ type Stresser interface { } type stresser struct { - Endpoint string - SuffexRange int + Endpoint string + // TODO: not implemented + SuffixRange int - N int + N int + // TODO: not implemented Interval time.Duration mu sync.Mutex @@ -32,7 +36,16 @@ type stresser struct { } func (s *stresser) Stress() error { - cfg := client.Config{Endpoints: []string{s.Endpoint}} + cfg := client.Config{ + Endpoints: []string{s.Endpoint}, + Transport: &http.Transport{ + Dial: (&net.Dialer{ + Timeout: time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + MaxIdleConnsPerHost: s.N, + }, + } c, err := client.New(cfg) if err != nil { return err