lib/api: Prevent leaks in tests (#6227)

This commit is contained in:
Simon Frei 2019-12-13 09:26:41 +01:00 committed by Jakob Borg
parent 8140350094
commit de64ffddab
2 changed files with 34 additions and 16 deletions

View File

@ -361,7 +361,10 @@ func (s *service) serve(ctx context.Context) {
l.Infoln("Access the GUI via the following URL:", guiCfg.URL()) l.Infoln("Access the GUI via the following URL:", guiCfg.URL())
if s.started != nil { if s.started != nil {
// only set when run by the tests // only set when run by the tests
s.started <- listener.Addr().String() select {
case <-ctx.Done(): // Shouldn't return directly due to cleanup below
case s.started <- listener.Addr().String():
}
} }
// Indicate successful initial startup, to ourselves and to interested // Indicate successful initial startup, to ourselves and to interested
@ -376,7 +379,10 @@ func (s *service) serve(ctx context.Context) {
serveError := make(chan error, 1) serveError := make(chan error, 1)
go func() { go func() {
serveError <- srv.Serve(listener) select {
case serveError <- srv.Serve(listener):
case <-ctx.Done():
}
}() }()
// Wait for stop, restart or error signals // Wait for stop, restart or error signals

View File

@ -239,10 +239,11 @@ func TestAPIServiceRequests(t *testing.T) {
const testAPIKey = "foobarbaz" const testAPIKey = "foobarbaz"
cfg := new(mockedConfig) cfg := new(mockedConfig)
cfg.gui.APIKey = testAPIKey cfg.gui.APIKey = testAPIKey
baseURL, err := startHTTP(cfg) baseURL, sup, err := startHTTP(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer sup.Stop()
cases := []httpTestCase{ cases := []httpTestCase{
// /rest/db // /rest/db
@ -451,10 +452,11 @@ func TestHTTPLogin(t *testing.T) {
cfg := new(mockedConfig) cfg := new(mockedConfig)
cfg.gui.User = "üser" cfg.gui.User = "üser"
cfg.gui.Password = "$2a$10$IdIZTxTg/dCNuNEGlmLynOjqg4B1FvDKuIV5e0BB3pnWVHNb8.GSq" // bcrypt of "räksmörgås" in UTF-8 cfg.gui.Password = "$2a$10$IdIZTxTg/dCNuNEGlmLynOjqg4B1FvDKuIV5e0BB3pnWVHNb8.GSq" // bcrypt of "räksmörgås" in UTF-8
baseURL, err := startHTTP(cfg) baseURL, sup, err := startHTTP(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer sup.Stop()
// Verify rejection when not using authorization // Verify rejection when not using authorization
@ -512,7 +514,7 @@ func TestHTTPLogin(t *testing.T) {
} }
} }
func startHTTP(cfg *mockedConfig) (string, error) { func startHTTP(cfg *mockedConfig) (string, *suture.Supervisor, error) {
m := new(mockedModel) m := new(mockedModel)
assetDir := "../../gui" assetDir := "../../gui"
eventSub := new(mockedEventSub) eventSub := new(mockedEventSub)
@ -542,7 +544,8 @@ func startHTTP(cfg *mockedConfig) (string, error) {
addr := <-addrChan addr := <-addrChan
tcpAddr, err := net.ResolveTCPAddr("tcp", addr) tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil { if err != nil {
return "", fmt.Errorf("Weird address from API service: %v", err) supervisor.Stop()
return "", nil, fmt.Errorf("Weird address from API service: %v", err)
} }
host, _, _ := net.SplitHostPort(cfg.gui.RawAddress) host, _, _ := net.SplitHostPort(cfg.gui.RawAddress)
@ -551,7 +554,7 @@ func startHTTP(cfg *mockedConfig) (string, error) {
} }
baseURL := fmt.Sprintf("http://%s", net.JoinHostPort(host, strconv.Itoa(tcpAddr.Port))) baseURL := fmt.Sprintf("http://%s", net.JoinHostPort(host, strconv.Itoa(tcpAddr.Port)))
return baseURL, nil return baseURL, supervisor, nil
} }
func TestCSRFRequired(t *testing.T) { func TestCSRFRequired(t *testing.T) {
@ -560,10 +563,11 @@ func TestCSRFRequired(t *testing.T) {
const testAPIKey = "foobarbaz" const testAPIKey = "foobarbaz"
cfg := new(mockedConfig) cfg := new(mockedConfig)
cfg.gui.APIKey = testAPIKey cfg.gui.APIKey = testAPIKey
baseURL, err := startHTTP(cfg) baseURL, sup, err := startHTTP(cfg)
if err != nil { if err != nil {
t.Fatal("Unexpected error from getting base URL:", err) t.Fatal("Unexpected error from getting base URL:", err)
} }
defer sup.Stop()
cli := &http.Client{ cli := &http.Client{
Timeout: time.Minute, Timeout: time.Minute,
@ -635,10 +639,11 @@ func TestRandomString(t *testing.T) {
const testAPIKey = "foobarbaz" const testAPIKey = "foobarbaz"
cfg := new(mockedConfig) cfg := new(mockedConfig)
cfg.gui.APIKey = testAPIKey cfg.gui.APIKey = testAPIKey
baseURL, err := startHTTP(cfg) baseURL, sup, err := startHTTP(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer sup.Stop()
cli := &http.Client{ cli := &http.Client{
Timeout: time.Second, Timeout: time.Second,
} }
@ -727,10 +732,11 @@ func testConfigPost(data io.Reader) (*http.Response, error) {
const testAPIKey = "foobarbaz" const testAPIKey = "foobarbaz"
cfg := new(mockedConfig) cfg := new(mockedConfig)
cfg.gui.APIKey = testAPIKey cfg.gui.APIKey = testAPIKey
baseURL, err := startHTTP(cfg) baseURL, sup, err := startHTTP(cfg)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer sup.Stop()
cli := &http.Client{ cli := &http.Client{
Timeout: time.Second, Timeout: time.Second,
} }
@ -747,10 +753,11 @@ func TestHostCheck(t *testing.T) {
cfg := new(mockedConfig) cfg := new(mockedConfig)
cfg.gui.RawAddress = "127.0.0.1:0" cfg.gui.RawAddress = "127.0.0.1:0"
baseURL, err := startHTTP(cfg) baseURL, sup, err := startHTTP(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer sup.Stop()
// A normal HTTP get to the localhost-bound service should succeed // A normal HTTP get to the localhost-bound service should succeed
@ -807,10 +814,11 @@ func TestHostCheck(t *testing.T) {
cfg = new(mockedConfig) cfg = new(mockedConfig)
cfg.gui.RawAddress = "127.0.0.1:0" cfg.gui.RawAddress = "127.0.0.1:0"
cfg.gui.InsecureSkipHostCheck = true cfg.gui.InsecureSkipHostCheck = true
baseURL, err = startHTTP(cfg) baseURL, sup, err = startHTTP(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer sup.Stop()
// A request with a suspicious Host header should be allowed // A request with a suspicious Host header should be allowed
@ -830,10 +838,11 @@ func TestHostCheck(t *testing.T) {
cfg = new(mockedConfig) cfg = new(mockedConfig)
cfg.gui.RawAddress = "0.0.0.0:0" cfg.gui.RawAddress = "0.0.0.0:0"
cfg.gui.InsecureSkipHostCheck = true cfg.gui.InsecureSkipHostCheck = true
baseURL, err = startHTTP(cfg) baseURL, sup, err = startHTTP(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer sup.Stop()
// A request with a suspicious Host header should be allowed // A request with a suspicious Host header should be allowed
@ -857,10 +866,11 @@ func TestHostCheck(t *testing.T) {
cfg = new(mockedConfig) cfg = new(mockedConfig)
cfg.gui.RawAddress = "[::1]:0" cfg.gui.RawAddress = "[::1]:0"
baseURL, err = startHTTP(cfg) baseURL, sup, err = startHTTP(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer sup.Stop()
// A normal HTTP get to the localhost-bound service should succeed // A normal HTTP get to the localhost-bound service should succeed
@ -951,10 +961,11 @@ func TestAccessControlAllowOriginHeader(t *testing.T) {
const testAPIKey = "foobarbaz" const testAPIKey = "foobarbaz"
cfg := new(mockedConfig) cfg := new(mockedConfig)
cfg.gui.APIKey = testAPIKey cfg.gui.APIKey = testAPIKey
baseURL, err := startHTTP(cfg) baseURL, sup, err := startHTTP(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer sup.Stop()
cli := &http.Client{ cli := &http.Client{
Timeout: time.Second, Timeout: time.Second,
} }
@ -981,10 +992,11 @@ func TestOptionsRequest(t *testing.T) {
const testAPIKey = "foobarbaz" const testAPIKey = "foobarbaz"
cfg := new(mockedConfig) cfg := new(mockedConfig)
cfg.gui.APIKey = testAPIKey cfg.gui.APIKey = testAPIKey
baseURL, err := startHTTP(cfg) baseURL, sup, err := startHTTP(cfg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer sup.Stop()
cli := &http.Client{ cli := &http.Client{
Timeout: time.Second, Timeout: time.Second,
} }