21 // Gocheck boilerplate
22 func Test(t *testing.T) {
26 // Gocheck boilerplate
27 var _ = Suite(&ServerRequiredSuite{})
28 var _ = Suite(&StandaloneSuite{})
30 var no_server = flag.Bool("no-server", false, "Skip 'ServerRequireSuite'")
32 // Tests that require the Keep server running
33 type ServerRequiredSuite struct{}
36 type StandaloneSuite struct{}
38 func pythonDir() string {
39 gopath := os.Getenv("GOPATH")
40 return fmt.Sprintf("%s/../python/tests", strings.Split(gopath, ":")[0])
43 func (s *ServerRequiredSuite) SetUpSuite(c *C) {
45 c.Skip("Skipping tests that require server")
48 if err := exec.Command("python", "run_test_server.py", "start").Run(); err != nil {
49 panic("'python run_test_server.py start' returned error")
51 if err := exec.Command("python", "run_test_server.py", "start_keep").Run(); err != nil {
52 panic("'python run_test_server.py start_keep' returned error")
57 func (s *ServerRequiredSuite) TearDownSuite(c *C) {
59 exec.Command("python", "run_test_server.py", "stop_keep").Run()
60 exec.Command("python", "run_test_server.py", "stop").Run()
63 func (s *ServerRequiredSuite) TestMakeKeepClient(c *C) {
64 os.Setenv("ARVADOS_API_HOST", "localhost:3001")
65 os.Setenv("ARVADOS_API_TOKEN", "4axaw8zxe0qm22wa6urpp5nskcne8z88cvbupv653y1njyi05h")
66 os.Setenv("ARVADOS_API_HOST_INSECURE", "true")
68 arv, err := sdk.MakeArvadosClient()
69 c.Assert(err, Equals, nil)
71 kc, err := MakeKeepClient(&arv)
73 c.Assert(err, Equals, nil)
74 c.Check(len(kc.ServiceRoots()), Equals, 2)
75 c.Check(kc.ServiceRoots()[0], Equals, "http://localhost:25107")
76 c.Check(kc.ServiceRoots()[1], Equals, "http://localhost:25108")
79 func (s *StandaloneSuite) TestShuffleServiceRoots(c *C) {
81 kc.SetServiceRoots([]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 type StubPutHandler struct {
100 func (this StubPutHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
101 this.c.Check(req.URL.Path, Equals, "/"+this.expectPath)
102 this.c.Check(req.Header.Get("Authorization"), Equals, fmt.Sprintf("OAuth2 %s", this.expectApiToken))
103 body, err := ioutil.ReadAll(req.Body)
104 this.c.Check(err, Equals, nil)
105 this.c.Check(body, DeepEquals, []byte(this.expectBody))
106 resp.WriteHeader(200)
107 this.handled <- fmt.Sprintf("http://%s", req.Host)
110 func RunBogusKeepServer(st http.Handler, port int) (listener net.Listener, url string) {
112 listener, err = net.ListenTCP("tcp", &net.TCPAddr{Port: port})
114 panic(fmt.Sprintf("Could not listen on tcp port %v", port))
117 url = fmt.Sprintf("http://localhost:%d", port)
119 go http.Serve(listener, st)
123 func UploadToStubHelper(c *C, st http.Handler, f func(KeepClient, string,
124 io.ReadCloser, io.WriteCloser, chan uploadStatus)) {
126 listener, url := RunBogusKeepServer(st, 2990)
127 defer listener.Close()
129 arv, _ := sdk.MakeArvadosClient()
130 arv.ApiToken = "abc123"
132 kc, _ := MakeKeepClient(&arv)
134 reader, writer := io.Pipe()
135 upload_status := make(chan uploadStatus)
137 f(kc, url, reader, writer, upload_status)
140 func (s *StandaloneSuite) TestUploadToStubKeepServer(c *C) {
141 log.Printf("TestUploadToStubKeepServer")
143 st := StubPutHandler{
145 "acbd18db4cc2f85cedef654fccc4a4d8",
150 UploadToStubHelper(c, st,
151 func(kc KeepClient, url string, reader io.ReadCloser,
152 writer io.WriteCloser, upload_status chan uploadStatus) {
154 go kc.uploadToKeepServer(url, st.expectPath, reader, upload_status, int64(len("foo")))
156 writer.Write([]byte("foo"))
160 status := <-upload_status
161 c.Check(status, DeepEquals, uploadStatus{nil, fmt.Sprintf("%s/%s", url, st.expectPath), 200, 1, ""})
164 log.Printf("TestUploadToStubKeepServer done")
167 func (s *StandaloneSuite) TestUploadToStubKeepServerBufferReader(c *C) {
168 log.Printf("TestUploadToStubKeepServerBufferReader")
170 st := StubPutHandler{
172 "acbd18db4cc2f85cedef654fccc4a4d8",
177 UploadToStubHelper(c, st,
178 func(kc KeepClient, url string, reader io.ReadCloser,
179 writer io.WriteCloser, upload_status chan uploadStatus) {
181 tr := streamer.AsyncStreamFromReader(512, reader)
184 br1 := tr.MakeStreamReader()
186 go kc.uploadToKeepServer(url, st.expectPath, br1, upload_status, 3)
188 writer.Write([]byte("foo"))
193 status := <-upload_status
194 c.Check(status, DeepEquals, uploadStatus{nil, fmt.Sprintf("%s/%s", url, st.expectPath), 200, 1, ""})
197 log.Printf("TestUploadToStubKeepServerBufferReader done")
200 type FailHandler struct {
204 func (this FailHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
205 resp.WriteHeader(500)
206 this.handled <- fmt.Sprintf("http://%s", req.Host)
209 func (s *StandaloneSuite) TestFailedUploadToStubKeepServer(c *C) {
210 log.Printf("TestFailedUploadToStubKeepServer")
215 hash := "acbd18db4cc2f85cedef654fccc4a4d8"
217 UploadToStubHelper(c, st,
218 func(kc KeepClient, url string, reader io.ReadCloser,
219 writer io.WriteCloser, upload_status chan uploadStatus) {
221 go kc.uploadToKeepServer(url, hash, reader, upload_status, 3)
223 writer.Write([]byte("foo"))
228 status := <-upload_status
229 c.Check(status.url, Equals, fmt.Sprintf("%s/%s", url, hash))
230 c.Check(status.statusCode, Equals, 500)
232 log.Printf("TestFailedUploadToStubKeepServer done")
235 type KeepServer struct {
236 listener net.Listener
240 func RunSomeFakeKeepServers(st http.Handler, n int, port int) (ks []KeepServer) {
241 ks = make([]KeepServer, n)
243 for i := 0; i < n; i += 1 {
244 boguslistener, bogusurl := RunBogusKeepServer(st, port+i)
245 ks[i] = KeepServer{boguslistener, bogusurl}
251 func (s *StandaloneSuite) TestPutB(c *C) {
252 log.Printf("TestPutB")
254 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
256 st := StubPutHandler{
261 make(chan string, 2)}
263 arv, _ := sdk.MakeArvadosClient()
264 kc, _ := MakeKeepClient(&arv)
267 arv.ApiToken = "abc123"
268 service_roots := make([]string, 5)
270 ks := RunSomeFakeKeepServers(st, 5, 2990)
272 for i := 0; i < len(ks); i += 1 {
273 service_roots[i] = ks[i].url
274 defer ks[i].listener.Close()
277 kc.SetServiceRoots(service_roots)
279 kc.PutB([]byte("foo"))
281 shuff := kc.shuffledServiceRoots(fmt.Sprintf("%x", md5.Sum([]byte("foo"))))
285 c.Check((s1 == shuff[0] && s2 == shuff[1]) ||
286 (s1 == shuff[1] && s2 == shuff[0]),
290 log.Printf("TestPutB done")
293 func (s *StandaloneSuite) TestPutHR(c *C) {
294 log.Printf("TestPutHR")
296 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
298 st := StubPutHandler{
303 make(chan string, 2)}
305 arv, _ := sdk.MakeArvadosClient()
306 kc, _ := MakeKeepClient(&arv)
309 arv.ApiToken = "abc123"
310 service_roots := make([]string, 5)
312 ks := RunSomeFakeKeepServers(st, 5, 2990)
314 for i := 0; i < len(ks); i += 1 {
315 service_roots[i] = ks[i].url
316 defer ks[i].listener.Close()
319 kc.SetServiceRoots(service_roots)
321 reader, writer := io.Pipe()
324 writer.Write([]byte("foo"))
328 kc.PutHR(hash, reader, 3)
330 shuff := kc.shuffledServiceRoots(hash)
336 c.Check((s1 == shuff[0] && s2 == shuff[1]) ||
337 (s1 == shuff[1] && s2 == shuff[0]),
341 log.Printf("TestPutHR done")
344 func (s *StandaloneSuite) TestPutWithFail(c *C) {
345 log.Printf("TestPutWithFail")
347 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
349 st := StubPutHandler{
354 make(chan string, 2)}
357 make(chan string, 1)}
359 arv, err := sdk.MakeArvadosClient()
360 kc, _ := MakeKeepClient(&arv)
363 arv.ApiToken = "abc123"
364 service_roots := make([]string, 5)
366 ks1 := RunSomeFakeKeepServers(st, 4, 2990)
367 ks2 := RunSomeFakeKeepServers(fh, 1, 2995)
369 for i, k := range ks1 {
370 service_roots[i] = k.url
371 defer k.listener.Close()
373 for i, k := range ks2 {
374 service_roots[len(ks1)+i] = k.url
375 defer k.listener.Close()
378 kc.SetServiceRoots(service_roots)
380 shuff := kc.shuffledServiceRoots(fmt.Sprintf("%x", md5.Sum([]byte("foo"))))
382 phash, replicas, err := kc.PutB([]byte("foo"))
386 c.Check(err, Equals, nil)
387 c.Check(phash, Equals, "")
388 c.Check(replicas, Equals, 2)
389 c.Check(<-st.handled, Equals, shuff[1])
390 c.Check(<-st.handled, Equals, shuff[2])
393 func (s *StandaloneSuite) TestPutWithTooManyFail(c *C) {
394 log.Printf("TestPutWithTooManyFail")
396 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
398 st := StubPutHandler{
403 make(chan string, 1)}
406 make(chan string, 4)}
408 arv, err := sdk.MakeArvadosClient()
409 kc, _ := MakeKeepClient(&arv)
412 arv.ApiToken = "abc123"
413 service_roots := make([]string, 5)
415 ks1 := RunSomeFakeKeepServers(st, 1, 2990)
416 ks2 := RunSomeFakeKeepServers(fh, 4, 2991)
418 for i, k := range ks1 {
419 service_roots[i] = k.url
420 defer k.listener.Close()
422 for i, k := range ks2 {
423 service_roots[len(ks1)+i] = k.url
424 defer k.listener.Close()
427 kc.SetServiceRoots(service_roots)
429 shuff := kc.shuffledServiceRoots(fmt.Sprintf("%x", md5.Sum([]byte("foo"))))
431 _, replicas, err := kc.PutB([]byte("foo"))
433 c.Check(err, Equals, InsufficientReplicasError)
434 c.Check(replicas, Equals, 1)
435 c.Check(<-st.handled, Equals, shuff[1])
437 log.Printf("TestPutWithTooManyFail done")
440 type StubGetHandler struct {
443 expectApiToken string
447 func (this StubGetHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
448 this.c.Check(req.URL.Path, Equals, "/"+this.expectPath)
449 this.c.Check(req.Header.Get("Authorization"), Equals, fmt.Sprintf("OAuth2 %s", this.expectApiToken))
450 resp.Header().Set("Content-Length", fmt.Sprintf("%d", len(this.returnBody)))
451 resp.Write(this.returnBody)
454 func (s *StandaloneSuite) TestGet(c *C) {
455 log.Printf("TestGet")
457 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
459 st := StubGetHandler{
465 listener, url := RunBogusKeepServer(st, 2990)
466 defer listener.Close()
468 arv, err := sdk.MakeArvadosClient()
469 kc, _ := MakeKeepClient(&arv)
470 arv.ApiToken = "abc123"
471 kc.SetServiceRoots([]string{url})
473 r, n, url2, err := kc.Get(hash)
475 c.Check(err, Equals, nil)
476 c.Check(n, Equals, int64(3))
477 c.Check(url2, Equals, fmt.Sprintf("%s/%s", url, hash))
479 content, err2 := ioutil.ReadAll(r)
480 c.Check(err2, Equals, nil)
481 c.Check(content, DeepEquals, []byte("foo"))
483 log.Printf("TestGet done")
486 func (s *StandaloneSuite) TestGetFail(c *C) {
487 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
489 st := FailHandler{make(chan string, 1)}
491 listener, url := RunBogusKeepServer(st, 2990)
492 defer listener.Close()
494 arv, err := sdk.MakeArvadosClient()
495 kc, _ := MakeKeepClient(&arv)
496 arv.ApiToken = "abc123"
497 kc.SetServiceRoots([]string{url})
499 r, n, url2, err := kc.Get(hash)
500 c.Check(err, Equals, BlockNotFound)
501 c.Check(n, Equals, int64(0))
502 c.Check(url2, Equals, "")
503 c.Check(r, Equals, nil)
506 type BarHandler struct {
510 func (this BarHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
511 resp.Write([]byte("bar"))
512 this.handled <- fmt.Sprintf("http://%s", req.Host)
515 func (s *StandaloneSuite) TestChecksum(c *C) {
516 foohash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
517 barhash := fmt.Sprintf("%x", md5.Sum([]byte("bar")))
519 st := BarHandler{make(chan string, 1)}
521 listener, url := RunBogusKeepServer(st, 2990)
522 defer listener.Close()
524 arv, err := sdk.MakeArvadosClient()
525 kc, _ := MakeKeepClient(&arv)
526 arv.ApiToken = "abc123"
527 kc.SetServiceRoots([]string{url})
529 r, n, _, err := kc.Get(barhash)
530 _, err = ioutil.ReadAll(r)
531 c.Check(n, Equals, int64(3))
532 c.Check(err, Equals, nil)
536 r, n, _, err = kc.Get(foohash)
537 _, err = ioutil.ReadAll(r)
538 c.Check(n, Equals, int64(3))
539 c.Check(err, Equals, BadChecksum)
544 func (s *StandaloneSuite) TestGetWithFailures(c *C) {
546 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
549 make(chan string, 1)}
551 st := StubGetHandler{
557 arv, err := sdk.MakeArvadosClient()
558 kc, _ := MakeKeepClient(&arv)
559 arv.ApiToken = "abc123"
560 service_roots := make([]string, 5)
562 ks1 := RunSomeFakeKeepServers(st, 1, 2990)
563 ks2 := RunSomeFakeKeepServers(fh, 4, 2991)
565 for i, k := range ks1 {
566 service_roots[i] = k.url
567 defer k.listener.Close()
569 for i, k := range ks2 {
570 service_roots[len(ks1)+i] = k.url
571 defer k.listener.Close()
574 kc.SetServiceRoots(service_roots)
576 r, n, url2, err := kc.Get(hash)
578 c.Check(err, Equals, nil)
579 c.Check(n, Equals, int64(3))
580 c.Check(url2, Equals, fmt.Sprintf("%s/%s", ks1[0].url, hash))
582 content, err2 := ioutil.ReadAll(r)
583 c.Check(err2, Equals, nil)
584 c.Check(content, DeepEquals, []byte("foo"))
587 func (s *ServerRequiredSuite) TestPutGetHead(c *C) {
588 os.Setenv("ARVADOS_API_HOST", "localhost:3001")
589 os.Setenv("ARVADOS_API_TOKEN", "4axaw8zxe0qm22wa6urpp5nskcne8z88cvbupv653y1njyi05h")
590 os.Setenv("ARVADOS_API_HOST_INSECURE", "true")
592 arv, err := sdk.MakeArvadosClient()
593 kc, err := MakeKeepClient(&arv)
594 c.Assert(err, Equals, nil)
596 hash := fmt.Sprintf("%x", md5.Sum([]byte("foo")))
599 n, _, err := kc.Ask(hash)
600 c.Check(err, Equals, BlockNotFound)
601 c.Check(n, Equals, int64(0))
604 hash2, replicas, err := kc.PutB([]byte("foo"))
605 c.Check(hash2, Equals, fmt.Sprintf("%s+%v", hash, 3))
606 c.Check(replicas, Equals, 2)
607 c.Check(err, Equals, nil)
610 r, n, url2, err := kc.Get(hash)
611 c.Check(err, Equals, nil)
612 c.Check(n, Equals, int64(3))
613 c.Check(url2, Equals, fmt.Sprintf("http://localhost:25108/%s", hash))
615 content, err2 := ioutil.ReadAll(r)
616 c.Check(err2, Equals, nil)
617 c.Check(content, DeepEquals, []byte("foo"))
620 n, url2, err := kc.Ask(hash)
621 c.Check(err, Equals, nil)
622 c.Check(n, Equals, int64(3))
623 c.Check(url2, Equals, fmt.Sprintf("http://localhost:25108/%s", hash))
627 type StubProxyHandler struct {
631 func (this StubProxyHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
632 resp.Header().Set("X-Keep-Replicas-Stored", "2")
633 this.handled <- fmt.Sprintf("http://%s", req.Host)
636 func (s *StandaloneSuite) TestPutProxy(c *C) {
637 log.Printf("TestPutProxy")
639 st := StubProxyHandler{make(chan string, 1)}
641 arv, err := sdk.MakeArvadosClient()
642 kc, _ := MakeKeepClient(&arv)
645 kc.Using_proxy = true
646 arv.ApiToken = "abc123"
647 service_roots := make([]string, 1)
649 ks1 := RunSomeFakeKeepServers(st, 1, 2990)
651 for i, k := range ks1 {
652 service_roots[i] = k.url
653 defer k.listener.Close()
656 kc.SetServiceRoots(service_roots)
658 _, replicas, err := kc.PutB([]byte("foo"))
661 c.Check(err, Equals, nil)
662 c.Check(replicas, Equals, 2)
664 log.Printf("TestPutProxy done")
667 func (s *StandaloneSuite) TestPutProxyInsufficientReplicas(c *C) {
668 log.Printf("TestPutProxy")
670 st := StubProxyHandler{make(chan string, 1)}
672 arv, err := sdk.MakeArvadosClient()
673 kc, _ := MakeKeepClient(&arv)
676 kc.Using_proxy = true
677 arv.ApiToken = "abc123"
678 service_roots := make([]string, 1)
680 ks1 := RunSomeFakeKeepServers(st, 1, 2990)
682 for i, k := range ks1 {
683 service_roots[i] = k.url
684 defer k.listener.Close()
686 kc.SetServiceRoots(service_roots)
688 _, replicas, err := kc.PutB([]byte("foo"))
691 c.Check(err, Equals, InsufficientReplicasError)
692 c.Check(replicas, Equals, 2)
694 log.Printf("TestPutProxy done")
697 func (s *StandaloneSuite) TestMakeLocator(c *C) {
698 l := MakeLocator("91f372a266fe2bf2823cb8ec7fda31ce+3+Aabcde@12345678")
700 c.Check(l.Hash, Equals, "91f372a266fe2bf2823cb8ec7fda31ce")
701 c.Check(l.Size, Equals, 3)
702 c.Check(l.Signature, Equals, "abcde")
703 c.Check(l.Timestamp, Equals, "12345678")