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