github.com/shyftnetwork/go-empyrean@v1.8.3-0.20191127201940-fbfca9338f04/swarm/network/simulation/node_test.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package simulation 18 19 import ( 20 "context" 21 "fmt" 22 "sync" 23 "testing" 24 "time" 25 26 "github.com/ShyftNetwork/go-empyrean/log" 27 "github.com/ShyftNetwork/go-empyrean/node" 28 "github.com/ShyftNetwork/go-empyrean/p2p/enode" 29 "github.com/ShyftNetwork/go-empyrean/p2p/simulations" 30 "github.com/ShyftNetwork/go-empyrean/p2p/simulations/adapters" 31 "github.com/ShyftNetwork/go-empyrean/swarm/network" 32 ) 33 34 func TestUpDownNodeIDs(t *testing.T) { 35 sim := New(noopServiceFuncMap) 36 defer sim.Close() 37 38 ids, err := sim.AddNodes(10) 39 if err != nil { 40 t.Fatal(err) 41 } 42 43 gotIDs := sim.NodeIDs() 44 45 if !equalNodeIDs(ids, gotIDs) { 46 t.Error("returned nodes are not equal to added ones") 47 } 48 49 stoppedIDs, err := sim.StopRandomNodes(3) 50 if err != nil { 51 t.Fatal(err) 52 } 53 54 gotIDs = sim.UpNodeIDs() 55 56 for _, id := range gotIDs { 57 if !sim.Net.GetNode(id).Up { 58 t.Errorf("node %s should not be down", id) 59 } 60 } 61 62 if !equalNodeIDs(ids, append(gotIDs, stoppedIDs...)) { 63 t.Error("returned nodes are not equal to added ones") 64 } 65 66 gotIDs = sim.DownNodeIDs() 67 68 for _, id := range gotIDs { 69 if sim.Net.GetNode(id).Up { 70 t.Errorf("node %s should not be up", id) 71 } 72 } 73 74 if !equalNodeIDs(stoppedIDs, gotIDs) { 75 t.Error("returned nodes are not equal to the stopped ones") 76 } 77 } 78 79 func equalNodeIDs(one, other []enode.ID) bool { 80 if len(one) != len(other) { 81 return false 82 } 83 var count int 84 for _, a := range one { 85 var found bool 86 for _, b := range other { 87 if a == b { 88 found = true 89 break 90 } 91 } 92 if found { 93 count++ 94 } else { 95 return false 96 } 97 } 98 return count == len(one) 99 } 100 101 func TestAddNode(t *testing.T) { 102 sim := New(noopServiceFuncMap) 103 defer sim.Close() 104 105 id, err := sim.AddNode() 106 if err != nil { 107 t.Fatal(err) 108 } 109 110 n := sim.Net.GetNode(id) 111 if n == nil { 112 t.Fatal("node not found") 113 } 114 115 if !n.Up { 116 t.Error("node not started") 117 } 118 } 119 120 func TestAddNodeWithMsgEvents(t *testing.T) { 121 sim := New(noopServiceFuncMap) 122 defer sim.Close() 123 124 id, err := sim.AddNode(AddNodeWithMsgEvents(true)) 125 if err != nil { 126 t.Fatal(err) 127 } 128 129 if !sim.Net.GetNode(id).Config.EnableMsgEvents { 130 t.Error("EnableMsgEvents is false") 131 } 132 133 id, err = sim.AddNode(AddNodeWithMsgEvents(false)) 134 if err != nil { 135 t.Fatal(err) 136 } 137 138 if sim.Net.GetNode(id).Config.EnableMsgEvents { 139 t.Error("EnableMsgEvents is true") 140 } 141 } 142 143 func TestAddNodeWithService(t *testing.T) { 144 sim := New(map[string]ServiceFunc{ 145 "noop1": noopServiceFunc, 146 "noop2": noopServiceFunc, 147 }) 148 defer sim.Close() 149 150 id, err := sim.AddNode(AddNodeWithService("noop1")) 151 if err != nil { 152 t.Fatal(err) 153 } 154 155 n := sim.Net.GetNode(id).Node.(*adapters.SimNode) 156 if n.Service("noop1") == nil { 157 t.Error("service noop1 not found on node") 158 } 159 if n.Service("noop2") != nil { 160 t.Error("service noop2 should not be found on node") 161 } 162 } 163 164 func TestAddNodeMultipleServices(t *testing.T) { 165 sim := New(map[string]ServiceFunc{ 166 "noop1": noopServiceFunc, 167 "noop2": noopService2Func, 168 }) 169 defer sim.Close() 170 171 id, err := sim.AddNode() 172 if err != nil { 173 t.Fatal(err) 174 } 175 176 n := sim.Net.GetNode(id).Node.(*adapters.SimNode) 177 if n.Service("noop1") == nil { 178 t.Error("service noop1 not found on node") 179 } 180 if n.Service("noop2") == nil { 181 t.Error("service noop2 not found on node") 182 } 183 } 184 185 func TestAddNodeDuplicateServiceError(t *testing.T) { 186 sim := New(map[string]ServiceFunc{ 187 "noop1": noopServiceFunc, 188 "noop2": noopServiceFunc, 189 }) 190 defer sim.Close() 191 192 wantErr := "duplicate service: *simulation.noopService" 193 _, err := sim.AddNode() 194 if err.Error() != wantErr { 195 t.Errorf("got error %q, want %q", err, wantErr) 196 } 197 } 198 199 func TestAddNodes(t *testing.T) { 200 sim := New(noopServiceFuncMap) 201 defer sim.Close() 202 203 nodesCount := 12 204 205 ids, err := sim.AddNodes(nodesCount) 206 if err != nil { 207 t.Fatal(err) 208 } 209 210 count := len(ids) 211 if count != nodesCount { 212 t.Errorf("expected %v nodes, got %v", nodesCount, count) 213 } 214 215 count = len(sim.Net.GetNodes()) 216 if count != nodesCount { 217 t.Errorf("expected %v nodes, got %v", nodesCount, count) 218 } 219 } 220 221 func TestAddNodesAndConnectFull(t *testing.T) { 222 sim := New(noopServiceFuncMap) 223 defer sim.Close() 224 225 n := 12 226 227 ids, err := sim.AddNodesAndConnectFull(n) 228 if err != nil { 229 t.Fatal(err) 230 } 231 232 simulations.VerifyFull(t, sim.Net, ids) 233 } 234 235 func TestAddNodesAndConnectChain(t *testing.T) { 236 sim := New(noopServiceFuncMap) 237 defer sim.Close() 238 239 _, err := sim.AddNodesAndConnectChain(12) 240 if err != nil { 241 t.Fatal(err) 242 } 243 244 // add another set of nodes to test 245 // if two chains are connected 246 _, err = sim.AddNodesAndConnectChain(7) 247 if err != nil { 248 t.Fatal(err) 249 } 250 251 simulations.VerifyChain(t, sim.Net, sim.UpNodeIDs()) 252 } 253 254 func TestAddNodesAndConnectRing(t *testing.T) { 255 sim := New(noopServiceFuncMap) 256 defer sim.Close() 257 258 ids, err := sim.AddNodesAndConnectRing(12) 259 if err != nil { 260 t.Fatal(err) 261 } 262 263 simulations.VerifyRing(t, sim.Net, ids) 264 } 265 266 func TestAddNodesAndConnectStar(t *testing.T) { 267 sim := New(noopServiceFuncMap) 268 defer sim.Close() 269 270 ids, err := sim.AddNodesAndConnectStar(12) 271 if err != nil { 272 t.Fatal(err) 273 } 274 275 simulations.VerifyStar(t, sim.Net, ids, 0) 276 } 277 278 //To test that uploading a snapshot works 279 func TestUploadSnapshot(t *testing.T) { 280 log.Debug("Creating simulation") 281 s := New(map[string]ServiceFunc{ 282 "bzz": func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) { 283 addr := network.NewAddr(ctx.Config.Node()) 284 hp := network.NewHiveParams() 285 hp.Discovery = false 286 config := &network.BzzConfig{ 287 OverlayAddr: addr.Over(), 288 UnderlayAddr: addr.Under(), 289 HiveParams: hp, 290 } 291 kad := network.NewKademlia(addr.Over(), network.NewKadParams()) 292 return network.NewBzz(config, kad, nil, nil, nil), nil, nil 293 }, 294 }) 295 defer s.Close() 296 297 nodeCount := 16 298 log.Debug("Uploading snapshot") 299 err := s.UploadSnapshot(fmt.Sprintf("../stream/testing/snapshot_%d.json", nodeCount)) 300 if err != nil { 301 t.Fatalf("Error uploading snapshot to simulation network: %v", err) 302 } 303 304 ctx := context.Background() 305 log.Debug("Starting simulation...") 306 s.Run(ctx, func(ctx context.Context, sim *Simulation) error { 307 log.Debug("Checking") 308 nodes := sim.UpNodeIDs() 309 if len(nodes) != nodeCount { 310 t.Fatal("Simulation network node number doesn't match snapshot node number") 311 } 312 return nil 313 }) 314 log.Debug("Done.") 315 } 316 317 func TestStartStopNode(t *testing.T) { 318 sim := New(noopServiceFuncMap) 319 defer sim.Close() 320 321 id, err := sim.AddNode() 322 if err != nil { 323 t.Fatal(err) 324 } 325 326 n := sim.Net.GetNode(id) 327 if n == nil { 328 t.Fatal("node not found") 329 } 330 if !n.Up { 331 t.Error("node not started") 332 } 333 334 err = sim.StopNode(id) 335 if err != nil { 336 t.Fatal(err) 337 } 338 if n.Up { 339 t.Error("node not stopped") 340 } 341 342 // Sleep here to ensure that Network.watchPeerEvents defer function 343 // has set the `node.Up = false` before we start the node again. 344 // p2p/simulations/network.go:215 345 // 346 // The same node is stopped and started again, and upon start 347 // watchPeerEvents is started in a goroutine. If the node is stopped 348 // and then very quickly started, that goroutine may be scheduled later 349 // then start and force `node.Up = false` in its defer function. 350 // This will make this test unreliable. 351 time.Sleep(time.Second) 352 353 err = sim.StartNode(id) 354 if err != nil { 355 t.Fatal(err) 356 } 357 if !n.Up { 358 t.Error("node not started") 359 } 360 } 361 362 func TestStartStopRandomNode(t *testing.T) { 363 sim := New(noopServiceFuncMap) 364 defer sim.Close() 365 366 _, err := sim.AddNodes(3) 367 if err != nil { 368 t.Fatal(err) 369 } 370 371 id, err := sim.StopRandomNode() 372 if err != nil { 373 t.Fatal(err) 374 } 375 376 n := sim.Net.GetNode(id) 377 if n == nil { 378 t.Fatal("node not found") 379 } 380 if n.Up { 381 t.Error("node not stopped") 382 } 383 384 id2, err := sim.StopRandomNode() 385 if err != nil { 386 t.Fatal(err) 387 } 388 389 // Sleep here to ensure that Network.watchPeerEvents defer function 390 // has set the `node.Up = false` before we start the node again. 391 // p2p/simulations/network.go:215 392 // 393 // The same node is stopped and started again, and upon start 394 // watchPeerEvents is started in a goroutine. If the node is stopped 395 // and then very quickly started, that goroutine may be scheduled later 396 // then start and force `node.Up = false` in its defer function. 397 // This will make this test unreliable. 398 time.Sleep(time.Second) 399 400 idStarted, err := sim.StartRandomNode() 401 if err != nil { 402 t.Fatal(err) 403 } 404 405 if idStarted != id && idStarted != id2 { 406 t.Error("unexpected started node ID") 407 } 408 } 409 410 func TestStartStopRandomNodes(t *testing.T) { 411 sim := New(noopServiceFuncMap) 412 defer sim.Close() 413 414 _, err := sim.AddNodes(10) 415 if err != nil { 416 t.Fatal(err) 417 } 418 419 ids, err := sim.StopRandomNodes(3) 420 if err != nil { 421 t.Fatal(err) 422 } 423 424 for _, id := range ids { 425 n := sim.Net.GetNode(id) 426 if n == nil { 427 t.Fatal("node not found") 428 } 429 if n.Up { 430 t.Error("node not stopped") 431 } 432 } 433 434 // Sleep here to ensure that Network.watchPeerEvents defer function 435 // has set the `node.Up = false` before we start the node again. 436 // p2p/simulations/network.go:215 437 // 438 // The same node is stopped and started again, and upon start 439 // watchPeerEvents is started in a goroutine. If the node is stopped 440 // and then very quickly started, that goroutine may be scheduled later 441 // then start and force `node.Up = false` in its defer function. 442 // This will make this test unreliable. 443 time.Sleep(time.Second) 444 445 ids, err = sim.StartRandomNodes(2) 446 if err != nil { 447 t.Fatal(err) 448 } 449 450 for _, id := range ids { 451 n := sim.Net.GetNode(id) 452 if n == nil { 453 t.Fatal("node not found") 454 } 455 if !n.Up { 456 t.Error("node not started") 457 } 458 } 459 }