github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/network/simulation/simulation_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:43</date> 10 //</624450114856947712> 11 12 13 package simulation 14 15 import ( 16 "context" 17 "errors" 18 "flag" 19 "sync" 20 "testing" 21 "time" 22 23 "github.com/ethereum/go-ethereum/log" 24 "github.com/ethereum/go-ethereum/node" 25 "github.com/ethereum/go-ethereum/p2p/simulations" 26 "github.com/ethereum/go-ethereum/p2p/simulations/adapters" 27 "github.com/mattn/go-colorable" 28 ) 29 30 var ( 31 loglevel = flag.Int("loglevel", 2, "verbosity of logs") 32 ) 33 34 func init() { 35 flag.Parse() 36 log.PrintOrigins(true) 37 log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) 38 } 39 40 //如果run方法调用runfunc并正确处理上下文,则测试run。 41 func TestRun(t *testing.T) { 42 sim := New(noopServiceFuncMap) 43 defer sim.Close() 44 45 t.Run("call", func(t *testing.T) { 46 expect := "something" 47 var got string 48 r := sim.Run(context.Background(), func(ctx context.Context, sim *Simulation) error { 49 got = expect 50 return nil 51 }) 52 53 if r.Error != nil { 54 t.Errorf("unexpected error: %v", r.Error) 55 } 56 if got != expect { 57 t.Errorf("expected %q, got %q", expect, got) 58 } 59 }) 60 61 t.Run("cancellation", func(t *testing.T) { 62 ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) 63 defer cancel() 64 65 r := sim.Run(ctx, func(ctx context.Context, sim *Simulation) error { 66 time.Sleep(time.Second) 67 return nil 68 }) 69 70 if r.Error != context.DeadlineExceeded { 71 t.Errorf("unexpected error: %v", r.Error) 72 } 73 }) 74 75 t.Run("context value and duration", func(t *testing.T) { 76 ctx := context.WithValue(context.Background(), "hey", "there") 77 sleep := 50 * time.Millisecond 78 79 r := sim.Run(ctx, func(ctx context.Context, sim *Simulation) error { 80 if ctx.Value("hey") != "there" { 81 return errors.New("expected context value not passed") 82 } 83 time.Sleep(sleep) 84 return nil 85 }) 86 87 if r.Error != nil { 88 t.Errorf("unexpected error: %v", r.Error) 89 } 90 if r.Duration < sleep { 91 t.Errorf("reported run duration less then expected: %s", r.Duration) 92 } 93 }) 94 } 95 96 //testclose测试是close方法,触发所有close函数,所有节点都不再是up。 97 func TestClose(t *testing.T) { 98 var mu sync.Mutex 99 var cleanupCount int 100 101 sleep := 50 * time.Millisecond 102 103 sim := New(map[string]ServiceFunc{ 104 "noop": func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) { 105 return newNoopService(), func() { 106 time.Sleep(sleep) 107 mu.Lock() 108 defer mu.Unlock() 109 cleanupCount++ 110 }, nil 111 }, 112 }) 113 114 nodeCount := 30 115 116 _, err := sim.AddNodes(nodeCount) 117 if err != nil { 118 t.Fatal(err) 119 } 120 121 var upNodeCount int 122 for _, n := range sim.Net.GetNodes() { 123 if n.Up { 124 upNodeCount++ 125 } 126 } 127 if upNodeCount != nodeCount { 128 t.Errorf("all nodes should be up, insted only %v are up", upNodeCount) 129 } 130 131 sim.Close() 132 133 if cleanupCount != nodeCount { 134 t.Errorf("number of cleanups expected %v, got %v", nodeCount, cleanupCount) 135 } 136 137 upNodeCount = 0 138 for _, n := range sim.Net.GetNodes() { 139 if n.Up { 140 upNodeCount++ 141 } 142 } 143 if upNodeCount != 0 { 144 t.Errorf("all nodes should be down, insted %v are up", upNodeCount) 145 } 146 } 147 148 //testdone检查close方法是否触发了done通道的关闭。 149 func TestDone(t *testing.T) { 150 sim := New(noopServiceFuncMap) 151 sleep := 50 * time.Millisecond 152 timeout := 2 * time.Second 153 154 start := time.Now() 155 go func() { 156 time.Sleep(sleep) 157 sim.Close() 158 }() 159 160 select { 161 case <-time.After(timeout): 162 t.Error("done channel closing timed out") 163 case <-sim.Done(): 164 if d := time.Since(start); d < sleep { 165 t.Errorf("done channel closed sooner then expected: %s", d) 166 } 167 } 168 } 169 170 //用于不执行任何操作的常规服务的帮助者映射 171 var noopServiceFuncMap = map[string]ServiceFunc{ 172 "noop": noopServiceFunc, 173 } 174 175 //最基本的noop服务的助手函数 176 func noopServiceFunc(_ *adapters.ServiceContext, _ *sync.Map) (node.Service, func(), error) { 177 return newNoopService(), nil, nil 178 } 179 180 func newNoopService() node.Service { 181 return &noopService{} 182 } 183 184 //最基本的noop服务的助手函数 185 //不同类型的,然后NoopService进行测试 186 //一个节点上有多个服务。 187 func noopService2Func(_ *adapters.ServiceContext, _ *sync.Map) (node.Service, func(), error) { 188 return new(noopService2), nil, nil 189 } 190 191 //NoopService2是不做任何事情的服务 192 //但实现了node.service接口。 193 type noopService2 struct { 194 simulations.NoopService 195 } 196 197 type noopService struct { 198 simulations.NoopService 199 } 200