X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/2835665e43a3b85c85fefcd348015b5dee829cba..a2fc189f7a50964340bc60704c5cd3bef9114c7d:/sdk/go/health/handler_test.go?ds=sidebyside diff --git a/sdk/go/health/handler_test.go b/sdk/go/health/handler_test.go new file mode 100644 index 0000000000..055e2c3d8d --- /dev/null +++ b/sdk/go/health/handler_test.go @@ -0,0 +1,121 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: Apache-2.0 + +package health + +import ( + "encoding/json" + "errors" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + check "gopkg.in/check.v1" +) + +// Gocheck boilerplate +var _ = check.Suite(&Suite{}) + +func Test(t *testing.T) { + check.TestingT(t) +} + +type Suite struct{} + +const ( + goodToken = "supersecret" + badToken = "pwn" +) + +func (s *Suite) TestPassFailRefuse(c *check.C) { + h := &Handler{ + Token: goodToken, + Prefix: "/_health/", + Routes: Routes{ + "success": func() error { return nil }, + "miracle": func() error { return errors.New("unimplemented") }, + }, + } + + resp := httptest.NewRecorder() + h.ServeHTTP(resp, s.request("/_health/ping", goodToken)) + s.checkHealthy(c, resp) + + resp = httptest.NewRecorder() + h.ServeHTTP(resp, s.request("/_health/success", goodToken)) + s.checkHealthy(c, resp) + + resp = httptest.NewRecorder() + h.ServeHTTP(resp, s.request("/_health/miracle", goodToken)) + s.checkUnhealthy(c, resp) + + resp = httptest.NewRecorder() + h.ServeHTTP(resp, s.request("/_health/miracle", badToken)) + c.Check(resp.Code, check.Equals, http.StatusForbidden) + + resp = httptest.NewRecorder() + h.ServeHTTP(resp, s.request("/_health/miracle", "")) + c.Check(resp.Code, check.Equals, http.StatusUnauthorized) +} + +func (s *Suite) TestPingOverride(c *check.C) { + var ok bool + h := &Handler{ + Token: goodToken, + Routes: Routes{ + "ping": func() error { + ok = !ok + if ok { + return nil + } else { + return errors.New("good error") + } + }, + }, + } + resp := httptest.NewRecorder() + h.ServeHTTP(resp, s.request("/ping", goodToken)) + s.checkHealthy(c, resp) + + resp = httptest.NewRecorder() + h.ServeHTTP(resp, s.request("/ping", goodToken)) + s.checkUnhealthy(c, resp) +} + +func (s *Suite) TestZeroValue(c *check.C) { + resp := httptest.NewRecorder() + (&Handler{}).ServeHTTP(resp, s.request("/ping", goodToken)) + c.Check(resp.Code, check.Equals, http.StatusNotFound) +} + +func (s *Suite) request(path, token string) *http.Request { + u, _ := url.Parse("http://foo.local" + path) + req := &http.Request{ + Method: "GET", + Host: u.Host, + URL: u, + RequestURI: u.RequestURI(), + } + if token != "" { + req.Header = http.Header{ + "Authorization": {"Bearer " + token}, + } + } + return req +} + +func (s *Suite) checkHealthy(c *check.C, resp *httptest.ResponseRecorder) { + c.Check(resp.Code, check.Equals, http.StatusOK) + c.Check(resp.Body.String(), check.Equals, `{"health":"OK"}`+"\n") +} + +func (s *Suite) checkUnhealthy(c *check.C, resp *httptest.ResponseRecorder) { + c.Check(resp.Code, check.Equals, http.StatusOK) + var result map[string]interface{} + err := json.Unmarshal(resp.Body.Bytes(), &result) + c.Assert(err, check.IsNil) + c.Check(result["health"], check.Equals, "ERROR") + c.Check(result["error"].(string), check.Not(check.Equals), "") +}