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

     1  package conn
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"os"
     7  	"runtime"
     8  	"strconv"
     9  	"sync"
    10  	"testing"
    11  	"time"
    12  
    13  	peer "github.com/jbenet/go-ipfs/peer"
    14  
    15  	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
    16  )
    17  
    18  func setupSecureConn(t *testing.T, c Conn) Conn {
    19  	c, ok := c.(*secureConn)
    20  	if ok {
    21  		return c
    22  	}
    23  
    24  	// shouldn't happen, because dial + listen already return secure conns.
    25  	s, err := newSecureConn(c.Context(), c, peer.NewPeerstore())
    26  	if err != nil {
    27  		t.Fatal(err)
    28  	}
    29  	return s
    30  }
    31  
    32  func TestSecureClose(t *testing.T) {
    33  	// t.Skip("Skipping in favor of another test")
    34  
    35  	ctx, cancel := context.WithCancel(context.Background())
    36  	c1, c2 := setupConn(t, ctx, "/ip4/127.0.0.1/tcp/6634", "/ip4/127.0.0.1/tcp/6645")
    37  
    38  	c1 = setupSecureConn(t, c1)
    39  	c2 = setupSecureConn(t, c2)
    40  
    41  	select {
    42  	case <-c1.Closed():
    43  		t.Fatal("done before close")
    44  	case <-c2.Closed():
    45  		t.Fatal("done before close")
    46  	default:
    47  	}
    48  
    49  	c1.Close()
    50  
    51  	select {
    52  	case <-c1.Closed():
    53  	default:
    54  		t.Fatal("not done after close")
    55  	}
    56  
    57  	c2.Close()
    58  
    59  	select {
    60  	case <-c2.Closed():
    61  	default:
    62  		t.Fatal("not done after close")
    63  	}
    64  
    65  	cancel() // close the listener :P
    66  }
    67  
    68  func TestSecureCancel(t *testing.T) {
    69  	// t.Skip("Skipping in favor of another test")
    70  
    71  	ctx, cancel := context.WithCancel(context.Background())
    72  	c1, c2 := setupConn(t, ctx, "/ip4/127.0.0.1/tcp/6634", "/ip4/127.0.0.1/tcp/6645")
    73  
    74  	c1 = setupSecureConn(t, c1)
    75  	c2 = setupSecureConn(t, c2)
    76  
    77  	select {
    78  	case <-c1.Closed():
    79  		t.Fatal("done before close")
    80  	case <-c2.Closed():
    81  		t.Fatal("done before close")
    82  	default:
    83  	}
    84  
    85  	c1.Close()
    86  	c2.Close()
    87  	cancel() // listener
    88  
    89  	// wait to ensure other goroutines run and close things.
    90  	<-time.After(time.Microsecond * 10)
    91  	// test that cancel called Close.
    92  
    93  	select {
    94  	case <-c1.Closed():
    95  	default:
    96  		t.Fatal("not done after cancel")
    97  	}
    98  
    99  	select {
   100  	case <-c2.Closed():
   101  	default:
   102  		t.Fatal("not done after cancel")
   103  	}
   104  
   105  }
   106  
   107  func TestSecureCloseLeak(t *testing.T) {
   108  	// t.Skip("Skipping in favor of another test")
   109  	if os.Getenv("TRAVIS") == "true" {
   110  		t.Skip("this doesn't work well on travis")
   111  	}
   112  
   113  	var wg sync.WaitGroup
   114  
   115  	runPair := func(p1, p2, num int) {
   116  		a1 := strconv.Itoa(p1)
   117  		a2 := strconv.Itoa(p2)
   118  		ctx, cancel := context.WithCancel(context.Background())
   119  		c1, c2 := setupConn(t, ctx, "/ip4/127.0.0.1/tcp/"+a1, "/ip4/127.0.0.1/tcp/"+a2)
   120  
   121  		c1 = setupSecureConn(t, c1)
   122  		c2 = setupSecureConn(t, c2)
   123  
   124  		for i := 0; i < num; i++ {
   125  			b1 := []byte("beep")
   126  			c1.Out() <- b1
   127  			b2 := <-c2.In()
   128  			if !bytes.Equal(b1, b2) {
   129  				panic("bytes not equal")
   130  			}
   131  
   132  			b2 = []byte("boop")
   133  			c2.Out() <- b2
   134  			b1 = <-c1.In()
   135  			if !bytes.Equal(b1, b2) {
   136  				panic("bytes not equal")
   137  			}
   138  
   139  			<-time.After(time.Microsecond * 5)
   140  		}
   141  
   142  		c1.Close()
   143  		c2.Close()
   144  		cancel() // close the listener
   145  		wg.Done()
   146  	}
   147  
   148  	var cons = 20
   149  	var msgs = 100
   150  	fmt.Printf("Running %d connections * %d msgs.\n", cons, msgs)
   151  	for i := 0; i < cons; i++ {
   152  		wg.Add(1)
   153  		go runPair(2000+i, 2001+i, msgs)
   154  	}
   155  
   156  	fmt.Printf("Waiting...\n")
   157  	wg.Wait()
   158  	// done!
   159  
   160  	<-time.After(time.Millisecond * 150)
   161  	if runtime.NumGoroutine() > 20 {
   162  		// panic("uncomment me to debug")
   163  		t.Fatal("leaking goroutines:", runtime.NumGoroutine())
   164  	}
   165  }