github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/p2p/net/mock/mock_test.go (about)

     1  package mocknet
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"math"
     7  	"math/rand"
     8  	"sync"
     9  	"testing"
    10  	"time"
    11  
    12  	inet "github.com/ipfs/go-ipfs/p2p/net"
    13  	peer "github.com/ipfs/go-ipfs/p2p/peer"
    14  	protocol "github.com/ipfs/go-ipfs/p2p/protocol"
    15  	testutil "github.com/ipfs/go-ipfs/util/testutil"
    16  
    17  	detectrace "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-detect-race"
    18  	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
    19  )
    20  
    21  func randPeer(t *testing.T) peer.ID {
    22  	p, err := testutil.RandPeerID()
    23  	if err != nil {
    24  		t.Fatal(err)
    25  	}
    26  	return p
    27  }
    28  
    29  func TestNetworkSetup(t *testing.T) {
    30  
    31  	ctx := context.Background()
    32  	sk1, _, err := testutil.RandTestKeyPair(512)
    33  	if err != nil {
    34  		t.Fatal(t)
    35  	}
    36  	sk2, _, err := testutil.RandTestKeyPair(512)
    37  	if err != nil {
    38  		t.Fatal(t)
    39  	}
    40  	sk3, _, err := testutil.RandTestKeyPair(512)
    41  	if err != nil {
    42  		t.Fatal(t)
    43  	}
    44  	mn := New(ctx)
    45  	// peers := []peer.ID{p1, p2, p3}
    46  
    47  	// add peers to mock net
    48  
    49  	a1 := testutil.RandLocalTCPAddress()
    50  	a2 := testutil.RandLocalTCPAddress()
    51  	a3 := testutil.RandLocalTCPAddress()
    52  
    53  	h1, err := mn.AddPeer(sk1, a1)
    54  	if err != nil {
    55  		t.Fatal(err)
    56  	}
    57  	p1 := h1.ID()
    58  
    59  	h2, err := mn.AddPeer(sk2, a2)
    60  	if err != nil {
    61  		t.Fatal(err)
    62  	}
    63  	p2 := h2.ID()
    64  
    65  	h3, err := mn.AddPeer(sk3, a3)
    66  	if err != nil {
    67  		t.Fatal(err)
    68  	}
    69  	p3 := h3.ID()
    70  
    71  	// check peers and net
    72  	if mn.Host(p1) != h1 {
    73  		t.Error("host for p1.ID != h1")
    74  	}
    75  	if mn.Host(p2) != h2 {
    76  		t.Error("host for p2.ID != h2")
    77  	}
    78  	if mn.Host(p3) != h3 {
    79  		t.Error("host for p3.ID != h3")
    80  	}
    81  
    82  	n1 := h1.Network()
    83  	if mn.Net(p1) != n1 {
    84  		t.Error("net for p1.ID != n1")
    85  	}
    86  	n2 := h2.Network()
    87  	if mn.Net(p2) != n2 {
    88  		t.Error("net for p2.ID != n1")
    89  	}
    90  	n3 := h3.Network()
    91  	if mn.Net(p3) != n3 {
    92  		t.Error("net for p3.ID != n1")
    93  	}
    94  
    95  	// link p1<-->p2, p1<-->p1, p2<-->p3, p3<-->p2
    96  
    97  	l12, err := mn.LinkPeers(p1, p2)
    98  	if err != nil {
    99  		t.Fatal(err)
   100  	}
   101  	if !(l12.Networks()[0] == n1 && l12.Networks()[1] == n2) &&
   102  		!(l12.Networks()[0] == n2 && l12.Networks()[1] == n1) {
   103  		t.Error("l12 networks incorrect")
   104  	}
   105  
   106  	l11, err := mn.LinkPeers(p1, p1)
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  	if !(l11.Networks()[0] == n1 && l11.Networks()[1] == n1) {
   111  		t.Error("l11 networks incorrect")
   112  	}
   113  
   114  	l23, err := mn.LinkPeers(p2, p3)
   115  	if err != nil {
   116  		t.Fatal(err)
   117  	}
   118  	if !(l23.Networks()[0] == n2 && l23.Networks()[1] == n3) &&
   119  		!(l23.Networks()[0] == n3 && l23.Networks()[1] == n2) {
   120  		t.Error("l23 networks incorrect")
   121  	}
   122  
   123  	l32, err := mn.LinkPeers(p3, p2)
   124  	if err != nil {
   125  		t.Fatal(err)
   126  	}
   127  	if !(l32.Networks()[0] == n2 && l32.Networks()[1] == n3) &&
   128  		!(l32.Networks()[0] == n3 && l32.Networks()[1] == n2) {
   129  		t.Error("l32 networks incorrect")
   130  	}
   131  
   132  	// check things
   133  
   134  	links12 := mn.LinksBetweenPeers(p1, p2)
   135  	if len(links12) != 1 {
   136  		t.Errorf("should be 1 link bt. p1 and p2 (found %d)", len(links12))
   137  	}
   138  	if links12[0] != l12 {
   139  		t.Error("links 1-2 should be l12.")
   140  	}
   141  
   142  	links11 := mn.LinksBetweenPeers(p1, p1)
   143  	if len(links11) != 1 {
   144  		t.Errorf("should be 1 link bt. p1 and p1 (found %d)", len(links11))
   145  	}
   146  	if links11[0] != l11 {
   147  		t.Error("links 1-1 should be l11.")
   148  	}
   149  
   150  	links23 := mn.LinksBetweenPeers(p2, p3)
   151  	if len(links23) != 2 {
   152  		t.Errorf("should be 2 link bt. p2 and p3 (found %d)", len(links23))
   153  	}
   154  	if !((links23[0] == l23 && links23[1] == l32) ||
   155  		(links23[0] == l32 && links23[1] == l23)) {
   156  		t.Error("links 2-3 should be l23 and l32.")
   157  	}
   158  
   159  	// unlinking
   160  
   161  	if err := mn.UnlinkPeers(p2, p1); err != nil {
   162  		t.Error(err)
   163  	}
   164  
   165  	// check only one link affected:
   166  
   167  	links12 = mn.LinksBetweenPeers(p1, p2)
   168  	if len(links12) != 0 {
   169  		t.Errorf("should be 0 now...", len(links12))
   170  	}
   171  
   172  	links11 = mn.LinksBetweenPeers(p1, p1)
   173  	if len(links11) != 1 {
   174  		t.Errorf("should be 1 link bt. p1 and p1 (found %d)", len(links11))
   175  	}
   176  	if links11[0] != l11 {
   177  		t.Error("links 1-1 should be l11.")
   178  	}
   179  
   180  	links23 = mn.LinksBetweenPeers(p2, p3)
   181  	if len(links23) != 2 {
   182  		t.Errorf("should be 2 link bt. p2 and p3 (found %d)", len(links23))
   183  	}
   184  	if !((links23[0] == l23 && links23[1] == l32) ||
   185  		(links23[0] == l32 && links23[1] == l23)) {
   186  		t.Error("links 2-3 should be l23 and l32.")
   187  	}
   188  
   189  	// check connecting
   190  
   191  	// first, no conns
   192  	if len(n2.Conns()) > 0 || len(n3.Conns()) > 0 {
   193  		t.Error("should have 0 conn. Got: (%d, %d)", len(n2.Conns()), len(n3.Conns()))
   194  	}
   195  
   196  	// connect p2->p3
   197  	if _, err := n2.DialPeer(ctx, p3); err != nil {
   198  		t.Error(err)
   199  	}
   200  
   201  	if len(n2.Conns()) != 1 || len(n3.Conns()) != 1 {
   202  		t.Errorf("should have (1,1) conn. Got: (%d, %d)", len(n2.Conns()), len(n3.Conns()))
   203  	}
   204  
   205  	// p := PrinterTo(os.Stdout)
   206  	// p.NetworkConns(n1)
   207  	// p.NetworkConns(n2)
   208  	// p.NetworkConns(n3)
   209  
   210  	// can create a stream 2->3, 3->2,
   211  	if _, err := n2.NewStream(p3); err != nil {
   212  		t.Error(err)
   213  	}
   214  	if _, err := n3.NewStream(p2); err != nil {
   215  		t.Error(err)
   216  	}
   217  
   218  	// but not 1->2 nor 2->2 (not linked), nor 1->1 (not connected)
   219  	if _, err := n1.NewStream(p2); err == nil {
   220  		t.Error("should not be able to connect")
   221  	}
   222  	if _, err := n2.NewStream(p2); err == nil {
   223  		t.Error("should not be able to connect")
   224  	}
   225  	if _, err := n1.NewStream(p1); err == nil {
   226  		t.Error("should not be able to connect")
   227  	}
   228  
   229  	// connect p1->p1 (should work)
   230  	if _, err := n1.DialPeer(ctx, p1); err != nil {
   231  		t.Error("p1 should be able to dial self.", err)
   232  	}
   233  
   234  	// and a stream too
   235  	if _, err := n1.NewStream(p1); err != nil {
   236  		t.Error(err)
   237  	}
   238  
   239  	// connect p1->p2
   240  	if _, err := n1.DialPeer(ctx, p2); err == nil {
   241  		t.Error("p1 should not be able to dial p2, not connected...")
   242  	}
   243  
   244  	// connect p3->p1
   245  	if _, err := n3.DialPeer(ctx, p1); err == nil {
   246  		t.Error("p3 should not be able to dial p1, not connected...")
   247  	}
   248  
   249  	// relink p1->p2
   250  
   251  	l12, err = mn.LinkPeers(p1, p2)
   252  	if err != nil {
   253  		t.Fatal(err)
   254  	}
   255  	if !(l12.Networks()[0] == n1 && l12.Networks()[1] == n2) &&
   256  		!(l12.Networks()[0] == n2 && l12.Networks()[1] == n1) {
   257  		t.Error("l12 networks incorrect")
   258  	}
   259  
   260  	// should now be able to connect
   261  
   262  	// connect p1->p2
   263  	if _, err := n1.DialPeer(ctx, p2); err != nil {
   264  		t.Error(err)
   265  	}
   266  
   267  	// and a stream should work now too :)
   268  	if _, err := n2.NewStream(p3); err != nil {
   269  		t.Error(err)
   270  	}
   271  
   272  }
   273  
   274  func TestStreams(t *testing.T) {
   275  
   276  	mn, err := FullMeshConnected(context.Background(), 3)
   277  	if err != nil {
   278  		t.Fatal(err)
   279  	}
   280  
   281  	handler := func(s inet.Stream) {
   282  		b := make([]byte, 4)
   283  		if _, err := io.ReadFull(s, b); err != nil {
   284  			panic(err)
   285  		}
   286  		if !bytes.Equal(b, []byte("beep")) {
   287  			panic("bytes mismatch")
   288  		}
   289  		if _, err := s.Write([]byte("boop")); err != nil {
   290  			panic(err)
   291  		}
   292  		s.Close()
   293  	}
   294  
   295  	hosts := mn.Hosts()
   296  	for _, h := range mn.Hosts() {
   297  		h.SetStreamHandler(protocol.TestingID, handler)
   298  	}
   299  
   300  	s, err := hosts[0].NewStream(protocol.TestingID, hosts[1].ID())
   301  	if err != nil {
   302  		t.Fatal(err)
   303  	}
   304  
   305  	if _, err := s.Write([]byte("beep")); err != nil {
   306  		panic(err)
   307  	}
   308  	b := make([]byte, 4)
   309  	if _, err := io.ReadFull(s, b); err != nil {
   310  		panic(err)
   311  	}
   312  	if !bytes.Equal(b, []byte("boop")) {
   313  		panic("bytes mismatch 2")
   314  	}
   315  
   316  }
   317  
   318  func makePinger(st string, n int) func(inet.Stream) {
   319  	return func(s inet.Stream) {
   320  		go func() {
   321  			defer s.Close()
   322  
   323  			for i := 0; i < n; i++ {
   324  				b := make([]byte, 4+len(st))
   325  				if _, err := s.Write([]byte("ping" + st)); err != nil {
   326  					panic(err)
   327  				}
   328  				if _, err := io.ReadFull(s, b); err != nil {
   329  					panic(err)
   330  				}
   331  				if !bytes.Equal(b, []byte("pong"+st)) {
   332  					panic("bytes mismatch")
   333  				}
   334  			}
   335  		}()
   336  	}
   337  }
   338  
   339  func makePonger(st string) func(inet.Stream) {
   340  	return func(s inet.Stream) {
   341  		go func() {
   342  			defer s.Close()
   343  
   344  			for {
   345  				b := make([]byte, 4+len(st))
   346  				if _, err := io.ReadFull(s, b); err != nil {
   347  					if err == io.EOF {
   348  						return
   349  					}
   350  					panic(err)
   351  				}
   352  				if !bytes.Equal(b, []byte("ping"+st)) {
   353  					panic("bytes mismatch")
   354  				}
   355  				if _, err := s.Write([]byte("pong" + st)); err != nil {
   356  					panic(err)
   357  				}
   358  			}
   359  		}()
   360  	}
   361  }
   362  
   363  func TestStreamsStress(t *testing.T) {
   364  	nnodes := 100
   365  	if detectrace.WithRace() {
   366  		nnodes = 50
   367  	}
   368  
   369  	mn, err := FullMeshConnected(context.Background(), nnodes)
   370  	if err != nil {
   371  		t.Fatal(err)
   372  	}
   373  
   374  	hosts := mn.Hosts()
   375  	for _, h := range hosts {
   376  		ponger := makePonger(string(protocol.TestingID))
   377  		h.SetStreamHandler(protocol.TestingID, ponger)
   378  	}
   379  
   380  	var wg sync.WaitGroup
   381  	for i := 0; i < 1000; i++ {
   382  		wg.Add(1)
   383  		go func(i int) {
   384  			defer wg.Done()
   385  			from := rand.Intn(len(hosts))
   386  			to := rand.Intn(len(hosts))
   387  			s, err := hosts[from].NewStream(protocol.TestingID, hosts[to].ID())
   388  			if err != nil {
   389  				log.Debugf("%d (%s) %d (%s)", from, hosts[from], to, hosts[to])
   390  				panic(err)
   391  			}
   392  
   393  			log.Infof("%d start pinging", i)
   394  			makePinger("pingpong", rand.Intn(100))(s)
   395  			log.Infof("%d done pinging", i)
   396  		}(i)
   397  	}
   398  
   399  	wg.Wait()
   400  }
   401  
   402  func TestAdding(t *testing.T) {
   403  
   404  	mn := New(context.Background())
   405  
   406  	peers := []peer.ID{}
   407  	for i := 0; i < 3; i++ {
   408  		sk, _, err := testutil.RandTestKeyPair(512)
   409  		if err != nil {
   410  			t.Fatal(err)
   411  		}
   412  
   413  		a := testutil.RandLocalTCPAddress()
   414  		h, err := mn.AddPeer(sk, a)
   415  		if err != nil {
   416  			t.Fatal(err)
   417  		}
   418  
   419  		peers = append(peers, h.ID())
   420  	}
   421  
   422  	p1 := peers[0]
   423  	p2 := peers[1]
   424  
   425  	// link them
   426  	for _, p1 := range peers {
   427  		for _, p2 := range peers {
   428  			if _, err := mn.LinkPeers(p1, p2); err != nil {
   429  				t.Error(err)
   430  			}
   431  		}
   432  	}
   433  
   434  	// set the new stream handler on p2
   435  	h2 := mn.Host(p2)
   436  	if h2 == nil {
   437  		t.Fatalf("no host for %s", p2)
   438  	}
   439  	h2.SetStreamHandler(protocol.TestingID, func(s inet.Stream) {
   440  		defer s.Close()
   441  
   442  		b := make([]byte, 4)
   443  		if _, err := io.ReadFull(s, b); err != nil {
   444  			panic(err)
   445  		}
   446  		if string(b) != "beep" {
   447  			panic("did not beep!")
   448  		}
   449  
   450  		if _, err := s.Write([]byte("boop")); err != nil {
   451  			panic(err)
   452  		}
   453  	})
   454  
   455  	// connect p1 to p2
   456  	if _, err := mn.ConnectPeers(p1, p2); err != nil {
   457  		t.Fatal(err)
   458  	}
   459  
   460  	// talk to p2
   461  	h1 := mn.Host(p1)
   462  	if h1 == nil {
   463  		t.Fatalf("no network for %s", p1)
   464  	}
   465  
   466  	s, err := h1.NewStream(protocol.TestingID, p2)
   467  	if err != nil {
   468  		t.Fatal(err)
   469  	}
   470  
   471  	if _, err := s.Write([]byte("beep")); err != nil {
   472  		t.Error(err)
   473  	}
   474  	b := make([]byte, 4)
   475  	if _, err := io.ReadFull(s, b); err != nil {
   476  		t.Error(err)
   477  	}
   478  	if !bytes.Equal(b, []byte("boop")) {
   479  		t.Error("bytes mismatch 2")
   480  	}
   481  
   482  }
   483  
   484  func TestRateLimiting(t *testing.T) {
   485  	rl := NewRatelimiter(10)
   486  
   487  	if !within(rl.Limit(10), time.Duration(float32(time.Second)), time.Millisecond/10) {
   488  		t.Fail()
   489  	}
   490  	if !within(rl.Limit(10), time.Duration(float32(time.Second*2)), time.Millisecond) {
   491  		t.Fail()
   492  	}
   493  	if !within(rl.Limit(10), time.Duration(float32(time.Second*3)), time.Millisecond) {
   494  		t.Fail()
   495  	}
   496  
   497  	if within(rl.Limit(10), time.Duration(float32(time.Second*3)), time.Millisecond) {
   498  		t.Fail()
   499  	}
   500  
   501  	rl.UpdateBandwidth(50)
   502  	if !within(rl.Limit(75), time.Duration(float32(time.Second)*1.5), time.Millisecond/10) {
   503  		t.Fail()
   504  	}
   505  
   506  	if within(rl.Limit(75), time.Duration(float32(time.Second)*1.5), time.Millisecond/10) {
   507  		t.Fail()
   508  	}
   509  
   510  	rl.UpdateBandwidth(100)
   511  	if !within(rl.Limit(1), time.Duration(time.Millisecond*10), time.Millisecond/10) {
   512  		t.Fail()
   513  	}
   514  
   515  	if within(rl.Limit(1), time.Duration(time.Millisecond*10), time.Millisecond/10) {
   516  		t.Fail()
   517  	}
   518  }
   519  
   520  func within(t1 time.Duration, t2 time.Duration, tolerance time.Duration) bool {
   521  	return math.Abs(float64(t1)-float64(t2)) < float64(tolerance)
   522  }
   523  
   524  func TestLimitedStreams(t *testing.T) {
   525  	mn, err := FullMeshConnected(context.Background(), 2)
   526  	if err != nil {
   527  		t.Fatal(err)
   528  	}
   529  
   530  	var wg sync.WaitGroup
   531  	messages := 4
   532  	messageSize := 500
   533  	handler := func(s inet.Stream) {
   534  		b := make([]byte, messageSize)
   535  		for i := 0; i < messages; i++ {
   536  			if _, err := io.ReadFull(s, b); err != nil {
   537  				log.Fatal(err)
   538  			}
   539  			if !bytes.Equal(b[:4], []byte("ping")) {
   540  				log.Fatal("bytes mismatch")
   541  			}
   542  			wg.Done()
   543  		}
   544  		s.Close()
   545  	}
   546  
   547  	hosts := mn.Hosts()
   548  	for _, h := range mn.Hosts() {
   549  		h.SetStreamHandler(protocol.TestingID, handler)
   550  	}
   551  
   552  	peers := mn.Peers()
   553  	links := mn.LinksBetweenPeers(peers[0], peers[1])
   554  	//  1000 byte per second bandwidth
   555  	bps := float64(1000)
   556  	opts := links[0].Options()
   557  	opts.Bandwidth = bps
   558  	for _, link := range links {
   559  		link.SetOptions(opts)
   560  	}
   561  
   562  	s, err := hosts[0].NewStream(protocol.TestingID, hosts[1].ID())
   563  	if err != nil {
   564  		t.Fatal(err)
   565  	}
   566  
   567  	filler := make([]byte, messageSize-4)
   568  	data := append([]byte("ping"), filler...)
   569  	before := time.Now()
   570  	for i := 0; i < messages; i++ {
   571  		wg.Add(1)
   572  		if _, err := s.Write(data); err != nil {
   573  			panic(err)
   574  		}
   575  	}
   576  
   577  	wg.Wait()
   578  	if !within(time.Since(before), time.Duration(time.Second*2), time.Second/3) {
   579  		t.Fatal("Expected 2ish seconds but got ", time.Since(before))
   580  	}
   581  }