go.etcd.io/etcd@v3.3.27+incompatible/tests/e2e/ctl_v3_member_test.go (about) 1 // Copyright 2016 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 15 package e2e 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "io" 21 "strings" 22 "testing" 23 24 "github.com/coreos/etcd/etcdserver/etcdserverpb" 25 ) 26 27 func TestCtlV3MemberList(t *testing.T) { testCtl(t, memberListTest) } 28 func TestCtlV3MemberListNoTLS(t *testing.T) { testCtl(t, memberListTest, withCfg(configNoTLS)) } 29 func TestCtlV3MemberListClientTLS(t *testing.T) { testCtl(t, memberListTest, withCfg(configClientTLS)) } 30 func TestCtlV3MemberListClientAutoTLS(t *testing.T) { 31 testCtl(t, memberListTest, withCfg(configClientAutoTLS)) 32 } 33 func TestCtlV3MemberListPeerTLS(t *testing.T) { testCtl(t, memberListTest, withCfg(configPeerTLS)) } 34 func TestCtlV3MemberRemove(t *testing.T) { 35 testCtl(t, memberRemoveTest, withQuorum(), withNoStrictReconfig()) 36 } 37 func TestCtlV3MemberRemoveNoTLS(t *testing.T) { 38 testCtl(t, memberRemoveTest, withQuorum(), withNoStrictReconfig(), withCfg(configNoTLS)) 39 } 40 func TestCtlV3MemberRemoveClientTLS(t *testing.T) { 41 testCtl(t, memberRemoveTest, withQuorum(), withNoStrictReconfig(), withCfg(configClientTLS)) 42 } 43 func TestCtlV3MemberRemoveClientAutoTLS(t *testing.T) { 44 testCtl(t, memberRemoveTest, withQuorum(), withNoStrictReconfig(), withCfg( 45 // default clusterSize is 1 46 etcdProcessClusterConfig{ 47 clusterSize: 3, 48 isClientAutoTLS: true, 49 clientTLS: clientTLS, 50 initialToken: "new", 51 })) 52 } 53 func TestCtlV3MemberRemovePeerTLS(t *testing.T) { 54 testCtl(t, memberRemoveTest, withQuorum(), withNoStrictReconfig(), withCfg(configPeerTLS)) 55 } 56 func TestCtlV3MemberAdd(t *testing.T) { testCtl(t, memberAddTest) } 57 func TestCtlV3MemberAddNoTLS(t *testing.T) { testCtl(t, memberAddTest, withCfg(configNoTLS)) } 58 func TestCtlV3MemberAddClientTLS(t *testing.T) { testCtl(t, memberAddTest, withCfg(configClientTLS)) } 59 func TestCtlV3MemberAddClientAutoTLS(t *testing.T) { 60 testCtl(t, memberAddTest, withCfg(configClientAutoTLS)) 61 } 62 func TestCtlV3MemberAddPeerTLS(t *testing.T) { testCtl(t, memberAddTest, withCfg(configPeerTLS)) } 63 func TestCtlV3MemberUpdate(t *testing.T) { testCtl(t, memberUpdateTest) } 64 func TestCtlV3MemberUpdateNoTLS(t *testing.T) { testCtl(t, memberUpdateTest, withCfg(configNoTLS)) } 65 func TestCtlV3MemberUpdateClientTLS(t *testing.T) { 66 testCtl(t, memberUpdateTest, withCfg(configClientTLS)) 67 } 68 func TestCtlV3MemberUpdateClientAutoTLS(t *testing.T) { 69 testCtl(t, memberUpdateTest, withCfg(configClientAutoTLS)) 70 } 71 func TestCtlV3MemberUpdatePeerTLS(t *testing.T) { testCtl(t, memberUpdateTest, withCfg(configPeerTLS)) } 72 73 func memberListTest(cx ctlCtx) { 74 if err := ctlV3MemberList(cx); err != nil { 75 cx.t.Fatalf("memberListTest ctlV3MemberList error (%v)", err) 76 } 77 } 78 79 func ctlV3MemberList(cx ctlCtx) error { 80 cmdArgs := append(cx.PrefixArgs(), "member", "list") 81 lines := make([]string, cx.cfg.clusterSize) 82 for i := range lines { 83 lines[i] = "started" 84 } 85 return spawnWithExpects(cmdArgs, lines...) 86 } 87 88 func getMemberList(cx ctlCtx) (etcdserverpb.MemberListResponse, error) { 89 cmdArgs := append(cx.PrefixArgs(), "--write-out", "json", "member", "list") 90 91 proc, err := spawnCmd(cmdArgs) 92 if err != nil { 93 return etcdserverpb.MemberListResponse{}, err 94 } 95 var txt string 96 txt, err = proc.Expect("members") 97 if err != nil { 98 return etcdserverpb.MemberListResponse{}, err 99 } 100 if err = proc.Close(); err != nil { 101 return etcdserverpb.MemberListResponse{}, err 102 } 103 104 resp := etcdserverpb.MemberListResponse{} 105 dec := json.NewDecoder(strings.NewReader(txt)) 106 if err := dec.Decode(&resp); err == io.EOF { 107 return etcdserverpb.MemberListResponse{}, err 108 } 109 return resp, nil 110 } 111 112 func memberRemoveTest(cx ctlCtx) { 113 ep, memIDToRemove, clusterID := cx.memberToRemove() 114 if err := ctlV3MemberRemove(cx, ep, memIDToRemove, clusterID); err != nil { 115 cx.t.Fatal(err) 116 } 117 } 118 119 func ctlV3MemberRemove(cx ctlCtx, ep, memberID, clusterID string) error { 120 cmdArgs := append(cx.prefixArgs([]string{ep}), "member", "remove", memberID) 121 return spawnWithExpect(cmdArgs, fmt.Sprintf("%s removed from cluster %s", memberID, clusterID)) 122 } 123 124 func memberAddTest(cx ctlCtx) { 125 if err := ctlV3MemberAdd(cx, fmt.Sprintf("http://localhost:%d", etcdProcessBasePort+11), false); err != nil { 126 cx.t.Fatal(err) 127 } 128 } 129 130 func ctlV3MemberAdd(cx ctlCtx, peerURL string, isLearner bool) error { 131 cmdArgs := append(cx.PrefixArgs(), "member", "add", "newmember", fmt.Sprintf("--peer-urls=%s", peerURL)) 132 if isLearner { 133 cmdArgs = append(cmdArgs, "--learner") 134 } 135 return spawnWithExpect(cmdArgs, " added to cluster ") 136 } 137 138 func memberUpdateTest(cx ctlCtx) { 139 mr, err := getMemberList(cx) 140 if err != nil { 141 cx.t.Fatal(err) 142 } 143 144 peerURL := fmt.Sprintf("http://localhost:%d", etcdProcessBasePort+11) 145 memberID := fmt.Sprintf("%x", mr.Members[0].ID) 146 if err = ctlV3MemberUpdate(cx, memberID, peerURL); err != nil { 147 cx.t.Fatal(err) 148 } 149 } 150 151 func ctlV3MemberUpdate(cx ctlCtx, memberID, peerURL string) error { 152 cmdArgs := append(cx.PrefixArgs(), "member", "update", memberID, fmt.Sprintf("--peer-urls=%s", peerURL)) 153 return spawnWithExpect(cmdArgs, " updated in cluster ") 154 }