github.com/searKing/golang/go@v1.2.74/net/mux/server_test.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package mux_test 6 7 import ( 8 "context" 9 "io" 10 "log" 11 "net" 12 "strings" 13 "sync" 14 "sync/atomic" 15 "testing" 16 "time" 17 18 "github.com/searKing/golang/go/net/mux" 19 "github.com/searKing/golang/go/testing/leakcheck" 20 21 "golang.org/x/net/http2" 22 ) 23 24 const ( 25 handleHTTP1Close = 1 26 handleHTTP1Request = 2 27 handleAnyClose = 3 28 handleAnyRequest = 4 29 ) 30 31 func TestTimeout(t *testing.T) { 32 defer leakcheck.Check(t) 33 loopbackLis := testListener(t) 34 defer loopbackLis.Close() 35 result := make(chan int, 5) 36 testDuration := time.Millisecond * 500 37 srv := mux.NewServer() 38 39 mux.DefaultServeMux.SetReadTimeout(testDuration) 40 41 http1Listener := mux.HandleListener(mux.HTTP1Fast()) 42 defer http1Listener.Close() 43 anyListener := mux.HandleListener(mux.Any()) 44 defer anyListener.Close() 45 46 ctx, cancelFn := context.WithCancel(context.TODO()) 47 defer cancelFn() 48 go func() { 49 _ = srv.Serve(loopbackLis) 50 }() 51 go func() { 52 for { 53 select { 54 case <-ctx.Done(): 55 return 56 default: 57 } 58 con, err := http1Listener.Accept() 59 if err != nil { 60 result <- handleHTTP1Close 61 } else { 62 _, _ = con.Write([]byte("http1Listener")) 63 result <- handleHTTP1Request 64 select { 65 case <-ctx.Done(): 66 break 67 } 68 _ = con.Close() 69 } 70 select { 71 case <-ctx.Done(): 72 return 73 } 74 } 75 }() 76 go func() { 77 for { 78 select { 79 case <-ctx.Done(): 80 return 81 default: 82 } 83 con, err := anyListener.Accept() 84 if err != nil { 85 result <- handleAnyClose 86 } else { 87 _, err = con.Write([]byte("any")) 88 result <- handleAnyRequest 89 select { 90 case <-ctx.Done(): 91 break 92 } 93 _ = con.Close() 94 } 95 } 96 }() 97 time.Sleep(testDuration) // wait to prevent timeouts on slow test-runners 98 client, err := net.Dial("tcp", loopbackLis.Addr().String()) 99 if err != nil { 100 log.Fatal("testTimeout client failed: ", err) 101 } 102 defer client.Close() 103 time.Sleep(testDuration / 2) 104 if len(result) != 0 { 105 log.Print("tcp ") 106 t.Fatal("testTimeout failed: accepted to fast: ", len(result)) 107 } 108 //_ = client.SetReadDeadline(time.Now().Add(testDuration * 3)) 109 buffer := make([]byte, 10) 110 rl, err := client.Read(buffer) 111 if err != nil { 112 t.Fatal("testTimeout failed: client error: ", err, rl) 113 } 114 _ = srv.Close() 115 if rl != len("any") { 116 log.Print("testTimeout failed: response from wrong service ", rl) 117 } 118 if string(buffer[0:3]) != "any" { 119 log.Print("testTimeout failed: response from wrong service ") 120 } 121 time.Sleep(testDuration * 2) 122 if len(result) != 2 { 123 t.Fatal("testTimeout failed: accepted to less: ", len(result)) 124 } 125 if a := <-result; a != handleAnyRequest { 126 t.Fatal("testTimeout failed: anyListener rule did not match") 127 } 128 if a := <-result; a != handleHTTP1Close { 129 t.Fatal("testTimeout failed: no close an http rule") 130 } 131 } 132 133 func TestRead(t *testing.T) { 134 defer leakcheck.Check(t) 135 errCh := make(chan error) 136 defer func() { 137 select { 138 case err := <-errCh: 139 t.Fatal(err) 140 default: 141 } 142 }() 143 const payload = "hello world\r\n" 144 const mult = 2 145 146 writer, reader := net.Pipe() 147 go func() { 148 if _, err := io.WriteString(writer, strings.Repeat(payload, mult)); err != nil { 149 t.Fatal(err) 150 } 151 if err := writer.Close(); err != nil { 152 t.Fatal(err) 153 } 154 }() 155 156 l := newChanListener() 157 l.Notify(reader) 158 defer l.Close() 159 srv := mux.NewServer() 160 defer srv.Close() 161 162 // Register a bogus matcher to force buffering exactly the right amount. 163 // Before this fix, this would trigger a bug where `Read` would incorrectly 164 // report `io.EOF` when only the buffer had been consumed. 165 _ = mux.HandleListener(mux.MatcherFunc(func(w io.Writer, r io.Reader) bool { 166 var b [len(payload)]byte 167 _, _ = r.Read(b[:]) 168 return false 169 })) 170 anyl := mux.HandleListener(mux.Any()) 171 go safeServe(errCh, srv, l) 172 muxedConn, err := anyl.Accept() 173 if err != nil { 174 t.Fatal(err) 175 } 176 for i := 0; i < mult; i++ { 177 var b [len(payload)]byte 178 n, err := muxedConn.Read(b[:]) 179 if err != nil { 180 t.Error(err) 181 continue 182 } 183 if e := len(b); n != e { 184 t.Errorf("expected to read %d bytes, but read %d bytes", e, n) 185 } 186 } 187 var b [1]byte 188 if _, err := muxedConn.Read(b[:]); err != io.EOF { 189 t.Errorf("unexpected error %v, expected %v", err, io.EOF) 190 } 191 192 } 193 194 func TestAny(t *testing.T) { 195 defer leakcheck.Check(t) 196 errCh := make(chan error, 5) 197 defer func() { 198 for { 199 select { 200 case err, ok := <-errCh: 201 if !ok { 202 return 203 } 204 t.Fatal(err) 205 default: 206 close(errCh) 207 return 208 } 209 } 210 }() 211 l := testListener(t) 212 defer l.Close() 213 214 var wg sync.WaitGroup 215 func() { 216 srv := mux.NewServer() 217 defer srv.Close() 218 219 httpl := mux.HandleListener(mux.Any()) 220 wg.Add(1) 221 go func() { 222 defer wg.Done() 223 runTestHTTPServer(errCh, httpl) 224 }() 225 wg.Add(1) 226 go func() { 227 defer wg.Done() 228 safeServe(errCh, srv, l) 229 }() 230 runTestHTTP1Client(t, l.Addr()) 231 }() 232 wg.Wait() 233 } 234 235 func TestTLS(t *testing.T) { 236 generateTLSCert(t) 237 defer cleanupTLSCert(t) 238 defer leakcheck.Check(t) 239 errCh := make(chan error) 240 defer func() { 241 for { 242 select { 243 case err, ok := <-errCh: 244 if !ok { 245 return 246 } 247 t.Fatal(err) 248 default: 249 close(errCh) 250 return 251 } 252 } 253 }() 254 l := testListener(t) 255 defer l.Close() 256 257 srv := mux.NewServer() 258 defer srv.Close() 259 260 tlsl := mux.HandleListener(mux.TLS()) 261 httpl := mux.HandleListener(mux.Any()) 262 263 go runTestTLSServer(errCh, tlsl) 264 go runTestHTTPServer(errCh, httpl) 265 go safeServe(errCh, srv, l) 266 267 runTestHTTP1Client(t, l.Addr()) 268 runTestTLSClient(t, l.Addr()) 269 } 270 271 func TestHTTP2(t *testing.T) { 272 defer leakcheck.Check(t) 273 errCh := make(chan error) 274 defer func() { 275 for { 276 select { 277 case err, ok := <-errCh: 278 if !ok { 279 return 280 } 281 t.Fatal(err) 282 default: 283 close(errCh) 284 return 285 } 286 } 287 }() 288 writer, reader := net.Pipe() 289 go func() { 290 if _, err := io.WriteString(writer, http2.ClientPreface); err != nil { 291 t.Fatal(err) 292 } 293 if err := writer.Close(); err != nil { 294 t.Fatal(err) 295 } 296 }() 297 298 l := newChanListener() 299 l.Notify(reader) 300 srv := mux.NewServer() 301 defer srv.Close() 302 303 // Register a bogus matcher that only reads one byte. 304 mux.HandleListener(mux.MatcherFunc(func(w io.Writer, r io.Reader) bool { 305 var b [1]byte 306 _, _ = r.Read(b[:]) 307 return false 308 })) 309 h2l := mux.HandleListener(mux.HTTP2()) 310 go safeServe(errCh, srv, l) 311 muxedConn, err := h2l.Accept() 312 _ = l.Close() 313 if err != nil { 314 t.Fatal(err) 315 } 316 var b [len(http2.ClientPreface)]byte 317 var n int 318 // We have the sniffed buffer first... 319 if n, err = muxedConn.Read(b[:]); err == io.EOF { 320 t.Fatal(err) 321 } 322 // and then we read from the source. 323 if _, err = muxedConn.Read(b[n:]); err != nil && err != io.EOF { 324 t.Fatal(err) 325 } 326 if string(b[:]) != http2.ClientPreface { 327 t.Errorf("got unexpected read %s, expected %s", b, http2.ClientPreface) 328 } 329 } 330 331 func TestHTTP2MatchHeaderField(t *testing.T) { 332 testHTTP2HeaderField(t, mux.HTTP2HeaderFieldEqual, "value", "value", "anothervalue") 333 } 334 335 func TestHTTP2MatchHeaderFieldPrefix(t *testing.T) { 336 testHTTP2HeaderField(t, mux.HTTP2HeaderFieldPrefix, "application/grpc+proto", "application/grpc", "application/json") 337 } 338 339 func TestHTTPGoRPC(t *testing.T) { 340 defer leakcheck.Check(t) 341 errCh := make(chan error) 342 defer func() { 343 for { 344 select { 345 case err, ok := <-errCh: 346 if !ok { 347 return 348 } 349 t.Fatal(err) 350 default: 351 close(errCh) 352 return 353 } 354 } 355 }() 356 l := testListener(t) 357 defer l.Close() 358 359 srv := mux.NewServer() 360 defer srv.Close() 361 362 httpl := mux.HandleListener(mux.MatcherAny(mux.HTTP2(), mux.HTTP1Fast())) 363 364 rpcl := mux.HandleListener(mux.Any()) 365 366 go runTestHTTPServer(errCh, httpl) 367 go runTestRPCServer(errCh, rpcl) 368 go safeServe(errCh, srv, l) 369 370 runTestHTTP1Client(t, l.Addr()) 371 runTestRPCClient(t, l.Addr()) 372 } 373 374 func TestErrorHandler(t *testing.T) { 375 defer leakcheck.Check(t) 376 errCh := make(chan error) 377 defer func() { 378 for { 379 select { 380 case err, ok := <-errCh: 381 if !ok { 382 return 383 } 384 t.Fatal(err) 385 default: 386 close(errCh) 387 return 388 } 389 } 390 }() 391 l := testListener(t) 392 393 srv := mux.NewServer() 394 defer srv.Close() 395 396 httpl := mux.HandleListener(mux.MatcherAny(mux.HTTP2(), mux.HTTP1Fast())) 397 398 go runTestHTTPServer(errCh, httpl) 399 go safeServe(errCh, srv, l) 400 401 var errCount uint32 402 srv.HandleError(mux.ErrorHandlerFunc(func(err error) bool { 403 if atomic.AddUint32(&errCount, 1) == 1 { 404 t.Logf("expected error: %v", err) 405 } 406 return true 407 })) 408 409 //runTestRPCClient(t, l.Addr()) 410 c, clean := safeDial(t, l.Addr()) 411 defer clean() 412 413 l.Close() 414 415 var num int 416 for atomic.LoadUint32(&errCount) == 0 { 417 if err := c.Call("TestRPCRcvr.Test", rpcVal, &num); err == nil { 418 // The connection is simply closed. 419 t.Errorf("unexpected rpc success after %d errors", atomic.LoadUint32(&errCount)) 420 } 421 } 422 } 423 424 func TestMultipleMatchers(t *testing.T) { 425 defer leakcheck.Check(t) 426 errCh := make(chan error) 427 defer func() { 428 for { 429 select { 430 case err, ok := <-errCh: 431 if !ok { 432 return 433 } 434 t.Fatal(err) 435 default: 436 close(errCh) 437 return 438 } 439 } 440 }() 441 l := testListener(t) 442 defer l.Close() 443 444 matcher := func(w io.Writer, r io.Reader) bool { 445 return true 446 } 447 unmatcher := func(w io.Writer, r io.Reader) bool { 448 return false 449 } 450 451 srv := mux.NewServer() 452 defer srv.Close() 453 454 lis := mux.HandleListener(mux.MatcherAny(mux.MatcherFunc(unmatcher), mux.MatcherFunc(matcher), mux.MatcherFunc(unmatcher))) 455 456 go runTestHTTPServer(errCh, lis) 457 go safeServe(errCh, srv, l) 458 459 runTestHTTP1Client(t, l.Addr()) 460 } 461 462 func TestClose(t *testing.T) { 463 defer leakcheck.Check(t) 464 errCh := make(chan error) 465 defer func() { 466 for { 467 select { 468 case err, ok := <-errCh: 469 if !ok { 470 return 471 } 472 t.Fatal(err) 473 default: 474 close(errCh) 475 return 476 } 477 } 478 }() 479 l := newChanListener() 480 481 c1, c2 := net.Pipe() 482 483 srv := mux.NewServer() 484 defer srv.Close() 485 486 anyl := mux.HandleListener(mux.Any()) 487 488 go safeServe(errCh, srv, l) 489 490 l.Notify(c1) 491 492 // First connection goes through. 493 if _, err := anyl.Accept(); err != nil { 494 t.Fatal(err) 495 } 496 497 // Second connection is sent 498 l.Notify(c2) 499 500 // Listener is closed. 501 l.Close() 502 503 // Second connection either goes through or it is closed. 504 if _, err := anyl.Accept(); err != nil { 505 if err != mux.ErrListenerClosed { 506 t.Fatal(err) 507 } 508 // The error is either io.ErrClosedPipe or net.OpError wrapping 509 // a net.pipeError depending on the go version. 510 if _, err := c2.Read([]byte{}); !strings.Contains(err.Error(), "closed") { 511 t.Fatalf("connection is not closed and is leaked: %v", err) 512 } 513 } 514 }