github.com/gdamore/mangos@v1.4.0/transport/tcp/tcp_test.go (about) 1 // Copyright 2018 The Mangos Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use file except in compliance with the License. 5 // You may obtain a copy of the license at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tcp 16 17 import ( 18 "bytes" 19 "testing" 20 "time" 21 22 "nanomsg.org/go-mangos" 23 "nanomsg.org/go-mangos/protocol/rep" 24 "nanomsg.org/go-mangos/protocol/req" 25 ) 26 27 var tran = NewTransport() 28 var sockRep, _ = rep.NewSocket() 29 var sockReq, _ = req.NewSocket() 30 31 func TestTCPListenAndAccept(t *testing.T) { 32 addr := "tcp://127.0.0.1:3333" 33 t.Logf("Establishing accepter") 34 l, err := tran.NewListener(addr, sockRep) 35 if err != nil { 36 t.Errorf("NewListener failed: %v", err) 37 return 38 } 39 defer l.Close() 40 if err = l.Listen(); err != nil { 41 t.Errorf("Listen failed: %v", err) 42 return 43 } 44 45 go func() { 46 d, err := tran.NewDialer(addr, sockReq) 47 if err != nil { 48 t.Errorf("NewDialier failed: %v", err) 49 return 50 } 51 t.Logf("Connecting") 52 client, err := d.Dial() 53 if err != nil { 54 t.Errorf("Dial failed: %v", err) 55 return 56 } 57 t.Logf("Connected client: %d (server %d)", 58 client.LocalProtocol(), client.RemoteProtocol()) 59 t.Logf("Client open: %t", client.IsOpen()) 60 if !client.IsOpen() { 61 t.Error("Client is closed") 62 return 63 } 64 }() 65 66 server, err := l.Accept() 67 if err != nil { 68 t.Errorf("Accept failed: %v", err) 69 return 70 } 71 defer server.Close() 72 73 t.Logf("Connected server: %d (client %d)", 74 server.LocalProtocol(), server.RemoteProtocol()) 75 t.Logf("Server open: %t", server.IsOpen()) 76 if !server.IsOpen() { 77 t.Error("Server is closed") 78 return 79 } 80 } 81 82 func TestTCPAnonymousPort(t *testing.T) { 83 addr := "tcp://127.0.0.1:0" 84 t.Logf("Establishing accepter") 85 l, err := tran.NewListener(addr, sockRep) 86 if err != nil { 87 t.Errorf("NewListener failed: %v", err) 88 return 89 } 90 defer l.Close() 91 if err = l.Listen(); err != nil { 92 t.Errorf("Listen failed: %v", err) 93 return 94 } 95 baddr := l.Address() 96 t.Logf("Bound to %s", baddr) 97 98 go func() { 99 d, err := tran.NewDialer(baddr, sockReq) 100 if err != nil { 101 t.Errorf("NewDialier failed: %v", err) 102 return 103 } 104 t.Logf("Connecting") 105 client, err := d.Dial() 106 if err != nil { 107 t.Errorf("Dial failed: %v", err) 108 return 109 } 110 t.Logf("Connected client: %d (server %d)", 111 client.LocalProtocol(), client.RemoteProtocol()) 112 t.Logf("Client open: %t", client.IsOpen()) 113 if !client.IsOpen() { 114 t.Error("Client is closed") 115 return 116 } 117 }() 118 119 server, err := l.Accept() 120 if err != nil { 121 t.Errorf("Accept failed: %v", err) 122 return 123 } 124 defer server.Close() 125 126 t.Logf("Connected server: %d (client %d)", 127 server.LocalProtocol(), server.RemoteProtocol()) 128 t.Logf("Server open: %t", server.IsOpen()) 129 if !server.IsOpen() { 130 t.Error("Server is closed") 131 return 132 } 133 } 134 135 func TestTCPDuplicateListen(t *testing.T) { 136 addr := "tcp://127.0.0.1:3333" 137 var err error 138 l1, err := tran.NewListener(addr, sockRep) 139 if err != nil { 140 t.Errorf("NewListener failed: %v", err) 141 return 142 } 143 defer l1.Close() 144 if err = l1.Listen(); err != nil { 145 t.Errorf("Listen failed: %v", err) 146 return 147 } 148 149 l2, err := tran.NewListener(addr, sockReq) 150 if err != nil { 151 t.Errorf("NewListener failed: %v", err) 152 return 153 } 154 defer l2.Close() 155 if err = l2.Listen(); err == nil { 156 t.Errorf("Duplicate listen should not be permitted!") 157 return 158 } 159 t.Logf("Got expected error: %v", err) 160 } 161 162 func TestTCPConnRefused(t *testing.T) { 163 addr := "tcp://127.0.0.1:19" // Port 19 is chargen, rarely in use 164 var err error 165 d, err := tran.NewDialer(addr, sockReq) 166 if err != nil || d == nil { 167 t.Errorf("New Dialer failed: %v", err) 168 return 169 } 170 c, err := d.Dial() 171 if err == nil || c != nil { 172 t.Errorf("Connection not refused (%s)!", addr) 173 return 174 } 175 t.Logf("Got expected error: %v", err) 176 } 177 178 func TestTCPSendRecv(t *testing.T) { 179 addr := "tcp://127.0.0.1:3333" 180 ping := []byte("REQUEST_MESSAGE") 181 ack := []byte("RESPONSE_MESSAGE") 182 183 ch := make(chan *mangos.Message) 184 185 t.Logf("Establishing listener") 186 l, err := tran.NewListener(addr, sockRep) 187 if err != nil { 188 t.Errorf("NewListener failed: %v", err) 189 return 190 } 191 defer l.Close() 192 if err = l.Listen(); err != nil { 193 t.Errorf("Listen failed: %v", err) 194 return 195 } 196 197 go func() { 198 defer close(ch) 199 200 // Client side 201 t.Logf("Connecting") 202 d, err := tran.NewDialer(addr, sockReq) 203 204 client, err := d.Dial() 205 if err != nil { 206 t.Errorf("Dial failed: %v", err) 207 return 208 } 209 t.Logf("Connected client: %t", client.IsOpen()) 210 defer client.Close() 211 212 req := mangos.NewMessage(len(ping)) 213 req.Body = append(req.Body, ping...) 214 215 // Now try to send data 216 t.Logf("Sending %d bytes", len(req.Body)) 217 218 err = client.Send(req) 219 if err != nil { 220 t.Errorf("Client send error: %v", err) 221 return 222 } 223 t.Logf("Client sent") 224 225 rep, err := client.Recv() 226 if err != nil { 227 t.Errorf("Client receive error: %v", err) 228 return 229 } 230 231 if !bytes.Equal(rep.Body, ack) { 232 t.Errorf("Reply mismatch: %v, %v", rep.Body, ack) 233 return 234 } 235 if len(rep.Header) != 0 { 236 t.Errorf("Client reply non-empty header: %v", 237 rep.Header) 238 return 239 } 240 select { 241 case ch <- rep: 242 t.Log("Client reply forwarded") 243 case <-time.After(5 * time.Second): // 5 secs should be plenty 244 t.Error("Client timeout forwarding reply") 245 return 246 } 247 }() 248 249 server, err := l.Accept() 250 if err != nil { 251 t.Errorf("Accept failed: %v", err) 252 return 253 } 254 t.Logf("Connected server: %t", server.IsOpen()) 255 defer server.Close() 256 257 // Now we can try to send and receive 258 req, err := server.Recv() 259 if err != nil { 260 t.Errorf("Server receive error: %v", err) 261 return 262 } 263 t.Logf("Server received %d bytes", len(req.Body)) 264 if !bytes.Equal(req.Body, ping) { 265 t.Errorf("Request mismatch: %v, %v", req.Body, ping) 266 return 267 } 268 269 if len(req.Header) != 0 { 270 t.Errorf("Server request non-empty header: %v", req.Header) 271 return 272 } 273 274 // Now reply 275 rep := mangos.NewMessage(len(ack)) 276 rep.Body = append(rep.Body, ack...) 277 278 t.Logf("Server sending %d bytes", len(rep.Body)) 279 280 err = server.Send(rep) 281 if err != nil { 282 t.Errorf("Server send error: %v", err) 283 return 284 } 285 t.Log("Server reply sent") 286 287 // Wait for client to ack reply over back channel. 288 select { 289 case nrep := <-ch: 290 if !bytes.Equal(nrep.Body, ack) { 291 t.Errorf("Client forward mismatch: %v, %v", ack, rep) 292 return 293 } 294 case <-time.After(5 * time.Second): 295 t.Error("Client timeout?") 296 return 297 } 298 } 299 300 func TestTCPOptions(t *testing.T) { 301 addr := "tcp://127.0.0.1:19" // Port 19 is chargen, rarely in use 302 var err error 303 d, err := tran.NewDialer(addr, sockReq) 304 if err != nil || d == nil { 305 t.Errorf("New Dialer failed: %v", err) 306 return 307 } 308 309 t.Logf("Options are %v", interface{}(d).(*dialer).opts) 310 311 // Valid Boolean Options 312 for _, n := range []string{mangos.OptionNoDelay, mangos.OptionKeepAlive} { 313 t.Logf("Checking option %s", n) 314 315 if err := d.SetOption(n, true); err != nil { 316 t.Errorf("Set option %s failed: %v", n, err) 317 return 318 } 319 320 val, err := d.GetOption(n) 321 if err != nil { 322 t.Errorf("Get option %s failed: %v", n, err) 323 return 324 } 325 switch v := val.(type) { 326 case bool: 327 if !v { 328 t.Errorf("Option %s value not true", n) 329 return 330 } 331 default: 332 t.Errorf("Option %s wrong type!", n) 333 return 334 } 335 336 if err = d.SetOption(n, 1234); err != mangos.ErrBadValue { 337 t.Errorf("Expected ErrBadValue, but did not get it") 338 return 339 } 340 } 341 342 // Negative test: try a bad option 343 if err = d.SetOption("NO-SUCH-OPTION", 0); err != mangos.ErrBadOption { 344 t.Errorf("Expected ErrBadOption, but did not get it") 345 return 346 } 347 }