diff --git a/agent/consul/authmethod/kubeauth/testing.go b/agent/consul/authmethod/kubeauth/testing.go index 7e6340dd9..08c5cdad6 100644 --- a/agent/consul/authmethod/kubeauth/testing.go +++ b/agent/consul/authmethod/kubeauth/testing.go @@ -4,16 +4,21 @@ import ( "bytes" "encoding/json" "encoding/pem" + "fmt" "io/ioutil" + "log" + "net" "net/http" "net/http/httptest" "net/url" "regexp" + "strconv" "strings" "sync" - "testing" "time" + "github.com/hashicorp/consul/sdk/freeport" + "github.com/mitchellh/go-testing-interface" "github.com/stretchr/testify/require" authv1 "k8s.io/api/authentication/v1" corev1 "k8s.io/api/core/v1" @@ -28,9 +33,9 @@ import ( // - GET /api/v1/namespaces//serviceaccounts/ // type TestAPIServer struct { - t *testing.T - srv *httptest.Server - caCert string + srv *httptest.Server + caCert string + returnFunc func() mu sync.Mutex authorizedJWT string // token review and sa read @@ -41,10 +46,16 @@ type TestAPIServer struct { // StartTestAPIServer creates a disposable TestAPIServer and binds it to a // random free port. -func StartTestAPIServer(t *testing.T) *TestAPIServer { - s := &TestAPIServer{t: t} +func StartTestAPIServer(t testing.T) *TestAPIServer { + s := &TestAPIServer{} - s.srv = httptest.NewTLSServer(s) + ports := freeport.MustTake(1) + s.returnFunc = func() { + freeport.Return(ports) + } + s.srv = httptestNewUnstartedServerWithPort(s, ports[0]) + s.srv.Config.ErrorLog = log.New(ioutil.Discard, "", 0) + s.srv.StartTLS() bs := s.srv.TLS.Certificates[0].Certificate[0] @@ -90,6 +101,10 @@ func (s *TestAPIServer) SetAllowedServiceAccount( // Stop stops the running TestAPIServer. func (s *TestAPIServer) Stop() { s.srv.Close() + if s.returnFunc != nil { + s.returnFunc() + s.returnFunc = nil + } } // Addr returns the current base URL for the running webserver. @@ -530,3 +545,19 @@ func createStatus(status, message string, reason metav1.StatusReason, details *m Code: code, } } + +func httptestNewUnstartedServerWithPort(handler http.Handler, port int) *httptest.Server { + if port == 0 { + return httptest.NewUnstartedServer(handler) + } + addr := net.JoinHostPort("127.0.0.1", strconv.Itoa(port)) + l, err := net.Listen("tcp", addr) + if err != nil { + panic(fmt.Sprintf("httptest: failed to listen on a port: %v", err)) + } + + return &httptest.Server{ + Listener: l, + Config: &http.Server{Handler: handler}, + } +}