7 "git.curoverse.com/arvados.git/sdk/go/arvadosclient"
8 "git.curoverse.com/arvados.git/sdk/go/arvadostest"
9 "git.curoverse.com/arvados.git/sdk/go/streamer"
20 // Gocheck boilerplate
21 func Test(t *testing.T) {
25 // Gocheck boilerplate
26 var _ = Suite(&ServerRequiredSuite{})
27 var _ = Suite(&StandaloneSuite{})
29 var no_server = flag.Bool("no-server", false, "Skip 'ServerRequireSuite'")
31 // Tests that require the Keep server running
32 type ServerRequiredSuite struct{}
35 type StandaloneSuite struct{}
37 func pythonDir() string {
39 return fmt.Sprintf("%s/../../python/tests", cwd)
42 func (s *ServerRequiredSuite) SetUpSuite(c *C) {
44 c.Skip("Skipping tests that require server")
47 arvadostest.StartAPI()
48 arvadostest.StartKeep()
51 func (s *ServerRequiredSuite) TearDownSuite(c *C) {
55 arvadostest.StopKeep()
59 func (s *ServerRequiredSuite) TestMakeKeepClient(c *C) {
60 arv, err := arvadosclient.MakeArvadosClient()
61 c.Assert(err, Equals, nil)
63 kc, err := MakeKeepClient(&arv)
65 c.Assert(err, Equals, nil)
66 c.Check(len(kc.LocalRoots()), Equals, 2)
67 for _, root := range kc.LocalRoots() {
68 c.Check(root, Matches, "http://localhost:\\d+")
72 type StubPutHandler struct {
80 func (sph StubPutHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
81 sph.c.Check(req.URL.Path, Equals, "/"+sph.expectPath)
82 sph.c.Check(req.Header.Get("Authorization"), Equals, fmt.Sprintf("OAuth2 %s", sph.expectApiToken))
83 body, err := ioutil.ReadAll(req.Body)
84 sph.c.Check(err, Equals, nil)
85 sph.c.Check(body, DeepEquals, []byte(sph.expectBody))
87 sph.handled <- fmt.Sprintf("http://%s", req.Host)
90 func RunFakeKeepServer(st http.Handler) (ks KeepServer) {
92 ks.listener, err = net.ListenTCP("tcp", &net.TCPAddr{Port: 0})
94 panic(fmt.Sprintf("Could not listen on any port"))
96 ks.url = fmt.Sprintf("http://%s", ks.listener.Addr().String())
97 go http.Serve(ks.listener, st)
101 func UploadToStubHelper(c *C, st http.Handler, f func(*KeepClient, string,
102 io.ReadCloser, io.WriteCloser, chan uploadStatus)) {
104 ks := RunFakeKeepServer(st)
105 defer ks.listener.Close()
107 arv, _ := arvadosclient.MakeArvadosClient()
108 arv.ApiToken = "abc123"
110 kc, _ := MakeKeepClient(&arv)
112 reader, writer := io.Pipe()
113 upload_status := make(chan uploadStatus)
115 f(kc, ks.url, reader, writer, upload_status)
118 func (s *StandaloneSuite) TestUploadToStubKeepServer(c *C) {
119 log.Printf("TestUploadToStubKeepServer")
121 st := StubPutHandler{
123 "acbd18db4cc2f85cedef654fccc4a4d8",
128 UploadToStubHelper(c, st,
129 func(kc *KeepClient, url string, reader io.ReadCloser,
130 writer io.WriteCloser, upload_status chan uploadStatus) {
132 go kc.uploadToKeepServer(url, st.expectPath, reader, upload_status, int64(len("foo")), "TestUploadToStubKeepServer")
134 writer.Write([]byte("foo"))
138 status := <-upload_status
139 c.Check(status, DeepEquals, uploadStatus{nil, fmt.Sprintf("%s/%s", url, st.expectPath), 200, 1, ""})
142 log.Printf("TestUploadToStubKeepServer done")
145 func (s *StandaloneSuite) TestUploadToStubKeepServerBufferReader(c *C) {
146 log.Printf("TestUploadToStubKeepServerBufferReader")
148 st := StubPutHandler{
150 "acbd18db4cc2f85cedef654fccc4a4d8",
155 UploadToStubHelper(c, st,
156 func(kc *KeepClient, url string, reader io.ReadCloser,
157 writer io.WriteCloser, upload_status chan uploadStatus) {
159 tr := streamer.AsyncStreamFromReader(512, reader)
162 br1 := tr.MakeStreamReader()
164 go kc.uploadToKeepServer(url, st.expectPath, br1, upload_status, 3, "TestUploadToStubKeepServerBufferReader")
166 writer.Write([]byte("foo"))
171 status := <-upload_status
172 c.Check(status, DeepEquals, uploadStatus{nil, fmt.Sprintf("%s/%s", url, st.expectPath), 200, 1, ""})
175 log.Printf("TestUploadToStubKeepServerBufferReader done")
178 type FailHandler struct {
182 func (fh FailHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
183 resp.WriteHeader(500)
184 fh.handled <- fmt.Sprintf("http://%s", req.Host)
187 func (s *StandaloneSuite) TestFailedUploadToStubKeepServer(c *C) {
188 log.Printf("TestFailedUploadToStubKeepServer")
193 hash := "acbd18db4cc2f85cedef654fccc4a4d8"
195 UploadToStubHelper(c, st,
196 func(kc *KeepClient, url string, reader io.ReadCloser,
197 writer io.WriteCloser, upload_status chan uploadStatus) {
199 go kc.uploadToKeepServer(url, hash, reader, upload_status, 3, "TestFailedUploadToStubKeepServer")
201 writer.Write([]byte("foo"))
206 status := <-upload_status
207 c.Check(status.url, Equals, fmt.Sprintf("%s/%s", url, hash))
208 c.Check(status.statusCode, Equals, 500)
210 log.Printf("TestFailedUploadToStubKeepServer done")
213 type KeepServer struct {
214 listener net.Listener
218 func RunSomeFakeKeepServers(st http.Handler, n int) (ks []KeepServer) {
219 ks = make([]KeepServer, n)
221 for i := 0; i < n; i += 1 {
222 ks[i] = RunFakeKeepServer(st)
228 func (s *StandaloneSuite) TestPutB(c *C) {
229 log.Printf("TestPutB")
231 hash := Md5String("foo")
233 st := StubPutHandler{
238 make(chan string, 5)}
240 arv, _ := arvadosclient.MakeArvadosClient()
241 kc, _ := MakeKeepClient(&arv)
244 arv.ApiToken = "abc123"
245 localRoots := make(map[string]string)
246 writableLocalRoots := make(map[string]string)
248 ks := RunSomeFakeKeepServers(st, 5)
250 for i, k := range ks {
251 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
252 writableLocalRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
253 defer k.listener.Close()
256 kc.SetServiceRoots(localRoots, writableLocalRoots, nil)
258 kc.PutB([]byte("foo"))
260 shuff := NewRootSorter(
261 kc.LocalRoots(), Md5String("foo")).GetSortedRoots()
265 c.Check((s1 == shuff[0] && s2 == shuff[1]) ||
266 (s1 == shuff[1] && s2 == shuff[0]),
270 log.Printf("TestPutB done")
273 func (s *StandaloneSuite) TestPutHR(c *C) {
274 log.Printf("TestPutHR")
276 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
278 st := StubPutHandler{
283 make(chan string, 5)}
285 arv, _ := arvadosclient.MakeArvadosClient()
286 kc, _ := MakeKeepClient(&arv)
289 arv.ApiToken = "abc123"
290 localRoots := make(map[string]string)
291 writableLocalRoots := make(map[string]string)
293 ks := RunSomeFakeKeepServers(st, 5)
295 for i, k := range ks {
296 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
297 writableLocalRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
298 defer k.listener.Close()
301 kc.SetServiceRoots(localRoots, writableLocalRoots, nil)
303 reader, writer := io.Pipe()
306 writer.Write([]byte("foo"))
310 kc.PutHR(hash, reader, 3)
312 shuff := NewRootSorter(kc.LocalRoots(), hash).GetSortedRoots()
318 c.Check((s1 == shuff[0] && s2 == shuff[1]) ||
319 (s1 == shuff[1] && s2 == shuff[0]),
323 log.Printf("TestPutHR done")
326 func (s *StandaloneSuite) TestPutWithFail(c *C) {
327 log.Printf("TestPutWithFail")
329 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
331 st := StubPutHandler{
336 make(chan string, 4)}
339 make(chan string, 1)}
341 arv, err := arvadosclient.MakeArvadosClient()
342 kc, _ := MakeKeepClient(&arv)
345 arv.ApiToken = "abc123"
346 localRoots := make(map[string]string)
347 writableLocalRoots := make(map[string]string)
349 ks1 := RunSomeFakeKeepServers(st, 4)
350 ks2 := RunSomeFakeKeepServers(fh, 1)
352 for i, k := range ks1 {
353 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
354 writableLocalRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
355 defer k.listener.Close()
357 for i, k := range ks2 {
358 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i+len(ks1))] = k.url
359 writableLocalRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i+len(ks1))] = k.url
360 defer k.listener.Close()
363 kc.SetServiceRoots(localRoots, writableLocalRoots, nil)
365 shuff := NewRootSorter(
366 kc.LocalRoots(), Md5String("foo")).GetSortedRoots()
368 phash, replicas, err := kc.PutB([]byte("foo"))
372 c.Check(err, Equals, nil)
373 c.Check(phash, Equals, "")
374 c.Check(replicas, Equals, 2)
379 c.Check((s1 == shuff[1] && s2 == shuff[2]) ||
380 (s1 == shuff[2] && s2 == shuff[1]),
385 func (s *StandaloneSuite) TestPutWithTooManyFail(c *C) {
386 log.Printf("TestPutWithTooManyFail")
388 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
390 st := StubPutHandler{
395 make(chan string, 1)}
398 make(chan string, 4)}
400 arv, err := arvadosclient.MakeArvadosClient()
401 kc, _ := MakeKeepClient(&arv)
404 arv.ApiToken = "abc123"
405 localRoots := make(map[string]string)
406 writableLocalRoots := make(map[string]string)
408 ks1 := RunSomeFakeKeepServers(st, 1)
409 ks2 := RunSomeFakeKeepServers(fh, 4)
411 for i, k := range ks1 {
412 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
413 writableLocalRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
414 defer k.listener.Close()
416 for i, k := range ks2 {
417 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i+len(ks1))] = k.url
418 writableLocalRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i+len(ks1))] = k.url
419 defer k.listener.Close()
422 kc.SetServiceRoots(localRoots, writableLocalRoots, nil)
424 _, replicas, err := kc.PutB([]byte("foo"))
426 c.Check(err, Equals, InsufficientReplicasError)
427 c.Check(replicas, Equals, 1)
428 c.Check(<-st.handled, Equals, ks1[0].url)
430 log.Printf("TestPutWithTooManyFail done")
433 type StubGetHandler struct {
436 expectApiToken string
441 func (sgh StubGetHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
442 sgh.c.Check(req.URL.Path, Equals, "/"+sgh.expectPath)
443 sgh.c.Check(req.Header.Get("Authorization"), Equals, fmt.Sprintf("OAuth2 %s", sgh.expectApiToken))
444 resp.WriteHeader(sgh.httpStatus)
445 resp.Header().Set("Content-Length", fmt.Sprintf("%d", len(sgh.body)))
449 func (s *StandaloneSuite) TestGet(c *C) {
450 log.Printf("TestGet")
452 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
454 st := StubGetHandler{
461 ks := RunFakeKeepServer(st)
462 defer ks.listener.Close()
464 arv, err := arvadosclient.MakeArvadosClient()
465 kc, _ := MakeKeepClient(&arv)
466 arv.ApiToken = "abc123"
467 kc.SetServiceRoots(map[string]string{"x": ks.url}, map[string]string{ks.url: ""}, nil)
469 r, n, url2, err := kc.Get(hash)
471 c.Check(err, Equals, nil)
472 c.Check(n, Equals, int64(3))
473 c.Check(url2, Equals, fmt.Sprintf("%s/%s", ks.url, hash))
475 content, err2 := ioutil.ReadAll(r)
476 c.Check(err2, Equals, nil)
477 c.Check(content, DeepEquals, []byte("foo"))
479 log.Printf("TestGet done")
482 func (s *StandaloneSuite) TestGetFail(c *C) {
483 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
485 st := FailHandler{make(chan string, 1)}
487 ks := RunFakeKeepServer(st)
488 defer ks.listener.Close()
490 arv, err := arvadosclient.MakeArvadosClient()
491 kc, _ := MakeKeepClient(&arv)
492 arv.ApiToken = "abc123"
493 kc.SetServiceRoots(map[string]string{"x": ks.url}, map[string]string{ks.url: ""}, nil)
495 r, n, url2, err := kc.Get(hash)
496 c.Check(err, Equals, BlockNotFound)
497 c.Check(n, Equals, int64(0))
498 c.Check(url2, Equals, "")
499 c.Check(r, Equals, nil)
502 func (s *StandaloneSuite) TestGetWithServiceHint(c *C) {
503 uuid := "zzzzz-bi6l4-123451234512345"
504 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
506 // This one shouldn't be used:
507 ks0 := RunFakeKeepServer(StubGetHandler{
513 defer ks0.listener.Close()
514 // This one should be used:
515 ks := RunFakeKeepServer(StubGetHandler{
521 defer ks.listener.Close()
523 arv, err := arvadosclient.MakeArvadosClient()
524 kc, _ := MakeKeepClient(&arv)
525 arv.ApiToken = "abc123"
527 map[string]string{"x": ks0.url},
528 map[string]string{"x": ks0.url},
529 map[string]string{uuid: ks.url})
531 r, n, uri, err := kc.Get(hash + "+K@" + uuid)
533 c.Check(err, Equals, nil)
534 c.Check(n, Equals, int64(3))
535 c.Check(uri, Equals, fmt.Sprintf("%s/%s", ks.url, hash+"+K@"+uuid))
537 content, err := ioutil.ReadAll(r)
538 c.Check(err, Equals, nil)
539 c.Check(content, DeepEquals, []byte("foo"))
542 // Use a service hint to fetch from a local disk service, overriding
543 // rendezvous probe order.
544 func (s *StandaloneSuite) TestGetWithLocalServiceHint(c *C) {
545 uuid := "zzzzz-bi6l4-zzzzzzzzzzzzzzz"
546 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
548 // This one shouldn't be used, although it appears first in
549 // rendezvous probe order:
550 ks0 := RunFakeKeepServer(StubGetHandler{
556 defer ks0.listener.Close()
557 // This one should be used:
558 ks := RunFakeKeepServer(StubGetHandler{
564 defer ks.listener.Close()
566 arv, err := arvadosclient.MakeArvadosClient()
567 kc, _ := MakeKeepClient(&arv)
568 arv.ApiToken = "abc123"
571 "zzzzz-bi6l4-yyyyyyyyyyyyyyy": ks0.url,
572 "zzzzz-bi6l4-xxxxxxxxxxxxxxx": ks0.url,
573 "zzzzz-bi6l4-wwwwwwwwwwwwwww": ks0.url,
576 "zzzzz-bi6l4-yyyyyyyyyyyyyyy": ks0.url,
577 "zzzzz-bi6l4-xxxxxxxxxxxxxxx": ks0.url,
578 "zzzzz-bi6l4-wwwwwwwwwwwwwww": ks0.url,
581 "zzzzz-bi6l4-yyyyyyyyyyyyyyy": ks0.url,
582 "zzzzz-bi6l4-xxxxxxxxxxxxxxx": ks0.url,
583 "zzzzz-bi6l4-wwwwwwwwwwwwwww": ks0.url,
587 r, n, uri, err := kc.Get(hash + "+K@" + uuid)
589 c.Check(err, Equals, nil)
590 c.Check(n, Equals, int64(3))
591 c.Check(uri, Equals, fmt.Sprintf("%s/%s", ks.url, hash+"+K@"+uuid))
593 content, err := ioutil.ReadAll(r)
594 c.Check(err, Equals, nil)
595 c.Check(content, DeepEquals, []byte("foo"))
598 func (s *StandaloneSuite) TestGetWithServiceHintFailoverToLocals(c *C) {
599 uuid := "zzzzz-bi6l4-123451234512345"
600 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
602 ksLocal := RunFakeKeepServer(StubGetHandler{
608 defer ksLocal.listener.Close()
609 ksGateway := RunFakeKeepServer(StubGetHandler{
613 http.StatusInternalServerError,
615 defer ksGateway.listener.Close()
617 arv, err := arvadosclient.MakeArvadosClient()
618 kc, _ := MakeKeepClient(&arv)
619 arv.ApiToken = "abc123"
621 map[string]string{"zzzzz-bi6l4-keepdisk0000000": ksLocal.url},
622 map[string]string{"zzzzz-bi6l4-keepdisk0000000": ksLocal.url},
623 map[string]string{uuid: ksGateway.url})
625 r, n, uri, err := kc.Get(hash + "+K@" + uuid)
626 c.Assert(err, Equals, nil)
628 c.Check(n, Equals, int64(3))
629 c.Check(uri, Equals, fmt.Sprintf("%s/%s", ksLocal.url, hash+"+K@"+uuid))
631 content, err := ioutil.ReadAll(r)
632 c.Check(err, Equals, nil)
633 c.Check(content, DeepEquals, []byte("foo"))
636 type BarHandler struct {
640 func (this BarHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
641 resp.Write([]byte("bar"))
642 this.handled <- fmt.Sprintf("http://%s", req.Host)
645 func (s *StandaloneSuite) TestChecksum(c *C) {
646 foohash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
647 barhash := fmt.Sprintf("%x", md5.Sum([]byte("bar")))
649 st := BarHandler{make(chan string, 1)}
651 ks := RunFakeKeepServer(st)
652 defer ks.listener.Close()
654 arv, err := arvadosclient.MakeArvadosClient()
655 kc, _ := MakeKeepClient(&arv)
656 arv.ApiToken = "abc123"
657 kc.SetServiceRoots(map[string]string{"x": ks.url}, map[string]string{ks.url: ""}, nil)
659 r, n, _, err := kc.Get(barhash)
660 _, err = ioutil.ReadAll(r)
661 c.Check(n, Equals, int64(3))
662 c.Check(err, Equals, nil)
666 r, n, _, err = kc.Get(foohash)
667 _, err = ioutil.ReadAll(r)
668 c.Check(n, Equals, int64(3))
669 c.Check(err, Equals, BadChecksum)
674 func (s *StandaloneSuite) TestGetWithFailures(c *C) {
675 content := []byte("waz")
676 hash := fmt.Sprintf("%x", md5.Sum(content))
679 make(chan string, 4)}
681 st := StubGetHandler{
688 arv, err := arvadosclient.MakeArvadosClient()
689 kc, _ := MakeKeepClient(&arv)
690 arv.ApiToken = "abc123"
691 localRoots := make(map[string]string)
692 writableLocalRoots := make(map[string]string)
694 ks1 := RunSomeFakeKeepServers(st, 1)
695 ks2 := RunSomeFakeKeepServers(fh, 4)
697 for i, k := range ks1 {
698 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
699 writableLocalRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
700 defer k.listener.Close()
702 for i, k := range ks2 {
703 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i+len(ks1))] = k.url
704 writableLocalRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i+len(ks1))] = k.url
705 defer k.listener.Close()
708 kc.SetServiceRoots(localRoots, writableLocalRoots, nil)
710 // This test works only if one of the failing services is
711 // attempted before the succeeding service. Otherwise,
712 // <-fh.handled below will just hang! (Probe order depends on
713 // the choice of block content "waz" and the UUIDs of the fake
714 // servers, so we just tried different strings until we found
715 // an example that passes this Assert.)
716 c.Assert(NewRootSorter(localRoots, hash).GetSortedRoots()[0], Not(Equals), ks1[0].url)
718 r, n, url2, err := kc.Get(hash)
721 c.Check(err, Equals, nil)
722 c.Check(n, Equals, int64(3))
723 c.Check(url2, Equals, fmt.Sprintf("%s/%s", ks1[0].url, hash))
725 read_content, err2 := ioutil.ReadAll(r)
726 c.Check(err2, Equals, nil)
727 c.Check(read_content, DeepEquals, content)
730 func (s *ServerRequiredSuite) TestPutGetHead(c *C) {
731 content := []byte("TestPutGetHead")
733 arv, err := arvadosclient.MakeArvadosClient()
734 kc, err := MakeKeepClient(&arv)
735 c.Assert(err, Equals, nil)
737 hash := fmt.Sprintf("%x", md5.Sum(content))
740 n, _, err := kc.Ask(hash)
741 c.Check(err, Equals, BlockNotFound)
742 c.Check(n, Equals, int64(0))
745 hash2, replicas, err := kc.PutB(content)
746 c.Check(hash2, Matches, fmt.Sprintf(`%s\+%d\b.*`, hash, len(content)))
747 c.Check(replicas, Equals, 2)
748 c.Check(err, Equals, nil)
751 r, n, url2, err := kc.Get(hash)
752 c.Check(err, Equals, nil)
753 c.Check(n, Equals, int64(len(content)))
754 c.Check(url2, Matches, fmt.Sprintf("http://localhost:\\d+/%s", hash))
756 read_content, err2 := ioutil.ReadAll(r)
757 c.Check(err2, Equals, nil)
758 c.Check(read_content, DeepEquals, content)
761 n, url2, err := kc.Ask(hash)
762 c.Check(err, Equals, nil)
763 c.Check(n, Equals, int64(len(content)))
764 c.Check(url2, Matches, fmt.Sprintf("http://localhost:\\d+/%s", hash))
768 type StubProxyHandler struct {
772 func (this StubProxyHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
773 resp.Header().Set("X-Keep-Replicas-Stored", "2")
774 this.handled <- fmt.Sprintf("http://%s", req.Host)
777 func (s *StandaloneSuite) TestPutProxy(c *C) {
778 log.Printf("TestPutProxy")
780 st := StubProxyHandler{make(chan string, 1)}
782 arv, err := arvadosclient.MakeArvadosClient()
783 kc, _ := MakeKeepClient(&arv)
786 kc.Using_proxy = true
787 arv.ApiToken = "abc123"
788 localRoots := make(map[string]string)
789 writableLocalRoots := make(map[string]string)
791 ks1 := RunSomeFakeKeepServers(st, 1)
793 for i, k := range ks1 {
794 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
795 writableLocalRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
796 defer k.listener.Close()
799 kc.SetServiceRoots(localRoots, writableLocalRoots, nil)
801 _, replicas, err := kc.PutB([]byte("foo"))
804 c.Check(err, Equals, nil)
805 c.Check(replicas, Equals, 2)
807 log.Printf("TestPutProxy done")
810 func (s *StandaloneSuite) TestPutProxyInsufficientReplicas(c *C) {
811 log.Printf("TestPutProxy")
813 st := StubProxyHandler{make(chan string, 1)}
815 arv, err := arvadosclient.MakeArvadosClient()
816 kc, _ := MakeKeepClient(&arv)
819 kc.Using_proxy = true
820 arv.ApiToken = "abc123"
821 localRoots := make(map[string]string)
822 writableLocalRoots := make(map[string]string)
824 ks1 := RunSomeFakeKeepServers(st, 1)
826 for i, k := range ks1 {
827 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
828 writableLocalRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
829 defer k.listener.Close()
831 kc.SetServiceRoots(localRoots, writableLocalRoots, nil)
833 _, replicas, err := kc.PutB([]byte("foo"))
836 c.Check(err, Equals, InsufficientReplicasError)
837 c.Check(replicas, Equals, 2)
839 log.Printf("TestPutProxy done")
842 func (s *StandaloneSuite) TestMakeLocator(c *C) {
843 l, err := MakeLocator("91f372a266fe2bf2823cb8ec7fda31ce+3+Aabcde@12345678")
844 c.Check(err, Equals, nil)
845 c.Check(l.Hash, Equals, "91f372a266fe2bf2823cb8ec7fda31ce")
846 c.Check(l.Size, Equals, 3)
847 c.Check(l.Hints, DeepEquals, []string{"3", "Aabcde@12345678"})
850 func (s *StandaloneSuite) TestMakeLocatorNoHints(c *C) {
851 l, err := MakeLocator("91f372a266fe2bf2823cb8ec7fda31ce")
852 c.Check(err, Equals, nil)
853 c.Check(l.Hash, Equals, "91f372a266fe2bf2823cb8ec7fda31ce")
854 c.Check(l.Size, Equals, -1)
855 c.Check(l.Hints, DeepEquals, []string{})
858 func (s *StandaloneSuite) TestMakeLocatorNoSizeHint(c *C) {
859 l, err := MakeLocator("91f372a266fe2bf2823cb8ec7fda31ce+Aabcde@12345678")
860 c.Check(err, Equals, nil)
861 c.Check(l.Hash, Equals, "91f372a266fe2bf2823cb8ec7fda31ce")
862 c.Check(l.Size, Equals, -1)
863 c.Check(l.Hints, DeepEquals, []string{"Aabcde@12345678"})
866 func (s *StandaloneSuite) TestMakeLocatorPreservesUnrecognizedHints(c *C) {
867 str := "91f372a266fe2bf2823cb8ec7fda31ce+3+Unknown+Kzzzzz+Afoobar"
868 l, err := MakeLocator(str)
869 c.Check(err, Equals, nil)
870 c.Check(l.Hash, Equals, "91f372a266fe2bf2823cb8ec7fda31ce")
871 c.Check(l.Size, Equals, 3)
872 c.Check(l.Hints, DeepEquals, []string{"3", "Unknown", "Kzzzzz", "Afoobar"})
873 c.Check(l.String(), Equals, str)
876 func (s *StandaloneSuite) TestMakeLocatorInvalidInput(c *C) {
877 _, err := MakeLocator("91f372a266fe2bf2823cb8ec7fda31c")
878 c.Check(err, Equals, InvalidLocatorError)
881 func (s *StandaloneSuite) TestPutBWant2ReplicasWithOnlyOneWritableLocalRoot(c *C) {
882 hash := Md5String("foo")
884 st := StubPutHandler{
889 make(chan string, 5)}
891 arv, _ := arvadosclient.MakeArvadosClient()
892 kc, _ := MakeKeepClient(&arv)
895 arv.ApiToken = "abc123"
896 localRoots := make(map[string]string)
897 writableLocalRoots := make(map[string]string)
899 ks := RunSomeFakeKeepServers(st, 5)
901 for i, k := range ks {
902 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
904 writableLocalRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
906 defer k.listener.Close()
909 kc.SetServiceRoots(localRoots, writableLocalRoots, nil)
911 _, replicas, err := kc.PutB([]byte("foo"))
913 c.Check(err, Equals, InsufficientReplicasError)
914 c.Check(replicas, Equals, 1)
916 c.Check(<-st.handled, Equals, localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", 0)])
919 func (s *StandaloneSuite) TestPutBWithNoWritableLocalRoots(c *C) {
920 hash := Md5String("foo")
922 st := StubPutHandler{
927 make(chan string, 5)}
929 arv, _ := arvadosclient.MakeArvadosClient()
930 kc, _ := MakeKeepClient(&arv)
933 arv.ApiToken = "abc123"
934 localRoots := make(map[string]string)
935 writableLocalRoots := make(map[string]string)
937 ks := RunSomeFakeKeepServers(st, 5)
939 for i, k := range ks {
940 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
941 defer k.listener.Close()
944 kc.SetServiceRoots(localRoots, writableLocalRoots, nil)
946 _, replicas, err := kc.PutB([]byte("foo"))
948 c.Check(err, Equals, InsufficientReplicasError)
949 c.Check(replicas, Equals, 0)
952 type StubGetIndexHandler struct {
955 expectAPIToken string
960 func (h StubGetIndexHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
961 h.c.Check(req.URL.Path, Equals, h.expectPath)
962 h.c.Check(req.Header.Get("Authorization"), Equals, fmt.Sprintf("OAuth2 %s", h.expectAPIToken))
963 resp.WriteHeader(h.httpStatus)
964 resp.Header().Set("Content-Length", fmt.Sprintf("%d", len(h.body)))
968 func (s *StandaloneSuite) TestGetIndexWithNoPrefix(c *C) {
969 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
971 st := StubGetIndexHandler{
976 []byte(hash + "+3 1443559274\n\n")}
978 ks := RunFakeKeepServer(st)
979 defer ks.listener.Close()
981 arv, err := arvadosclient.MakeArvadosClient()
982 kc, _ := MakeKeepClient(&arv)
983 arv.ApiToken = "abc123"
984 kc.SetServiceRoots(map[string]string{"x": ks.url}, map[string]string{ks.url: ""}, nil)
986 r, err := kc.GetIndex("x", "")
987 c.Check(err, Equals, nil)
989 content, err2 := ioutil.ReadAll(r)
990 c.Check(err2, Equals, nil)
991 c.Check(content, DeepEquals, st.body[0:len(st.body)-1])
994 func (s *StandaloneSuite) TestGetIndexWithPrefix(c *C) {
995 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
997 st := StubGetIndexHandler{
999 "/index/" + hash[0:3],
1002 []byte(hash + "+3 1443559274\n\n")}
1004 ks := RunFakeKeepServer(st)
1005 defer ks.listener.Close()
1007 arv, err := arvadosclient.MakeArvadosClient()
1008 kc, _ := MakeKeepClient(&arv)
1009 arv.ApiToken = "abc123"
1010 kc.SetServiceRoots(map[string]string{"x": ks.url}, map[string]string{ks.url: ""}, nil)
1012 r, err := kc.GetIndex("x", hash[0:3])
1013 c.Check(err, Equals, nil)
1015 content, err2 := ioutil.ReadAll(r)
1016 c.Check(err2, Equals, nil)
1017 c.Check(content, DeepEquals, st.body[0:len(st.body)-1])
1020 func (s *StandaloneSuite) TestGetIndexIncomplete(c *C) {
1021 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
1023 st := StubGetIndexHandler{
1025 "/index/" + hash[0:3],
1030 ks := RunFakeKeepServer(st)
1031 defer ks.listener.Close()
1033 arv, err := arvadosclient.MakeArvadosClient()
1034 kc, _ := MakeKeepClient(&arv)
1035 arv.ApiToken = "abc123"
1036 kc.SetServiceRoots(map[string]string{"x": ks.url}, map[string]string{ks.url: ""}, nil)
1038 _, err = kc.GetIndex("x", hash[0:3])
1039 c.Check(err, Equals, ErrIncompleteIndex)
1042 func (s *StandaloneSuite) TestGetIndexWithNoSuchServer(c *C) {
1043 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
1045 st := StubGetIndexHandler{
1047 "/index/" + hash[0:3],
1052 ks := RunFakeKeepServer(st)
1053 defer ks.listener.Close()
1055 arv, err := arvadosclient.MakeArvadosClient()
1056 kc, _ := MakeKeepClient(&arv)
1057 arv.ApiToken = "abc123"
1058 kc.SetServiceRoots(map[string]string{"x": ks.url}, map[string]string{ks.url: ""}, nil)
1060 _, err = kc.GetIndex("y", hash[0:3])
1061 c.Check(err, Equals, ErrNoSuchKeepServer)
1064 func (s *StandaloneSuite) TestGetIndexWithNoSuchPrefix(c *C) {
1065 st := StubGetIndexHandler{
1072 ks := RunFakeKeepServer(st)
1073 defer ks.listener.Close()
1075 arv, err := arvadosclient.MakeArvadosClient()
1076 kc, _ := MakeKeepClient(&arv)
1077 arv.ApiToken = "abc123"
1078 kc.SetServiceRoots(map[string]string{"x": ks.url}, map[string]string{ks.url: ""}, nil)
1080 r, err := kc.GetIndex("x", "abcd")
1081 c.Check(err, Equals, nil)
1083 content, err2 := ioutil.ReadAll(r)
1084 c.Check(err2, Equals, nil)
1085 c.Check(content, DeepEquals, st.body[0:len(st.body)-1])