github.com/susy-go/susy-graviton@v0.0.0-20190614130430-36cddae42305/swarm/network/hive_test.go (about)

     1  // Copyleft 2016 The susy-graviton Authors
     2  // This file is part of the susy-graviton library.
     3  //
     4  // The susy-graviton 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 susy-graviton library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MSRCHANTABILITY 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 susy-graviton library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package network
    18  
    19  import (
    20  	"io/ioutil"
    21  	"os"
    22  	"testing"
    23  	"time"
    24  
    25  	p2ptest "github.com/susy-go/susy-graviton/p2p/testing"
    26  	"github.com/susy-go/susy-graviton/swarm/state"
    27  )
    28  
    29  func newHiveTester(t *testing.T, params *HiveParams, n int, store state.Store) (*bzzTester, *Hive) {
    30  	// setup
    31  	addr := RandomAddr() // tested peers peer address
    32  	to := NewKademlia(addr.OAddr, NewKadParams())
    33  	pp := NewHive(params, to, store) // hive
    34  
    35  	return newBzzBaseTester(t, n, addr, DiscoverySpec, pp.Run), pp
    36  }
    37  
    38  // TestRegisterAndConnect verifies that the protocol runs successfully
    39  // and that the peer connection exists afterwards
    40  func TestRegisterAndConnect(t *testing.T) {
    41  	params := NewHiveParams()
    42  	s, pp := newHiveTester(t, params, 1, nil)
    43  
    44  	node := s.Nodes[0]
    45  	raddr := NewAddr(node)
    46  	pp.Register(raddr)
    47  
    48  	// start the hive
    49  	err := pp.Start(s.Server)
    50  	if err != nil {
    51  		t.Fatal(err)
    52  	}
    53  	defer pp.Stop()
    54  
    55  	// both hive connect and disconect check have time delays
    56  	// therefore we need to verify that peer is connected
    57  	// so that we are sure that the disconnect timeout doesn't complete
    58  	// before the hive connect method is run at least once
    59  	timeout := time.After(time.Second)
    60  	for {
    61  		select {
    62  		case <-timeout:
    63  			t.Fatalf("expected connection")
    64  		default:
    65  		}
    66  		i := 0
    67  		pp.Kademlia.EachConn(nil, 256, func(addr *Peer, po int) bool {
    68  			i++
    69  			return true
    70  		})
    71  		if i > 0 {
    72  			break
    73  		}
    74  		time.Sleep(time.Millisecond)
    75  	}
    76  
    77  	// check that the connection actually exists
    78  	// the timeout error means no disconnection events
    79  	// were received within the a certain timeout
    80  	err = s.TestDisconnected(&p2ptest.Disconnect{
    81  		Peer:  s.Nodes[0].ID(),
    82  		Error: nil,
    83  	})
    84  
    85  	if err == nil || err.Error() != "timed out waiting for peers to disconnect" {
    86  		t.Fatalf("expected no disconnection event")
    87  	}
    88  }
    89  
    90  // TestHiveStatePersistance creates a protocol simulation with n peers for a node
    91  // After protocols complete, the node is shut down and the state is stored.
    92  // Another simulation is created, where 0 nodes are created, but where the stored state is passed
    93  // The test succeeds if all the peers from the stored state are known after the protocols of the
    94  // second simulation have completed
    95  //
    96  // Actual connectivity is not in scope for this test, as the peers loaded from state are not known to
    97  // the simulation; the test only verifies that the peers are known to the node
    98  func TestHiveStatePersistance(t *testing.T) {
    99  
   100  	dir, err := ioutil.TempDir("", "hive_test_store")
   101  	if err != nil {
   102  		panic(err)
   103  	}
   104  	defer os.RemoveAll(dir)
   105  
   106  	store, err := state.NewDBStore(dir) //start the hive with an empty dbstore
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  
   111  	params := NewHiveParams()
   112  	s, pp := newHiveTester(t, params, 5, store)
   113  
   114  	peers := make(map[string]bool)
   115  	for _, node := range s.Nodes {
   116  		raddr := NewAddr(node)
   117  		pp.Register(raddr)
   118  		peers[raddr.String()] = true
   119  	}
   120  
   121  	// start and stop the hive
   122  	// the known peers should be saved upon stopping
   123  	err = pp.Start(s.Server)
   124  	if err != nil {
   125  		t.Fatal(err)
   126  	}
   127  	pp.Stop()
   128  	store.Close()
   129  
   130  	// start the hive with an empty dbstore
   131  	persistedStore, err := state.NewDBStore(dir)
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  
   136  	s1, pp := newHiveTester(t, params, 0, persistedStore)
   137  
   138  	// start the hive and check that we know of all expected peers
   139  	pp.Start(s1.Server)
   140  	i := 0
   141  	pp.Kademlia.EachAddr(nil, 256, func(addr *BzzAddr, po int) bool {
   142  		delete(peers, addr.String())
   143  		i++
   144  		return true
   145  	})
   146  	// TODO remove this line when verified that test passes
   147  	time.Sleep(time.Second)
   148  	if i != 5 {
   149  		t.Fatalf("invalid number of entries: got %v, want %v", i, 5)
   150  	}
   151  	if len(peers) != 0 {
   152  		t.Fatalf("%d peers left over: %v", len(peers), peers)
   153  	}
   154  
   155  }