1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
14 "git.arvados.org/arvados.git/sdk/go/arvados"
15 "git.arvados.org/arvados.git/sdk/go/arvadostest"
19 func (s *IntegrationSuite) checkCacheMetrics(c *check.C, regs ...string) {
20 s.handler.Cache.updateGauges()
21 mm := arvadostest.GatherMetricsAsString(s.handler.Cache.registry)
22 // Remove comments to make the "value vs. regexp" failure
23 // output easier to read.
24 mm = regexp.MustCompile(`(?m)^#.*\n`).ReplaceAllString(mm, "")
25 for _, reg := range regs {
26 c.Check(mm, check.Matches, `(?ms).*keepweb_sessions_`+reg+`\n.*`)
30 func (s *IntegrationSuite) TestCache(c *check.C) {
31 // Hit the same collection 5 times using the same token. Only
32 // the first req should cause an API call; the next 4 should
34 u := mustParseURL("http://" + arvadostest.FooCollection + ".keep-web.example/foo")
39 RequestURI: u.RequestURI(),
41 "Authorization": {"Bearer " + arvadostest.ActiveToken},
44 for i := 0; i < 5; i++ {
45 resp := httptest.NewRecorder()
46 s.handler.ServeHTTP(resp, req)
47 c.Check(resp.Code, check.Equals, http.StatusOK)
49 s.checkCacheMetrics(c,
54 // Hit a shared collection 3 times using PDH, using a
56 u2 := mustParseURL("http://" + strings.Replace(arvadostest.BarFileCollectionPDH, "+", "-", 1) + ".keep-web.example/bar")
57 req2 := &http.Request{
61 RequestURI: u2.RequestURI(),
63 "Authorization": {"Bearer " + arvadostest.SpectatorToken},
66 for i := 0; i < 3; i++ {
67 resp2 := httptest.NewRecorder()
68 s.handler.ServeHTTP(resp2, req2)
69 c.Check(resp2.Code, check.Equals, http.StatusOK)
71 s.checkCacheMetrics(c,
76 // Alternating between two collections/tokens N times should
77 // use the existing sessions.
78 for i := 0; i < 7; i++ {
79 resp := httptest.NewRecorder()
80 s.handler.ServeHTTP(resp, req)
81 c.Check(resp.Code, check.Equals, http.StatusOK)
83 resp2 := httptest.NewRecorder()
84 s.handler.ServeHTTP(resp2, req2)
85 c.Check(resp2.Code, check.Equals, http.StatusOK)
87 s.checkCacheMetrics(c,
93 func (s *IntegrationSuite) TestForceReloadPDH(c *check.C) {
94 filename := strings.Replace(time.Now().Format(time.RFC3339Nano), ":", ".", -1)
95 manifest := ". d41d8cd98f00b204e9800998ecf8427e+0 0:0:" + filename + "\n"
96 pdh := arvados.PortableDataHash(manifest)
97 client := arvados.NewClientFromEnv()
98 client.AuthToken = arvadostest.ActiveToken
100 _, resp := s.do("GET", "http://"+strings.Replace(pdh, "+", "-", 1)+".keep-web.example/"+filename, arvadostest.ActiveToken, nil)
101 c.Check(resp.Code, check.Equals, http.StatusNotFound)
103 var coll arvados.Collection
104 err := client.RequestAndDecode(&coll, "POST", "arvados/v1/collections", nil, map[string]interface{}{
105 "collection": map[string]string{
106 "manifest_text": manifest,
109 c.Assert(err, check.IsNil)
110 defer client.RequestAndDecode(nil, "DELETE", "arvados/v1/collections/"+coll.UUID, nil, nil)
111 c.Assert(coll.PortableDataHash, check.Equals, pdh)
113 _, resp = s.do("GET", "http://"+strings.Replace(pdh, "+", "-", 1)+".keep-web.example/"+filename, "", http.Header{
114 "Authorization": {"Bearer " + arvadostest.ActiveToken},
115 "Cache-Control": {"must-revalidate"},
117 c.Check(resp.Code, check.Equals, http.StatusOK)
119 _, resp = s.do("GET", "http://"+strings.Replace(pdh, "+", "-", 1)+".keep-web.example/missingfile", "", http.Header{
120 "Authorization": {"Bearer " + arvadostest.ActiveToken},
121 "Cache-Control": {"must-revalidate"},
123 c.Check(resp.Code, check.Equals, http.StatusNotFound)
126 func (s *IntegrationSuite) TestForceReloadUUID(c *check.C) {
127 client := arvados.NewClientFromEnv()
128 client.AuthToken = arvadostest.ActiveToken
129 var coll arvados.Collection
130 err := client.RequestAndDecode(&coll, "POST", "arvados/v1/collections", nil, map[string]interface{}{
131 "collection": map[string]string{
132 "manifest_text": ". d41d8cd98f00b204e9800998ecf8427e+0 0:0:empty_file\n",
135 c.Assert(err, check.IsNil)
136 defer client.RequestAndDecode(nil, "DELETE", "arvados/v1/collections/"+coll.UUID, nil, nil)
138 _, resp := s.do("GET", "http://"+coll.UUID+".keep-web.example/different_empty_file", arvadostest.ActiveToken, nil)
139 c.Check(resp.Code, check.Equals, http.StatusNotFound)
140 _, resp = s.do("GET", "http://"+coll.UUID+".keep-web.example/empty_file", arvadostest.ActiveToken, nil)
141 c.Check(resp.Code, check.Equals, http.StatusOK)
142 _, resp = s.do("GET", "http://"+coll.UUID+".keep-web.example/different_empty_file", arvadostest.ActiveToken, nil)
143 c.Check(resp.Code, check.Equals, http.StatusNotFound)
144 err = client.RequestAndDecode(&coll, "PATCH", "arvados/v1/collections/"+coll.UUID, nil, map[string]interface{}{
145 "collection": map[string]string{
146 "manifest_text": ". d41d8cd98f00b204e9800998ecf8427e+0 0:0:different_empty_file\n",
149 c.Assert(err, check.IsNil)
150 // Before we set the force-reload header, the cached version
151 // with empty_file is still accessible.
152 _, resp = s.do("GET", "http://"+coll.UUID+".keep-web.example/empty_file", arvadostest.ActiveToken, nil)
153 c.Check(resp.Code, check.Equals, http.StatusOK)
154 // If we set the force-reload header, we get the latest
155 // version and empty_file is gone.
156 _, resp = s.do("GET", "http://"+coll.UUID+".keep-web.example/empty_file", "", http.Header{
157 "Authorization": {"Bearer " + arvadostest.ActiveToken},
158 "Cache-Control": {"must-revalidate"},
160 c.Check(resp.Code, check.Equals, http.StatusNotFound)
161 _, resp = s.do("GET", "http://"+coll.UUID+".keep-web.example/different_empty_file", arvadostest.ActiveToken, nil)
162 c.Check(resp.Code, check.Equals, http.StatusOK)