X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/a1745a13f68363598cc121b617436f3ac5b1654d..fa9a17bf1ea10d9130188730a1aa160e89daaa13:/services/keepstore/proxy_remote_test.go diff --git a/services/keepstore/proxy_remote_test.go b/services/keepstore/proxy_remote_test.go index b15e0b0683..a244561dfa 100644 --- a/services/keepstore/proxy_remote_test.go +++ b/services/keepstore/proxy_remote_test.go @@ -5,6 +5,7 @@ package main import ( + "context" "crypto/md5" "encoding/json" "fmt" @@ -16,10 +17,11 @@ import ( "sync/atomic" "time" - "git.curoverse.com/arvados.git/sdk/go/arvados" - "git.curoverse.com/arvados.git/sdk/go/arvadostest" - "git.curoverse.com/arvados.git/sdk/go/auth" - "git.curoverse.com/arvados.git/sdk/go/keepclient" + "git.arvados.org/arvados.git/sdk/go/arvados" + "git.arvados.org/arvados.git/sdk/go/arvadostest" + "git.arvados.org/arvados.git/sdk/go/auth" + "git.arvados.org/arvados.git/sdk/go/keepclient" + "github.com/prometheus/client_golang/prometheus" check "gopkg.in/check.v1" ) @@ -27,8 +29,7 @@ var _ = check.Suite(&ProxyRemoteSuite{}) type ProxyRemoteSuite struct { cluster *arvados.Cluster - vm VolumeManager - rtr http.Handler + handler *handler remoteClusterID string remoteBlobSigningKey []byte @@ -86,7 +87,9 @@ func (s *ProxyRemoteSuite) SetUpTest(c *check.C) { s.remoteKeepproxy = httptest.NewServer(http.HandlerFunc(s.remoteKeepproxyHandler)) s.remoteAPI = httptest.NewUnstartedServer(http.HandlerFunc(s.remoteAPIHandler)) s.remoteAPI.StartTLS() - s.cluster = arvados.IntegrationTestCluster() + s.cluster = testCluster(c) + s.cluster.Collections.BlobSigningKey = knownKey + s.cluster.SystemRootToken = arvadostest.SystemRootToken s.cluster.RemoteClusters = map[string]arvados.RemoteCluster{ s.remoteClusterID: arvados.RemoteCluster{ Host: strings.Split(s.remoteAPI.URL, "//")[1], @@ -95,19 +98,12 @@ func (s *ProxyRemoteSuite) SetUpTest(c *check.C) { Insecure: true, }, } - s.vm = MakeTestVolumeManager(2) - KeepVM = s.vm - theConfig = DefaultConfig() - theConfig.systemAuthToken = arvadostest.DataManagerToken - theConfig.Start() - s.rtr = MakeRESTRouter(s.cluster) + s.cluster.Volumes = map[string]arvados.Volume{"zzzzz-nyw5e-000000000000000": {Driver: "mock"}} + s.handler = &handler{} + c.Assert(s.handler.setup(context.Background(), s.cluster, "", prometheus.NewRegistry(), testServiceURL), check.IsNil) } func (s *ProxyRemoteSuite) TearDownTest(c *check.C) { - s.vm.Close() - KeepVM = nil - theConfig = DefaultConfig() - theConfig.Start() s.remoteAPI.Close() s.remoteKeepproxy.Close() } @@ -122,28 +118,59 @@ func (s *ProxyRemoteSuite) TestProxyRemote(c *check.C) { for _, trial := range []struct { label string + method string token string + xKeepSignature string expectRemoteReqs int64 expectCode int + expectSignature bool }{ { - label: "happy path", + label: "GET only", + method: "GET", token: arvadostest.ActiveTokenV2, expectRemoteReqs: 1, expectCode: http.StatusOK, }, { label: "obsolete token", + method: "GET", token: arvadostest.ActiveToken, expectRemoteReqs: 0, expectCode: http.StatusBadRequest, }, { label: "bad token", + method: "GET", token: arvadostest.ActiveTokenV2[:len(arvadostest.ActiveTokenV2)-3] + "xxx", expectRemoteReqs: 1, expectCode: http.StatusNotFound, }, + { + label: "HEAD only", + method: "HEAD", + token: arvadostest.ActiveTokenV2, + expectRemoteReqs: 1, + expectCode: http.StatusOK, + }, + { + label: "HEAD with local signature", + method: "HEAD", + xKeepSignature: "local, time=" + time.Now().Format(time.RFC3339), + token: arvadostest.ActiveTokenV2, + expectRemoteReqs: 1, + expectCode: http.StatusOK, + expectSignature: true, + }, + { + label: "GET with local signature", + method: "GET", + xKeepSignature: "local, time=" + time.Now().Format(time.RFC3339), + token: arvadostest.ActiveTokenV2, + expectRemoteReqs: 1, + expectCode: http.StatusOK, + expectSignature: true, + }, } { c.Logf("trial: %s", trial.label) @@ -151,10 +178,13 @@ func (s *ProxyRemoteSuite) TestProxyRemote(c *check.C) { var req *http.Request var resp *httptest.ResponseRecorder - req = httptest.NewRequest("GET", path, nil) + req = httptest.NewRequest(trial.method, path, nil) req.Header.Set("Authorization", "Bearer "+trial.token) + if trial.xKeepSignature != "" { + req.Header.Set("X-Keep-Signature", trial.xKeepSignature) + } resp = httptest.NewRecorder() - s.rtr.ServeHTTP(resp, req) + s.handler.ServeHTTP(resp, req) c.Check(s.remoteKeepRequests, check.Equals, trial.expectRemoteReqs) c.Check(resp.Code, check.Equals, trial.expectCode) if resp.Code == http.StatusOK { @@ -162,5 +192,25 @@ func (s *ProxyRemoteSuite) TestProxyRemote(c *check.C) { } else { c.Check(resp.Body.String(), check.Not(check.Equals), string(data)) } + + c.Check(resp.Header().Get("Vary"), check.Matches, `(.*, )?X-Keep-Signature(, .*)?`) + + locHdr := resp.Header().Get("X-Keep-Locator") + if !trial.expectSignature { + c.Check(locHdr, check.Equals, "") + continue + } + + c.Check(locHdr, check.Not(check.Equals), "") + c.Check(locHdr, check.Not(check.Matches), `.*\+R.*`) + c.Check(VerifySignature(s.cluster, locHdr, trial.token), check.IsNil) + + // Ensure block can be requested using new signature + req = httptest.NewRequest("GET", "/"+locHdr, nil) + req.Header.Set("Authorization", "Bearer "+trial.token) + resp = httptest.NewRecorder() + s.handler.ServeHTTP(resp, req) + c.Check(resp.Code, check.Equals, http.StatusOK) + c.Check(s.remoteKeepRequests, check.Equals, trial.expectRemoteReqs) } }