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  }