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 writableRoots := 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 writableRoots[k.url] = ""
253 defer k.listener.Close()
256 kc.SetServiceRoots(localRoots, nil, writableRoots)
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 writableRoots := 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 writableRoots[k.url] = ""
298 defer k.listener.Close()
301 kc.SetServiceRoots(localRoots, nil, writableRoots)
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 writableRoots := 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 writableRoots[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 writableRoots[k.url] = ""
360 defer k.listener.Close()
363 kc.SetServiceRoots(localRoots, nil, writableRoots)
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 writableRoots := 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 writableRoots[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 writableRoots[k.url] = ""
419 defer k.listener.Close()
422 kc.SetServiceRoots(localRoots, nil, writableRoots)
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}, nil, map[string]string{ks.url: ""})
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}, nil, map[string]string{ks.url: ""})
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{uuid: ks.url},
529 map[string]string{ks0.url: "", 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,
580 map[string]string{ks.url: ""},
583 r, n, uri, err := kc.Get(hash + "+K@" + uuid)
585 c.Check(err, Equals, nil)
586 c.Check(n, Equals, int64(3))
587 c.Check(uri, Equals, fmt.Sprintf("%s/%s", ks.url, hash+"+K@"+uuid))
589 content, err := ioutil.ReadAll(r)
590 c.Check(err, Equals, nil)
591 c.Check(content, DeepEquals, []byte("foo"))
594 func (s *StandaloneSuite) TestGetWithServiceHintFailoverToLocals(c *C) {
595 uuid := "zzzzz-bi6l4-123451234512345"
596 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
598 ksLocal := RunFakeKeepServer(StubGetHandler{
604 defer ksLocal.listener.Close()
605 ksGateway := RunFakeKeepServer(StubGetHandler{
609 http.StatusInternalServerError,
611 defer ksGateway.listener.Close()
613 arv, err := arvadosclient.MakeArvadosClient()
614 kc, _ := MakeKeepClient(&arv)
615 arv.ApiToken = "abc123"
617 map[string]string{"zzzzz-bi6l4-keepdisk0000000": ksLocal.url},
618 map[string]string{uuid: ksGateway.url},
619 map[string]string{ksLocal.url: "", ksGateway.url: ""})
621 r, n, uri, err := kc.Get(hash + "+K@" + uuid)
622 c.Assert(err, Equals, nil)
624 c.Check(n, Equals, int64(3))
625 c.Check(uri, Equals, fmt.Sprintf("%s/%s", ksLocal.url, hash+"+K@"+uuid))
627 content, err := ioutil.ReadAll(r)
628 c.Check(err, Equals, nil)
629 c.Check(content, DeepEquals, []byte("foo"))
632 type BarHandler struct {
636 func (this BarHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
637 resp.Write([]byte("bar"))
638 this.handled <- fmt.Sprintf("http://%s", req.Host)
641 func (s *StandaloneSuite) TestChecksum(c *C) {
642 foohash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
643 barhash := fmt.Sprintf("%x", md5.Sum([]byte("bar")))
645 st := BarHandler{make(chan string, 1)}
647 ks := RunFakeKeepServer(st)
648 defer ks.listener.Close()
650 arv, err := arvadosclient.MakeArvadosClient()
651 kc, _ := MakeKeepClient(&arv)
652 arv.ApiToken = "abc123"
653 kc.SetServiceRoots(map[string]string{"x": ks.url}, nil, map[string]string{ks.url: ""})
655 r, n, _, err := kc.Get(barhash)
656 _, err = ioutil.ReadAll(r)
657 c.Check(n, Equals, int64(3))
658 c.Check(err, Equals, nil)
662 r, n, _, err = kc.Get(foohash)
663 _, err = ioutil.ReadAll(r)
664 c.Check(n, Equals, int64(3))
665 c.Check(err, Equals, BadChecksum)
670 func (s *StandaloneSuite) TestGetWithFailures(c *C) {
671 content := []byte("waz")
672 hash := fmt.Sprintf("%x", md5.Sum(content))
675 make(chan string, 4)}
677 st := StubGetHandler{
684 arv, err := arvadosclient.MakeArvadosClient()
685 kc, _ := MakeKeepClient(&arv)
686 arv.ApiToken = "abc123"
687 localRoots := make(map[string]string)
688 writableRoots := make(map[string]string)
690 ks1 := RunSomeFakeKeepServers(st, 1)
691 ks2 := RunSomeFakeKeepServers(fh, 4)
693 for i, k := range ks1 {
694 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
695 writableRoots[k.url] = ""
696 defer k.listener.Close()
698 for i, k := range ks2 {
699 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i+len(ks1))] = k.url
700 writableRoots[k.url] = ""
701 defer k.listener.Close()
704 kc.SetServiceRoots(localRoots, nil, writableRoots)
706 // This test works only if one of the failing services is
707 // attempted before the succeeding service. Otherwise,
708 // <-fh.handled below will just hang! (Probe order depends on
709 // the choice of block content "waz" and the UUIDs of the fake
710 // servers, so we just tried different strings until we found
711 // an example that passes this Assert.)
712 c.Assert(NewRootSorter(localRoots, hash).GetSortedRoots()[0], Not(Equals), ks1[0].url)
714 r, n, url2, err := kc.Get(hash)
717 c.Check(err, Equals, nil)
718 c.Check(n, Equals, int64(3))
719 c.Check(url2, Equals, fmt.Sprintf("%s/%s", ks1[0].url, hash))
721 read_content, err2 := ioutil.ReadAll(r)
722 c.Check(err2, Equals, nil)
723 c.Check(read_content, DeepEquals, content)
726 func (s *ServerRequiredSuite) TestPutGetHead(c *C) {
727 content := []byte("TestPutGetHead")
729 arv, err := arvadosclient.MakeArvadosClient()
730 kc, err := MakeKeepClient(&arv)
731 c.Assert(err, Equals, nil)
733 hash := fmt.Sprintf("%x", md5.Sum(content))
736 n, _, err := kc.Ask(hash)
737 c.Check(err, Equals, BlockNotFound)
738 c.Check(n, Equals, int64(0))
741 hash2, replicas, err := kc.PutB(content)
742 c.Check(hash2, Equals, fmt.Sprintf("%s+%d", hash, len(content)))
743 c.Check(replicas, Equals, 2)
744 c.Check(err, Equals, nil)
747 r, n, url2, err := kc.Get(hash)
748 c.Check(err, Equals, nil)
749 c.Check(n, Equals, int64(len(content)))
750 c.Check(url2, Matches, fmt.Sprintf("http://localhost:\\d+/%s", hash))
752 read_content, err2 := ioutil.ReadAll(r)
753 c.Check(err2, Equals, nil)
754 c.Check(read_content, DeepEquals, content)
757 n, url2, err := kc.Ask(hash)
758 c.Check(err, Equals, nil)
759 c.Check(n, Equals, int64(len(content)))
760 c.Check(url2, Matches, fmt.Sprintf("http://localhost:\\d+/%s", hash))
764 type StubProxyHandler struct {
768 func (this StubProxyHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
769 resp.Header().Set("X-Keep-Replicas-Stored", "2")
770 this.handled <- fmt.Sprintf("http://%s", req.Host)
773 func (s *StandaloneSuite) TestPutProxy(c *C) {
774 log.Printf("TestPutProxy")
776 st := StubProxyHandler{make(chan string, 1)}
778 arv, err := arvadosclient.MakeArvadosClient()
779 kc, _ := MakeKeepClient(&arv)
782 kc.Using_proxy = true
783 arv.ApiToken = "abc123"
784 localRoots := make(map[string]string)
785 writableRoots := make(map[string]string)
787 ks1 := RunSomeFakeKeepServers(st, 1)
789 for i, k := range ks1 {
790 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
791 writableRoots[k.url] = ""
792 defer k.listener.Close()
795 kc.SetServiceRoots(localRoots, nil, writableRoots)
797 _, replicas, err := kc.PutB([]byte("foo"))
800 c.Check(err, Equals, nil)
801 c.Check(replicas, Equals, 2)
803 log.Printf("TestPutProxy done")
806 func (s *StandaloneSuite) TestPutProxyInsufficientReplicas(c *C) {
807 log.Printf("TestPutProxy")
809 st := StubProxyHandler{make(chan string, 1)}
811 arv, err := arvadosclient.MakeArvadosClient()
812 kc, _ := MakeKeepClient(&arv)
815 kc.Using_proxy = true
816 arv.ApiToken = "abc123"
817 localRoots := make(map[string]string)
818 writableRoots := make(map[string]string)
820 ks1 := RunSomeFakeKeepServers(st, 1)
822 for i, k := range ks1 {
823 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
824 writableRoots[k.url] = ""
825 defer k.listener.Close()
827 kc.SetServiceRoots(localRoots, nil, writableRoots)
829 _, replicas, err := kc.PutB([]byte("foo"))
832 c.Check(err, Equals, InsufficientReplicasError)
833 c.Check(replicas, Equals, 2)
835 log.Printf("TestPutProxy done")
838 func (s *StandaloneSuite) TestMakeLocator(c *C) {
839 l, err := MakeLocator("91f372a266fe2bf2823cb8ec7fda31ce+3+Aabcde@12345678")
840 c.Check(err, Equals, nil)
841 c.Check(l.Hash, Equals, "91f372a266fe2bf2823cb8ec7fda31ce")
842 c.Check(l.Size, Equals, 3)
843 c.Check(l.Hints, DeepEquals, []string{"3", "Aabcde@12345678"})
846 func (s *StandaloneSuite) TestMakeLocatorNoHints(c *C) {
847 l, err := MakeLocator("91f372a266fe2bf2823cb8ec7fda31ce")
848 c.Check(err, Equals, nil)
849 c.Check(l.Hash, Equals, "91f372a266fe2bf2823cb8ec7fda31ce")
850 c.Check(l.Size, Equals, -1)
851 c.Check(l.Hints, DeepEquals, []string{})
854 func (s *StandaloneSuite) TestMakeLocatorNoSizeHint(c *C) {
855 l, err := MakeLocator("91f372a266fe2bf2823cb8ec7fda31ce+Aabcde@12345678")
856 c.Check(err, Equals, nil)
857 c.Check(l.Hash, Equals, "91f372a266fe2bf2823cb8ec7fda31ce")
858 c.Check(l.Size, Equals, -1)
859 c.Check(l.Hints, DeepEquals, []string{"Aabcde@12345678"})
862 func (s *StandaloneSuite) TestMakeLocatorPreservesUnrecognizedHints(c *C) {
863 str := "91f372a266fe2bf2823cb8ec7fda31ce+3+Unknown+Kzzzzz+Afoobar"
864 l, err := MakeLocator(str)
865 c.Check(err, Equals, nil)
866 c.Check(l.Hash, Equals, "91f372a266fe2bf2823cb8ec7fda31ce")
867 c.Check(l.Size, Equals, 3)
868 c.Check(l.Hints, DeepEquals, []string{"3", "Unknown", "Kzzzzz", "Afoobar"})
869 c.Check(l.String(), Equals, str)
872 func (s *StandaloneSuite) TestMakeLocatorInvalidInput(c *C) {
873 _, err := MakeLocator("91f372a266fe2bf2823cb8ec7fda31c")
874 c.Check(err, Equals, InvalidLocatorError)
877 func (s *StandaloneSuite) TestPutBWant2ReplicasWithOnlyOneWritableRoots(c *C) {
878 log.Printf("TestPutWant2ReplicasWithOnlyOneWritableRoots")
880 hash := Md5String("foo")
882 st := StubPutHandler{
887 make(chan string, 5)}
889 arv, _ := arvadosclient.MakeArvadosClient()
890 kc, _ := MakeKeepClient(&arv)
893 arv.ApiToken = "abc123"
894 localRoots := make(map[string]string)
895 writableRoots := make(map[string]string)
897 ks := RunSomeFakeKeepServers(st, 5)
899 for i, k := range ks {
900 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
902 writableRoots[k.url] = ""
904 defer k.listener.Close()
907 kc.SetServiceRoots(localRoots, nil, writableRoots)
909 _, replicas, err := kc.PutB([]byte("foo"))
911 c.Check(err, Equals, InsufficientReplicasError)
912 c.Check(replicas, Equals, 1)
914 c.Check(<-st.handled, Equals, localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", 0)])
916 log.Printf("TestPutWant2ReplicasWithOnlyOneWritableRoots done")
919 func (s *StandaloneSuite) TestPutBWithNoWritableRoots(c *C) {
920 log.Printf("TestPutBWithNoWritableRoots")
922 hash := Md5String("foo")
924 st := StubPutHandler{
929 make(chan string, 5)}
931 arv, _ := arvadosclient.MakeArvadosClient()
932 kc, _ := MakeKeepClient(&arv)
935 arv.ApiToken = "abc123"
936 localRoots := make(map[string]string)
937 writableRoots := make(map[string]string)
939 ks := RunSomeFakeKeepServers(st, 5)
941 for i, k := range ks {
942 localRoots[fmt.Sprintf("zzzzz-bi6l4-fakefakefake%03d", i)] = k.url
943 defer k.listener.Close()
946 kc.SetServiceRoots(localRoots, nil, writableRoots)
948 _, replicas, err := kc.PutB([]byte("foo"))
950 c.Check(err, Equals, InsufficientReplicasError)
951 c.Check(replicas, Equals, 0)
953 log.Printf("TestPutBWithNoWritableRoots done")