10 "git.curoverse.com/arvados.git/sdk/go/arvados"
11 "git.curoverse.com/arvados.git/sdk/go/arvadostest"
15 type AggregatorSuite struct {
18 resp *httptest.ResponseRecorder
21 // Gocheck boilerplate
22 var _ = check.Suite(&AggregatorSuite{})
24 func (s *AggregatorSuite) TestInterface(c *check.C) {
25 var _ http.Handler = &Aggregator{}
28 func (s *AggregatorSuite) SetUpTest(c *check.C) {
29 s.handler = &Aggregator{Config: &arvados.Config{
30 Clusters: map[string]arvados.Cluster{
32 ManagementToken: arvadostest.ManagementToken,
33 SystemNodes: map[string]arvados.SystemNode{},
37 s.req = httptest.NewRequest("GET", "/_health/all", nil)
38 s.req.Header.Set("Authorization", "Bearer "+arvadostest.ManagementToken)
39 s.resp = httptest.NewRecorder()
42 func (s *AggregatorSuite) TestNoAuth(c *check.C) {
43 s.req.Header.Del("Authorization")
44 s.handler.ServeHTTP(s.resp, s.req)
46 c.Check(s.resp.Code, check.Equals, http.StatusUnauthorized)
49 func (s *AggregatorSuite) TestBadAuth(c *check.C) {
50 s.req.Header.Set("Authorization", "xyzzy")
51 s.handler.ServeHTTP(s.resp, s.req)
53 c.Check(s.resp.Code, check.Equals, http.StatusUnauthorized)
56 func (s *AggregatorSuite) TestEmptyConfig(c *check.C) {
57 s.handler.ServeHTTP(s.resp, s.req)
61 func (s *AggregatorSuite) stubServer(handler http.Handler) (*httptest.Server, string) {
62 srv := httptest.NewServer(handler)
64 if parts := strings.Split(srv.URL, ":"); len(parts) < 3 {
67 port = parts[len(parts)-1]
69 return srv, ":" + port
72 type unhealthyHandler struct{}
74 func (*unhealthyHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
75 if req.URL.Path == "/_health/ping" {
76 resp.Write([]byte(`{"health":"ERROR","error":"the bends"}`))
78 http.Error(resp, "not found", http.StatusNotFound)
82 func (s *AggregatorSuite) TestUnhealthy(c *check.C) {
83 srv, listen := s.stubServer(&unhealthyHandler{})
85 s.handler.Config.Clusters["zzzzz"].SystemNodes["localhost"] = arvados.SystemNode{
86 Keepstore: arvados.SystemServiceInstance{Listen: listen},
88 s.handler.ServeHTTP(s.resp, s.req)
92 type healthyHandler struct{}
94 func (*healthyHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
95 if req.URL.Path == "/_health/ping" {
96 resp.Write([]byte(`{"health":"OK"}`))
98 http.Error(resp, "not found", http.StatusNotFound)
102 func (s *AggregatorSuite) TestHealthy(c *check.C) {
103 srv, listen := s.stubServer(&healthyHandler{})
105 s.handler.Config.Clusters["zzzzz"].SystemNodes["localhost"] = arvados.SystemNode{
106 Keepproxy: arvados.SystemServiceInstance{Listen: listen},
107 Keepstore: arvados.SystemServiceInstance{Listen: listen},
108 Keepweb: arvados.SystemServiceInstance{Listen: listen},
109 Nodemanager: arvados.SystemServiceInstance{Listen: listen},
110 RailsAPI: arvados.SystemServiceInstance{Listen: listen},
111 Websocket: arvados.SystemServiceInstance{Listen: listen},
112 Workbench: arvados.SystemServiceInstance{Listen: listen},
114 s.handler.ServeHTTP(s.resp, s.req)
116 svc := "keepstore+http://localhost" + listen + "/_health/ping"
118 ep := resp.Checks[svc]
119 c.Check(ep.Health, check.Equals, "OK")
120 c.Check(ep.HTTPStatusCode, check.Equals, 200)
123 func (s *AggregatorSuite) TestHealthyAndUnhealthy(c *check.C) {
124 srvH, listenH := s.stubServer(&healthyHandler{})
126 srvU, listenU := s.stubServer(&unhealthyHandler{})
128 s.handler.Config.Clusters["zzzzz"].SystemNodes["localhost"] = arvados.SystemNode{
129 Keepproxy: arvados.SystemServiceInstance{Listen: listenH},
130 Keepstore: arvados.SystemServiceInstance{Listen: listenH},
131 Keepweb: arvados.SystemServiceInstance{Listen: listenH},
132 Nodemanager: arvados.SystemServiceInstance{Listen: listenH},
133 RailsAPI: arvados.SystemServiceInstance{Listen: listenH},
134 Websocket: arvados.SystemServiceInstance{Listen: listenH},
135 Workbench: arvados.SystemServiceInstance{Listen: listenH},
137 s.handler.Config.Clusters["zzzzz"].SystemNodes["127.0.0.1"] = arvados.SystemNode{
138 Keepstore: arvados.SystemServiceInstance{Listen: listenU},
140 s.handler.ServeHTTP(s.resp, s.req)
141 resp := s.checkUnhealthy(c)
142 ep := resp.Checks["keepstore+http://localhost"+listenH+"/_health/ping"]
143 c.Check(ep.Health, check.Equals, "OK")
144 c.Check(ep.HTTPStatusCode, check.Equals, 200)
145 ep = resp.Checks["keepstore+http://127.0.0.1"+listenU+"/_health/ping"]
146 c.Check(ep.Health, check.Equals, "ERROR")
147 c.Check(ep.HTTPStatusCode, check.Equals, 200)
151 func (s *AggregatorSuite) checkError(c *check.C) {
152 c.Check(s.resp.Code, check.Not(check.Equals), http.StatusOK)
153 var resp ClusterHealthResponse
154 err := json.NewDecoder(s.resp.Body).Decode(&resp)
155 c.Check(err, check.IsNil)
156 c.Check(resp.Health, check.Not(check.Equals), "OK")
159 func (s *AggregatorSuite) checkUnhealthy(c *check.C) ClusterHealthResponse {
160 return s.checkResult(c, "ERROR")
163 func (s *AggregatorSuite) checkOK(c *check.C) ClusterHealthResponse {
164 return s.checkResult(c, "OK")
167 func (s *AggregatorSuite) checkResult(c *check.C, health string) ClusterHealthResponse {
168 c.Check(s.resp.Code, check.Equals, http.StatusOK)
169 var resp ClusterHealthResponse
170 err := json.NewDecoder(s.resp.Body).Decode(&resp)
171 c.Check(err, check.IsNil)
172 c.Check(resp.Health, check.Equals, health)
176 type slowHandler struct{}
178 func (*slowHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
179 if req.URL.Path == "/_health/ping" {
180 time.Sleep(3 * time.Second)
181 resp.Write([]byte(`{"health":"OK"}`))
183 http.Error(resp, "not found", http.StatusNotFound)
187 func (s *AggregatorSuite) TestPingTimeout(c *check.C) {
188 s.handler.timeout = arvados.Duration(100 * time.Millisecond)
189 srv, listen := s.stubServer(&slowHandler{})
191 s.handler.Config.Clusters["zzzzz"].SystemNodes["localhost"] = arvados.SystemNode{
192 Keepstore: arvados.SystemServiceInstance{Listen: listen},
194 s.handler.ServeHTTP(s.resp, s.req)
195 resp := s.checkUnhealthy(c)
196 ep := resp.Checks["keepstore+http://localhost"+listen+"/_health/ping"]
197 c.Check(ep.Health, check.Equals, "ERROR")
198 c.Check(ep.HTTPStatusCode, check.Equals, 0)
199 rt, err := ep.ResponseTime.Float64()
200 c.Check(err, check.IsNil)
201 c.Check(rt > 0.005, check.Equals, true)