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

     1  /*
     2   * @file
     3   * @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  package p2p
     7  
     8  import (
     9  	"github.com/aergoio/aergo-lib/log"
    10  	"github.com/aergoio/aergo/message"
    11  	"github.com/aergoio/aergo/p2p/p2pcommon"
    12  	"github.com/aergoio/aergo/p2p/p2pmock"
    13  	"github.com/aergoio/aergo/types"
    14  	"github.com/golang/mock/gomock"
    15  	"testing"
    16  	"time"
    17  )
    18  
    19  func Test_newTxNoticeTracer(t *testing.T) {
    20  	logger := log.NewLogger("p2p.test")
    21  
    22  	tests := []struct {
    23  		name string
    24  	}{
    25  		{"T1"},
    26  	}
    27  	for _, tt := range tests {
    28  		t.Run(tt.name, func(t *testing.T) {
    29  			ctrl := gomock.NewController(t)
    30  			defer ctrl.Finish()
    31  
    32  			mockActor := p2pmock.NewMockActorService(ctrl)
    33  			got := newTxNoticeTracer(logger, mockActor)
    34  
    35  			if got.retryC == nil {
    36  				t.Errorf("member not inited retryC")
    37  			}
    38  			if got.reportC == nil {
    39  				t.Errorf("member not inited reportC")
    40  			}
    41  		})
    42  	}
    43  }
    44  
    45  func Test_txNoticeTracer_traceTxNoticeRegister(t *testing.T) {
    46  	logger := log.NewLogger("p2p.test")
    47  	dummyHashes := make([]types.TxID, 0)
    48  	dummyHashes = append(dummyHashes, sampleTxHashes...)
    49  
    50  	type args struct {
    51  		peerCnt int
    52  		ids     []types.TxID
    53  	}
    54  	tests := []struct {
    55  		name string
    56  
    57  		report args
    58  
    59  		wantRetryIDs int
    60  	}{
    61  		{"TSingle", args{5, dummyHashes}, 0},
    62  		{"TNoPeer", args{0, dummyHashes}, len(dummyHashes)},
    63  		// TODO: Add test cases.
    64  	}
    65  	for _, tt := range tests {
    66  		t.Run(tt.name, func(t *testing.T) {
    67  			ctrl := gomock.NewController(t)
    68  			defer ctrl.Finish()
    69  
    70  			mockActor := p2pmock.NewMockActorService(ctrl)
    71  
    72  			tnt := newTxNoticeTracer(logger, mockActor)
    73  
    74  			tnt.RegisterTxNotice(tt.report.ids, tt.report.peerCnt, nil)
    75  			select {
    76  			case r := <-tnt.reportC:
    77  				if r.tType != create {
    78  					t.Errorf("RegisterTxNotice() rType %v, want %v", r.tType, create)
    79  				} else {
    80  					tnt.newTrace(r)
    81  				}
    82  			default:
    83  				t.Errorf("RegisterTxNotice()  unexpected behaviour ")
    84  			}
    85  			if len(tnt.retryIDs) != tt.wantRetryIDs {
    86  				t.Errorf("retryIDs = %v , want %v ", len(tnt.retryIDs), tt.wantRetryIDs)
    87  			}
    88  
    89  		})
    90  	}
    91  }
    92  
    93  func Test_txNoticeTracer_traceTxNoticeRegisterResult(t *testing.T) {
    94  	logger := log.NewLogger("p2p.test")
    95  	dummyHashes := make([]types.TxID, 0)
    96  	dummyHashes = append(dummyHashes, sampleTxHashes...)
    97  
    98  	AllSucc := txNoticeSendReport{tType: p2pcommon.Send, expect: 1, hashes: dummyHashes, peerIDs:[]types.PeerID{dummyPeerID}}
    99  	AllFail := txNoticeSendReport{tType: p2pcommon.Fail, expect: 1, hashes: dummyHashes}
   100  	PartSucc := txNoticeSendReport{tType: p2pcommon.Send, expect: 1, hashes: dummyHashes[1:4], peerIDs:[]types.PeerID{dummyPeerID}}
   101  	PartFail := txNoticeSendReport{tType: p2pcommon.Fail, expect: 1, hashes: dummyHashes[1:4]}
   102  	tests := []struct {
   103  		name string
   104  
   105  		args []txNoticeSendReport
   106  
   107  		wantStatCnt  int
   108  		wantRetryIDs int
   109  	}{
   110  		{"TSucc", ad(AllSucc, AllSucc, AllSucc), 0, 0},
   111  		{"TSucc2", ad(AllSucc, AllSucc, AllFail), 0, 0},
   112  		{"TSucc3", ad(AllFail, AllSucc, AllSucc), 0, 0},
   113  		{"TFail1", ad(AllFail, AllFail, AllFail), 0, 6},
   114  
   115  		{"TPartSucc", ad(PartSucc, PartSucc, PartSucc), 3, 0},
   116  		{"TPartFail1", ad(PartFail, PartFail, PartFail), 3, 3},
   117  	}
   118  	for _, tt := range tests {
   119  		t.Run(tt.name, func(t *testing.T) {
   120  			ctrl := gomock.NewController(t)
   121  			defer ctrl.Finish()
   122  
   123  			mockActor := p2pmock.NewMockActorService(ctrl)
   124  
   125  			tnt := newTxNoticeTracer(logger, mockActor)
   126  			// add initial items
   127  			tnt.newTrace(txNoticeSendReport{create, dummyHashes, 3, peerIDHolder})
   128  
   129  			for _, r := range tt.args {
   130  				tnt.handleReport(r)
   131  			}
   132  
   133  			if tnt.txSendStats.Len() != tt.wantStatCnt {
   134  				t.Errorf("stats = %v , want %v ", tnt.txSendStats.Len(), tt.wantStatCnt)
   135  			}
   136  
   137  			if len(tnt.retryIDs) != tt.wantRetryIDs {
   138  				t.Errorf("retryIDs = %v , want %v ", len(tnt.retryIDs), tt.wantRetryIDs)
   139  			}
   140  
   141  		})
   142  	}
   143  }
   144  
   145  func ad(rs ...txNoticeSendReport) []txNoticeSendReport {
   146  	return rs
   147  }
   148  
   149  func Test_txNoticeTracer_retryNotice(t *testing.T) {
   150  	logger := log.NewLogger("p2p.test")
   151  
   152  	tests := []struct {
   153  		name string
   154  
   155  		inStock    []types.TxID
   156  		wantHashes int
   157  	}{
   158  		{"TNothing", nil, 0},
   159  		{"TMulti", sampleTxHashes, len(sampleTxHashes)},
   160  		{"TSameIDs", append(sampleTxHashes, sampleTxHashes[0:3]...), len(sampleTxHashes)},
   161  	}
   162  	for _, tt := range tests {
   163  		t.Run(tt.name, func(t *testing.T) {
   164  			ctrl := gomock.NewController(t)
   165  			defer ctrl.Finish()
   166  
   167  			mockActor := p2pmock.NewMockActorService(ctrl)
   168  
   169  			tnt := newTxNoticeTracer(logger, mockActor)
   170  			tnt.retryIDs = append(tnt.retryIDs, tt.inStock...)
   171  			if tt.wantHashes > 0 {
   172  				mockActor.EXPECT().TellRequest(message.P2PSvc, gomock.Any()).Do(func(a string, b interface{}) {
   173  					bb := b.(notifyNewTXs)
   174  					if len(bb.ids) != tt.wantHashes {
   175  						t.Errorf("send hash count %v, want %v", len(bb.ids), tt.wantHashes)
   176  					}
   177  				})
   178  			}
   179  
   180  			tnt.retryNotice()
   181  		})
   182  	}
   183  }
   184  
   185  func Test_txNoticeTracer_cleanupStales(t *testing.T) {
   186  	logger := log.NewLogger("p2p.test")
   187  	dummyHashes := make([]types.TxID, 0)
   188  	dummyHashes = append(dummyHashes, sampleTxHashes...)
   189  
   190  	n := time.Now()
   191  	o := n.Add(time.Minute * -12)
   192  
   193  	tests := []struct {
   194  		name           string
   195  		aTimes         []time.Time
   196  		sents          []int
   197  		wantRetryIDCnt int
   198  	}{
   199  		{"TAllNew", compT(n, n, n, n, n, n), compI(0, 1, 2, 3, 4, 0), 0},
   200  		{"TOldButSent", compT(o, o, o, n, n, n), compI(3, 5, 3, 0, 4, 0), 0},
   201  		{"TOldMixed", compT(o, o, o, n, n, n), compI(3, 1, 2, 0, 4, 0), 0},
   202  		{"TOldNotEnough", compT(o, o, o, o, n, n), compI(3, 0, 0, 4, 4, 0), 2},
   203  		{"TOldUnsent", compT(o, o, o, o, n, n), compI(0, 0, 0, 0, 4, 0), 4},
   204  	}
   205  	for _, tt := range tests {
   206  		t.Run(tt.name, func(t *testing.T) {
   207  			ctrl := gomock.NewController(t)
   208  			defer ctrl.Finish()
   209  
   210  			mockActor := p2pmock.NewMockActorService(ctrl)
   211  			tnt := newTxNoticeTracer(logger, mockActor)
   212  			for i, h := range dummyHashes {
   213  				st := &txNoticeSendStat{hash: h, created: o, accessed: tt.aTimes[i], sentCnt: tt.sents[i]}
   214  				tnt.txSendStats.Add(h, st)
   215  			}
   216  
   217  			tnt.cleanupStales()
   218  			if len(tnt.retryIDs) != tt.wantRetryIDCnt {
   219  				t.Errorf("cleanupStales() retry cnt %v ,want %v", len(tnt.retryIDs), tt.wantRetryIDCnt)
   220  			}
   221  		})
   222  	}
   223  }
   224  
   225  func compT(ts ...time.Time) []time.Time {
   226  	return ts
   227  }
   228  func compI(ts ...int) []int {
   229  	return ts
   230  }