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