github.com/aergoio/aergo@v1.3.1/polaris/server/peerstate_test.go (about)

     1  /*
     2   * @file
     3   * @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  package server
     7  
     8  import (
     9  	"fmt"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/aergoio/aergo-lib/log"
    14  	"github.com/aergoio/aergo/p2p/p2pcommon"
    15  	"github.com/aergoio/aergo/p2p/p2pmock"
    16  	"github.com/aergoio/aergo/p2p/p2putil"
    17  	"github.com/aergoio/aergo/pkg/component"
    18  	"github.com/aergoio/aergo/types"
    19  	"github.com/golang/mock/gomock"
    20  	"github.com/stretchr/testify/assert"
    21  )
    22  
    23  var NetError = fmt.Errorf("network err for unittest")
    24  
    25  func Test_pingChecker_DoCall(t *testing.T) {
    26  	ctrl := gomock.NewController(t)
    27  
    28  	type args struct {
    29  		rw        p2pcommon.MsgReadWriter
    30  		writeWait int
    31  		writeRet  error
    32  		readWait  int
    33  		respSub   p2pcommon.SubProtocol
    34  		readRet2  error
    35  	}
    36  	tests := []struct {
    37  		name    string
    38  		args    args
    39  		wantErr bool
    40  	}{
    41  		// 1. msg writer succeeded send and succeeded read
    42  		{"Tsucc", args{writeRet: nil, readRet2: nil, respSub: p2pcommon.PingResponse}, false},
    43  		// 2. failed to write
    44  		{"TFailWrite", args{writeRet: NetError, readRet2: nil, respSub: p2pcommon.PingResponse}, true},
    45  		// 3. failed to read
    46  		{"TFailRead", args{writeRet: nil, readRet2: NetError, respSub: p2pcommon.PingResponse}, true},
    47  		// 4. read but not ping response
    48  		{"TWrongResp", args{writeRet: nil, readRet2: nil, respSub: p2pcommon.AddressesResponse}, true},
    49  		// 5. cancel signal  while writing
    50  		{"TTimeoutWrite", args{writeRet: nil, writeWait: 3, readRet2: nil, respSub: p2pcommon.PingResponse}, true},
    51  		// 6. cancel signal while reading
    52  		{"TTimeoutRead", args{writeRet: nil, readWait: 3, readRet2: nil, respSub: p2pcommon.PingResponse}, true},
    53  
    54  		// verification . check return value, (or err
    55  		// TODO: Add test cases.
    56  	}
    57  	for _, tt := range tests {
    58  
    59  		t.Run(tt.name, func(t *testing.T) {
    60  			ps := &peerState{temporary: true, PeerMapService: &PeerMapService{BaseComponent: &component.BaseComponent{Logger: log.NewLogger("test")}}}
    61  			rw := p2pmock.NewMockMsgReadWriter(ctrl)
    62  			pc := &pingChecker{
    63  				peerState: ps,
    64  				rw:        rw,
    65  			}
    66  
    67  			var reqID p2pcommon.MsgID
    68  			rw.EXPECT().WriteMsg(gomock.Any()).Do(func(msg p2pcommon.Message) {
    69  				reqID = msg.ID()
    70  				if tt.args.writeWait > 0 {
    71  					pc.Cancel()
    72  					time.Sleep(time.Millisecond << 4)
    73  				}
    74  			}).Return(tt.args.writeRet)
    75  			rw.EXPECT().ReadMsg().MaxTimes(1).DoAndReturn(func() (p2pcommon.Message, error) {
    76  				if tt.args.readWait > 0 {
    77  					pc.Cancel()
    78  					time.Sleep(time.Millisecond << 4)
    79  				}
    80  				ret := p2pcommon.NewMessageValue(tt.args.respSub, EmptyMsgID, reqID, time.Now().UnixNano(), []byte{})
    81  				return ret, tt.args.readRet2
    82  			})
    83  
    84  			done := make(chan interface{}, 1)
    85  			pc.DoCall(done)
    86  			result := <-done
    87  			if tt.wantErr {
    88  				assert.Nil(t, result.(*types.Ping))
    89  			} else {
    90  				assert.NotNil(t, result.(*types.Ping))
    91  			}
    92  		})
    93  
    94  	}
    95  	ctrl.Finish()
    96  }
    97  
    98  func Test_pingChecker_DoCallWithTimer(t *testing.T) {
    99  	ctrl := gomock.NewController(t)
   100  
   101  	type args struct {
   102  		rw        p2pcommon.MsgReadWriter
   103  		writeWait int
   104  		writeRet  error
   105  		readWait  int
   106  		respSub   p2pcommon.SubProtocol
   107  		readRet2  error
   108  	}
   109  	tests := []struct {
   110  		name    string
   111  		args    args
   112  		wantErr bool
   113  	}{
   114  		// 1. msg writer succeeded send and succeeded read
   115  		{"Tsucc", args{writeRet: nil, readRet2: nil, respSub: p2pcommon.PingResponse}, false},
   116  		// 2. failed to write
   117  		{"TFailWrite", args{writeRet: NetError, readRet2: nil, respSub: p2pcommon.PingResponse}, true},
   118  		// 3. failed to read
   119  		{"TFailRead", args{writeRet: nil, readRet2: NetError, respSub: p2pcommon.PingResponse}, true},
   120  		// 4. read but not ping response
   121  		{"TWrongPayload", args{writeRet: nil, readRet2: nil, respSub: p2pcommon.StatusRequest}, true},
   122  		// 5. cancel signal  while writing
   123  		{"TTimeoutWrite", args{writeRet: nil, writeWait: 3, readRet2: nil, respSub: p2pcommon.PingResponse}, true},
   124  		// 6. cancel signal while reading
   125  		{"TTimeoutRead", args{writeRet: nil, readWait: 3, readRet2: nil, respSub: p2pcommon.PingResponse}, true},
   126  
   127  		// verification . check return value, (or err
   128  		// TODO: Add test cases.
   129  	}
   130  	for _, tt := range tests {
   131  
   132  		t.Run(tt.name, func(t *testing.T) {
   133  			ps := &peerState{temporary: true, PeerMapService: &PeerMapService{BaseComponent: &component.BaseComponent{Logger: log.NewLogger("test")}}}
   134  			rw := p2pmock.NewMockMsgReadWriter(ctrl)
   135  			pc := &pingChecker{
   136  				peerState: ps,
   137  				rw:        rw,
   138  			}
   139  
   140  			var reqID p2pcommon.MsgID
   141  			rw.EXPECT().WriteMsg(gomock.Any()).Do(func(msg p2pcommon.Message) {
   142  				reqID = msg.ID()
   143  				if tt.args.writeWait > 0 {
   144  					time.Sleep(time.Second)
   145  				}
   146  			}).Return(tt.args.writeRet)
   147  			rw.EXPECT().ReadMsg().MaxTimes(1).DoAndReturn(func() (p2pcommon.Message, error) {
   148  				if tt.args.readWait > 0 {
   149  					time.Sleep(time.Second)
   150  				}
   151  				ret := p2pcommon.NewMessageValue(tt.args.respSub, EmptyMsgID, reqID, time.Now().UnixNano(), []byte{})
   152  				return ret, tt.args.readRet2
   153  			})
   154  
   155  			result, err := p2putil.InvokeWithTimer(pc, time.NewTimer(time.Millisecond<<5))
   156  			if tt.args.readWait > 0 || tt.args.writeWait > 0 {
   157  				assert.NotNil(t, err)
   158  			} else {
   159  				assert.Nil(t, err)
   160  				if tt.wantErr {
   161  					assert.Nil(t, result.(*types.Ping))
   162  				} else {
   163  					assert.NotNil(t, result.(*types.Ping))
   164  				}
   165  			}
   166  		})
   167  
   168  	}
   169  	ctrl.Finish()
   170  }