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