Merge branch 'master' into 10797-ruby-2.3
[arvados.git] / services / keep-web / ranges_test.go
1 package main
2
3 import (
4         "fmt"
5         "net/http"
6         "net/http/httptest"
7
8         "git.curoverse.com/arvados.git/sdk/go/arvadosclient"
9         "git.curoverse.com/arvados.git/sdk/go/arvadostest"
10         "git.curoverse.com/arvados.git/sdk/go/keepclient"
11         check "gopkg.in/check.v1"
12 )
13
14 func (s *IntegrationSuite) TestRanges(c *check.C) {
15         blocksize := 1000000
16         var uuid string
17         {
18                 testdata := make([]byte, blocksize)
19                 for i := 0; i < blocksize; i++ {
20                         testdata[i] = byte(' ')
21                 }
22                 copy(testdata[1:4], []byte("foo"))
23                 arv, err := arvadosclient.MakeArvadosClient()
24                 c.Assert(err, check.Equals, nil)
25                 arv.ApiToken = arvadostest.ActiveToken
26                 kc, err := keepclient.MakeKeepClient(arv)
27                 c.Assert(err, check.Equals, nil)
28                 loc, _, err := kc.PutB(testdata[:])
29                 c.Assert(err, check.Equals, nil)
30                 loc2, _, err := kc.PutB([]byte{'Z'})
31                 c.Assert(err, check.Equals, nil)
32
33                 mtext := fmt.Sprintf(". %s %s %s %s %s 1:%d:testdata.bin 0:1:space.txt\n", loc, loc, loc, loc, loc2, blocksize*4)
34                 coll := map[string]interface{}{}
35                 err = arv.Create("collections",
36                         map[string]interface{}{
37                                 "collection": map[string]interface{}{
38                                         "name":          "test data for keep-web TestRanges",
39                                         "manifest_text": mtext,
40                                 },
41                         }, &coll)
42                 c.Assert(err, check.Equals, nil)
43                 uuid = coll["uuid"].(string)
44                 defer arv.Delete("collections", uuid, nil, nil)
45         }
46
47         url := mustParseURL("http://" + uuid + ".collections.example.com/testdata.bin")
48         for _, trial := range []struct {
49                 header     string
50                 expectObey bool
51                 expectBody string
52         }{
53                 {"0-2", true, "foo"},
54                 {"-2", true, " Z"},
55                 {"1-4", true, "oo  "},
56                 {"z-y", false, ""},
57                 {"1000000-1000003", true, "foo "},
58                 {"999999-1000003", true, " foo "},
59                 {"2000000-2000003", true, "foo "},
60                 {"1999999-2000002", true, " foo"},
61                 {"3999998-3999999", true, " Z"},
62                 {"3999998-4000004", true, " Z"},
63                 {"3999998-", true, " Z"},
64         } {
65                 c.Logf("trial: %#v", trial)
66                 resp := httptest.NewRecorder()
67                 req := &http.Request{
68                         Method:     "GET",
69                         URL:        url,
70                         Host:       url.Host,
71                         RequestURI: url.RequestURI(),
72                         Header: http.Header{
73                                 "Authorization": {"OAuth2 " + arvadostest.ActiveToken},
74                                 "Range":         {"bytes=" + trial.header},
75                         },
76                 }
77                 s.testServer.Handler.ServeHTTP(resp, req)
78                 if trial.expectObey {
79                         c.Check(resp.Code, check.Equals, http.StatusPartialContent)
80                         c.Check(resp.Body.Len(), check.Equals, len(trial.expectBody))
81                         if resp.Body.Len() > 1000 {
82                                 c.Check(resp.Body.String()[:1000]+"[...]", check.Equals, trial.expectBody)
83                         } else {
84                                 c.Check(resp.Body.String(), check.Equals, trial.expectBody)
85                         }
86                 } else {
87                         c.Check(resp.Code, check.Equals, http.StatusRequestedRangeNotSatisfiable)
88                 }
89         }
90 }