21 // Gocheck boilerplate
22 func Test(t *testing.T) { TestingT(t) }
24 // Gocheck boilerplate
25 var _ = Suite(&ServerRequiredSuite{})
26 var _ = Suite(&StandaloneSuite{})
28 var no_server = flag.Bool("no-server", false, "Skip 'ServerRequireSuite'")
30 // Tests that require the Keep server running
31 type ServerRequiredSuite struct{}
34 type StandaloneSuite struct{}
36 func pythonDir() string {
37 gopath := os.Getenv("GOPATH")
38 return fmt.Sprintf("%s/../python", strings.Split(gopath, ":")[0])
41 func (s *ServerRequiredSuite) SetUpSuite(c *C) {
43 c.Skip("Skipping tests that require server")
46 exec.Command("python", "run_test_server.py", "start").Run()
47 exec.Command("python", "run_test_server.py", "start_keep").Run()
51 func (s *ServerRequiredSuite) TearDownSuite(c *C) {
53 exec.Command("python", "run_test_server.py", "stop_keep").Run()
54 exec.Command("python", "run_test_server.py", "stop").Run()
57 func (s *ServerRequiredSuite) TestMakeKeepClient(c *C) {
58 os.Setenv("ARVADOS_API_HOST", "localhost:3001")
59 os.Setenv("ARVADOS_API_TOKEN", "4axaw8zxe0qm22wa6urpp5nskcne8z88cvbupv653y1njyi05h")
60 os.Setenv("ARVADOS_API_HOST_INSECURE", "")
62 kc, err := MakeKeepClient()
63 c.Assert(kc.ApiServer, Equals, "localhost:3001")
64 c.Assert(kc.ApiToken, Equals, "4axaw8zxe0qm22wa6urpp5nskcne8z88cvbupv653y1njyi05h")
65 c.Assert(kc.ApiInsecure, Equals, false)
67 os.Setenv("ARVADOS_API_HOST_INSECURE", "true")
69 kc, err = MakeKeepClient()
70 c.Assert(kc.ApiServer, Equals, "localhost:3001")
71 c.Assert(kc.ApiToken, Equals, "4axaw8zxe0qm22wa6urpp5nskcne8z88cvbupv653y1njyi05h")
72 c.Assert(kc.ApiInsecure, Equals, true)
74 c.Assert(err, Equals, nil)
75 c.Assert(len(kc.Service_roots), Equals, 2)
76 c.Assert(kc.Service_roots[0], Equals, "http://localhost:25107")
77 c.Assert(kc.Service_roots[1], Equals, "http://localhost:25108")
80 func (s *StandaloneSuite) TestShuffleServiceRoots(c *C) {
81 kc := KeepClient{Service_roots: []string{"http://localhost:25107", "http://localhost:25108", "http://localhost:25109", "http://localhost:25110", "http://localhost:25111", "http://localhost:25112", "http://localhost:25113", "http://localhost:25114", "http://localhost:25115", "http://localhost:25116", "http://localhost:25117", "http://localhost:25118", "http://localhost:25119", "http://localhost:25120", "http://localhost:25121", "http://localhost:25122", "http://localhost:25123"}}
83 // "foo" acbd18db4cc2f85cedef654fccc4a4d8
84 foo_shuffle := []string{"http://localhost:25116", "http://localhost:25120", "http://localhost:25119", "http://localhost:25122", "http://localhost:25108", "http://localhost:25114", "http://localhost:25112", "http://localhost:25107", "http://localhost:25118", "http://localhost:25111", "http://localhost:25113", "http://localhost:25121", "http://localhost:25110", "http://localhost:25117", "http://localhost:25109", "http://localhost:25115", "http://localhost:25123"}
85 c.Check(kc.ShuffledServiceRoots("acbd18db4cc2f85cedef654fccc4a4d8"), DeepEquals, foo_shuffle)
87 // "bar" 37b51d194a7513e45b56f6524f2d51f2
88 bar_shuffle := []string{"http://localhost:25108", "http://localhost:25112", "http://localhost:25119", "http://localhost:25107", "http://localhost:25110", "http://localhost:25116", "http://localhost:25122", "http://localhost:25120", "http://localhost:25121", "http://localhost:25117", "http://localhost:25111", "http://localhost:25123", "http://localhost:25118", "http://localhost:25113", "http://localhost:25114", "http://localhost:25115", "http://localhost:25109"}
89 c.Check(kc.ShuffledServiceRoots("37b51d194a7513e45b56f6524f2d51f2"), DeepEquals, bar_shuffle)
92 func ReadIntoBufferHelper(c *C, bufsize int) {
93 buffer := make([]byte, bufsize)
95 reader, writer := io.Pipe()
96 slices := make(chan ReaderSlice)
98 go ReadIntoBuffer(buffer, reader, slices)
101 out := make([]byte, 128)
102 for i := 0; i < 128; i += 1 {
107 c.Check(len(s1.slice), Equals, 128)
108 c.Check(s1.reader_error, Equals, nil)
109 for i := 0; i < 128; i += 1 {
110 c.Check(s1.slice[i], Equals, byte(i))
112 for i := 0; i < len(buffer); i += 1 {
114 c.Check(buffer[i], Equals, byte(i))
116 c.Check(buffer[i], Equals, byte(0))
121 out := make([]byte, 96)
122 for i := 0; i < 96; i += 1 {
127 c.Check(len(s1.slice), Equals, 96)
128 c.Check(s1.reader_error, Equals, nil)
129 for i := 0; i < 96; i += 1 {
130 c.Check(s1.slice[i], Equals, byte(i/2))
132 for i := 0; i < len(buffer); i += 1 {
134 c.Check(buffer[i], Equals, byte(i))
135 } else if i < (128 + 96) {
136 c.Check(buffer[i], Equals, byte((i-128)/2))
138 c.Check(buffer[i], Equals, byte(0))
145 c.Check(len(s1.slice), Equals, 0)
146 c.Check(s1.reader_error, Equals, io.EOF)
150 func (s *StandaloneSuite) TestReadIntoBuffer(c *C) {
151 ReadIntoBufferHelper(c, 512)
152 ReadIntoBufferHelper(c, 225)
153 ReadIntoBufferHelper(c, 224)
156 func (s *StandaloneSuite) TestReadIntoShortBuffer(c *C) {
157 buffer := make([]byte, 223)
158 reader, writer := io.Pipe()
159 slices := make(chan ReaderSlice)
161 go ReadIntoBuffer(buffer, reader, slices)
164 out := make([]byte, 128)
165 for i := 0; i < 128; i += 1 {
170 c.Check(len(s1.slice), Equals, 128)
171 c.Check(s1.reader_error, Equals, nil)
172 for i := 0; i < 128; i += 1 {
173 c.Check(s1.slice[i], Equals, byte(i))
175 for i := 0; i < len(buffer); i += 1 {
177 c.Check(buffer[i], Equals, byte(i))
179 c.Check(buffer[i], Equals, byte(0))
184 out := make([]byte, 96)
185 for i := 0; i < 96; i += 1 {
189 // Write will deadlock because it can't write all the data, so
190 // spin it off to a goroutine
194 c.Check(len(s1.slice), Equals, 95)
195 c.Check(s1.reader_error, Equals, nil)
196 for i := 0; i < 95; i += 1 {
197 c.Check(s1.slice[i], Equals, byte(i/2))
199 for i := 0; i < len(buffer); i += 1 {
201 c.Check(buffer[i], Equals, byte(i))
202 } else if i < (128 + 95) {
203 c.Check(buffer[i], Equals, byte((i-128)/2))
205 c.Check(buffer[i], Equals, byte(0))
212 c.Check(len(s1.slice), Equals, 0)
213 c.Check(s1.reader_error, Equals, io.ErrShortBuffer)
218 func (s *StandaloneSuite) TestTransfer(c *C) {
219 reader, writer := io.Pipe()
221 // Buffer for reads from 'r'
222 buffer := make([]byte, 512)
224 // Read requests on Transfer() buffer
225 requests := make(chan ReadRequest)
226 defer close(requests)
228 // Reporting reader error states
229 reader_status := make(chan error)
231 go Transfer(buffer, reader, requests, reader_status)
233 br1 := MakeBufferReader(requests)
234 out := make([]byte, 128)
237 // Write some data, and read into a buffer shorter than
239 for i := 0; i < 128; i += 1 {
243 writer.Write(out[:100])
245 in := make([]byte, 64)
246 n, err := br1.Read(in)
248 c.Check(n, Equals, 64)
249 c.Check(err, Equals, nil)
251 for i := 0; i < 64; i += 1 {
252 c.Check(in[i], Equals, out[i])
257 // Write some more data, and read into buffer longer than
259 in := make([]byte, 64)
260 n, err := br1.Read(in)
261 c.Check(n, Equals, 36)
262 c.Check(err, Equals, nil)
264 for i := 0; i < 36; i += 1 {
265 c.Check(in[i], Equals, out[64+i])
271 // Test read before write
277 in := make([]byte, 64)
280 n, err := br1.Read(in)
284 time.Sleep(100 * time.Millisecond)
285 writer.Write(out[100:])
289 c.Check(got.n, Equals, 28)
290 c.Check(got.err, Equals, nil)
292 for i := 0; i < 28; i += 1 {
293 c.Check(in[i], Equals, out[100+i])
297 br2 := MakeBufferReader(requests)
299 // Test 'catch up' reader
300 in := make([]byte, 256)
301 n, err := br2.Read(in)
303 c.Check(n, Equals, 128)
304 c.Check(err, Equals, nil)
306 for i := 0; i < 128; i += 1 {
307 c.Check(in[i], Equals, out[i])
312 // Test closing the reader
314 status := <-reader_status
315 c.Check(status, Equals, io.EOF)
317 in := make([]byte, 256)
318 n1, err1 := br1.Read(in)
319 n2, err2 := br2.Read(in)
320 c.Check(n1, Equals, 0)
321 c.Check(err1, Equals, io.EOF)
322 c.Check(n2, Equals, 0)
323 c.Check(err2, Equals, io.EOF)
327 // Test 'catch up' reader after closing
328 br3 := MakeBufferReader(requests)
329 in := make([]byte, 256)
330 n, err := br3.Read(in)
332 c.Check(n, Equals, 128)
333 c.Check(err, Equals, nil)
335 for i := 0; i < 128; i += 1 {
336 c.Check(in[i], Equals, out[i])
339 n, err = br3.Read(in)
341 c.Check(n, Equals, 0)
342 c.Check(err, Equals, io.EOF)
346 func (s *StandaloneSuite) TestTransferShortBuffer(c *C) {
347 reader, writer := io.Pipe()
349 // Buffer for reads from 'r'
350 buffer := make([]byte, 100)
352 // Read requests on Transfer() buffer
353 requests := make(chan ReadRequest)
354 defer close(requests)
356 // Reporting reader error states
357 reader_status := make(chan error)
359 go Transfer(buffer, reader, requests, reader_status)
361 out := make([]byte, 101)
364 status := <-reader_status
365 c.Check(status, Equals, io.ErrShortBuffer)
368 func (s *StandaloneSuite) TestTransferFromBuffer(c *C) {
369 // Buffer for reads from 'r'
370 buffer := make([]byte, 100)
371 for i := 0; i < 100; i += 1 {
375 // Read requests on Transfer() buffer
376 requests := make(chan ReadRequest)
377 defer close(requests)
379 go Transfer(buffer, nil, requests, nil)
381 br1 := MakeBufferReader(requests)
383 in := make([]byte, 64)
385 n, err := br1.Read(in)
387 c.Check(n, Equals, 64)
388 c.Check(err, Equals, nil)
390 for i := 0; i < 64; i += 1 {
391 c.Check(in[i], Equals, buffer[i])
395 n, err := br1.Read(in)
397 c.Check(n, Equals, 36)
398 c.Check(err, Equals, nil)
400 for i := 0; i < 36; i += 1 {
401 c.Check(in[i], Equals, buffer[64+i])
405 n, err := br1.Read(in)
407 c.Check(n, Equals, 0)
408 c.Check(err, Equals, io.EOF)
412 func (s *StandaloneSuite) TestTransferIoCopy(c *C) {
413 // Buffer for reads from 'r'
414 buffer := make([]byte, 100)
415 for i := 0; i < 100; i += 1 {
419 // Read requests on Transfer() buffer
420 requests := make(chan ReadRequest)
421 defer close(requests)
423 go Transfer(buffer, nil, requests, nil)
425 br1 := MakeBufferReader(requests)
427 reader, writer := io.Pipe()
430 p := make([]byte, 100)
431 n, err := reader.Read(p)
432 c.Check(n, Equals, 100)
433 c.Check(err, Equals, nil)
434 c.Check(p, DeepEquals, buffer)
440 type StubPutHandler struct {
443 expectApiToken string
448 func (this StubPutHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
449 this.c.Check(req.URL.Path, Equals, "/"+this.expectPath)
450 this.c.Check(req.Header.Get("Authorization"), Equals, fmt.Sprintf("OAuth2 %s", this.expectApiToken))
451 body, err := ioutil.ReadAll(req.Body)
452 this.c.Check(err, Equals, nil)
453 this.c.Check(body, DeepEquals, []byte(this.expectBody))
454 resp.WriteHeader(200)
455 this.handled <- fmt.Sprintf("http://%s", req.Host)
458 func RunBogusKeepServer(st http.Handler, port int) (listener net.Listener, url string) {
459 server := http.Server{Handler: st}
462 listener, err = net.ListenTCP("tcp", &net.TCPAddr{Port: port})
464 panic(fmt.Sprintf("Could not listen on tcp port %v", port))
467 url = fmt.Sprintf("http://localhost:%d", listener.Addr().(*net.TCPAddr).Port)
469 go server.Serve(listener)
473 func UploadToStubHelper(c *C, st http.Handler, f func(*KeepClient, string,
474 io.ReadCloser, io.WriteCloser, chan UploadStatus)) {
476 listener, url := RunBogusKeepServer(st, 2990)
477 defer listener.Close()
479 kc, _ := MakeKeepClient()
480 kc.ApiToken = "abc123"
482 reader, writer := io.Pipe()
483 upload_status := make(chan UploadStatus)
485 f(kc, url, reader, writer, upload_status)
488 func (s *StandaloneSuite) TestUploadToStubKeepServer(c *C) {
489 st := StubPutHandler{
491 "acbd18db4cc2f85cedef654fccc4a4d8",
496 UploadToStubHelper(c, st,
497 func(kc *KeepClient, url string, reader io.ReadCloser,
498 writer io.WriteCloser, upload_status chan UploadStatus) {
500 go kc.uploadToKeepServer(url, st.expectPath, reader, upload_status, int64(len("foo")))
502 writer.Write([]byte("foo"))
506 status := <-upload_status
507 c.Check(status, DeepEquals, UploadStatus{nil, fmt.Sprintf("%s/%s", url, st.expectPath), 200})
511 func (s *StandaloneSuite) TestUploadToStubKeepServerBufferReader(c *C) {
512 st := StubPutHandler{
514 "acbd18db4cc2f85cedef654fccc4a4d8",
519 UploadToStubHelper(c, st,
520 func(kc *KeepClient, url string, reader io.ReadCloser,
521 writer io.WriteCloser, upload_status chan UploadStatus) {
523 // Buffer for reads from 'r'
524 buffer := make([]byte, 512)
526 // Read requests on Transfer() buffer
527 requests := make(chan ReadRequest)
528 defer close(requests)
530 // Reporting reader error states
531 reader_status := make(chan error)
533 go Transfer(buffer, reader, requests, reader_status)
535 br1 := MakeBufferReader(requests)
537 go kc.uploadToKeepServer(url, st.expectPath, br1, upload_status, 3)
539 writer.Write([]byte("foo"))
545 status := <-upload_status
546 c.Check(status, DeepEquals, UploadStatus{nil, fmt.Sprintf("%s/%s", url, st.expectPath), 200})
548 //c.Check(true, Equals, false)
552 type FailHandler struct {
556 func (this FailHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
557 resp.WriteHeader(400)
558 this.handled <- fmt.Sprintf("http://%s", req.Host)
561 func (s *StandaloneSuite) TestFailedUploadToStubKeepServer(c *C) {
565 hash := "acbd18db4cc2f85cedef654fccc4a4d8"
567 UploadToStubHelper(c, st,
568 func(kc *KeepClient, url string, reader io.ReadCloser,
569 writer io.WriteCloser, upload_status chan UploadStatus) {
571 go kc.uploadToKeepServer(url, hash, reader, upload_status, 3)
573 writer.Write([]byte("foo"))
578 status := <-upload_status
579 c.Check(status.Url, Equals, fmt.Sprintf("%s/%s", url, hash))
580 c.Check(status.StatusCode, Equals, 400)
585 type KeepServer struct {
586 listener net.Listener
590 func RunSomeFakeKeepServers(st http.Handler, n int, port int) (ks []KeepServer) {
591 ks = make([]KeepServer, n)
593 for i := 0; i < n; i += 1 {
594 boguslistener, bogusurl := RunBogusKeepServer(st, port+i)
595 ks[i] = KeepServer{boguslistener, bogusurl}
601 func (s *StandaloneSuite) TestPutB(c *C) {
602 log.Printf("TestPutB")
604 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
606 st := StubPutHandler{
611 make(chan string, 2)}
613 kc, _ := MakeKeepClient()
616 kc.ApiToken = "abc123"
617 kc.Service_roots = make([]string, 5)
619 ks := RunSomeFakeKeepServers(st, 5, 2990)
621 for i := 0; i < len(ks); i += 1 {
622 kc.Service_roots[i] = ks[i].url
623 defer ks[i].listener.Close()
626 sort.Strings(kc.Service_roots)
628 kc.PutB([]byte("foo"))
630 shuff := kc.ShuffledServiceRoots(fmt.Sprintf("%x", md5.Sum([]byte("foo"))))
632 c.Check(<-st.handled, Equals, shuff[0])
633 c.Check(<-st.handled, Equals, shuff[1])
636 func (s *StandaloneSuite) TestPutHR(c *C) {
637 log.Printf("TestPutHR")
639 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
641 st := StubPutHandler{
646 make(chan string, 2)}
648 kc, _ := MakeKeepClient()
651 kc.ApiToken = "abc123"
652 kc.Service_roots = make([]string, 5)
654 ks := RunSomeFakeKeepServers(st, 5, 2990)
656 for i := 0; i < len(ks); i += 1 {
657 kc.Service_roots[i] = ks[i].url
658 defer ks[i].listener.Close()
661 sort.Strings(kc.Service_roots)
663 reader, writer := io.Pipe()
666 writer.Write([]byte("foo"))
670 kc.PutHR(hash, reader, 3)
672 shuff := kc.ShuffledServiceRoots(hash)
678 c.Check((s1 == shuff[0] && s2 == shuff[1]) ||
679 (s1 == shuff[1] && s2 == shuff[0]),
684 func (s *StandaloneSuite) TestPutWithFail(c *C) {
685 log.Printf("TestPutWithFail")
687 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
689 st := StubPutHandler{
694 make(chan string, 2)}
697 make(chan string, 1)}
699 kc, _ := MakeKeepClient()
702 kc.ApiToken = "abc123"
703 kc.Service_roots = make([]string, 5)
705 ks1 := RunSomeFakeKeepServers(st, 4, 2990)
706 ks2 := RunSomeFakeKeepServers(fh, 1, 2995)
708 for i, k := range ks1 {
709 kc.Service_roots[i] = k.url
710 defer k.listener.Close()
712 for i, k := range ks2 {
713 kc.Service_roots[len(ks1)+i] = k.url
714 defer k.listener.Close()
717 sort.Strings(kc.Service_roots)
719 shuff := kc.ShuffledServiceRoots(fmt.Sprintf("%x", md5.Sum([]byte("foo"))))
721 phash, replicas, err := kc.PutB([]byte("foo"))
725 c.Check(err, Equals, nil)
726 c.Check(phash, Equals, hash)
727 c.Check(replicas, Equals, 2)
728 c.Check(<-st.handled, Equals, shuff[1])
729 c.Check(<-st.handled, Equals, shuff[2])
732 func (s *StandaloneSuite) TestPutWithTooManyFail(c *C) {
733 log.Printf("TestPutWithTooManyFail")
735 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
737 st := StubPutHandler{
742 make(chan string, 1)}
745 make(chan string, 4)}
747 kc, _ := MakeKeepClient()
750 kc.ApiToken = "abc123"
751 kc.Service_roots = make([]string, 5)
753 ks1 := RunSomeFakeKeepServers(st, 1, 2990)
754 ks2 := RunSomeFakeKeepServers(fh, 4, 2991)
756 for i, k := range ks1 {
757 kc.Service_roots[i] = k.url
758 defer k.listener.Close()
760 for i, k := range ks2 {
761 kc.Service_roots[len(ks1)+i] = k.url
762 defer k.listener.Close()
765 sort.Strings(kc.Service_roots)
767 shuff := kc.ShuffledServiceRoots(fmt.Sprintf("%x", md5.Sum([]byte("foo"))))
769 _, replicas, err := kc.PutB([]byte("foo"))
771 c.Check(err, Equals, InsufficientReplicasError)
772 c.Check(replicas, Equals, 1)
773 c.Check(<-st.handled, Equals, shuff[1])
776 type StubGetHandler struct {
779 expectApiToken string
783 func (this StubGetHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
784 this.c.Check(req.URL.Path, Equals, "/"+this.expectPath)
785 this.c.Check(req.Header.Get("Authorization"), Equals, fmt.Sprintf("OAuth2 %s", this.expectApiToken))
786 resp.Header().Set("Content-Length", fmt.Sprintf("%d", len(this.returnBody)))
787 resp.Write(this.returnBody)
790 func (s *StandaloneSuite) TestGet(c *C) {
792 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
794 st := StubGetHandler{
800 listener, url := RunBogusKeepServer(st, 2990)
801 defer listener.Close()
803 kc, _ := MakeKeepClient()
804 kc.ApiToken = "abc123"
805 kc.Service_roots = []string{url}
807 r, n, url2, err := kc.Get(hash)
808 c.Check(err, Equals, nil)
809 c.Check(n, Equals, int64(3))
810 c.Check(url2, Equals, fmt.Sprintf("%s/%s", url, hash))
812 content, err2 := ioutil.ReadAll(r)
813 c.Check(err2, Equals, nil)
814 c.Check(content, DeepEquals, []byte("foo"))
817 func (s *StandaloneSuite) TestGetFail(c *C) {
818 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
820 st := FailHandler{make(chan string, 1)}
822 listener, url := RunBogusKeepServer(st, 2990)
823 defer listener.Close()
825 kc, _ := MakeKeepClient()
826 kc.ApiToken = "abc123"
827 kc.Service_roots = []string{url}
829 r, n, url2, err := kc.Get(hash)
830 c.Check(err, Equals, BlockNotFound)
831 c.Check(n, Equals, int64(0))
832 c.Check(url2, Equals, "")
833 c.Check(r, Equals, nil)
836 func (s *StandaloneSuite) TestGetWithFailures(c *C) {
838 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
841 make(chan string, 1)}
843 st := StubGetHandler{
849 kc, _ := MakeKeepClient()
850 kc.ApiToken = "abc123"
851 kc.Service_roots = make([]string, 5)
853 ks1 := RunSomeFakeKeepServers(st, 1, 2990)
854 ks2 := RunSomeFakeKeepServers(fh, 4, 2991)
856 for i, k := range ks1 {
857 kc.Service_roots[i] = k.url
858 defer k.listener.Close()
860 for i, k := range ks2 {
861 kc.Service_roots[len(ks1)+i] = k.url
862 defer k.listener.Close()
865 sort.Strings(kc.Service_roots)
867 r, n, url2, err := kc.Get(hash)
869 c.Check(err, Equals, nil)
870 c.Check(n, Equals, int64(3))
871 c.Check(url2, Equals, fmt.Sprintf("%s/%s", ks1[0].url, hash))
873 content, err2 := ioutil.ReadAll(r)
874 c.Check(err2, Equals, nil)
875 c.Check(content, DeepEquals, []byte("foo"))
878 func (s *ServerRequiredSuite) TestPutGetHead(c *C) {
879 os.Setenv("ARVADOS_API_HOST", "localhost:3001")
880 os.Setenv("ARVADOS_API_TOKEN", "4axaw8zxe0qm22wa6urpp5nskcne8z88cvbupv653y1njyi05h")
881 os.Setenv("ARVADOS_API_HOST_INSECURE", "true")
883 kc, err := MakeKeepClient()
884 c.Assert(err, Equals, nil)
886 hash, replicas, err := kc.PutB([]byte("foo"))
887 c.Check(hash, Equals, fmt.Sprintf("%x", md5.Sum([]byte("foo"))))
888 c.Check(replicas, Equals, 2)
889 c.Check(err, Equals, nil)
892 r, n, url2, err := kc.Get(hash)
893 c.Check(err, Equals, nil)
894 c.Check(n, Equals, int64(3))
895 c.Check(url2, Equals, fmt.Sprintf("http://localhost:25108/%s", hash))
897 content, err2 := ioutil.ReadAll(r)
898 c.Check(err2, Equals, nil)
899 c.Check(content, DeepEquals, []byte("foo"))
903 n, url2, err := kc.Ask(hash)
904 c.Check(err, Equals, nil)
905 c.Check(n, Equals, int64(3))
906 c.Check(url2, Equals, fmt.Sprintf("http://localhost:25108/%s", hash))