1// Copyright 2015 The etcd Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package integration 16 17import ( 18 "context" 19 "fmt" 20 "io/ioutil" 21 "reflect" 22 "testing" 23 24 "github.com/stretchr/testify/assert" 25 "go.etcd.io/etcd/client/v2" 26) 27 28func TestPauseMember(t *testing.T) { 29 BeforeTest(t) 30 31 c := NewCluster(t, 5) 32 c.Launch(t) 33 defer c.Terminate(t) 34 35 for i := 0; i < 5; i++ { 36 c.Members[i].Pause() 37 membs := append([]*member{}, c.Members[:i]...) 38 membs = append(membs, c.Members[i+1:]...) 39 c.waitLeader(t, membs) 40 clusterMustProgress(t, membs) 41 c.Members[i].Resume() 42 } 43 c.waitLeader(t, c.Members) 44 clusterMustProgress(t, c.Members) 45} 46 47func TestRestartMember(t *testing.T) { 48 BeforeTest(t) 49 c := NewCluster(t, 3) 50 c.Launch(t) 51 defer c.Terminate(t) 52 53 for i := 0; i < 3; i++ { 54 c.Members[i].Stop(t) 55 membs := append([]*member{}, c.Members[:i]...) 56 membs = append(membs, c.Members[i+1:]...) 57 c.waitLeader(t, membs) 58 clusterMustProgress(t, membs) 59 err := c.Members[i].Restart(t) 60 if err != nil { 61 t.Fatal(err) 62 } 63 } 64 c.waitLeader(t, c.Members) 65 clusterMustProgress(t, c.Members) 66} 67 68func TestLaunchDuplicateMemberShouldFail(t *testing.T) { 69 BeforeTest(t) 70 size := 3 71 c := NewCluster(t, size) 72 m := c.Members[0].Clone(t) 73 var err error 74 m.DataDir, err = ioutil.TempDir(t.TempDir(), "etcd") 75 if err != nil { 76 t.Fatal(err) 77 } 78 c.Launch(t) 79 defer c.Terminate(t) 80 81 if err := m.Launch(); err == nil { 82 t.Errorf("unexpect successful launch") 83 } else { 84 t.Logf("launch failed as expected: %v", err) 85 assert.Contains(t, err.Error(), "has already been bootstrapped") 86 } 87} 88 89func TestSnapshotAndRestartMember(t *testing.T) { 90 BeforeTest(t) 91 m := mustNewMember(t, memberConfig{name: "snapAndRestartTest"}) 92 m.SnapshotCount = 100 93 m.Launch() 94 defer m.Terminate(t) 95 m.WaitOK(t) 96 97 resps := make([]*client.Response, 120) 98 var err error 99 for i := 0; i < 120; i++ { 100 cc := MustNewHTTPClient(t, []string{m.URL()}, nil) 101 kapi := client.NewKeysAPI(cc) 102 ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) 103 key := fmt.Sprintf("foo%d", i) 104 resps[i], err = kapi.Create(ctx, "/"+key, "bar") 105 if err != nil { 106 t.Fatalf("#%d: create on %s error: %v", i, m.URL(), err) 107 } 108 cancel() 109 } 110 m.Stop(t) 111 m.Restart(t) 112 113 m.WaitOK(t) 114 for i := 0; i < 120; i++ { 115 cc := MustNewHTTPClient(t, []string{m.URL()}, nil) 116 kapi := client.NewKeysAPI(cc) 117 ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) 118 key := fmt.Sprintf("foo%d", i) 119 resp, err := kapi.Get(ctx, "/"+key, nil) 120 if err != nil { 121 t.Fatalf("#%d: get on %s error: %v", i, m.URL(), err) 122 } 123 cancel() 124 125 if !reflect.DeepEqual(resp.Node, resps[i].Node) { 126 t.Errorf("#%d: node = %v, want %v", i, resp.Node, resps[i].Node) 127 } 128 } 129} 130