github.com/daeglee/go-ethereum@v0.0.0-20190504220456-cad3e8d18e9b/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/ethereum/go-ethereum/log"
    27  	"github.com/ethereum/go-ethereum/node"
    28  	"github.com/ethereum/go-ethereum/p2p/enode"
    29  	"github.com/ethereum/go-ethereum/p2p/simulations"
    30  	"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
    31  	"github.com/ethereum/go-ethereum/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  			b.Store(BucketKeyKademlia, kad)
   293  			return network.NewBzz(config, kad, nil, nil, nil), nil, nil
   294  		},
   295  	})
   296  	defer s.Close()
   297  
   298  	nodeCount := 16
   299  	log.Debug("Uploading snapshot")
   300  	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
   301  	defer cancel()
   302  	err := s.UploadSnapshot(ctx, fmt.Sprintf("../stream/testing/snapshot_%d.json", nodeCount))
   303  	if err != nil {
   304  		t.Fatalf("Error uploading snapshot to simulation network: %v", err)
   305  	}
   306  
   307  	log.Debug("Starting simulation...")
   308  	s.Run(ctx, func(ctx context.Context, sim *Simulation) error {
   309  		log.Debug("Checking")
   310  		nodes := sim.UpNodeIDs()
   311  		if len(nodes) != nodeCount {
   312  			t.Fatal("Simulation network node number doesn't match snapshot node number")
   313  		}
   314  		return nil
   315  	})
   316  	log.Debug("Done.")
   317  }
   318  
   319  func TestStartStopNode(t *testing.T) {
   320  	sim := New(noopServiceFuncMap)
   321  	defer sim.Close()
   322  
   323  	id, err := sim.AddNode()
   324  	if err != nil {
   325  		t.Fatal(err)
   326  	}
   327  
   328  	n := sim.Net.GetNode(id)
   329  	if n == nil {
   330  		t.Fatal("node not found")
   331  	}
   332  	if !n.Up() {
   333  		t.Error("node not started")
   334  	}
   335  
   336  	err = sim.StopNode(id)
   337  	if err != nil {
   338  		t.Fatal(err)
   339  	}
   340  	if n.Up() {
   341  		t.Error("node not stopped")
   342  	}
   343  
   344  	waitForPeerEventPropagation()
   345  
   346  	err = sim.StartNode(id)
   347  	if err != nil {
   348  		t.Fatal(err)
   349  	}
   350  	if !n.Up() {
   351  		t.Error("node not started")
   352  	}
   353  }
   354  
   355  func TestStartStopRandomNode(t *testing.T) {
   356  	sim := New(noopServiceFuncMap)
   357  	defer sim.Close()
   358  
   359  	_, err := sim.AddNodes(3)
   360  	if err != nil {
   361  		t.Fatal(err)
   362  	}
   363  
   364  	id, err := sim.StopRandomNode()
   365  	if err != nil {
   366  		t.Fatal(err)
   367  	}
   368  
   369  	n := sim.Net.GetNode(id)
   370  	if n == nil {
   371  		t.Fatal("node not found")
   372  	}
   373  	if n.Up() {
   374  		t.Error("node not stopped")
   375  	}
   376  
   377  	id2, err := sim.StopRandomNode()
   378  	if err != nil {
   379  		t.Fatal(err)
   380  	}
   381  
   382  	waitForPeerEventPropagation()
   383  
   384  	idStarted, err := sim.StartRandomNode()
   385  	if err != nil {
   386  		t.Fatal(err)
   387  	}
   388  
   389  	if idStarted != id && idStarted != id2 {
   390  		t.Error("unexpected started node ID")
   391  	}
   392  }
   393  
   394  func TestStartStopRandomNodes(t *testing.T) {
   395  	sim := New(noopServiceFuncMap)
   396  	defer sim.Close()
   397  
   398  	_, err := sim.AddNodes(10)
   399  	if err != nil {
   400  		t.Fatal(err)
   401  	}
   402  
   403  	ids, err := sim.StopRandomNodes(3)
   404  	if err != nil {
   405  		t.Fatal(err)
   406  	}
   407  
   408  	for _, id := range ids {
   409  		n := sim.Net.GetNode(id)
   410  		if n == nil {
   411  			t.Fatal("node not found")
   412  		}
   413  		if n.Up() {
   414  			t.Error("node not stopped")
   415  		}
   416  	}
   417  
   418  	waitForPeerEventPropagation()
   419  
   420  	ids, err = sim.StartRandomNodes(2)
   421  	if err != nil {
   422  		t.Fatal(err)
   423  	}
   424  
   425  	for _, id := range ids {
   426  		n := sim.Net.GetNode(id)
   427  		if n == nil {
   428  			t.Fatal("node not found")
   429  		}
   430  		if !n.Up() {
   431  			t.Error("node not started")
   432  		}
   433  	}
   434  }
   435  
   436  func waitForPeerEventPropagation() {
   437  	// Sleep here to ensure that Network.watchPeerEvents defer function
   438  	// has set the `node.Up() = false` before we start the node again.
   439  	//
   440  	// The same node is stopped and started again, and upon start
   441  	// watchPeerEvents is started in a goroutine. If the node is stopped
   442  	// and then very quickly started, that goroutine may be scheduled later
   443  	// then start and force `node.Up() = false` in its defer function.
   444  	// This will make this test unreliable.
   445  	time.Sleep(1 * time.Second)
   446  }