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 }