go-micro.dev/v5@v5.12.0/transport/http_transport_test.go (about) 1 package transport 2 3 import ( 4 "errors" 5 "io" 6 "net" 7 "sync" 8 "testing" 9 "time" 10 ) 11 12 func expectedPort(t *testing.T, expected string, lsn Listener) { 13 _, port, err := net.SplitHostPort(lsn.Addr()) 14 if err != nil { 15 t.Errorf("Expected address to be `%s`, got error: %v", expected, err) 16 } 17 18 if port != expected { 19 lsn.Close() 20 t.Errorf("Expected address to be `%s`, got `%s`", expected, port) 21 } 22 } 23 24 func TestHTTPTransportCommunication(t *testing.T) { 25 tr := NewHTTPTransport() 26 27 l, err := tr.Listen("127.0.0.1:0") 28 if err != nil { 29 t.Errorf("Unexpected listen err: %v", err) 30 } 31 defer l.Close() 32 33 fn := func(sock Socket) { 34 defer sock.Close() 35 36 for { 37 var m Message 38 if err := sock.Recv(&m); err != nil { 39 return 40 } 41 42 if err := sock.Send(&m); err != nil { 43 return 44 } 45 } 46 } 47 48 done := make(chan bool) 49 50 go func() { 51 if err := l.Accept(fn); err != nil { 52 select { 53 case <-done: 54 default: 55 t.Errorf("Unexpected accept err: %v", err) 56 } 57 } 58 }() 59 60 c, err := tr.Dial(l.Addr()) 61 if err != nil { 62 t.Errorf("Unexpected dial err: %v", err) 63 } 64 defer c.Close() 65 66 m := Message{ 67 Header: map[string]string{ 68 "Content-Type": "application/json", 69 }, 70 Body: []byte(`{"message": "Hello World"}`), 71 } 72 73 if err := c.Send(&m); err != nil { 74 t.Errorf("Unexpected send err: %v", err) 75 } 76 77 var rm Message 78 79 if err := c.Recv(&rm); err != nil { 80 t.Errorf("Unexpected recv err: %v", err) 81 } 82 83 if string(rm.Body) != string(m.Body) { 84 t.Errorf("Expected %v, got %v", m.Body, rm.Body) 85 } 86 87 close(done) 88 } 89 90 func TestHTTPTransportError(t *testing.T) { 91 tr := NewHTTPTransport() 92 93 l, err := tr.Listen("127.0.0.1:0") 94 if err != nil { 95 t.Errorf("Unexpected listen err: %v", err) 96 } 97 defer l.Close() 98 99 fn := func(sock Socket) { 100 defer sock.Close() 101 102 for { 103 var m Message 104 if err := sock.Recv(&m); err != nil { 105 if errors.Is(err, io.EOF) { 106 return 107 } 108 t.Fatal(err) 109 } 110 111 sock.(*httpTransportSocket).error(&Message{ 112 Body: []byte(`an error occurred`), 113 }) 114 } 115 } 116 117 done := make(chan bool) 118 119 go func() { 120 if err := l.Accept(fn); err != nil { 121 select { 122 case <-done: 123 default: 124 t.Errorf("Unexpected accept err: %v", err) 125 } 126 } 127 }() 128 129 c, err := tr.Dial(l.Addr()) 130 if err != nil { 131 t.Errorf("Unexpected dial err: %v", err) 132 } 133 defer c.Close() 134 135 m := Message{ 136 Header: map[string]string{ 137 "Content-Type": "application/json", 138 }, 139 Body: []byte(`{"message": "Hello World"}`), 140 } 141 142 if err := c.Send(&m); err != nil { 143 t.Errorf("Unexpected send err: %v", err) 144 } 145 146 var rm Message 147 148 err = c.Recv(&rm) 149 if err == nil { 150 t.Fatal("Expected error but got nil") 151 } 152 153 if err.Error() != "500 Internal Server Error: an error occurred" { 154 t.Fatalf("Did not receive expected error, got: %v", err) 155 } 156 157 close(done) 158 } 159 160 func TestHTTPTransportTimeout(t *testing.T) { 161 tr := NewHTTPTransport(Timeout(time.Millisecond * 100)) 162 163 l, err := tr.Listen("127.0.0.1:0") 164 if err != nil { 165 t.Errorf("Unexpected listen err: %v", err) 166 } 167 defer l.Close() 168 169 done := make(chan bool) 170 171 fn := func(sock Socket) { 172 defer func() { 173 sock.Close() 174 close(done) 175 }() 176 177 go func() { 178 select { 179 case <-done: 180 return 181 case <-time.After(time.Second): 182 t.Fatal("deadline not executed") 183 } 184 }() 185 186 for { 187 var m Message 188 189 if err := sock.Recv(&m); err != nil { 190 return 191 } 192 } 193 } 194 195 go func() { 196 if err := l.Accept(fn); err != nil { 197 select { 198 case <-done: 199 default: 200 t.Errorf("Unexpected accept err: %v", err) 201 } 202 } 203 }() 204 205 c, err := tr.Dial(l.Addr()) 206 if err != nil { 207 t.Errorf("Unexpected dial err: %v", err) 208 } 209 defer c.Close() 210 211 m := Message{ 212 Header: map[string]string{ 213 "Content-Type": "application/json", 214 }, 215 Body: []byte(`{"message": "Hello World"}`), 216 } 217 218 if err := c.Send(&m); err != nil { 219 t.Errorf("Unexpected send err: %v", err) 220 } 221 222 <-done 223 } 224 225 func TestHTTPTransportCloseWhenRecv(t *testing.T) { 226 tr := NewHTTPTransport() 227 228 l, err := tr.Listen("127.0.0.1:0") 229 if err != nil { 230 t.Errorf("Unexpected listen err: %v", err) 231 } 232 defer l.Close() 233 234 fn := func(sock Socket) { 235 defer sock.Close() 236 237 for { 238 var m Message 239 if err := sock.Recv(&m); err != nil { 240 return 241 } 242 if err := sock.Send(&m); err != nil { 243 return 244 } 245 } 246 } 247 248 done := make(chan bool) 249 250 go func() { 251 if err := l.Accept(fn); err != nil { 252 select { 253 case <-done: 254 default: 255 t.Errorf("Unexpected accept err: %v", err) 256 } 257 } 258 }() 259 260 c, err := tr.Dial(l.Addr()) 261 if err != nil { 262 t.Errorf("Unexpected dial err: %v", err) 263 } 264 defer c.Close() 265 266 m := Message{ 267 Header: map[string]string{ 268 "Content-Type": "application/json", 269 }, 270 Body: []byte(`{"message": "Hello World"}`), 271 } 272 var wg sync.WaitGroup 273 wg.Add(1) 274 go func() { 275 defer wg.Done() 276 for { 277 var rm Message 278 279 if err := c.Recv(&rm); err != nil { 280 if err == io.EOF { 281 return 282 } 283 } 284 } 285 }() 286 for i := 1; i < 3; i++ { 287 if err := c.Send(&m); err != nil { 288 t.Errorf("Unexpected send err: %v", err) 289 } 290 } 291 close(done) 292 293 c.Close() 294 wg.Wait() 295 } 296 297 func TestHTTPTransportMultipleSendWhenRecv(t *testing.T) { 298 tr := NewHTTPTransport() 299 300 l, err := tr.Listen("127.0.0.1:0") 301 if err != nil { 302 t.Errorf("Unexpected listen err: %v", err) 303 } 304 defer l.Close() 305 306 readyToSend := make(chan struct{}) 307 m := Message{ 308 Header: map[string]string{ 309 "Content-Type": "application/json", 310 }, 311 Body: []byte(`{"message": "Hello World"}`), 312 } 313 314 var wgSend sync.WaitGroup 315 fn := func(sock Socket) { 316 defer sock.Close() 317 318 for { 319 var mr Message 320 if err := sock.Recv(&mr); err != nil { 321 return 322 } 323 go func() { 324 defer wgSend.Done() 325 <-readyToSend 326 if err := sock.Send(&m); err != nil { 327 return 328 } 329 }() 330 } 331 } 332 333 done := make(chan bool) 334 335 go func() { 336 if err := l.Accept(fn); err != nil { 337 select { 338 case <-done: 339 default: 340 t.Errorf("Unexpected accept err: %v", err) 341 } 342 } 343 }() 344 345 c, err := tr.Dial(l.Addr(), WithStream()) 346 if err != nil { 347 t.Errorf("Unexpected dial err: %v", err) 348 } 349 defer c.Close() 350 351 var wg sync.WaitGroup 352 wg.Add(1) 353 readyForRecv := make(chan struct{}) 354 go func() { 355 defer wg.Done() 356 close(readyForRecv) 357 for { 358 var rm Message 359 if err := c.Recv(&rm); err != nil { 360 if err == io.EOF { 361 return 362 } 363 } 364 } 365 }() 366 wgSend.Add(3) 367 <-readyForRecv 368 for i := 0; i < 3; i++ { 369 if err := c.Send(&m); err != nil { 370 t.Errorf("Unexpected send err: %v", err) 371 } 372 } 373 close(readyToSend) 374 wgSend.Wait() 375 close(done) 376 377 c.Close() 378 wg.Wait() 379 } 380 381 func TestHttpTransportListenerNetListener(t *testing.T) { 382 address := "127.0.0.1:0" 383 384 customListener, err := net.Listen("tcp", address) 385 if err != nil { 386 return 387 } 388 389 tr := NewHTTPTransport(Timeout(time.Millisecond * 100)) 390 391 // injection 392 l, err := tr.Listen(address, NetListener(customListener)) 393 if err != nil { 394 t.Errorf("Unexpected listen err: %v", err) 395 } 396 defer l.Close() 397 398 done := make(chan bool) 399 400 fn := func(sock Socket) { 401 defer func() { 402 sock.Close() 403 close(done) 404 }() 405 406 go func() { 407 select { 408 case <-done: 409 return 410 case <-time.After(time.Second): 411 t.Fatal("deadline not executed") 412 } 413 }() 414 415 for { 416 var m Message 417 418 if err := sock.Recv(&m); err != nil { 419 return 420 } 421 } 422 } 423 424 go func() { 425 if err := l.Accept(fn); err != nil { 426 select { 427 case <-done: 428 default: 429 t.Errorf("Unexpected accept err: %v", err) 430 } 431 } 432 }() 433 434 c, err := tr.Dial(l.Addr()) 435 if err != nil { 436 t.Errorf("Unexpected dial err: %v", err) 437 } 438 defer c.Close() 439 440 m := Message{ 441 Header: map[string]string{ 442 "Content-Type": "application/json", 443 }, 444 Body: []byte(`{"message": "Hello World"}`), 445 } 446 447 if err := c.Send(&m); err != nil { 448 t.Errorf("Unexpected send err: %v", err) 449 } 450 451 <-done 452 }