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 }