github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/p2p/net/conn/secure_conn_test.go (about) 1 package conn 2 3 import ( 4 "bytes" 5 "runtime" 6 "sync" 7 "testing" 8 "time" 9 10 ic "github.com/ipfs/go-ipfs/p2p/crypto" 11 travis "github.com/ipfs/go-ipfs/util/testutil/ci/travis" 12 13 context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" 14 ) 15 16 func upgradeToSecureConn(t *testing.T, ctx context.Context, sk ic.PrivKey, c Conn) (Conn, error) { 17 if c, ok := c.(*secureConn); ok { 18 return c, nil 19 } 20 21 // shouldn't happen, because dial + listen already return secure conns. 22 s, err := newSecureConn(ctx, sk, c) 23 if err != nil { 24 return nil, err 25 } 26 27 // need to read + write, as that's what triggers the handshake. 28 h := []byte("hello") 29 if _, err := s.Write(h); err != nil { 30 return nil, err 31 } 32 if _, err := s.Read(h); err != nil { 33 return nil, err 34 } 35 return s, nil 36 } 37 38 func secureHandshake(t *testing.T, ctx context.Context, sk ic.PrivKey, c Conn, done chan error) { 39 _, err := upgradeToSecureConn(t, ctx, sk, c) 40 done <- err 41 } 42 43 func TestSecureSimple(t *testing.T) { 44 // t.Skip("Skipping in favor of another test") 45 46 numMsgs := 100 47 if testing.Short() { 48 numMsgs = 10 49 } 50 51 ctx := context.Background() 52 c1, c2, p1, p2 := setupSingleConn(t, ctx) 53 54 done := make(chan error) 55 go secureHandshake(t, ctx, p1.PrivKey, c1, done) 56 go secureHandshake(t, ctx, p2.PrivKey, c2, done) 57 58 for i := 0; i < 2; i++ { 59 if err := <-done; err != nil { 60 t.Fatal(err) 61 } 62 } 63 64 for i := 0; i < numMsgs; i++ { 65 testOneSendRecv(t, c1, c2) 66 testOneSendRecv(t, c2, c1) 67 } 68 69 c1.Close() 70 c2.Close() 71 } 72 73 func TestSecureClose(t *testing.T) { 74 // t.Skip("Skipping in favor of another test") 75 76 ctx := context.Background() 77 c1, c2, p1, p2 := setupSingleConn(t, ctx) 78 79 done := make(chan error) 80 go secureHandshake(t, ctx, p1.PrivKey, c1, done) 81 go secureHandshake(t, ctx, p2.PrivKey, c2, done) 82 83 for i := 0; i < 2; i++ { 84 if err := <-done; err != nil { 85 t.Fatal(err) 86 } 87 } 88 89 testOneSendRecv(t, c1, c2) 90 91 c1.Close() 92 testNotOneSendRecv(t, c1, c2) 93 94 c2.Close() 95 testNotOneSendRecv(t, c1, c2) 96 testNotOneSendRecv(t, c2, c1) 97 98 } 99 100 func TestSecureCancelHandshake(t *testing.T) { 101 // t.Skip("Skipping in favor of another test") 102 103 ctx, cancel := context.WithCancel(context.Background()) 104 c1, c2, p1, p2 := setupSingleConn(t, ctx) 105 106 done := make(chan error) 107 go secureHandshake(t, ctx, p1.PrivKey, c1, done) 108 <-time.After(time.Millisecond) 109 cancel() // cancel ctx 110 go secureHandshake(t, ctx, p2.PrivKey, c2, done) 111 112 for i := 0; i < 2; i++ { 113 if err := <-done; err == nil { 114 t.Error("cancel should've errored out") 115 } 116 } 117 } 118 119 func TestSecureHandshakeFailsWithWrongKeys(t *testing.T) { 120 // t.Skip("Skipping in favor of another test") 121 122 ctx, cancel := context.WithCancel(context.Background()) 123 defer cancel() 124 c1, c2, p1, p2 := setupSingleConn(t, ctx) 125 126 done := make(chan error) 127 go secureHandshake(t, ctx, p2.PrivKey, c1, done) 128 go secureHandshake(t, ctx, p1.PrivKey, c2, done) 129 130 for i := 0; i < 2; i++ { 131 if err := <-done; err == nil { 132 t.Fatal("wrong keys should've errored out.") 133 } 134 } 135 } 136 137 func TestSecureCloseLeak(t *testing.T) { 138 // t.Skip("Skipping in favor of another test") 139 140 if testing.Short() { 141 t.SkipNow() 142 } 143 if travis.IsRunning() { 144 t.Skip("this doesn't work well on travis") 145 } 146 147 runPair := func(c1, c2 Conn, num int) { 148 log.Debugf("runPair %d", num) 149 150 for i := 0; i < num; i++ { 151 log.Debugf("runPair iteration %d", i) 152 b1 := []byte("beep") 153 c1.WriteMsg(b1) 154 b2, err := c2.ReadMsg() 155 if err != nil { 156 panic(err) 157 } 158 if !bytes.Equal(b1, b2) { 159 panic("bytes not equal") 160 } 161 162 b2 = []byte("beep") 163 c2.WriteMsg(b2) 164 b1, err = c1.ReadMsg() 165 if err != nil { 166 panic(err) 167 } 168 if !bytes.Equal(b1, b2) { 169 panic("bytes not equal") 170 } 171 172 <-time.After(time.Microsecond * 5) 173 } 174 } 175 176 var cons = 5 177 var msgs = 50 178 log.Debugf("Running %d connections * %d msgs.\n", cons, msgs) 179 180 var wg sync.WaitGroup 181 for i := 0; i < cons; i++ { 182 wg.Add(1) 183 184 ctx, cancel := context.WithCancel(context.Background()) 185 c1, c2, _, _ := setupSecureConn(t, ctx) 186 go func(c1, c2 Conn) { 187 188 defer func() { 189 c1.Close() 190 c2.Close() 191 cancel() 192 wg.Done() 193 }() 194 195 runPair(c1, c2, msgs) 196 }(c1, c2) 197 } 198 199 log.Debugf("Waiting...\n") 200 wg.Wait() 201 // done! 202 203 <-time.After(time.Millisecond * 150) 204 if runtime.NumGoroutine() > 20 { 205 // panic("uncomment me to debug") 206 t.Fatal("leaking goroutines:", runtime.NumGoroutine()) 207 } 208 }