X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/57647945b08a74bab02fed6adf947eb9adb8321f..8a2035547ad8bf6abad6a4a03bb0b59211a00932:/services/keepproxy/keepproxy_test.go diff --git a/services/keepproxy/keepproxy_test.go b/services/keepproxy/keepproxy_test.go index 25619bbb91..de72e747f3 100644 --- a/services/keepproxy/keepproxy_test.go +++ b/services/keepproxy/keepproxy_test.go @@ -10,11 +10,12 @@ import ( "errors" "fmt" "io/ioutil" - "log" + "math/rand" "net/http" "net/http/httptest" "os" "strings" + "sync" "testing" "time" @@ -55,7 +56,7 @@ func waitForListener() { time.Sleep(ms * time.Millisecond) } if listener == nil { - log.Fatalf("Timed out waiting for listener to start") + panic("Timed out waiting for listener to start") } } @@ -216,6 +217,33 @@ func (s *ServerRequiredSuite) TestPutWrongContentLength(c *C) { } } +func (s *ServerRequiredSuite) TestManyFailedPuts(c *C) { + kc := runProxy(c, nil, false) + defer closeListener() + router.(*proxyHandler).timeout = time.Nanosecond + + buf := make([]byte, 1<<20) + rand.Read(buf) + var wg sync.WaitGroup + for i := 0; i < 128; i++ { + wg.Add(1) + go func() { + defer wg.Done() + kc.PutB(buf) + }() + } + done := make(chan bool) + go func() { + wg.Wait() + close(done) + }() + select { + case <-done: + case <-time.After(10 * time.Second): + c.Error("timeout") + } +} + func (s *ServerRequiredSuite) TestPutAskGet(c *C) { kc := runProxy(c, nil, false) defer closeListener() @@ -226,14 +254,14 @@ func (s *ServerRequiredSuite) TestPutAskGet(c *C) { { _, _, err := kc.Ask(hash) c.Check(err, Equals, keepclient.BlockNotFound) - log.Print("Finished Ask (expected BlockNotFound)") + c.Log("Finished Ask (expected BlockNotFound)") } { reader, _, _, err := kc.Get(hash) c.Check(reader, Equals, nil) c.Check(err, Equals, keepclient.BlockNotFound) - log.Print("Finished Get (expected BlockNotFound)") + c.Log("Finished Get (expected BlockNotFound)") } // Note in bug #5309 among other errors keepproxy would set @@ -252,14 +280,14 @@ func (s *ServerRequiredSuite) TestPutAskGet(c *C) { c.Check(hash2, Matches, fmt.Sprintf(`^%s\+3(\+.+)?$`, hash)) c.Check(rep, Equals, 2) c.Check(err, Equals, nil) - log.Print("Finished PutB (expected success)") + c.Log("Finished PutB (expected success)") } { blocklen, _, err := kc.Ask(hash2) c.Assert(err, Equals, nil) c.Check(blocklen, Equals, int64(3)) - log.Print("Finished Ask (expected success)") + c.Log("Finished Ask (expected success)") } { @@ -268,7 +296,7 @@ func (s *ServerRequiredSuite) TestPutAskGet(c *C) { all, err := ioutil.ReadAll(reader) c.Check(all, DeepEquals, []byte("foo")) c.Check(blocklen, Equals, int64(3)) - log.Print("Finished Get (expected success)") + c.Log("Finished Get (expected success)") } { @@ -278,7 +306,7 @@ func (s *ServerRequiredSuite) TestPutAskGet(c *C) { c.Check(hash2, Matches, `^d41d8cd98f00b204e9800998ecf8427e\+0(\+.+)?$`) c.Check(rep, Equals, 2) c.Check(err, Equals, nil) - log.Print("Finished PutB zero block") + c.Log("Finished PutB zero block") } { @@ -287,7 +315,7 @@ func (s *ServerRequiredSuite) TestPutAskGet(c *C) { all, err := ioutil.ReadAll(reader) c.Check(all, DeepEquals, []byte("")) c.Check(blocklen, Equals, int64(0)) - log.Print("Finished Get zero block") + c.Log("Finished Get zero block") } } @@ -295,41 +323,26 @@ func (s *ServerRequiredSuite) TestPutAskGetForbidden(c *C) { kc := runProxy(c, nil, true) defer closeListener() - hash := fmt.Sprintf("%x", md5.Sum([]byte("bar"))) + hash := fmt.Sprintf("%x+3", md5.Sum([]byte("bar"))) - { - _, _, err := kc.Ask(hash) - errNotFound, _ := err.(keepclient.ErrNotFound) - c.Check(errNotFound, NotNil) - c.Assert(strings.Contains(err.Error(), "HTTP 403"), Equals, true) - log.Print("Ask 1") - } + _, _, err := kc.Ask(hash) + c.Check(err, FitsTypeOf, &keepclient.ErrNotFound{}) - { - hash2, rep, err := kc.PutB([]byte("bar")) - c.Check(hash2, Equals, "") - c.Check(rep, Equals, 0) - c.Check(err, FitsTypeOf, keepclient.InsufficientReplicasError(errors.New(""))) - log.Print("PutB") - } + hash2, rep, err := kc.PutB([]byte("bar")) + c.Check(hash2, Equals, "") + c.Check(rep, Equals, 0) + c.Check(err, FitsTypeOf, keepclient.InsufficientReplicasError(errors.New(""))) - { - blocklen, _, err := kc.Ask(hash) - errNotFound, _ := err.(keepclient.ErrNotFound) - c.Check(errNotFound, NotNil) - c.Assert(strings.Contains(err.Error(), "HTTP 403"), Equals, true) - c.Check(blocklen, Equals, int64(0)) - log.Print("Ask 2") - } + blocklen, _, err := kc.Ask(hash) + c.Check(err, FitsTypeOf, &keepclient.ErrNotFound{}) + c.Check(err, ErrorMatches, ".*not found.*") + c.Check(blocklen, Equals, int64(0)) + + _, blocklen, _, err = kc.Get(hash) + c.Check(err, FitsTypeOf, &keepclient.ErrNotFound{}) + c.Check(err, ErrorMatches, ".*not found.*") + c.Check(blocklen, Equals, int64(0)) - { - _, blocklen, _, err := kc.Get(hash) - errNotFound, _ := err.(keepclient.ErrNotFound) - c.Check(errNotFound, NotNil) - c.Assert(strings.Contains(err.Error(), "HTTP 403"), Equals, true) - c.Check(blocklen, Equals, int64(0)) - log.Print("Get") - } } func (s *ServerRequiredSuite) TestGetDisabled(c *C) { @@ -342,8 +355,8 @@ func (s *ServerRequiredSuite) TestGetDisabled(c *C) { _, _, err := kc.Ask(hash) errNotFound, _ := err.(keepclient.ErrNotFound) c.Check(errNotFound, NotNil) - c.Assert(strings.Contains(err.Error(), "HTTP 400"), Equals, true) - log.Print("Ask 1") + c.Assert(err, ErrorMatches, `.*HTTP 405.*`) + c.Log("Ask 1") } { @@ -351,25 +364,25 @@ func (s *ServerRequiredSuite) TestGetDisabled(c *C) { c.Check(hash2, Matches, fmt.Sprintf(`^%s\+3(\+.+)?$`, hash)) c.Check(rep, Equals, 2) c.Check(err, Equals, nil) - log.Print("PutB") + c.Log("PutB") } { blocklen, _, err := kc.Ask(hash) errNotFound, _ := err.(keepclient.ErrNotFound) c.Check(errNotFound, NotNil) - c.Assert(strings.Contains(err.Error(), "HTTP 400"), Equals, true) + c.Assert(err, ErrorMatches, `.*HTTP 405.*`) c.Check(blocklen, Equals, int64(0)) - log.Print("Ask 2") + c.Log("Ask 2") } { _, blocklen, _, err := kc.Get(hash) errNotFound, _ := err.(keepclient.ErrNotFound) c.Check(errNotFound, NotNil) - c.Assert(strings.Contains(err.Error(), "HTTP 400"), Equals, true) + c.Assert(err, ErrorMatches, `.*HTTP 405.*`) c.Check(blocklen, Equals, int64(0)) - log.Print("Get") + c.Log("Get") } } @@ -516,35 +529,53 @@ func (s *ServerRequiredSuite) TestGetIndex(c *C) { c.Assert((err != nil), Equals, true) } +func (s *ServerRequiredSuite) TestCollectionSharingToken(c *C) { + kc := runProxy(c, nil, false) + defer closeListener() + hash, _, err := kc.PutB([]byte("shareddata")) + c.Check(err, IsNil) + kc.Arvados.ApiToken = arvadostest.FooCollectionSharingToken + rdr, _, _, err := kc.Get(hash) + c.Assert(err, IsNil) + data, err := ioutil.ReadAll(rdr) + c.Check(err, IsNil) + c.Check(data, DeepEquals, []byte("shareddata")) +} + func (s *ServerRequiredSuite) TestPutAskGetInvalidToken(c *C) { kc := runProxy(c, nil, false) defer closeListener() // Put a test block hash, rep, err := kc.PutB([]byte("foo")) - c.Check(err, Equals, nil) + c.Check(err, IsNil) c.Check(rep, Equals, 2) - for _, token := range []string{ + for _, badToken := range []string{ "nosuchtoken", "2ym314ysp27sk7h943q6vtc378srb06se3pq6ghurylyf3pdmx", // expired } { - // Change token to given bad token - kc.Arvados.ApiToken = token + kc.Arvados.ApiToken = badToken + + // Ask and Get will fail only if the upstream + // keepstore server checks for valid signatures. + // Without knowing the blob signing key, there is no + // way for keepproxy to know whether a given token is + // permitted to read a block. So these tests fail: + if false { + _, _, err = kc.Ask(hash) + c.Assert(err, FitsTypeOf, &keepclient.ErrNotFound{}) + c.Check(err.(*keepclient.ErrNotFound).Temporary(), Equals, false) + c.Check(err, ErrorMatches, ".*HTTP 403.*") + + _, _, _, err = kc.Get(hash) + c.Assert(err, FitsTypeOf, &keepclient.ErrNotFound{}) + c.Check(err.(*keepclient.ErrNotFound).Temporary(), Equals, false) + c.Check(err, ErrorMatches, ".*HTTP 403 \"Missing or invalid Authorization header\".*") + } - // Ask should result in error - _, _, err = kc.Ask(hash) - c.Check(err, NotNil) - errNotFound, _ := err.(keepclient.ErrNotFound) - c.Check(errNotFound.Temporary(), Equals, false) - c.Assert(strings.Contains(err.Error(), "HTTP 403"), Equals, true) - - // Get should result in error - _, _, _, err = kc.Get(hash) - c.Check(err, NotNil) - errNotFound, _ = err.(keepclient.ErrNotFound) - c.Check(errNotFound.Temporary(), Equals, false) - c.Assert(strings.Contains(err.Error(), "HTTP 403 \"Missing or invalid Authorization header\""), Equals, true) + _, _, err = kc.PutB([]byte("foo")) + c.Check(err, ErrorMatches, ".*403.*Missing or invalid Authorization header") } } @@ -565,14 +596,14 @@ func (s *ServerRequiredSuite) TestAskGetKeepProxyConnectionError(c *C) { c.Check(err, NotNil) errNotFound, _ := err.(*keepclient.ErrNotFound) c.Check(errNotFound.Temporary(), Equals, true) - c.Assert(strings.Contains(err.Error(), "connection refused"), Equals, true) + c.Assert(err, ErrorMatches, ".*connection refused.*") // Get should result in temporary connection refused error _, _, _, err = kc.Get(hash) c.Check(err, NotNil) errNotFound, _ = err.(*keepclient.ErrNotFound) c.Check(errNotFound.Temporary(), Equals, true) - c.Assert(strings.Contains(err.Error(), "connection refused"), Equals, true) + c.Assert(err, ErrorMatches, ".*connection refused.*") } func (s *NoKeepServerSuite) TestAskGetNoKeepServerError(c *C) { @@ -613,5 +644,5 @@ func (s *ServerRequiredSuite) TestPing(c *C) { resp := httptest.NewRecorder() rtr.ServeHTTP(resp, req) c.Check(resp.Code, Equals, 200) - c.Assert(strings.Contains(resp.Body.String(), `{"health":"OK"}`), Equals, true) + c.Assert(resp.Body.String(), Matches, `{"health":"OK"}\n?`) }