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

     1  package swarm
     2  
     3  import (
     4  	"net"
     5  	"sync"
     6  	"testing"
     7  	"time"
     8  
     9  	addrutil "github.com/ipfs/go-ipfs/p2p/net/swarm/addr"
    10  	peer "github.com/ipfs/go-ipfs/p2p/peer"
    11  
    12  	testutil "github.com/ipfs/go-ipfs/util/testutil"
    13  	ci "github.com/ipfs/go-ipfs/util/testutil/ci"
    14  
    15  	ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
    16  	manet "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
    17  	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
    18  )
    19  
    20  func acceptAndHang(l net.Listener) {
    21  	conns := make([]net.Conn, 0, 10)
    22  	for {
    23  		c, err := l.Accept()
    24  		if err != nil {
    25  			break
    26  		}
    27  		if c != nil {
    28  			conns = append(conns, c)
    29  		}
    30  	}
    31  	for _, c := range conns {
    32  		c.Close()
    33  	}
    34  }
    35  
    36  func TestSimultDials(t *testing.T) {
    37  	// t.Skip("skipping for another test")
    38  	t.Parallel()
    39  
    40  	ctx := context.Background()
    41  	swarms := makeSwarms(ctx, t, 2)
    42  
    43  	// connect everyone
    44  	{
    45  		var wg sync.WaitGroup
    46  		connect := func(s *Swarm, dst peer.ID, addr ma.Multiaddr) {
    47  			// copy for other peer
    48  			log.Debugf("TestSimultOpen: connecting: %s --> %s (%s)", s.local, dst, addr)
    49  			s.peers.AddAddr(dst, addr, peer.TempAddrTTL)
    50  			if _, err := s.Dial(ctx, dst); err != nil {
    51  				t.Fatal("error swarm dialing to peer", err)
    52  			}
    53  			wg.Done()
    54  		}
    55  
    56  		ifaceAddrs0, err := swarms[0].InterfaceListenAddresses()
    57  		if err != nil {
    58  			t.Fatal(err)
    59  		}
    60  		ifaceAddrs1, err := swarms[1].InterfaceListenAddresses()
    61  		if err != nil {
    62  			t.Fatal(err)
    63  		}
    64  
    65  		log.Info("Connecting swarms simultaneously.")
    66  		for i := 0; i < 10; i++ { // connect 10x for each.
    67  			wg.Add(2)
    68  			go connect(swarms[0], swarms[1].local, ifaceAddrs1[0])
    69  			go connect(swarms[1], swarms[0].local, ifaceAddrs0[0])
    70  		}
    71  		wg.Wait()
    72  	}
    73  
    74  	// should still just have 1, at most 2 connections :)
    75  	c01l := len(swarms[0].ConnectionsToPeer(swarms[1].local))
    76  	if c01l > 2 {
    77  		t.Error("0->1 has", c01l)
    78  	}
    79  	c10l := len(swarms[1].ConnectionsToPeer(swarms[0].local))
    80  	if c10l > 2 {
    81  		t.Error("1->0 has", c10l)
    82  	}
    83  
    84  	for _, s := range swarms {
    85  		s.Close()
    86  	}
    87  }
    88  
    89  func newSilentPeer(t *testing.T) (peer.ID, ma.Multiaddr, net.Listener) {
    90  	dst := testutil.RandPeerIDFatal(t)
    91  	lst, err := net.Listen("tcp", ":0")
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  	addr, err := manet.FromNetAddr(lst.Addr())
    96  	if err != nil {
    97  		t.Fatal(err)
    98  	}
    99  	addrs := []ma.Multiaddr{addr}
   100  	addrs, err = addrutil.ResolveUnspecifiedAddresses(addrs, nil)
   101  	if err != nil {
   102  		t.Fatal(err)
   103  	}
   104  	t.Log("new silent peer:", dst, addrs[0])
   105  	return dst, addrs[0], lst
   106  }
   107  
   108  func TestDialWait(t *testing.T) {
   109  	// t.Skip("skipping for another test")
   110  	t.Parallel()
   111  
   112  	ctx := context.Background()
   113  	swarms := makeSwarms(ctx, t, 1)
   114  	s1 := swarms[0]
   115  	defer s1.Close()
   116  
   117  	s1.dialT = time.Millisecond * 300 // lower timeout for tests.
   118  	if ci.IsRunning() {
   119  		s1.dialT = time.Second
   120  	}
   121  
   122  	// dial to a non-existent peer.
   123  	s2p, s2addr, s2l := newSilentPeer(t)
   124  	go acceptAndHang(s2l)
   125  	defer s2l.Close()
   126  	s1.peers.AddAddr(s2p, s2addr, peer.PermanentAddrTTL)
   127  
   128  	before := time.Now()
   129  	if c, err := s1.Dial(ctx, s2p); err == nil {
   130  		defer c.Close()
   131  		t.Fatal("error swarm dialing to unknown peer worked...", err)
   132  	} else {
   133  		t.Log("correctly got error:", err)
   134  	}
   135  	duration := time.Now().Sub(before)
   136  
   137  	dt := s1.dialT
   138  	if duration < dt*dialAttempts {
   139  		t.Error("< DialTimeout * dialAttempts not being respected", duration, dt*dialAttempts)
   140  	}
   141  	if duration > 2*dt*dialAttempts {
   142  		t.Error("> 2*DialTimeout * dialAttempts not being respected", duration, 2*dt*dialAttempts)
   143  	}
   144  
   145  	if !s1.backf.Backoff(s2p) {
   146  		t.Error("s2 should now be on backoff")
   147  	}
   148  }
   149  
   150  func TestDialBackoff(t *testing.T) {
   151  	// t.Skip("skipping for another test")
   152  	if ci.IsRunning() {
   153  		t.Skip("travis and jenkins will never have fun with this test")
   154  	}
   155  
   156  	t.Parallel()
   157  
   158  	ctx := context.Background()
   159  	swarms := makeSwarms(ctx, t, 2)
   160  	s1 := swarms[0]
   161  	s2 := swarms[1]
   162  	defer s1.Close()
   163  	defer s2.Close()
   164  
   165  	s1.dialT = time.Second // lower timeout for tests.
   166  	s2.dialT = time.Second // lower timeout for tests.
   167  
   168  	s2addrs, err := s2.InterfaceListenAddresses()
   169  	if err != nil {
   170  		t.Fatal(err)
   171  	}
   172  	s1.peers.AddAddrs(s2.local, s2addrs, peer.PermanentAddrTTL)
   173  
   174  	// dial to a non-existent peer.
   175  	s3p, s3addr, s3l := newSilentPeer(t)
   176  	go acceptAndHang(s3l)
   177  	defer s3l.Close()
   178  	s1.peers.AddAddr(s3p, s3addr, peer.PermanentAddrTTL)
   179  
   180  	// in this test we will:
   181  	//   1) dial 10x to each node.
   182  	//   2) all dials should hang
   183  	//   3) s1->s2 should succeed.
   184  	//   4) s1->s3 should not (and should place s3 on backoff)
   185  	//   5) disconnect entirely
   186  	//   6) dial 10x to each node again
   187  	//   7) s3 dials should all return immediately (except 1)
   188  	//   8) s2 dials should all hang, and succeed
   189  	//   9) last s3 dial ends, unsuccessful
   190  
   191  	dialOnlineNode := func(dst peer.ID, times int) <-chan bool {
   192  		ch := make(chan bool)
   193  		for i := 0; i < times; i++ {
   194  			go func() {
   195  				if _, err := s1.Dial(ctx, dst); err != nil {
   196  					t.Error("error dialing", dst, err)
   197  					ch <- false
   198  				} else {
   199  					ch <- true
   200  				}
   201  			}()
   202  		}
   203  		return ch
   204  	}
   205  
   206  	dialOfflineNode := func(dst peer.ID, times int) <-chan bool {
   207  		ch := make(chan bool)
   208  		for i := 0; i < times; i++ {
   209  			go func() {
   210  				if c, err := s1.Dial(ctx, dst); err != nil {
   211  					ch <- false
   212  				} else {
   213  					t.Error("succeeded in dialing", dst)
   214  					ch <- true
   215  					c.Close()
   216  				}
   217  			}()
   218  		}
   219  		return ch
   220  	}
   221  
   222  	{
   223  		// 1) dial 10x to each node.
   224  		N := 10
   225  		s2done := dialOnlineNode(s2.local, N)
   226  		s3done := dialOfflineNode(s3p, N)
   227  
   228  		// when all dials should be done by:
   229  		dialTimeout1x := time.After(s1.dialT)
   230  		// dialTimeout1Ax := time.After(s1.dialT * 2)       // dialAttempts)
   231  		dialTimeout10Ax := time.After(s1.dialT * 2 * 10) // dialAttempts * 10)
   232  
   233  		// 2) all dials should hang
   234  		select {
   235  		case <-s2done:
   236  			t.Error("s2 should not happen immediately")
   237  		case <-s3done:
   238  			t.Error("s3 should not happen yet")
   239  		case <-time.After(time.Millisecond):
   240  			// s2 may finish very quickly, so let's get out.
   241  		}
   242  
   243  		// 3) s1->s2 should succeed.
   244  		for i := 0; i < N; i++ {
   245  			select {
   246  			case r := <-s2done:
   247  				if !r {
   248  					t.Error("s2 should not fail")
   249  				}
   250  			case <-s3done:
   251  				t.Error("s3 should not happen yet")
   252  			case <-dialTimeout1x:
   253  				t.Error("s2 took too long")
   254  			}
   255  		}
   256  
   257  		select {
   258  		case <-s2done:
   259  			t.Error("s2 should have no more")
   260  		case <-s3done:
   261  			t.Error("s3 should not happen yet")
   262  		case <-dialTimeout1x: // let it pass
   263  		}
   264  
   265  		// 4) s1->s3 should not (and should place s3 on backoff)
   266  		// N-1 should finish before dialTimeout1x * 2
   267  		for i := 0; i < N; i++ {
   268  			select {
   269  			case <-s2done:
   270  				t.Error("s2 should have no more")
   271  			case r := <-s3done:
   272  				if r {
   273  					t.Error("s3 should not succeed")
   274  				}
   275  			case <-(dialTimeout1x):
   276  				if i < (N - 1) {
   277  					t.Fatal("s3 took too long")
   278  				}
   279  				t.Log("dialTimeout1x * 1.3 hit for last peer")
   280  			case <-dialTimeout10Ax:
   281  				t.Fatal("s3 took too long")
   282  			}
   283  		}
   284  
   285  		// check backoff state
   286  		if s1.backf.Backoff(s2.local) {
   287  			t.Error("s2 should not be on backoff")
   288  		}
   289  		if !s1.backf.Backoff(s3p) {
   290  			t.Error("s3 should be on backoff")
   291  		}
   292  
   293  		// 5) disconnect entirely
   294  
   295  		for _, c := range s1.Connections() {
   296  			c.Close()
   297  		}
   298  		for i := 0; i < 100 && len(s1.Connections()) > 0; i++ {
   299  			<-time.After(time.Millisecond)
   300  		}
   301  		if len(s1.Connections()) > 0 {
   302  			t.Fatal("s1 conns must exit")
   303  		}
   304  	}
   305  
   306  	{
   307  		// 6) dial 10x to each node again
   308  		N := 10
   309  		s2done := dialOnlineNode(s2.local, N)
   310  		s3done := dialOfflineNode(s3p, N)
   311  
   312  		// when all dials should be done by:
   313  		dialTimeout1x := time.After(s1.dialT)
   314  		// dialTimeout1Ax := time.After(s1.dialT * 2)       // dialAttempts)
   315  		dialTimeout10Ax := time.After(s1.dialT * 2 * 10) // dialAttempts * 10)
   316  
   317  		// 7) s3 dials should all return immediately (except 1)
   318  		for i := 0; i < N-1; i++ {
   319  			select {
   320  			case <-s2done:
   321  				t.Error("s2 should not succeed yet")
   322  			case r := <-s3done:
   323  				if r {
   324  					t.Error("s3 should not succeed")
   325  				}
   326  			case <-dialTimeout1x:
   327  				t.Fatal("s3 took too long")
   328  			}
   329  		}
   330  
   331  		// 8) s2 dials should all hang, and succeed
   332  		for i := 0; i < N; i++ {
   333  			select {
   334  			case r := <-s2done:
   335  				if !r {
   336  					t.Error("s2 should succeed")
   337  				}
   338  			// case <-s3done:
   339  			case <-(dialTimeout1x):
   340  				t.Fatal("s3 took too long")
   341  			}
   342  		}
   343  
   344  		// 9) the last s3 should return, failed.
   345  		select {
   346  		case <-s2done:
   347  			t.Error("s2 should have no more")
   348  		case r := <-s3done:
   349  			if r {
   350  				t.Error("s3 should not succeed")
   351  			}
   352  		case <-dialTimeout10Ax:
   353  			t.Fatal("s3 took too long")
   354  		}
   355  
   356  		// check backoff state (the same)
   357  		if s1.backf.Backoff(s2.local) {
   358  			t.Error("s2 should not be on backoff")
   359  		}
   360  		if !s1.backf.Backoff(s3p) {
   361  			t.Error("s3 should be on backoff")
   362  		}
   363  
   364  	}
   365  }
   366  
   367  func TestDialBackoffClears(t *testing.T) {
   368  	// t.Skip("skipping for another test")
   369  	t.Parallel()
   370  
   371  	ctx := context.Background()
   372  	swarms := makeSwarms(ctx, t, 2)
   373  	s1 := swarms[0]
   374  	s2 := swarms[1]
   375  	defer s1.Close()
   376  	defer s2.Close()
   377  	s1.dialT = time.Millisecond * 300 // lower timeout for tests.
   378  	s2.dialT = time.Millisecond * 300 // lower timeout for tests.
   379  	if ci.IsRunning() {
   380  		s1.dialT = 2 * time.Second
   381  		s2.dialT = 2 * time.Second
   382  	}
   383  
   384  	// use another address first, that accept and hang on conns
   385  	_, s2bad, s2l := newSilentPeer(t)
   386  	go acceptAndHang(s2l)
   387  	defer s2l.Close()
   388  
   389  	// phase 1 -- dial to non-operational addresses
   390  	s1.peers.AddAddr(s2.local, s2bad, peer.PermanentAddrTTL)
   391  
   392  	before := time.Now()
   393  	if c, err := s1.Dial(ctx, s2.local); err == nil {
   394  		t.Fatal("dialing to broken addr worked...", err)
   395  		defer c.Close()
   396  	} else {
   397  		t.Log("correctly got error:", err)
   398  	}
   399  	duration := time.Now().Sub(before)
   400  
   401  	dt := s1.dialT
   402  	if duration < dt*dialAttempts {
   403  		t.Error("< DialTimeout * dialAttempts not being respected", duration, dt*dialAttempts)
   404  	}
   405  	if duration > 2*dt*dialAttempts {
   406  		t.Error("> 2*DialTimeout * dialAttempts not being respected", duration, 2*dt*dialAttempts)
   407  	}
   408  
   409  	if !s1.backf.Backoff(s2.local) {
   410  		t.Error("s2 should now be on backoff")
   411  	} else {
   412  		t.Log("correctly added to backoff")
   413  	}
   414  
   415  	// phase 2 -- add the working address. dial should succeed.
   416  	ifaceAddrs1, err := swarms[1].InterfaceListenAddresses()
   417  	if err != nil {
   418  		t.Fatal(err)
   419  	}
   420  	s1.peers.AddAddrs(s2.local, ifaceAddrs1, peer.PermanentAddrTTL)
   421  
   422  	before = time.Now()
   423  	if c, err := s1.Dial(ctx, s2.local); err != nil {
   424  		t.Fatal(err)
   425  	} else {
   426  		c.Close()
   427  		t.Log("correctly connected")
   428  	}
   429  	duration = time.Now().Sub(before)
   430  
   431  	if duration >= dt {
   432  		// t.Error("took too long", duration, dt)
   433  	}
   434  
   435  	if s1.backf.Backoff(s2.local) {
   436  		t.Error("s2 should no longer be on backoff")
   437  	} else {
   438  		t.Log("correctly cleared backoff")
   439  	}
   440  }