// Copyright 2015 The etcd 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 integration import ( "context" "fmt" "io/ioutil" "os" "reflect" "testing" "go.etcd.io/etcd/client" "go.etcd.io/etcd/pkg/testutil" ) func TestPauseMember(t *testing.T) { defer testutil.AfterTest(t) c := NewCluster(t, 5) c.Launch(t) defer c.Terminate(t) for i := 0; i < 5; i++ { c.Members[i].Pause() membs := append([]*member{}, c.Members[:i]...) membs = append(membs, c.Members[i+1:]...) c.waitLeader(t, membs) clusterMustProgress(t, membs) c.Members[i].Resume() } c.waitLeader(t, c.Members) clusterMustProgress(t, c.Members) } func TestRestartMember(t *testing.T) { defer testutil.AfterTest(t) c := NewCluster(t, 3) c.Launch(t) defer c.Terminate(t) for i := 0; i < 3; i++ { c.Members[i].Stop(t) membs := append([]*member{}, c.Members[:i]...) membs = append(membs, c.Members[i+1:]...) c.waitLeader(t, membs) clusterMustProgress(t, membs) err := c.Members[i].Restart(t) if err != nil { t.Fatal(err) } } c.waitLeader(t, c.Members) clusterMustProgress(t, c.Members) } func TestLaunchDuplicateMemberShouldFail(t *testing.T) { size := 3 c := NewCluster(t, size) m := c.Members[0].Clone(t) var err error m.DataDir, err = ioutil.TempDir(os.TempDir(), "etcd") if err != nil { t.Fatal(err) } c.Launch(t) defer c.Terminate(t) if err := m.Launch(); err == nil { t.Errorf("unexpect successful launch") } } func TestSnapshotAndRestartMember(t *testing.T) { defer testutil.AfterTest(t) m := mustNewMember(t, memberConfig{name: "snapAndRestartTest"}) m.SnapshotCount = 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()}, nil) 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) m.WaitOK(t) for i := 0; i < 120; i++ { cc := MustNewHTTPClient(t, []string{m.URL()}, nil) 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) } } }