github.com/aergoio/aergo@v1.3.1/p2p/rolemanager_test.go (about)

     1  /*
     2   * @file
     3   * @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  package p2p
     7  
     8  import (
     9  	"fmt"
    10  	"reflect"
    11  	"testing"
    12  
    13  	"github.com/aergoio/aergo/message"
    14  	"github.com/aergoio/aergo/p2p/p2pcommon"
    15  	"github.com/aergoio/aergo/p2p/p2pmock"
    16  	"github.com/aergoio/aergo/types"
    17  	"github.com/golang/mock/gomock"
    18  )
    19  
    20  func TestRaftRoleManager_updateBP(t *testing.T) {
    21  	ctrl := gomock.NewController(t)
    22  	defer ctrl.Finish()
    23  
    24  	p1, p2, p3 := dummyPeerID, dummyPeerID2, dummyPeerID3
    25  
    26  	tests := []struct {
    27  		name   string
    28  		preset []types.PeerID
    29  		args   message.RaftClusterEvent
    30  
    31  		wantCnt   int
    32  		wantExist []types.PeerID
    33  		wantNot   []types.PeerID
    34  	}{
    35  		{"TAdd", nil, (&EB{}).A(p1, p2).C(), 2, []types.PeerID{p1, p2}, nil},
    36  		{"TRm", []types.PeerID{p1, p2, p3}, (&EB{}).R(p3, p2).C(), 1, []types.PeerID{p1}, []types.PeerID{p2, p3}},
    37  		{"TOverlap", []types.PeerID{p3}, (&EB{}).A(p1, p2).R(p3, p2).C(), 2, []types.PeerID{p1, p2}, []types.PeerID{p3}},
    38  		{"TEmpty", nil, (&EB{}).C(), 0, []types.PeerID{}, nil},
    39  	}
    40  	for _, tt := range tests {
    41  		t.Run(tt.name, func(t *testing.T) {
    42  			presetIDs := make(map[types.PeerID]bool)
    43  			for _, id := range tt.preset {
    44  				presetIDs[id] = true
    45  			}
    46  			mockPM := p2pmock.NewMockPeerManager(ctrl)
    47  			mockPM.EXPECT().GetPeer(gomock.Any()).Return(nil, false).AnyTimes()
    48  			mockPM.EXPECT().UpdatePeerRole(gomock.Any()).AnyTimes()
    49  
    50  			p2ps := &P2P{pm: mockPM}
    51  			rm := &RaftRoleManager{
    52  				p2ps:   p2ps,
    53  				logger: logger,
    54  				raftBP: presetIDs,
    55  			}
    56  			rm.UpdateBP(tt.args.BPAdded, tt.args.BPRemoved)
    57  
    58  			if len(rm.raftBP) != tt.wantCnt {
    59  				t.Errorf("P2P.UpdateBP() len = %v, want %v", len(rm.raftBP), tt.wantCnt)
    60  			}
    61  			for _, id := range tt.wantExist {
    62  				if _, found := rm.raftBP[id]; !found {
    63  					t.Errorf("P2P.UpdateBP() not exist %v, want exist ", id)
    64  				} else {
    65  					if rm.GetRole(id) != p2pcommon.BlockProducer {
    66  						t.Errorf("P2P.GetRole(%v) false, want true", id)
    67  					}
    68  				}
    69  			}
    70  			for _, id := range tt.wantNot {
    71  				if _, found := rm.raftBP[id]; found {
    72  					t.Errorf("P2P.UpdateBP() exist %v, want not ", id)
    73  				}
    74  			}
    75  		})
    76  	}
    77  }
    78  
    79  type EB struct {
    80  	a, r []types.PeerID
    81  }
    82  
    83  func (e *EB) A(ids ...types.PeerID) *EB {
    84  	e.a = append(e.a, ids...)
    85  	return e
    86  }
    87  func (e *EB) R(ids ...types.PeerID) *EB {
    88  	e.r = append(e.r, ids...)
    89  	return e
    90  }
    91  func (e *EB) C() message.RaftClusterEvent {
    92  	return message.RaftClusterEvent{BPAdded: e.a, BPRemoved: e.r}
    93  }
    94  
    95  func TestRaftRoleManager_NotifyNewBlockMsg(t *testing.T) {
    96  	ctrl := gomock.NewController(t)
    97  	defer ctrl.Finish()
    98  
    99  	pids := []types.PeerID{dummyPeerID, dummyPeerID2, dummyPeerID3}
   100  
   101  	tests := []struct {
   102  		name string
   103  
   104  		argPeer []rs
   105  
   106  		wantSkipped int
   107  		wantSent    int
   108  	}{
   109  		{"TAllBP", []rs{{p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}}, 3, 0},
   110  		{"TAllWat", []rs{{p2pcommon.Watcher, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}}, 0, 3},
   111  		{"TMIX", []rs{{p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}}, 2, 1},
   112  		{"TMIXStop", []rs{{p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.Watcher, types.STOPPING}}, 3, 0},
   113  		{"TMixStop2", []rs{{p2pcommon.BlockProducer, types.STOPPING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}}, 2, 1},
   114  	}
   115  	for _, tt := range tests {
   116  		t.Run(tt.name, func(t *testing.T) {
   117  			mockPM := p2pmock.NewMockPeerManager(ctrl)
   118  			mockPM.EXPECT().GetPeer(gomock.Any()).Return(nil, false).AnyTimes()
   119  			mockPM.EXPECT().UpdatePeerRole(gomock.Any()).AnyTimes()
   120  
   121  			mockMO := p2pmock.NewMockMsgOrder(ctrl)
   122  
   123  			rm := &RaftRoleManager{
   124  				p2ps:   nil,
   125  				logger: logger,
   126  			}
   127  			mockPeers := make([]p2pcommon.RemotePeer, 0, len(tt.argPeer))
   128  			for i, ap := range tt.argPeer {
   129  				mpeer := p2pmock.NewMockRemotePeer(ctrl)
   130  				mpeer.EXPECT().ID().Return(pids[i]).AnyTimes()
   131  				mpeer.EXPECT().Role().Return(ap.r).AnyTimes()
   132  				mpeer.EXPECT().State().Return(ap.s).AnyTimes()
   133  				mpeer.EXPECT().SendMessage(gomock.Any()).MaxTimes(1)
   134  
   135  				mockPeers = append(mockPeers, mpeer)
   136  			}
   137  			gotSkipped, gotSent := rm.NotifyNewBlockMsg(mockMO, mockPeers)
   138  			if gotSkipped != tt.wantSkipped {
   139  				t.Errorf("RaftRoleManager.NotifyNewBlockMsg() gotSkipped = %v, want %v", gotSkipped, tt.wantSkipped)
   140  			}
   141  			if gotSent != tt.wantSent {
   142  				t.Errorf("RaftRoleManager.NotifyNewBlockMsg() gotSent = %v, want %v", gotSent, tt.wantSent)
   143  			}
   144  		})
   145  	}
   146  }
   147  
   148  func TestDefaultRoleManager_updateBP(t *testing.T) {
   149  	ctrl := gomock.NewController(t)
   150  	defer ctrl.Finish()
   151  
   152  	p1, p2, p3 := dummyPeerID, dummyPeerID2, dummyPeerID3
   153  
   154  	tests := []struct {
   155  		name string
   156  		args message.RaftClusterEvent
   157  
   158  		wantCnt   int
   159  		wantExist []types.PeerID
   160  	}{
   161  		{"TAdd", (&EB{}).A(p1, p2).C(), 2, []types.PeerID{p1, p2}},
   162  		{"TRemove", (&EB{}).R(p3, p2).C(), 2, []types.PeerID{p3, p2}},
   163  		{"TOverlap", (&EB{}).A(p1, p2).R(p3, p2).C(), 3, []types.PeerID{p1, p2, p3}},
   164  		{"TEmpty", (&EB{}).C(), 0, []types.PeerID{}},
   165  	}
   166  	for _, tt := range tests {
   167  		t.Run(tt.name, func(t *testing.T) {
   168  			var sentIds []types.PeerID = nil
   169  			mockPM := p2pmock.NewMockPeerManager(ctrl)
   170  			mockPM.EXPECT().GetPeer(gomock.Any()).Return(nil, false).AnyTimes()
   171  			mockPM.EXPECT().UpdatePeerRole(gomock.Any()).Do(func(cs []p2pcommon.AttrModifier) {
   172  				for _, id := range cs {
   173  					sentIds = append(sentIds, id.ID)
   174  				}
   175  			})
   176  
   177  			p2ps := &P2P{pm: mockPM}
   178  			rm := &DefaultRoleManager{
   179  				p2ps: p2ps,
   180  			}
   181  			rm.UpdateBP(tt.args.BPAdded, tt.args.BPRemoved)
   182  
   183  			for _, id := range tt.wantExist {
   184  				found := false
   185  				for _, sent := range sentIds {
   186  					if id.Pretty() == sent.Pretty() {
   187  						found = true
   188  						break
   189  					}
   190  				}
   191  				if !found {
   192  					t.Errorf("DefaultRoleManager.UpdateBP() not exist %v, want exist ", id)
   193  				}
   194  			}
   195  		})
   196  	}
   197  }
   198  
   199  func TestDefaultRoleManager_NotifyNewBlockMsg(t *testing.T) {
   200  	ctrl := gomock.NewController(t)
   201  	defer ctrl.Finish()
   202  
   203  	pids := []types.PeerID{dummyPeerID, dummyPeerID2, dummyPeerID3}
   204  
   205  	tests := []struct {
   206  		name string
   207  
   208  		argPeer []rs
   209  
   210  		wantSkipped int
   211  		wantSent    int
   212  	}{
   213  		{"TAllBP", []rs{{p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}}, 0, 3},
   214  		{"TAllWat", []rs{{p2pcommon.Watcher, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}}, 0, 3},
   215  		{"TMix", []rs{{p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}}, 0, 3},
   216  		{"TMixStop", []rs{{p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.Watcher, types.STOPPING}}, 1, 2},
   217  		{"TMixStop2", []rs{{p2pcommon.BlockProducer, types.STOPPING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}}, 1, 2},
   218  	}
   219  	for _, tt := range tests {
   220  		t.Run(tt.name, func(t *testing.T) {
   221  			mockPM := p2pmock.NewMockPeerManager(ctrl)
   222  			mockPM.EXPECT().GetPeer(gomock.Any()).Return(nil, false).AnyTimes()
   223  			mockPM.EXPECT().UpdatePeerRole(gomock.Any()).AnyTimes()
   224  
   225  			mockMO := p2pmock.NewMockMsgOrder(ctrl)
   226  
   227  			rm := &DefaultRoleManager{
   228  				p2ps: nil,
   229  			}
   230  			mockPeers := make([]p2pcommon.RemotePeer, 0, len(tt.argPeer))
   231  			for i, ap := range tt.argPeer {
   232  				mPeer := p2pmock.NewMockRemotePeer(ctrl)
   233  				mPeer.EXPECT().ID().Return(pids[i]).AnyTimes()
   234  				mPeer.EXPECT().Role().Return(ap.r).AnyTimes()
   235  				mPeer.EXPECT().State().Return(ap.s).AnyTimes()
   236  				mPeer.EXPECT().SendMessage(gomock.Any()).MaxTimes(1)
   237  
   238  				mockPeers = append(mockPeers, mPeer)
   239  			}
   240  			gotSkipped, gotSent := rm.NotifyNewBlockMsg(mockMO, mockPeers)
   241  			if gotSkipped != tt.wantSkipped {
   242  				t.Errorf("RaftRoleManager.NotifyNewBlockMsg() gotSkipped = %v, want %v", gotSkipped, tt.wantSkipped)
   243  			}
   244  			if gotSent != tt.wantSent {
   245  				t.Errorf("RaftRoleManager.NotifyNewBlockMsg() gotSent = %v, want %v", gotSent, tt.wantSent)
   246  			}
   247  		})
   248  	}
   249  }
   250  
   251  type rs struct {
   252  	r p2pcommon.PeerRole
   253  	s types.PeerState
   254  }
   255  
   256  func TestDefaultRoleManager_GetRole(t *testing.T) {
   257  	ctrl := gomock.NewController(t)
   258  	defer ctrl.Finish()
   259  	p1, p2, p3 := dummyPeerID, dummyPeerID2, dummyPeerID3
   260  
   261  	tests := []struct {
   262  		name string
   263  
   264  		presetIds []types.PeerID
   265  		pid       types.PeerID
   266  		want      p2pcommon.PeerRole
   267  	}{
   268  		{"TBP", toPIDS(p1,p2), p1, p2pcommon.BlockProducer},
   269  		{"TWat", toPIDS(p1,p2), p3, p2pcommon.Watcher},
   270  	}
   271  	for i, tt := range tests {
   272  		t.Run(tt.name, func(t *testing.T) {
   273  			bps := make([]string,0,len(tt.presetIds))
   274  			for _, id := range tt.presetIds {
   275  				bps = append(bps, fmt.Sprintf("{\"%d\":\"%s\"}",i,id.Pretty()))
   276  			}
   277  			dummyConsensus := &types.ConsensusInfo{Bps:bps}
   278  			mockCC := p2pmock.NewMockConsensusAccessor(ctrl)
   279  			mockCC.EXPECT().ConsensusInfo().Return(dummyConsensus)
   280  			p2ps := &P2P{consacc: mockCC}
   281  			rm := &DefaultRoleManager{
   282  				p2ps: p2ps,
   283  			}
   284  			if got := rm.GetRole(tt.pid); !reflect.DeepEqual(got, tt.want) {
   285  				t.Errorf("DefaultRoleManager.GetRole() = %v, want %v", got, tt.want)
   286  			}
   287  		})
   288  	}
   289  }
   290  
   291  func toPIDS(ids ...types.PeerID) []types.PeerID {
   292  	return ids
   293  }