go.etcd.io/etcd@v3.3.27+incompatible/rafthttp/transport_test.go (about) 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 15 package rafthttp 16 17 import ( 18 "net/http" 19 "reflect" 20 "testing" 21 "time" 22 23 "github.com/coreos/etcd/etcdserver/stats" 24 "github.com/coreos/etcd/pkg/testutil" 25 "github.com/coreos/etcd/pkg/types" 26 "github.com/coreos/etcd/raft/raftpb" 27 "github.com/xiang90/probing" 28 ) 29 30 // TestTransportSend tests that transport can send messages using correct 31 // underlying peer, and drop local or unknown-target messages. 32 func TestTransportSend(t *testing.T) { 33 peer1 := newFakePeer() 34 peer2 := newFakePeer() 35 tr := &Transport{ 36 ServerStats: stats.NewServerStats("", ""), 37 peers: map[types.ID]Peer{types.ID(1): peer1, types.ID(2): peer2}, 38 pipelineProber: probing.NewProber(nil), 39 streamProber: probing.NewProber(nil), 40 } 41 wmsgsIgnored := []raftpb.Message{ 42 // bad local message 43 {Type: raftpb.MsgBeat}, 44 // bad remote message 45 {Type: raftpb.MsgProp, To: 3}, 46 } 47 wmsgsTo1 := []raftpb.Message{ 48 // good message 49 {Type: raftpb.MsgProp, To: 1}, 50 {Type: raftpb.MsgApp, To: 1}, 51 } 52 wmsgsTo2 := []raftpb.Message{ 53 // good message 54 {Type: raftpb.MsgProp, To: 2}, 55 {Type: raftpb.MsgApp, To: 2}, 56 } 57 tr.Send(wmsgsIgnored) 58 tr.Send(wmsgsTo1) 59 tr.Send(wmsgsTo2) 60 61 if !reflect.DeepEqual(peer1.msgs, wmsgsTo1) { 62 t.Errorf("msgs to peer 1 = %+v, want %+v", peer1.msgs, wmsgsTo1) 63 } 64 if !reflect.DeepEqual(peer2.msgs, wmsgsTo2) { 65 t.Errorf("msgs to peer 2 = %+v, want %+v", peer2.msgs, wmsgsTo2) 66 } 67 } 68 69 func TestTransportCutMend(t *testing.T) { 70 peer1 := newFakePeer() 71 peer2 := newFakePeer() 72 tr := &Transport{ 73 ServerStats: stats.NewServerStats("", ""), 74 peers: map[types.ID]Peer{types.ID(1): peer1, types.ID(2): peer2}, 75 pipelineProber: probing.NewProber(nil), 76 streamProber: probing.NewProber(nil), 77 } 78 79 tr.CutPeer(types.ID(1)) 80 81 wmsgsTo := []raftpb.Message{ 82 // good message 83 {Type: raftpb.MsgProp, To: 1}, 84 {Type: raftpb.MsgApp, To: 1}, 85 } 86 87 tr.Send(wmsgsTo) 88 if len(peer1.msgs) > 0 { 89 t.Fatalf("msgs expected to be ignored, got %+v", peer1.msgs) 90 } 91 92 tr.MendPeer(types.ID(1)) 93 94 tr.Send(wmsgsTo) 95 if !reflect.DeepEqual(peer1.msgs, wmsgsTo) { 96 t.Errorf("msgs to peer 1 = %+v, want %+v", peer1.msgs, wmsgsTo) 97 } 98 } 99 100 func TestTransportAdd(t *testing.T) { 101 ls := stats.NewLeaderStats("") 102 tr := &Transport{ 103 LeaderStats: ls, 104 streamRt: &roundTripperRecorder{}, 105 peers: make(map[types.ID]Peer), 106 pipelineProber: probing.NewProber(nil), 107 streamProber: probing.NewProber(nil), 108 } 109 tr.AddPeer(1, []string{"http://localhost:2380"}) 110 111 if _, ok := ls.Followers["1"]; !ok { 112 t.Errorf("FollowerStats[1] is nil, want exists") 113 } 114 s, ok := tr.peers[types.ID(1)] 115 if !ok { 116 tr.Stop() 117 t.Fatalf("senders[1] is nil, want exists") 118 } 119 120 // duplicate AddPeer is ignored 121 tr.AddPeer(1, []string{"http://localhost:2380"}) 122 ns := tr.peers[types.ID(1)] 123 if s != ns { 124 t.Errorf("sender = %v, want %v", ns, s) 125 } 126 127 tr.Stop() 128 } 129 130 func TestTransportRemove(t *testing.T) { 131 tr := &Transport{ 132 LeaderStats: stats.NewLeaderStats(""), 133 streamRt: &roundTripperRecorder{}, 134 peers: make(map[types.ID]Peer), 135 pipelineProber: probing.NewProber(nil), 136 streamProber: probing.NewProber(nil), 137 } 138 tr.AddPeer(1, []string{"http://localhost:2380"}) 139 tr.RemovePeer(types.ID(1)) 140 defer tr.Stop() 141 142 if _, ok := tr.peers[types.ID(1)]; ok { 143 t.Fatalf("senders[1] exists, want removed") 144 } 145 } 146 147 func TestTransportUpdate(t *testing.T) { 148 peer := newFakePeer() 149 tr := &Transport{ 150 peers: map[types.ID]Peer{types.ID(1): peer}, 151 pipelineProber: probing.NewProber(nil), 152 streamProber: probing.NewProber(nil), 153 } 154 u := "http://localhost:2380" 155 tr.UpdatePeer(types.ID(1), []string{u}) 156 wurls := types.URLs(testutil.MustNewURLs(t, []string{"http://localhost:2380"})) 157 if !reflect.DeepEqual(peer.peerURLs, wurls) { 158 t.Errorf("urls = %+v, want %+v", peer.peerURLs, wurls) 159 } 160 } 161 162 func TestTransportErrorc(t *testing.T) { 163 errorc := make(chan error, 1) 164 tr := &Transport{ 165 Raft: &fakeRaft{}, 166 LeaderStats: stats.NewLeaderStats(""), 167 ErrorC: errorc, 168 streamRt: newRespRoundTripper(http.StatusForbidden, nil), 169 pipelineRt: newRespRoundTripper(http.StatusForbidden, nil), 170 peers: make(map[types.ID]Peer), 171 pipelineProber: probing.NewProber(nil), 172 streamProber: probing.NewProber(nil), 173 } 174 tr.AddPeer(1, []string{"http://localhost:2380"}) 175 defer tr.Stop() 176 177 select { 178 case <-errorc: 179 t.Fatalf("received unexpected from errorc") 180 case <-time.After(10 * time.Millisecond): 181 } 182 tr.peers[1].send(raftpb.Message{}) 183 184 select { 185 case <-errorc: 186 case <-time.After(1 * time.Second): 187 t.Fatalf("cannot receive error from errorc") 188 } 189 }