16427: Move signing code to sdk/go/arvados, add SignManifest.
[arvados.git] / sdk / go / keepclient / collectionreader_test.go
index 6f49c590fdca4c1b1b4776562e3f5b78ee1bbe54..c6c9f044416a7fb93c4b898dfcafcdc121dfc1e4 100644 (file)
@@ -1,18 +1,22 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: Apache-2.0
+
 package keepclient
 
 import (
        "crypto/md5"
-       "crypto/rand"
        "fmt"
        "io"
        "io/ioutil"
+       "math/rand"
        "net/http"
        "os"
        "strconv"
        "strings"
 
-       "git.curoverse.com/arvados.git/sdk/go/arvadosclient"
-       "git.curoverse.com/arvados.git/sdk/go/arvadostest"
+       "git.arvados.org/arvados.git/sdk/go/arvadosclient"
+       "git.arvados.org/arvados.git/sdk/go/arvadostest"
        check "gopkg.in/check.v1"
 )
 
@@ -78,6 +82,7 @@ func (h SuccessHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
                if !ok {
                        resp.WriteHeader(http.StatusNotFound)
                } else {
+                       resp.Header().Set("Content-Length", fmt.Sprintf("%d", len(buf)))
                        resp.Write(buf)
                }
        default:
@@ -102,11 +107,11 @@ func (s *CollectionReaderUnit) TestCollectionReaderContent(c *check.C) {
        for _, testCase := range []rdrTest{
                {mt: mt, f: "zzzz", want: os.ErrNotExist},
                {mt: mt, f: "frob", want: os.ErrNotExist},
-               {mt: mt, f: "/segmented/frob", want: os.ErrNotExist},
-               {mt: mt, f: "./segmented/frob", want: os.ErrNotExist},
-               {mt: mt, f: "/f", want: os.ErrNotExist},
-               {mt: mt, f: "./f", want: os.ErrNotExist},
-               {mt: mt, f: "foo bar//baz", want: os.ErrNotExist},
+               {mt: mt, f: "/segmented/frob", want: "frob"},
+               {mt: mt, f: "./segmented/frob", want: "frob"},
+               {mt: mt, f: "/f", want: "f"},
+               {mt: mt, f: "./f", want: "f"},
+               {mt: mt, f: "foo bar//baz", want: "foo"},
                {mt: mt, f: "foo/zero", want: ""},
                {mt: mt, f: "zero@0", want: ""},
                {mt: mt, f: "zero@1", want: ""},
@@ -146,6 +151,7 @@ func (s *CollectionReaderUnit) TestCollectionReaderContent(c *check.C) {
                                        c.Check(offset, check.Equals, int64(a))
                                        buf := make([]byte, b-a)
                                        n, err := io.ReadFull(rdr, buf)
+                                       c.Check(err, check.IsNil)
                                        c.Check(n, check.Equals, b-a)
                                        c.Check(string(buf), check.Equals, want[a:b])
                                }
@@ -163,26 +169,69 @@ func (s *CollectionReaderUnit) TestCollectionReaderManyBlocks(c *check.C) {
        h := md5.New()
        buf := make([]byte, 4096)
        locs := make([]string, len(buf))
+       testdata := make([]byte, 0, len(buf)*len(buf))
        filesize := 0
-       for i := 0; i < len(locs); i++ {
-               _, err := io.ReadFull(rand.Reader, buf[:i])
-               c.Assert(err, check.IsNil)
+       for i := range locs {
+               _, err := rand.Read(buf[:i])
                h.Write(buf[:i])
                locs[i], _, err = s.kc.PutB(buf[:i])
                c.Assert(err, check.IsNil)
                filesize += i
+               testdata = append(testdata, buf[:i]...)
        }
        manifest := "./random " + strings.Join(locs, " ") + " 0:" + strconv.Itoa(filesize) + ":bytes.bin\n"
        dataMD5 := h.Sum(nil)
 
        checkMD5 := md5.New()
        rdr, err := s.kc.CollectionFileReader(map[string]interface{}{"manifest_text": manifest}, "random/bytes.bin")
-       c.Check(err, check.IsNil)
+       c.Assert(err, check.IsNil)
+       defer rdr.Close()
+
        _, err = io.Copy(checkMD5, rdr)
        c.Check(err, check.IsNil)
        _, err = rdr.Read(make([]byte, 1))
        c.Check(err, check.Equals, io.EOF)
        c.Check(checkMD5.Sum(nil), check.DeepEquals, dataMD5)
+
+       size, err := rdr.Seek(0, io.SeekEnd)
+       c.Check(err, check.IsNil)
+       buf = make([]byte, len(testdata))
+       copy(buf, testdata)
+       curPos := size
+       for i := 0; i < 16; i++ {
+               offset := rand.Intn(len(buf) - 1)
+               count := rand.Intn(len(buf) - offset)
+               if rand.Intn(2) == 0 {
+                       curPos, err = rdr.Seek(int64(offset)-curPos, io.SeekCurrent)
+               } else {
+                       curPos, err = rdr.Seek(int64(offset), io.SeekStart)
+               }
+               c.Check(curPos, check.Equals, int64(offset))
+               for count > 0 {
+                       n, err := rdr.Read(buf[offset : offset+count])
+                       c.Assert(err, check.IsNil)
+                       c.Assert(n > 0, check.Equals, true)
+                       offset += n
+                       count -= n
+               }
+               curPos, err = rdr.Seek(0, io.SeekCurrent)
+               c.Check(curPos, check.Equals, int64(offset))
+       }
+       c.Check(md5.Sum(buf), check.DeepEquals, md5.Sum(testdata))
+       c.Check(buf[:1000], check.DeepEquals, testdata[:1000])
+
+       expectPos := curPos + size + 12345
+       curPos, err = rdr.Seek(size+12345, io.SeekCurrent)
+       c.Check(err, check.IsNil)
+       c.Check(curPos, check.Equals, expectPos)
+
+       curPos, err = rdr.Seek(8-curPos, io.SeekCurrent)
+       c.Check(err, check.IsNil)
+       c.Check(curPos, check.Equals, int64(8))
+
+       curPos, err = rdr.Seek(-9, io.SeekCurrent)
+       c.Check(err, check.NotNil)
+       c.Check(curPos, check.Equals, int64(8))
 }
 
 func (s *CollectionReaderUnit) TestCollectionReaderCloseEarly(c *check.C) {