github.com/jincm/wesharechain@v0.0.0-20210122032815-1537409ce26a/chain/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  			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  	waitForPeerEventPropagation()
   343  
   344  	err = sim.StartNode(id)
   345  	if err != nil {
   346  		t.Fatal(err)
   347  	}
   348  	if !n.Up() {
   349  		t.Error("node not started")
   350  	}
   351  }
   352  
   353  func TestStartStopRandomNode(t *testing.T) {
   354  	sim := New(noopServiceFuncMap)
   355  	defer sim.Close()
   356  
   357  	_, err := sim.AddNodes(3)
   358  	if err != nil {
   359  		t.Fatal(err)
   360  	}
   361  
   362  	id, err := sim.StopRandomNode()
   363  	if err != nil {
   364  		t.Fatal(err)
   365  	}
   366  
   367  	n := sim.Net.GetNode(id)
   368  	if n == nil {
   369  		t.Fatal("node not found")
   370  	}
   371  	if n.Up() {
   372  		t.Error("node not stopped")
   373  	}
   374  
   375  	id2, err := sim.StopRandomNode()
   376  	if err != nil {
   377  		t.Fatal(err)
   378  	}
   379  
   380  	waitForPeerEventPropagation()
   381  
   382  	idStarted, err := sim.StartRandomNode()
   383  	if err != nil {
   384  		t.Fatal(err)
   385  	}
   386  
   387  	if idStarted != id && idStarted != id2 {
   388  		t.Error("unexpected started node ID")
   389  	}
   390  }
   391  
   392  func TestStartStopRandomNodes(t *testing.T) {
   393  	sim := New(noopServiceFuncMap)
   394  	defer sim.Close()
   395  
   396  	_, err := sim.AddNodes(10)
   397  	if err != nil {
   398  		t.Fatal(err)
   399  	}
   400  
   401  	ids, err := sim.StopRandomNodes(3)
   402  	if err != nil {
   403  		t.Fatal(err)
   404  	}
   405  
   406  	for _, id := range ids {
   407  		n := sim.Net.GetNode(id)
   408  		if n == nil {
   409  			t.Fatal("node not found")
   410  		}
   411  		if n.Up() {
   412  			t.Error("node not stopped")
   413  		}
   414  	}
   415  
   416  	waitForPeerEventPropagation()
   417  
   418  	ids, err = sim.StartRandomNodes(2)
   419  	if err != nil {
   420  		t.Fatal(err)
   421  	}
   422  
   423  	for _, id := range ids {
   424  		n := sim.Net.GetNode(id)
   425  		if n == nil {
   426  			t.Fatal("node not found")
   427  		}
   428  		if !n.Up() {
   429  			t.Error("node not started")
   430  		}
   431  	}
   432  }
   433  
   434  func waitForPeerEventPropagation() {
   435  	// Sleep here to ensure that Network.watchPeerEvents defer function
   436  	// has set the `node.Up() = false` before we start the node again.
   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(1 * time.Second)
   444  }