github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/p2p/netutil/iptrack_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:41</date> 10 //</624450105348460544> 11 12 13 package netutil 14 15 import ( 16 "fmt" 17 mrand "math/rand" 18 "testing" 19 "time" 20 21 "github.com/ethereum/go-ethereum/common/mclock" 22 ) 23 24 const ( 25 opStatement = iota 26 opContact 27 opPredict 28 opCheckFullCone 29 ) 30 31 type iptrackTestEvent struct { 32 op int 33 time int //绝对值(毫秒) 34 ip, from string 35 } 36 37 func TestIPTracker(t *testing.T) { 38 tests := map[string][]iptrackTestEvent{ 39 "minStatements": { 40 {opPredict, 0, "", ""}, 41 {opStatement, 0, "127.0.0.1", "127.0.0.2"}, 42 {opPredict, 1000, "", ""}, 43 {opStatement, 1000, "127.0.0.1", "127.0.0.3"}, 44 {opPredict, 1000, "", ""}, 45 {opStatement, 1000, "127.0.0.1", "127.0.0.4"}, 46 {opPredict, 1000, "127.0.0.1", ""}, 47 }, 48 "window": { 49 {opStatement, 0, "127.0.0.1", "127.0.0.2"}, 50 {opStatement, 2000, "127.0.0.1", "127.0.0.3"}, 51 {opStatement, 3000, "127.0.0.1", "127.0.0.4"}, 52 {opPredict, 10000, "127.0.0.1", ""}, 53 {opPredict, 10001, "", ""}, //第一条语句已过期 54 {opStatement, 10100, "127.0.0.1", "127.0.0.2"}, 55 {opPredict, 10200, "127.0.0.1", ""}, 56 }, 57 "fullcone": { 58 {opContact, 0, "", "127.0.0.2"}, 59 {opStatement, 10, "127.0.0.1", "127.0.0.2"}, 60 {opContact, 2000, "", "127.0.0.3"}, 61 {opStatement, 2010, "127.0.0.1", "127.0.0.3"}, 62 {opContact, 3000, "", "127.0.0.4"}, 63 {opStatement, 3010, "127.0.0.1", "127.0.0.4"}, 64 {opCheckFullCone, 3500, "false", ""}, 65 }, 66 "fullcone_2": { 67 {opContact, 0, "", "127.0.0.2"}, 68 {opStatement, 10, "127.0.0.1", "127.0.0.2"}, 69 {opContact, 2000, "", "127.0.0.3"}, 70 {opStatement, 2010, "127.0.0.1", "127.0.0.3"}, 71 {opStatement, 3000, "127.0.0.1", "127.0.0.4"}, 72 {opContact, 3010, "", "127.0.0.4"}, 73 {opCheckFullCone, 3500, "true", ""}, 74 }, 75 } 76 for name, test := range tests { 77 t.Run(name, func(t *testing.T) { runIPTrackerTest(t, test) }) 78 } 79 } 80 81 func runIPTrackerTest(t *testing.T, evs []iptrackTestEvent) { 82 var ( 83 clock mclock.Simulated 84 it = NewIPTracker(10*time.Second, 10*time.Second, 3) 85 ) 86 it.clock = &clock 87 for i, ev := range evs { 88 evtime := time.Duration(ev.time) * time.Millisecond 89 clock.Run(evtime - time.Duration(clock.Now())) 90 switch ev.op { 91 case opStatement: 92 it.AddStatement(ev.from, ev.ip) 93 case opContact: 94 it.AddContact(ev.from) 95 case opPredict: 96 if pred := it.PredictEndpoint(); pred != ev.ip { 97 t.Errorf("op %d: wrong prediction %q, want %q", i, pred, ev.ip) 98 } 99 case opCheckFullCone: 100 pred := fmt.Sprintf("%t", it.PredictFullConeNAT()) 101 if pred != ev.ip { 102 t.Errorf("op %d: wrong prediction %s, want %s", i, pred, ev.ip) 103 } 104 } 105 } 106 } 107 108 //这将检查旧的语句和联系人是否已GCED,即使没有调用Predict*。 109 func TestIPTrackerForceGC(t *testing.T) { 110 var ( 111 clock mclock.Simulated 112 window = 10 * time.Second 113 rate = 50 * time.Millisecond 114 max = int(window/rate) + 1 115 it = NewIPTracker(window, window, 3) 116 ) 117 it.clock = &clock 118 119 for i := 0; i < 5*max; i++ { 120 e1 := make([]byte, 4) 121 e2 := make([]byte, 4) 122 mrand.Read(e1) 123 mrand.Read(e2) 124 it.AddStatement(string(e1), string(e2)) 125 it.AddContact(string(e1)) 126 clock.Run(rate) 127 } 128 if len(it.contact) > 2*max { 129 t.Errorf("contacts not GCed, have %d", len(it.contact)) 130 } 131 if len(it.statements) > 2*max { 132 t.Errorf("statements not GCed, have %d", len(it.statements)) 133 } 134 } 135