go.uber.org/yarpc@v1.72.1/internal/net/httpserver_test.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package net 22 23 import ( 24 "context" 25 "net" 26 "net/http" 27 "os" 28 "syscall" 29 "testing" 30 "time" 31 32 "github.com/stretchr/testify/assert" 33 "github.com/stretchr/testify/require" 34 "go.uber.org/yarpc/internal/testtime" 35 "go.uber.org/yarpc/internal/yarpctest" 36 ) 37 38 func TestServeAndShutdown(t *testing.T) { 39 address := "127.0.0.1:0" 40 lis, err := net.Listen("tcp", address) 41 require.NoError(t, err) 42 43 server := NewHTTPServer(&http.Server{Addr: address}) 44 require.NoError(t, server.Serve(lis)) 45 require.NotNil(t, server.Listener()) 46 47 require.Error(t, server.Serve(lis)) // must fail on second serve 48 49 addr := yarpctest.ZeroAddrToHostPort(server.Listener().Addr()) 50 conn, err := net.Dial("tcp", addr) 51 require.NoError(t, err) 52 require.NoError(t, conn.Close()) 53 54 require.NoError(t, server.Shutdown(context.Background())) 55 _, err = net.Dial("tcp", addr) 56 require.Error(t, err) 57 } 58 59 func TestStartAndShutdown(t *testing.T) { 60 server := NewHTTPServer(&http.Server{Addr: "127.0.0.1:0"}) 61 require.NoError(t, server.ListenAndServe()) 62 63 require.NotNil(t, server.Listener()) 64 addr := yarpctest.ZeroAddrToHostPort(server.Listener().Addr()) 65 66 conn, err := net.Dial("tcp", addr) 67 require.NoError(t, err) 68 require.NoError(t, conn.Close()) 69 70 require.NoError(t, server.Shutdown(context.Background())) 71 _, err = net.Dial("tcp", addr) 72 require.Error(t, err) 73 } 74 75 func TestStartAddrInUse(t *testing.T) { 76 s1 := NewHTTPServer(&http.Server{Addr: "127.0.0.1:0"}) 77 require.NoError(t, s1.ListenAndServe()) 78 defer s1.Shutdown(context.Background()) 79 80 addr := yarpctest.ZeroAddrToHostPort(s1.Listener().Addr()) 81 s2 := NewHTTPServer(&http.Server{Addr: addr}) 82 err := s2.ListenAndServe() 83 84 require.Error(t, err) 85 oe, ok := err.(*net.OpError) 86 assert.True(t, ok && oe.Op == "listen", "expected a listen error") 87 if ok { 88 se, ok := oe.Err.(*os.SyscallError) 89 assert.True(t, ok && se.Syscall == "bind" && se.Err == syscall.EADDRINUSE, "expected a EADDRINUSE bind error") 90 } 91 } 92 func TestShutdownAndListen(t *testing.T) { 93 server := NewHTTPServer(&http.Server{Addr: "127.0.0.1:0"}) 94 require.NoError(t, server.ListenAndServe()) 95 require.NoError(t, server.Shutdown(context.Background())) 96 require.Error(t, server.ListenAndServe()) 97 } 98 99 func TestShutdownWithoutStart(t *testing.T) { 100 server := NewHTTPServer(&http.Server{Addr: "127.0.0.1:0"}) 101 require.NoError(t, server.Shutdown(context.Background())) 102 } 103 104 func TestStartTwice(t *testing.T) { 105 server := NewHTTPServer(&http.Server{Addr: "127.0.0.1:0"}) 106 require.NoError(t, server.ListenAndServe()) 107 require.Error(t, server.ListenAndServe()) 108 require.NoError(t, server.Shutdown(context.Background())) 109 } 110 111 func TestShutdownTwice(t *testing.T) { 112 server := NewHTTPServer(&http.Server{Addr: "127.0.0.1:0"}) 113 require.NoError(t, server.ListenAndServe()) 114 require.NoError(t, server.Shutdown(context.Background())) 115 require.NoError(t, server.Shutdown(context.Background())) 116 } 117 118 func TestListenFail(t *testing.T) { 119 server := NewHTTPServer(&http.Server{Addr: "invalid"}) 120 require.Error(t, server.ListenAndServe()) 121 } 122 123 func TestShutdownError(t *testing.T) { 124 server := NewHTTPServer(&http.Server{Addr: "127.0.0.1:0"}) 125 require.NoError(t, server.ListenAndServe()) 126 require.NoError(t, server.Listener().Close()) 127 time.Sleep(5 * testtime.Millisecond) 128 require.Error(t, server.Shutdown(context.Background())) 129 }