github.com/gdamore/mangos@v1.4.0/test/device_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 test 16 17 import ( 18 "strings" 19 "testing" 20 "time" 21 22 "nanomsg.org/go-mangos" 23 "nanomsg.org/go-mangos/protocol/pair" 24 "nanomsg.org/go-mangos/protocol/rep" 25 "nanomsg.org/go-mangos/protocol/req" 26 "nanomsg.org/go-mangos/transport/inproc" 27 "nanomsg.org/go-mangos/transport/ipc" 28 "nanomsg.org/go-mangos/transport/tcp" 29 "nanomsg.org/go-mangos/transport/tlstcp" 30 "nanomsg.org/go-mangos/transport/ws" 31 "nanomsg.org/go-mangos/transport/wss" 32 ) 33 34 func TestDeviceBadPair(t *testing.T) { 35 s1, err := req.NewSocket() 36 if err != nil { 37 t.Errorf("Failed to open S1: %v", err) 38 return 39 } 40 defer s1.Close() 41 s2, err := pair.NewSocket() 42 if err != nil { 43 t.Errorf("Failed to open S2: %v", err) 44 return 45 } 46 defer s2.Close() 47 48 switch err := mangos.Device(s1, s2); err { 49 case mangos.ErrBadProto: 50 t.Logf("Got expected err: %v", err) 51 return 52 case nil: 53 t.Errorf("Matching incompatible types succeeded") 54 return 55 default: 56 t.Errorf("Got unexpected err: %v", err) 57 return 58 } 59 } 60 61 func TestDeviceBadSingle(t *testing.T) { 62 s1, err := req.NewSocket() 63 if err != nil { 64 t.Errorf("Failed to open S1: %v", err) 65 return 66 } 67 defer s1.Close() 68 69 switch err := mangos.Device(s1, s1); err { 70 case mangos.ErrBadProto: 71 t.Logf("Got expected err: %v", err) 72 return 73 case nil: 74 t.Errorf("Matching incompatible types succeeded") 75 return 76 default: 77 t.Errorf("Got unexpected err: %v", err) 78 return 79 } 80 } 81 82 func TestDeviceFirstNil(t *testing.T) { 83 s1, err := pair.NewSocket() 84 if err != nil { 85 t.Errorf("Failed to open S1: %v", err) 86 return 87 } 88 defer s1.Close() 89 90 switch err := mangos.Device(nil, s1); err { 91 case nil: 92 t.Logf("Ok!") 93 return 94 default: 95 t.Errorf("Got unexpected err: %v", err) 96 return 97 } 98 } 99 100 func TestDeviceSecondNil(t *testing.T) { 101 s1, err := pair.NewSocket() 102 if err != nil { 103 t.Errorf("Failed to open S1: %v", err) 104 return 105 } 106 defer s1.Close() 107 108 switch err := mangos.Device(s1, nil); err { 109 case nil: 110 t.Logf("Ok!") 111 return 112 default: 113 t.Errorf("Got unexpected err: %v", err) 114 return 115 } 116 } 117 118 func TestDeviceBothNil(t *testing.T) { 119 switch err := mangos.Device(nil, nil); err { 120 case mangos.ErrClosed: 121 t.Logf("Got expected err: %v", err) 122 return 123 case nil: 124 t.Errorf("Matching incompatible types succeeded") 125 return 126 default: 127 t.Errorf("Got unexpected err: %v", err) 128 return 129 } 130 } 131 132 func TestDeviceReqRep(t *testing.T) { 133 s1, err := req.NewSocket() 134 if err != nil { 135 t.Errorf("Failed to open S1: %v", err) 136 return 137 } 138 defer s1.Close() 139 s2, err := rep.NewSocket() 140 if err != nil { 141 t.Errorf("Failed to open S2: %v", err) 142 return 143 } 144 defer s2.Close() 145 146 switch err := mangos.Device(s1, s2); err { 147 case nil: 148 t.Logf("Matching req/rep ok!") 149 return 150 default: 151 t.Errorf("Got unexpected err: %v", err) 152 return 153 } 154 } 155 156 // TODO: Add fanout and concurrency testing. 157 type devTest struct { 158 T 159 } 160 161 func (dt *devTest) Init(t *testing.T, addr string) bool { 162 var err error 163 if dt.Sock, err = pair.NewSocket(); err != nil { 164 t.Fatalf("pair.NewSocket(): %v", err) 165 } 166 return dt.T.Init(t, addr) 167 } 168 169 func (dt *devTest) SendHook(m *mangos.Message) bool { 170 m.Body = append(m.Body, byte(dt.GetSend())) 171 return dt.T.SendHook(m) 172 } 173 174 func (dt *devTest) RecvHook(m *mangos.Message) bool { 175 if len(m.Body) != 1 { 176 dt.Errorf("Recv message length %d != 1", len(m.Body)) 177 return false 178 } 179 if m.Body[0] != byte(dt.GetRecv()) { 180 dt.Errorf("Wrong message: %d != %d", m.Body[0], byte(dt.GetRecv())) 181 return false 182 } 183 return dt.T.RecvHook(m) 184 } 185 186 func deviceCaseClient() []TestCase { 187 dev := &devTest{} 188 dev.ID = 0 189 dev.MsgSize = 4 190 dev.WantTx = 50 191 dev.WantRx = 50 192 cases := []TestCase{dev} 193 return cases 194 } 195 196 func testDevLoop(t *testing.T, addr string) { 197 s1, err := pair.NewSocket() 198 if err != nil { 199 t.Errorf("Failed to open S1: %v", err) 200 return 201 } 202 defer s1.Close() 203 s1.AddTransport(tcp.NewTransport()) 204 s1.AddTransport(inproc.NewTransport()) 205 s1.AddTransport(ipc.NewTransport()) 206 s1.AddTransport(tlstcp.NewTransport()) 207 s1.AddTransport(ws.NewTransport()) 208 s1.AddTransport(wss.NewTransport()) 209 210 options := make(map[string]interface{}) 211 if strings.HasPrefix(addr, "wss://") || strings.HasPrefix(addr, "tls+tcp://") { 212 options[mangos.OptionTLSConfig] = srvCfg 213 } 214 215 if err := s1.ListenOptions(addr, options); err != nil { 216 t.Errorf("Failed listening to %s: %v", addr, err) 217 return 218 } 219 220 if err := mangos.Device(s1, s1); err != nil { 221 t.Errorf("Device failed: %v", err) 222 return 223 } 224 225 RunTests(t, addr, deviceCaseClient()) 226 } 227 228 func testDevChain(t *testing.T, addr1 string, addr2 string, addr3 string) { 229 // This tests using multiple devices across a few transports. 230 // It looks like this: addr1->addr2->addr3 <==> addr3->addr2->addr1 231 var err error 232 s := make([]mangos.Socket, 5) 233 for i := 0; i < 5; i++ { 234 if s[i], err = pair.NewSocket(); err != nil { 235 t.Errorf("Failed to open S1_1: %v", err) 236 return 237 } 238 defer s[i].Close() 239 s[i].AddTransport(tcp.NewTransport()) 240 s[i].AddTransport(inproc.NewTransport()) 241 s[i].AddTransport(tlstcp.NewTransport()) 242 s[i].AddTransport(ipc.NewTransport()) 243 s[i].AddTransport(ws.NewTransport()) 244 } 245 246 if err = s[0].Listen(addr1); err != nil { 247 t.Errorf("s[0] Listen: %v", err) 248 return 249 } 250 if err = s[1].Dial(addr2); err != nil { 251 t.Errorf("s[1] Dial: %v", err) 252 return 253 } 254 if err = s[2].Listen(addr2); err != nil { 255 t.Errorf("s[2] Listen: %v", err) 256 return 257 } 258 if err = s[3].Dial(addr3); err != nil { 259 t.Errorf("s[3] Dial: %v", err) 260 return 261 } 262 if err = s[4].Listen(addr3); err != nil { 263 t.Errorf("s[4] Listen: %v", err) 264 return 265 } 266 if err = mangos.Device(s[0], s[1]); err != nil { 267 t.Errorf("s[0],s[1] Device: %v", err) 268 return 269 } 270 if err = mangos.Device(s[2], s[3]); err != nil { 271 t.Errorf("s[2],s[3] Device: %v", err) 272 return 273 } 274 if err = mangos.Device(s[4], nil); err != nil { 275 t.Errorf("s[4] Device: %v", err) 276 return 277 } 278 RunTests(t, addr1, deviceCaseClient()) 279 } 280 281 func TestDeviceChain(t *testing.T) { 282 testDevChain(t, AddrTestTCP, AddrTestWS, AddrTestInp) 283 // Some platforms (windows) need a little time to wind up the close 284 time.Sleep(100 * time.Millisecond) 285 } 286 287 func TestDeviceLoopTCP(t *testing.T) { 288 testDevLoop(t, AddrTestTCP) 289 } 290 291 func TestDeviceLoopInp(t *testing.T) { 292 testDevLoop(t, AddrTestInp) 293 } 294 295 func TestDeviceLoopIPC(t *testing.T) { 296 testDevLoop(t, AddrTestIPC) 297 } 298 299 func TestDeviceLoopTLS(t *testing.T) { 300 testDevLoop(t, AddrTestTLS) 301 } 302 303 func TestDeviceLoopWS(t *testing.T) { 304 testDevLoop(t, AddrTestWS) 305 } 306 307 func TestDeviceLoopWSS(t *testing.T) { 308 testDevLoop(t, AddrTestWSS) 309 }