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  }