github.com/zignig/go-ipfs@v0.0.0-20141111235910-c9e5fdf55a52/net/swarm/swarm_test.go (about)

     1  package swarm
     2  
     3  import (
     4  	"bytes"
     5  	"sync"
     6  	"testing"
     7  	"time"
     8  
     9  	ci "github.com/jbenet/go-ipfs/crypto"
    10  	msg "github.com/jbenet/go-ipfs/net/message"
    11  	peer "github.com/jbenet/go-ipfs/peer"
    12  	u "github.com/jbenet/go-ipfs/util"
    13  
    14  	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
    15  	ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
    16  )
    17  
    18  func pong(ctx context.Context, swarm *Swarm) {
    19  	i := 0
    20  	for {
    21  		select {
    22  		case <-ctx.Done():
    23  			return
    24  		case m1 := <-swarm.Incoming:
    25  			if bytes.Equal(m1.Data(), []byte("ping")) {
    26  				m2 := msg.New(m1.Peer(), []byte("pong"))
    27  				i++
    28  				log.Debugf("%s pong %s (%d)", swarm.local, m1.Peer(), i)
    29  				swarm.Outgoing <- m2
    30  			}
    31  		}
    32  	}
    33  }
    34  
    35  func setupPeer(t *testing.T, addr string) peer.Peer {
    36  	tcp, err := ma.NewMultiaddr(addr)
    37  	if err != nil {
    38  		t.Fatal(err)
    39  	}
    40  
    41  	sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512)
    42  	if err != nil {
    43  		t.Fatal(err)
    44  	}
    45  
    46  	p, err := peer.WithKeyPair(sk, pk)
    47  	if err != nil {
    48  		t.Fatal(err)
    49  	}
    50  	p.AddAddress(tcp)
    51  	return p
    52  }
    53  
    54  func makeSwarms(ctx context.Context, t *testing.T, addrs []string) ([]*Swarm, []peer.Peer) {
    55  	swarms := []*Swarm{}
    56  
    57  	for _, addr := range addrs {
    58  		local := setupPeer(t, addr)
    59  		peerstore := peer.NewPeerstore()
    60  		swarm, err := NewSwarm(ctx, local.Addresses(), local, peerstore)
    61  		if err != nil {
    62  			t.Fatal(err)
    63  		}
    64  		swarms = append(swarms, swarm)
    65  	}
    66  
    67  	peers := make([]peer.Peer, len(swarms))
    68  	for i, s := range swarms {
    69  		peers[i] = s.local
    70  	}
    71  
    72  	return swarms, peers
    73  }
    74  
    75  func SubtestSwarm(t *testing.T, addrs []string, MsgNum int) {
    76  	// t.Skip("skipping for another test")
    77  
    78  	ctx := context.Background()
    79  	swarms, peers := makeSwarms(ctx, t, addrs)
    80  
    81  	// connect everyone
    82  	{
    83  		var wg sync.WaitGroup
    84  		connect := func(s *Swarm, dst peer.Peer) {
    85  			// copy for other peer
    86  
    87  			cp, err := s.peers.Get(dst.ID())
    88  			if err != nil {
    89  				t.Fatal(err)
    90  			}
    91  			cp.AddAddress(dst.Addresses()[0])
    92  
    93  			log.Info("SWARM TEST: %s dialing %s", s.local, dst)
    94  			if _, err := s.Dial(cp); err != nil {
    95  				t.Fatal("error swarm dialing to peer", err)
    96  			}
    97  			log.Info("SWARM TEST: %s connected to %s", s.local, dst)
    98  			wg.Done()
    99  		}
   100  
   101  		log.Info("Connecting swarms simultaneously.")
   102  		for _, s := range swarms {
   103  			for _, p := range peers {
   104  				if p != s.local { // don't connect to self.
   105  					wg.Add(1)
   106  					connect(s, p)
   107  				}
   108  			}
   109  		}
   110  		wg.Wait()
   111  	}
   112  
   113  	// ping/pong
   114  	for _, s1 := range swarms {
   115  		ctx, cancel := context.WithCancel(ctx)
   116  
   117  		// setup all others to pong
   118  		for _, s2 := range swarms {
   119  			if s1 == s2 {
   120  				continue
   121  			}
   122  
   123  			go pong(ctx, s2)
   124  		}
   125  
   126  		peers, err := s1.peers.All()
   127  		if err != nil {
   128  			t.Fatal(err)
   129  		}
   130  
   131  		for k := 0; k < MsgNum; k++ {
   132  			for _, p := range *peers {
   133  				log.Debugf("%s ping %s (%d)", s1.local, p, k)
   134  				s1.Outgoing <- msg.New(p, []byte("ping"))
   135  			}
   136  		}
   137  
   138  		got := map[u.Key]int{}
   139  		for k := 0; k < (MsgNum * len(*peers)); k++ {
   140  			log.Debugf("%s waiting for pong (%d)", s1.local, k)
   141  			msg := <-s1.Incoming
   142  			if string(msg.Data()) != "pong" {
   143  				t.Error("unexpected conn output", msg.Data)
   144  			}
   145  
   146  			n, _ := got[msg.Peer().Key()]
   147  			got[msg.Peer().Key()] = n + 1
   148  		}
   149  
   150  		if len(*peers) != len(got) {
   151  			t.Error("got less messages than sent")
   152  		}
   153  
   154  		for p, n := range got {
   155  			if n != MsgNum {
   156  				t.Error("peer did not get all msgs", p, n, "/", MsgNum)
   157  			}
   158  		}
   159  
   160  		cancel()
   161  		<-time.After(50 * time.Microsecond)
   162  	}
   163  
   164  	for _, s := range swarms {
   165  		s.Close()
   166  	}
   167  }
   168  
   169  func TestSwarm(t *testing.T) {
   170  	// t.Skip("skipping for another test")
   171  
   172  	addrs := []string{
   173  		"/ip4/127.0.0.1/tcp/10234",
   174  		"/ip4/127.0.0.1/tcp/10235",
   175  		"/ip4/127.0.0.1/tcp/10236",
   176  		"/ip4/127.0.0.1/tcp/10237",
   177  		"/ip4/127.0.0.1/tcp/10238",
   178  	}
   179  
   180  	// msgs := 1000
   181  	msgs := 100
   182  	SubtestSwarm(t, addrs, msgs)
   183  }