13198: Test case for keep-web metrics.
authorTom Clegg <tclegg@veritasgenetics.com>
Mon, 16 Jul 2018 19:01:42 +0000 (15:01 -0400)
committerTom Clegg <tclegg@veritasgenetics.com>
Mon, 16 Jul 2018 19:01:42 +0000 (15:01 -0400)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg@veritasgenetics.com>

services/keep-web/handler_test.go
services/keep-web/server.go
services/keep-web/server_test.go

index 206bf6f4381fd98d4e7c4244e787c040de558aad..68ed062160401e59bb79479c71fbfde21a2495e1 100644 (file)
@@ -29,7 +29,7 @@ type UnitSuite struct{}
 
 func (s *UnitSuite) TestCORSPreflight(c *check.C) {
        h := handler{Config: DefaultConfig()}
-       u, _ := url.Parse("http://keep-web.example/c=" + arvadostest.FooCollection + "/foo")
+       u := mustParseURL("http://keep-web.example/c=" + arvadostest.FooCollection + "/foo")
        req := &http.Request{
                Method:     "OPTIONS",
                Host:       u.Host,
@@ -70,8 +70,7 @@ func (s *UnitSuite) TestInvalidUUID(c *check.C) {
                "http://" + bogusID + ".keep-web/t=" + token + "/" + bogusID + "/foo",
        } {
                c.Log(trial)
-               u, err := url.Parse(trial)
-               c.Assert(err, check.IsNil)
+               u := mustParseURL(trial)
                req := &http.Request{
                        Method:     "GET",
                        Host:       u.Host,
index e51376c3bc35cc10a92bf5a6f7c646a18bea3476..269f5d36896a6b7ea8f1bf40bd23b547cd8acadb 100644 (file)
@@ -14,7 +14,7 @@ type server struct {
 }
 
 func (srv *server) Start() error {
-       srv.Handler = httpserver.AddRequestIDs(httpserver.LogRequests(nil, &handler{Config: srv.Config}))
+       srv.Handler = httpserver.Instrument(nil, httpserver.AddRequestIDs(httpserver.LogRequests(nil, &handler{Config: srv.Config})))
        srv.Addr = srv.Config.Listen
        return srv.Server.Start()
 }
index ee585ad5b212af1f12f2bad3f162f8c1c11f3a2f..63a84289c31b9bba94bfaa1215489320c387dd3f 100644 (file)
@@ -6,10 +6,12 @@ package main
 
 import (
        "crypto/md5"
+       "encoding/json"
        "fmt"
        "io"
        "io/ioutil"
        "net"
+       "net/http"
        "os"
        "os/exec"
        "strings"
@@ -294,6 +296,75 @@ func (s *IntegrationSuite) runCurl(c *check.C, token, host, uri string, args ...
        return
 }
 
+func (s *IntegrationSuite) TestMetrics(c *check.C) {
+       origin := "http://" + s.testServer.Addr
+       req, _ := http.NewRequest("GET", origin+"/notfound", nil)
+       _, err := http.DefaultClient.Do(req)
+       c.Assert(err, check.IsNil)
+       req, _ = http.NewRequest("GET", origin+"/by_id/", nil)
+       req.Header.Set("Authorization", "Bearer "+arvadostest.ActiveToken)
+       resp, err := http.DefaultClient.Do(req)
+       c.Assert(err, check.IsNil)
+       c.Check(resp.StatusCode, check.Equals, http.StatusOK)
+       req, _ = http.NewRequest("GET", origin+"/foo", nil)
+       req.Host = arvadostest.FooCollection + ".example.com"
+       req.Header.Set("Authorization", "Bearer "+arvadostest.ActiveToken)
+       resp, err = http.DefaultClient.Do(req)
+       c.Assert(err, check.IsNil)
+       c.Check(resp.StatusCode, check.Equals, http.StatusOK)
+       buf, _ := ioutil.ReadAll(resp.Body)
+       c.Check(buf, check.DeepEquals, []byte("foo"))
+
+       req, _ = http.NewRequest("GET", origin+"/metrics.json", nil)
+       resp, err = http.DefaultClient.Do(req)
+       c.Assert(err, check.IsNil)
+       c.Check(resp.StatusCode, check.Equals, http.StatusOK)
+       type summary struct {
+               SampleCount string  `json:"sample_count"`
+               SampleSum   float64 `json:"sample_sum"`
+               Quantile    []struct {
+                       Quantile float64
+                       Value    float64
+               }
+       }
+       var ents []struct {
+               Name   string
+               Help   string
+               Type   string
+               Metric []struct {
+                       Label []struct {
+                               Name  string
+                               Value string
+                       }
+                       Summary summary
+               }
+       }
+       json.NewDecoder(resp.Body).Decode(&ents)
+       flat := map[string]summary{}
+       for _, e := range ents {
+               for _, m := range e.Metric {
+                       labels := map[string]string{}
+                       for _, lbl := range m.Label {
+                               labels[lbl.Name] = lbl.Value
+                       }
+                       flat[e.Name+"/"+labels["method"]+"/"+labels["code"]] = m.Summary
+               }
+       }
+       c.Check(flat["request_duration_seconds/get/200"].SampleSum, check.Not(check.Equals), 0)
+       c.Check(flat["request_duration_seconds/get/200"].SampleCount, check.Equals, "2")
+       c.Check(flat["request_duration_seconds/get/404"].SampleCount, check.Equals, "1")
+       c.Check(flat["time_to_status_seconds/get/404"].SampleCount, check.Equals, "1")
+
+       // If the Host header indicates a collection, /metrics.json
+       // refers to a file in the collection -- the metrics handler
+       // must not intercept that route.
+       req, _ = http.NewRequest("GET", origin+"/metrics.json", nil)
+       req.Host = strings.Replace(arvadostest.FooCollectionPDH, "+", "-", -1) + ".example.com"
+       resp, err = http.DefaultClient.Do(req)
+       c.Assert(err, check.IsNil)
+       c.Check(resp.StatusCode, check.Equals, http.StatusNotFound)
+}
+
 func (s *IntegrationSuite) SetUpSuite(c *check.C) {
        arvadostest.StartAPI()
        arvadostest.StartKeep(2, true)