X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/060d38d627bd1e51dd2b3c6e7de9af6aa7d7b6f3..8a2c490a3905dc85a438ea92aa5b020a87d7b8b0:/services/keepstore/mounts_test.go diff --git a/services/keepstore/mounts_test.go b/services/keepstore/mounts_test.go index b4544d0f92..ac30c369a5 100644 --- a/services/keepstore/mounts_test.go +++ b/services/keepstore/mounts_test.go @@ -5,12 +5,14 @@ package main import ( + "bytes" "context" "encoding/json" "net/http" "net/http/httptest" "git.curoverse.com/arvados.git/sdk/go/arvadostest" + "github.com/prometheus/client_golang/prometheus" check "gopkg.in/check.v1" ) @@ -24,15 +26,19 @@ type MountsSuite struct { func (s *MountsSuite) SetUpTest(c *check.C) { s.vm = MakeTestVolumeManager(2) KeepVM = s.vm - s.rtr = MakeRESTRouter() + theConfig = DefaultConfig() theConfig.systemAuthToken = arvadostest.DataManagerToken + theConfig.ManagementToken = arvadostest.ManagementToken + r := prometheus.NewRegistry() + theConfig.Start(r) + s.rtr = MakeRESTRouter(testCluster, r) } func (s *MountsSuite) TearDownTest(c *check.C) { s.vm.Close() KeepVM = nil theConfig = DefaultConfig() - theConfig.Start() + theConfig.Start(prometheus.NewRegistry()) } func (s *MountsSuite) TestMounts(c *check.C) { @@ -40,14 +46,14 @@ func (s *MountsSuite) TestMounts(c *check.C) { vols[0].Put(context.Background(), TestHash, TestBlock) vols[1].Put(context.Background(), TestHash2, TestBlock2) - resp := s.call("GET", "/mounts", "") + resp := s.call("GET", "/mounts", "", nil) c.Check(resp.Code, check.Equals, http.StatusOK) var mntList []struct { - UUID string - DeviceID string - ReadOnly bool - Replication int - Tier int + UUID string `json:"uuid"` + DeviceID string `json:"device_id"` + ReadOnly bool `json:"read_only"` + Replication int `json:"replication"` + StorageClasses []string `json:"storage_classes"` } err := json.Unmarshal(resp.Body.Bytes(), &mntList) c.Assert(err, check.IsNil) @@ -58,13 +64,13 @@ func (s *MountsSuite) TestMounts(c *check.C) { c.Check(m.DeviceID, check.Equals, "mock-device-id") c.Check(m.ReadOnly, check.Equals, false) c.Check(m.Replication, check.Equals, 1) - c.Check(m.Tier, check.Equals, 1) + c.Check(m.StorageClasses, check.DeepEquals, []string{"default"}) } c.Check(mntList[0].UUID, check.Not(check.Equals), mntList[1].UUID) // Bad auth for _, tok := range []string{"", "xyzzy"} { - resp = s.call("GET", "/mounts/"+mntList[1].UUID+"/blocks", tok) + resp = s.call("GET", "/mounts/"+mntList[1].UUID+"/blocks", tok, nil) c.Check(resp.Code, check.Equals, http.StatusUnauthorized) c.Check(resp.Body.String(), check.Equals, "Unauthorized\n") } @@ -72,36 +78,100 @@ func (s *MountsSuite) TestMounts(c *check.C) { tok := arvadostest.DataManagerToken // Nonexistent mount UUID - resp = s.call("GET", "/mounts/X/blocks", tok) + resp = s.call("GET", "/mounts/X/blocks", tok, nil) c.Check(resp.Code, check.Equals, http.StatusNotFound) c.Check(resp.Body.String(), check.Equals, "mount not found\n") // Complete index of first mount - resp = s.call("GET", "/mounts/"+mntList[0].UUID+"/blocks", tok) + resp = s.call("GET", "/mounts/"+mntList[0].UUID+"/blocks", tok, nil) c.Check(resp.Code, check.Equals, http.StatusOK) c.Check(resp.Body.String(), check.Matches, TestHash+`\+[0-9]+ [0-9]+\n\n`) // Partial index of first mount (one block matches prefix) - resp = s.call("GET", "/mounts/"+mntList[0].UUID+"/blocks?prefix="+TestHash[:2], tok) + resp = s.call("GET", "/mounts/"+mntList[0].UUID+"/blocks?prefix="+TestHash[:2], tok, nil) c.Check(resp.Code, check.Equals, http.StatusOK) c.Check(resp.Body.String(), check.Matches, TestHash+`\+[0-9]+ [0-9]+\n\n`) // Complete index of second mount (note trailing slash) - resp = s.call("GET", "/mounts/"+mntList[1].UUID+"/blocks/", tok) + resp = s.call("GET", "/mounts/"+mntList[1].UUID+"/blocks/", tok, nil) c.Check(resp.Code, check.Equals, http.StatusOK) c.Check(resp.Body.String(), check.Matches, TestHash2+`\+[0-9]+ [0-9]+\n\n`) // Partial index of second mount (no blocks match prefix) - resp = s.call("GET", "/mounts/"+mntList[1].UUID+"/blocks/?prefix="+TestHash[:2], tok) + resp = s.call("GET", "/mounts/"+mntList[1].UUID+"/blocks/?prefix="+TestHash[:2], tok, nil) c.Check(resp.Code, check.Equals, http.StatusOK) c.Check(resp.Body.String(), check.Equals, "\n") } -func (s *MountsSuite) call(method, path, tok string) *httptest.ResponseRecorder { +func (s *MountsSuite) TestMetrics(c *check.C) { + s.call("PUT", "/"+TestHash, "", TestBlock) + s.call("PUT", "/"+TestHash2, "", TestBlock2) + resp := s.call("GET", "/metrics.json", "", nil) + c.Check(resp.Code, check.Equals, http.StatusUnauthorized) + resp = s.call("GET", "/metrics.json", "foobar", nil) + c.Check(resp.Code, check.Equals, http.StatusForbidden) + resp = s.call("GET", "/metrics.json", arvadostest.ManagementToken, nil) + c.Check(resp.Code, check.Equals, http.StatusOK) + var j []struct { + Name string + Help string + Type string + Metric []struct { + Label []struct { + Name string + Value string + } + Summary struct { + SampleCount string `json:"sample_count"` + SampleSum float64 `json:"sample_sum"` + Quantile []struct { + Quantile float64 + Value float64 + } + } + } + } + json.NewDecoder(resp.Body).Decode(&j) + found := make(map[string]bool) + names := map[string]bool{} + for _, g := range j { + names[g.Name] = true + for _, m := range g.Metric { + if len(m.Label) == 2 && m.Label[0].Name == "code" && m.Label[0].Value == "200" && m.Label[1].Name == "method" && m.Label[1].Value == "put" { + c.Check(m.Summary.SampleCount, check.Equals, "2") + c.Check(len(m.Summary.Quantile), check.Not(check.Equals), 0) + c.Check(m.Summary.Quantile[0].Value, check.Not(check.Equals), float64(0)) + found[g.Name] = true + } + } + } + c.Check(found["request_duration_seconds"], check.Equals, true) + c.Check(found["time_to_status_seconds"], check.Equals, true) + + metricsNames := []string{ + "arvados_keepstore_bufferpool_buffers_in_use", + "arvados_keepstore_bufferpool_buffers_max", + "arvados_keepstore_bufferpool_bytes_allocated", + "arvados_keepstore_pull_queue_in_progress", + "arvados_keepstore_pull_queue_queued", + "arvados_keepstore_requests_current", + "arvados_keepstore_requests_max", + "arvados_keepstore_trash_queue_in_progress", + "arvados_keepstore_trash_queue_queued", + "request_duration_seconds", + "time_to_status_seconds", + } + for _, m := range metricsNames { + _, ok := names[m] + c.Check(ok, check.Equals, true) + } +} + +func (s *MountsSuite) call(method, path, tok string, body []byte) *httptest.ResponseRecorder { resp := httptest.NewRecorder() - req, _ := http.NewRequest(method, path, nil) + req, _ := http.NewRequest(method, path, bytes.NewReader(body)) if tok != "" { - req.Header.Set("Authorization", "OAuth2 "+tok) + req.Header.Set("Authorization", "Bearer "+tok) } s.rtr.ServeHTTP(resp, req) return resp