testing: use the new freeport interfaces

This commit is contained in:
Daniel Nephin 2021-11-27 15:27:59 -05:00
parent 56f9238d15
commit d795a73f78
14 changed files with 55 additions and 146 deletions

View File

@ -1737,11 +1737,7 @@ func TestAgent_RestoreServiceWithAliasCheck(t *testing.T) {
testCtx, testCancel := context.WithCancel(context.Background()) testCtx, testCancel := context.WithCancel(context.Background())
defer testCancel() defer testCancel()
testHTTPServer, returnPort := launchHTTPCheckServer(t, testCtx) testHTTPServer := launchHTTPCheckServer(t, testCtx)
defer func() {
testHTTPServer.Close()
returnPort()
}()
registerServicesAndChecks := func(t *testing.T, a *TestAgent) { registerServicesAndChecks := func(t *testing.T, a *TestAgent) {
// add one persistent service with a simple check // add one persistent service with a simple check
@ -1846,11 +1842,8 @@ node_name = "` + a.Config.NodeName + `"
} }
} }
func launchHTTPCheckServer(t *testing.T, ctx context.Context) (srv *httptest.Server, returnPortsFn func()) { func launchHTTPCheckServer(t *testing.T, ctx context.Context) *httptest.Server {
ports := freeport.MustTake(1) addr := net.JoinHostPort("127.0.0.1", strconv.Itoa(freeport.Port(t)))
port := ports[0]
addr := net.JoinHostPort("127.0.0.1", strconv.Itoa(port))
var lc net.ListenConfig var lc net.ListenConfig
listener, err := lc.Listen(ctx, "tcp", addr) listener, err := lc.Listen(ctx, "tcp", addr)
@ -1861,12 +1854,13 @@ func launchHTTPCheckServer(t *testing.T, ctx context.Context) (srv *httptest.Ser
_, _ = w.Write([]byte("OK\n")) _, _ = w.Write([]byte("OK\n"))
}) })
srv = &httptest.Server{ srv := &httptest.Server{
Listener: listener, Listener: listener,
Config: &http.Server{Handler: handler}, Config: &http.Server{Handler: handler},
} }
srv.Start() srv.Start()
return srv, func() { freeport.Return(ports) } t.Cleanup(srv.Close)
return srv
} }
func TestAgent_AddCheck_Alias(t *testing.T) { func TestAgent_AddCheck_Alias(t *testing.T) {
@ -4704,14 +4698,12 @@ func TestAgent_JoinWAN_viaMeshGateway(t *testing.T) {
t.Parallel() t.Parallel()
gwPort := freeport.MustTake(1) port := freeport.Port(t)
defer freeport.Return(gwPort) gwAddr := ipaddr.FormatAddressPort("127.0.0.1", port)
gwAddr := ipaddr.FormatAddressPort("127.0.0.1", gwPort[0])
// Due to some ordering, we'll have to manually configure these ports in // Due to some ordering, we'll have to manually configure these ports in
// advance. // advance.
secondaryRPCPorts := freeport.MustTake(2) secondaryRPCPorts := freeport.GetN(t, 2)
defer freeport.Return(secondaryRPCPorts)
a1 := StartTestAgent(t, TestAgent{Name: "bob", HCL: ` a1 := StartTestAgent(t, TestAgent{Name: "bob", HCL: `
domain = "consul" domain = "consul"
@ -4765,7 +4757,7 @@ func TestAgent_JoinWAN_viaMeshGateway(t *testing.T) {
ID: "mesh-gateway", ID: "mesh-gateway",
Name: "mesh-gateway", Name: "mesh-gateway",
Meta: map[string]string{structs.MetaWANFederationKey: "1"}, Meta: map[string]string{structs.MetaWANFederationKey: "1"},
Port: gwPort[0], Port: port,
} }
req, err := http.NewRequest("PUT", "/v1/agent/service/register", jsonReader(args)) req, err := http.NewRequest("PUT", "/v1/agent/service/register", jsonReader(args))
require.NoError(t, err) require.NoError(t, err)
@ -4879,7 +4871,7 @@ func TestAgent_JoinWAN_viaMeshGateway(t *testing.T) {
ID: "mesh-gateway", ID: "mesh-gateway",
Name: "mesh-gateway", Name: "mesh-gateway",
Meta: map[string]string{structs.MetaWANFederationKey: "1"}, Meta: map[string]string{structs.MetaWANFederationKey: "1"},
Port: gwPort[0], Port: port,
} }
req, err := http.NewRequest("PUT", "/v1/agent/service/register", jsonReader(args)) req, err := http.NewRequest("PUT", "/v1/agent/service/register", jsonReader(args))
require.NoError(t, err) require.NoError(t, err)
@ -4894,7 +4886,7 @@ func TestAgent_JoinWAN_viaMeshGateway(t *testing.T) {
ID: "mesh-gateway", ID: "mesh-gateway",
Name: "mesh-gateway", Name: "mesh-gateway",
Meta: map[string]string{structs.MetaWANFederationKey: "1"}, Meta: map[string]string{structs.MetaWANFederationKey: "1"},
Port: gwPort[0], Port: port,
} }
req, err := http.NewRequest("PUT", "/v1/agent/service/register", jsonReader(args)) req, err := http.NewRequest("PUT", "/v1/agent/service/register", jsonReader(args))
require.NoError(t, err) require.NoError(t, err)

View File

@ -120,11 +120,7 @@ func runTestVault(t testing.T) (*TestVaultServer, error) {
return nil, fmt.Errorf("%q not found on $PATH", vaultBinaryName) return nil, fmt.Errorf("%q not found on $PATH", vaultBinaryName)
} }
ports := freeport.MustTake(2) ports := freeport.GetN(t, 2)
returnPortsFn := func() {
freeport.Return(ports)
}
var ( var (
clientAddr = fmt.Sprintf("127.0.0.1:%d", ports[0]) clientAddr = fmt.Sprintf("127.0.0.1:%d", ports[0])
clusterAddr = fmt.Sprintf("127.0.0.1:%d", ports[1]) clusterAddr = fmt.Sprintf("127.0.0.1:%d", ports[1])
@ -136,7 +132,6 @@ func runTestVault(t testing.T) (*TestVaultServer, error) {
Address: "http://" + clientAddr, Address: "http://" + clientAddr,
}) })
if err != nil { if err != nil {
returnPortsFn()
return nil, err return nil, err
} }
client.SetToken(token) client.SetToken(token)
@ -156,16 +151,14 @@ func runTestVault(t testing.T) (*TestVaultServer, error) {
cmd.Stdout = ioutil.Discard cmd.Stdout = ioutil.Discard
cmd.Stderr = ioutil.Discard cmd.Stderr = ioutil.Discard
if err := cmd.Start(); err != nil { if err := cmd.Start(); err != nil {
returnPortsFn()
return nil, err return nil, err
} }
testVault := &TestVaultServer{ testVault := &TestVaultServer{
RootToken: token, RootToken: token,
Addr: "http://" + clientAddr, Addr: "http://" + clientAddr,
cmd: cmd, cmd: cmd,
client: client, client: client,
returnPortsFn: returnPortsFn,
} }
t.Cleanup(func() { t.Cleanup(func() {
if err := testVault.Stop(); err != nil { if err := testVault.Stop(); err != nil {
@ -181,9 +174,6 @@ type TestVaultServer struct {
Addr string Addr string
cmd *exec.Cmd cmd *exec.Cmd
client *vaultapi.Client client *vaultapi.Client
// returnPortsFn will put the ports claimed for the test back into the
returnPortsFn func()
} }
var printedVaultVersion sync.Once var printedVaultVersion sync.Once
@ -229,11 +219,6 @@ func (v *TestVaultServer) Stop() error {
if err := v.cmd.Wait(); err != nil { if err := v.cmd.Wait(); err != nil {
return err return err
} }
if v.returnPortsFn != nil {
v.returnPortsFn()
}
return nil return nil
} }

View File

@ -33,9 +33,8 @@ import (
// - GET /api/v1/namespaces/<NAMESPACE>/serviceaccounts/<NAME> // - GET /api/v1/namespaces/<NAMESPACE>/serviceaccounts/<NAME>
// //
type TestAPIServer struct { type TestAPIServer struct {
srv *httptest.Server srv *httptest.Server
caCert string caCert string
returnFunc func()
mu sync.Mutex mu sync.Mutex
authorizedJWT string // token review and sa read authorizedJWT string // token review and sa read
@ -48,12 +47,7 @@ type TestAPIServer struct {
// random free port. // random free port.
func StartTestAPIServer(t testing.T) *TestAPIServer { func StartTestAPIServer(t testing.T) *TestAPIServer {
s := &TestAPIServer{} s := &TestAPIServer{}
s.srv = httptestNewUnstartedServerWithPort(s, freeport.Port(t))
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.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
s.srv.StartTLS() s.srv.StartTLS()
@ -101,10 +95,6 @@ func (s *TestAPIServer) SetAllowedServiceAccount(
// Stop stops the running TestAPIServer. // Stop stops the running TestAPIServer.
func (s *TestAPIServer) Stop() { func (s *TestAPIServer) Stop() {
s.srv.Close() s.srv.Close()
if s.returnFunc != nil {
s.returnFunc()
s.returnFunc = nil
}
} }
// Addr returns the current base URL for the running webserver. // Addr returns the current base URL for the running webserver.

View File

@ -33,11 +33,7 @@ func testClientConfig(t *testing.T) (string, *Config) {
dir := testutil.TempDir(t, "consul") dir := testutil.TempDir(t, "consul")
config := DefaultConfig() config := DefaultConfig()
ports := freeport.MustTake(2) ports := freeport.GetN(t, 2)
t.Cleanup(func() {
freeport.Return(ports)
})
config.Datacenter = "dc1" config.Datacenter = "dc1"
config.DataDir = dir config.DataDir = dir
config.NodeName = uniqueNodeName(t.Name()) config.NodeName = uniqueNodeName(t.Name())

View File

@ -140,13 +140,10 @@ func TestOperator_RaftRemovePeerByAddress(t *testing.T) {
testrpc.WaitForLeader(t, s1.RPC, "dc1") testrpc.WaitForLeader(t, s1.RPC, "dc1")
ports := freeport.MustTake(1)
defer freeport.Return(ports)
// Try to remove a peer that's not there. // Try to remove a peer that's not there.
arg := structs.RaftRemovePeerRequest{ arg := structs.RaftRemovePeerRequest{
Datacenter: "dc1", Datacenter: "dc1",
Address: raft.ServerAddress(fmt.Sprintf("127.0.0.1:%d", ports[0])), Address: raft.ServerAddress(fmt.Sprintf("127.0.0.1:%d", freeport.Port(t))),
} }
var reply struct{} var reply struct{}
err := msgpackrpc.CallWithCodec(codec, "Operator.RaftRemovePeerByAddress", &arg, &reply) err := msgpackrpc.CallWithCodec(codec, "Operator.RaftRemovePeerByAddress", &arg, &reply)
@ -263,10 +260,7 @@ func TestOperator_RaftRemovePeerByID(t *testing.T) {
// Add it manually to Raft. // Add it manually to Raft.
{ {
ports := freeport.MustTake(1) future := s1.raft.AddVoter(arg.ID, raft.ServerAddress(fmt.Sprintf("127.0.0.1:%d", freeport.Port(t))), 0, 0)
defer freeport.Return(ports)
future := s1.raft.AddVoter(arg.ID, raft.ServerAddress(fmt.Sprintf("127.0.0.1:%d", ports[0])), 0, 0)
if err := future.Error(); err != nil { if err := future.Error(); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }

View File

@ -116,11 +116,7 @@ func testServerConfig(t *testing.T) (string, *Config) {
dir := testutil.TempDir(t, "consul") dir := testutil.TempDir(t, "consul")
config := DefaultConfig() config := DefaultConfig()
ports := freeport.MustTake(3) ports := freeport.GetN(t, 3)
t.Cleanup(func() {
freeport.Return(ports)
})
config.NodeName = uniqueNodeName(t.Name()) config.NodeName = uniqueNodeName(t.Name())
config.Bootstrap = true config.Bootstrap = true
config.Datacenter = "dc1" config.Datacenter = "dc1"
@ -516,10 +512,7 @@ func TestServer_JoinWAN_SerfAllowedCIDRs(t *testing.T) {
} }
func skipIfCannotBindToIP(t *testing.T, ip string) { func skipIfCannotBindToIP(t *testing.T, ip string) {
ports := freeport.MustTake(1) addr := ipaddr.FormatAddressPort(ip, freeport.Port(t))
defer freeport.Return(ports)
addr := ipaddr.FormatAddressPort(ip, ports[0])
l, err := net.Listen("tcp", addr) l, err := net.Listen("tcp", addr)
l.Close() l.Close()
if err != nil { if err != nil {
@ -725,9 +718,8 @@ func TestServer_JoinWAN_viaMeshGateway(t *testing.T) {
t.Parallel() t.Parallel()
gwPort := freeport.MustTake(1) port := freeport.Port(t)
defer freeport.Return(gwPort) gwAddr := ipaddr.FormatAddressPort("127.0.0.1", port)
gwAddr := ipaddr.FormatAddressPort("127.0.0.1", gwPort[0])
dir1, s1 := testServerWithConfig(t, func(c *Config) { dir1, s1 := testServerWithConfig(t, func(c *Config) {
c.TLSConfig.Domain = "consul" c.TLSConfig.Domain = "consul"
@ -813,7 +805,7 @@ func TestServer_JoinWAN_viaMeshGateway(t *testing.T) {
ID: "mesh-gateway", ID: "mesh-gateway",
Service: "mesh-gateway", Service: "mesh-gateway",
Meta: map[string]string{structs.MetaWANFederationKey: "1"}, Meta: map[string]string{structs.MetaWANFederationKey: "1"},
Port: gwPort[0], Port: port,
}, },
} }
@ -868,7 +860,7 @@ func TestServer_JoinWAN_viaMeshGateway(t *testing.T) {
ID: "mesh-gateway", ID: "mesh-gateway",
Service: "mesh-gateway", Service: "mesh-gateway",
Meta: map[string]string{structs.MetaWANFederationKey: "1"}, Meta: map[string]string{structs.MetaWANFederationKey: "1"},
Port: gwPort[0], Port: port,
}, },
} }
@ -885,7 +877,7 @@ func TestServer_JoinWAN_viaMeshGateway(t *testing.T) {
ID: "mesh-gateway", ID: "mesh-gateway",
Service: "mesh-gateway", Service: "mesh-gateway",
Meta: map[string]string{structs.MetaWANFederationKey: "1"}, Meta: map[string]string{structs.MetaWANFederationKey: "1"},
Port: gwPort[0], Port: port,
}, },
} }

View File

@ -29,10 +29,7 @@ func useTLSForDcAlwaysTrue(_ string) bool {
} }
func TestNewDialer_WithTLSWrapper(t *testing.T) { func TestNewDialer_WithTLSWrapper(t *testing.T) {
ports := freeport.MustTake(1) lis, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(freeport.Port(t))))
defer freeport.Return(ports)
lis, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(ports[0])))
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(logError(t, lis.Close)) t.Cleanup(logError(t, lis.Close))
@ -68,8 +65,7 @@ func TestNewDialer_WithTLSWrapper(t *testing.T) {
} }
func TestNewDialer_WithALPNWrapper(t *testing.T) { func TestNewDialer_WithALPNWrapper(t *testing.T) {
ports := freeport.MustTake(3) ports := freeport.GetN(t, 3)
defer freeport.Return(ports)
var ( var (
s1addr = ipaddr.FormatAddressPort("127.0.0.1", ports[0]) s1addr = ipaddr.FormatAddressPort("127.0.0.1", ports[0])
@ -193,10 +189,7 @@ func TestNewDialer_IntegrationWithTLSEnabledHandler(t *testing.T) {
func TestNewDialer_IntegrationWithTLSEnabledHandler_viaMeshGateway(t *testing.T) { func TestNewDialer_IntegrationWithTLSEnabledHandler_viaMeshGateway(t *testing.T) {
// if this test is failing because of expired certificates // if this test is failing because of expired certificates
// use the procedure in test/CA-GENERATION.md // use the procedure in test/CA-GENERATION.md
ports := freeport.MustTake(1) gwAddr := ipaddr.FormatAddressPort("127.0.0.1", freeport.Port(t))
defer freeport.Return(ports)
gwAddr := ipaddr.FormatAddressPort("127.0.0.1", ports[0])
res := resolver.NewServerResolverBuilder(newConfig(t)) res := resolver.NewServerResolverBuilder(newConfig(t))
registerWithGRPC(t, res) registerWithGRPC(t, res)

View File

@ -47,12 +47,7 @@ func newTestServer(t *testing.T, name string, dc string, tlsConf *tlsutil.Config
testservice.RegisterSimpleServer(server, &simple{name: name, dc: dc}) testservice.RegisterSimpleServer(server, &simple{name: name, dc: dc})
}) })
ports := freeport.MustTake(1) lis, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(freeport.Port(t))))
t.Cleanup(func() {
freeport.Return(ports)
})
lis, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(ports[0])))
require.NoError(t, err) require.NoError(t, err)
rpc := &fakeRPCListener{t: t, handler: handler, tlsConf: tlsConf} rpc := &fakeRPCListener{t: t, handler: handler, tlsConf: tlsConf}

View File

@ -165,8 +165,7 @@ func (a *TestAgent) Start(t *testing.T) error {
Name: name, Name: name,
}) })
portsConfig, returnPortsFn := randomPortsSource(a.UseTLS) portsConfig := randomPortsSource(t, a.UseTLS)
t.Cleanup(returnPortsFn)
// Create NodeID outside the closure, so that it does not change // Create NodeID outside the closure, so that it does not change
testHCLConfig := TestConfigHCL(NodeID()) testHCLConfig := TestConfigHCL(NodeID())
@ -378,8 +377,8 @@ func (a *TestAgent) consulConfig() *consul.Config {
// chance of port conflicts for concurrently executed test binaries. // chance of port conflicts for concurrently executed test binaries.
// Instead of relying on one set of ports to be sufficient we retry // Instead of relying on one set of ports to be sufficient we retry
// starting the agent with different ports on port conflict. // starting the agent with different ports on port conflict.
func randomPortsSource(tls bool) (data string, returnPortsFn func()) { func randomPortsSource(t *testing.T, tls bool) string {
ports := freeport.MustTake(7) ports := freeport.GetN(t, 7)
var http, https int var http, https int
if tls { if tls {
@ -400,7 +399,7 @@ func randomPortsSource(tls bool) (data string, returnPortsFn func()) {
server = ` + strconv.Itoa(ports[5]) + ` server = ` + strconv.Itoa(ports[5]) + `
grpc = ` + strconv.Itoa(ports[6]) + ` grpc = ` + strconv.Itoa(ports[6]) + `
} }
`, func() { freeport.Return(ports) } `
} }
func NodeID() string { func NodeID() string {

View File

@ -112,15 +112,13 @@ func TestPublicListener(t *testing.T) {
// Can't enable t.Parallel since we rely on the global metrics instance. // Can't enable t.Parallel since we rely on the global metrics instance.
ca := agConnect.TestCA(t, nil) ca := agConnect.TestCA(t, nil)
ports := freeport.MustTake(1)
defer freeport.Return(ports)
testApp := NewTestTCPServer(t) testApp := NewTestTCPServer(t)
defer testApp.Close() defer testApp.Close()
port := freeport.Port(t)
cfg := PublicListenerConfig{ cfg := PublicListenerConfig{
BindAddress: "127.0.0.1", BindAddress: "127.0.0.1",
BindPort: ports[0], BindPort: port,
LocalServiceAddress: testApp.Addr().String(), LocalServiceAddress: testApp.Addr().String(),
HandshakeTimeoutMs: 100, HandshakeTimeoutMs: 100,
LocalConnectTimeoutMs: 100, LocalConnectTimeoutMs: 100,
@ -144,7 +142,7 @@ func TestPublicListener(t *testing.T) {
// Proxy and backend are running, play the part of a TLS client using same // Proxy and backend are running, play the part of a TLS client using same
// cert for now. // cert for now.
conn, err := svc.Dial(context.Background(), &connect.StaticResolver{ conn, err := svc.Dial(context.Background(), &connect.StaticResolver{
Addr: TestLocalAddr(ports[0]), Addr: TestLocalAddr(port),
CertURI: agConnect.TestSpiffeIDService(t, "db"), CertURI: agConnect.TestSpiffeIDService(t, "db"),
}) })
require.NoError(t, err) require.NoError(t, err)
@ -166,9 +164,6 @@ func TestUpstreamListener(t *testing.T) {
// Can't enable t.Parallel since we rely on the global metrics instance. // Can't enable t.Parallel since we rely on the global metrics instance.
ca := agConnect.TestCA(t, nil) ca := agConnect.TestCA(t, nil)
ports := freeport.MustTake(1)
defer freeport.Return(ports)
// Run a test server that we can dial. // Run a test server that we can dial.
testSvr := connect.NewTestServer(t, "db", ca) testSvr := connect.NewTestServer(t, "db", ca)
go func() { go func() {
@ -184,7 +179,7 @@ func TestUpstreamListener(t *testing.T) {
DestinationName: "db", DestinationName: "db",
Config: map[string]interface{}{"connect_timeout_ms": 100}, Config: map[string]interface{}{"connect_timeout_ms": 100},
LocalBindAddress: "localhost", LocalBindAddress: "localhost",
LocalBindPort: ports[0], LocalBindPort: freeport.Port(t),
} }
// Setup metrics to test they are recorded // Setup metrics to test they are recorded

View File

@ -27,8 +27,7 @@ func TestProxy_public(t *testing.T) {
t.Skip("too slow for testing.Short") t.Skip("too slow for testing.Short")
} }
ports := freeport.MustTake(2) ports := freeport.GetN(t, 2)
defer freeport.Return(ports)
a := agent.NewTestAgent(t, "") a := agent.NewTestAgent(t, "")
defer a.Shutdown() defer a.Shutdown()

View File

@ -24,24 +24,19 @@ type TestTCPServer struct {
l net.Listener l net.Listener
stopped int32 stopped int32
accepted, closed, active int32 accepted, closed, active int32
returnPortsFn func()
} }
// NewTestTCPServer opens as a listening socket on the given address and returns // NewTestTCPServer opens as a listening socket on the given address and returns
// a TestTCPServer serving requests to it. The server is already started and can // a TestTCPServer serving requests to it. The server is already started and can
// be stopped by calling Close(). // be stopped by calling Close().
func NewTestTCPServer(t testing.T) *TestTCPServer { func NewTestTCPServer(t testing.T) *TestTCPServer {
ports := freeport.MustTake(1) addr := TestLocalAddr(freeport.Port(t))
addr := TestLocalAddr(ports[0])
l, err := net.Listen("tcp", addr) l, err := net.Listen("tcp", addr)
require.NoError(t, err) require.NoError(t, err)
log.Printf("test tcp server listening on %s", addr) log.Printf("test tcp server listening on %s", addr)
s := &TestTCPServer{ s := &TestTCPServer{l: l}
l: l,
returnPortsFn: func() { freeport.Return(ports) },
}
go s.accept() go s.accept()
return s return s
@ -53,10 +48,6 @@ func (s *TestTCPServer) Close() {
if s.l != nil { if s.l != nil {
s.l.Close() s.l.Close()
} }
if s.returnPortsFn != nil {
s.returnPortsFn()
s.returnPortsFn = nil
}
} }
// Addr returns the address that this server is listening on. // Addr returns the address that this server is listening on.

View File

@ -96,24 +96,21 @@ type TestServer struct {
// Listening is closed when the listener is run. // Listening is closed when the listener is run.
Listening chan struct{} Listening chan struct{}
l net.Listener l net.Listener
returnPortsFn func() stopFlag int32
stopFlag int32 stopChan chan struct{}
stopChan chan struct{}
} }
// NewTestServer returns a TestServer. It should be closed when test is // NewTestServer returns a TestServer. It should be closed when test is
// complete. // complete.
func NewTestServer(t testing.T, service string, ca *structs.CARoot) *TestServer { func NewTestServer(t testing.T, service string, ca *structs.CARoot) *TestServer {
ports := freeport.MustTake(1)
return &TestServer{ return &TestServer{
Service: service, Service: service,
CA: ca, CA: ca,
stopChan: make(chan struct{}), stopChan: make(chan struct{}),
TLSCfg: TestTLSConfig(t, service, ca), TLSCfg: TestTLSConfig(t, service, ca),
Addr: fmt.Sprintf("127.0.0.1:%d", ports[0]), Addr: fmt.Sprintf("127.0.0.1:%d", freeport.Port(t)),
Listening: make(chan struct{}), Listening: make(chan struct{}),
returnPortsFn: func() { freeport.Return(ports) },
} }
} }
@ -190,10 +187,6 @@ func (s *TestServer) Close() error {
if s.l != nil { if s.l != nil {
s.l.Close() s.l.Close()
} }
if s.returnPortsFn != nil {
s.returnPortsFn()
s.returnPortsFn = nil
}
close(s.stopChan) close(s.stopChan)
} }
return nil return nil

View File

@ -18,12 +18,7 @@ import (
// _know_ nothing is listening. If you simply assumed unbound ports were free // _know_ nothing is listening. If you simply assumed unbound ports were free
// you'd end up with test cross-talk and weirdness. // you'd end up with test cross-talk and weirdness.
func StartTestServer(t testing.T, handler http.Handler) string { func StartTestServer(t testing.T, handler http.Handler) string {
ports := freeport.MustTake(1) addr := ipaddr.FormatAddressPort("127.0.0.1", freeport.Port(t))
t.Cleanup(func() {
freeport.Return(ports)
})
addr := ipaddr.FormatAddressPort("127.0.0.1", ports[0])
server := &http.Server{Addr: addr, Handler: handler} server := &http.Server{Addr: addr, Handler: handler}
t.Cleanup(func() { t.Cleanup(func() {