func TestSnapshotAndRestartMember(t *testing.T) { defer afterTest(t) m := mustNewMember(t, "snapAndRestartTest", false) m.SnapCount = 100 m.Launch() defer m.Terminate(t) m.WaitOK(t) resps := make([]*client.Response, 120) var err error for i := 0; i < 120; i++ { cc := mustNewHTTPClient(t, []string{m.URL()}) kapi := client.NewKeysAPI(cc) ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) key := fmt.Sprintf("foo%d", i) resps[i], err = kapi.Create(ctx, "/"+key, "bar") if err != nil { t.Fatalf("#%d: create on %s error: %v", i, m.URL(), err) } cancel() } m.Stop(t) m.Restart(t) for i := 0; i < 120; i++ { cc := mustNewHTTPClient(t, []string{m.URL()}) kapi := client.NewKeysAPI(cc) ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) key := fmt.Sprintf("foo%d", i) resp, err := kapi.Get(ctx, "/"+key, nil) if err != nil { t.Fatalf("#%d: get on %s error: %v", i, m.URL(), err) } cancel() if !reflect.DeepEqual(resp.Node, resps[i].Node) { t.Errorf("#%d: node = %v, want %v", i, resp.Node, resps[i].Node) } } }
func TestForceNewCluster(t *testing.T) { c := NewCluster(t, 3) c.Launch(t) cc := mustNewHTTPClient(t, []string{c.Members[0].URL()}) kapi := client.NewKeysAPI(cc) ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) resp, err := kapi.Create(ctx, "/foo", "bar") if err != nil { t.Fatalf("unexpected create error: %v", err) } cancel() // ensure create has been applied in this machine ctx, cancel = context.WithTimeout(context.Background(), requestTimeout) if _, err = kapi.Watcher("/foo", &client.WatcherOptions{AfterIndex: resp.Node.ModifiedIndex - 1}).Next(ctx); err != nil { t.Fatalf("unexpected watch error: %v", err) } cancel() c.Members[0].Stop(t) c.Members[1].Terminate(t) c.Members[2].Terminate(t) c.Members[0].ForceNewCluster = true err = c.Members[0].Restart(t) if err != nil { t.Fatalf("unexpected ForceRestart error: %v", err) } defer c.Members[0].Terminate(t) c.waitLeader(t, c.Members[:1]) // use new http client to init new connection cc = mustNewHTTPClient(t, []string{c.Members[0].URL()}) kapi = client.NewKeysAPI(cc) // ensure force restart keep the old data, and new cluster can make progress ctx, cancel = context.WithTimeout(context.Background(), requestTimeout) if _, err := kapi.Watcher("/foo", &client.WatcherOptions{AfterIndex: resp.Node.ModifiedIndex - 1}).Next(ctx); err != nil { t.Fatalf("unexpected watch error: %v", err) } cancel() clusterMustProgress(t, c.Members[:1]) }
// clusterMustProgress ensures that cluster can make progress. It creates // a random key first, and check the new key could be got from all client urls // of the cluster. func clusterMustProgress(t *testing.T, membs []*member) { cc := mustNewHTTPClient(t, []string{membs[0].URL()}) kapi := client.NewKeysAPI(cc) ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) key := fmt.Sprintf("foo%d", rand.Int()) resp, err := kapi.Create(ctx, "/"+key, "bar") if err != nil { t.Fatalf("create on %s error: %v", membs[0].URL(), err) } cancel() for i, m := range membs { u := m.URL() mcc := mustNewHTTPClient(t, []string{u}) mkapi := client.NewKeysAPI(mcc) mctx, mcancel := context.WithTimeout(context.Background(), requestTimeout) if _, err := mkapi.Watcher(key, &client.WatcherOptions{AfterIndex: resp.Node.ModifiedIndex - 1}).Next(mctx); err != nil { t.Fatalf("#%d: watch on %s error: %v", i, u, err) } mcancel() } }
func (m *member) WaitOK(t *testing.T) { cc := mustNewHTTPClient(t, []string{m.URL()}) kapi := client.NewKeysAPI(cc) for { ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) _, err := kapi.Get(ctx, "/", nil) if err != nil { time.Sleep(tickDuration) continue } cancel() break } for m.s.Leader() == 0 { time.Sleep(tickDuration) } }
func (s *stresser) Stress() error { 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 } kv := client.NewKeysAPI(c) ctx, cancel := context.WithCancel(context.Background()) s.cancel = cancel for i := 0; i < s.N; i++ { go func() { for { setctx, setcancel := context.WithTimeout(ctx, time.Second) key := fmt.Sprintf("foo%d", rand.Intn(s.KeySuffixRange)) _, err := kv.Set(setctx, key, randStr(s.KeySize), nil) setcancel() if err == context.Canceled { return } s.mu.Lock() if err != nil { s.failure++ } else { s.success++ } s.mu.Unlock() } }() } <-ctx.Done() return nil }
// setHealthKey sets health key on all given urls. func setHealthKey(us []string) error { for _, u := range us { cfg := etcdclient.Config{ Endpoints: []string{u}, } c, err := etcdclient.New(cfg) if err != nil { return err } ctx, cancel := context.WithTimeout(context.Background(), time.Second) kapi := etcdclient.NewKeysAPI(c) _, err = kapi.Set(ctx, "health", "good", nil) cancel() if err != nil { return err } } return nil }
func testClusterUsingDiscovery(t *testing.T, size int) { defer afterTest(t) dc := NewCluster(t, 1) dc.Launch(t) defer dc.Terminate(t) // init discovery token space dcc := mustNewHTTPClient(t, dc.URLs()) dkapi := client.NewKeysAPI(dcc) ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) if _, err := dkapi.Create(ctx, "/_config/size", fmt.Sprintf("%d", size)); err != nil { t.Fatal(err) } cancel() c := NewClusterByDiscovery(t, size, dc.URL(0)+"/v2/keys") c.Launch(t) defer c.Terminate(t) clusterMustProgress(t, c.Members) }
func mustNewKeyAPI(c *cli.Context) client.KeysAPI { return client.NewKeysAPI(mustNewClient(c)) }