Merge pull request #2221 from AkihiroSuda/content-small-blob
services/content: fix reading a blob which is smaller than the read buffer
This commit is contained in:
commit
ad6d02b881
@ -46,6 +46,7 @@ func ContentSuite(t *testing.T, name string, storeFn func(ctx context.Context, r
|
|||||||
t.Run("ResumeCopy", makeTest(t, name, storeFn, checkResume(resumeCopy)))
|
t.Run("ResumeCopy", makeTest(t, name, storeFn, checkResume(resumeCopy)))
|
||||||
t.Run("ResumeCopySeeker", makeTest(t, name, storeFn, checkResume(resumeCopySeeker)))
|
t.Run("ResumeCopySeeker", makeTest(t, name, storeFn, checkResume(resumeCopySeeker)))
|
||||||
t.Run("ResumeCopyReaderAt", makeTest(t, name, storeFn, checkResume(resumeCopyReaderAt)))
|
t.Run("ResumeCopyReaderAt", makeTest(t, name, storeFn, checkResume(resumeCopyReaderAt)))
|
||||||
|
t.Run("SmallBlob", makeTest(t, name, storeFn, checkSmallBlob))
|
||||||
t.Run("Labels", makeTest(t, name, storeFn, checkLabels))
|
t.Run("Labels", makeTest(t, name, storeFn, checkLabels))
|
||||||
|
|
||||||
t.Run("CrossNamespaceAppend", makeTest(t, name, storeFn, checkCrossNSAppend))
|
t.Run("CrossNamespaceAppend", makeTest(t, name, storeFn, checkCrossNSAppend))
|
||||||
@ -523,6 +524,46 @@ func resumeCopyReaderAt(ctx context.Context, w content.Writer, b []byte, _, size
|
|||||||
return errors.Wrap(content.Copy(ctx, w, r, size, dgst), "copy failed")
|
return errors.Wrap(content.Copy(ctx, w, r, size, dgst), "copy failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkSmallBlob tests reading a blob which is smaller than the read size.
|
||||||
|
func checkSmallBlob(ctx context.Context, t *testing.T, store content.Store) {
|
||||||
|
blob := []byte(`foobar`)
|
||||||
|
blobSize := int64(len(blob))
|
||||||
|
blobDigest := digest.FromBytes(blob)
|
||||||
|
// test write
|
||||||
|
w, err := store.Writer(ctx, t.Name(), blobSize, blobDigest)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := w.Write(blob); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := w.Commit(ctx, blobSize, blobDigest); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := w.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
// test read.
|
||||||
|
readSize := blobSize + 1
|
||||||
|
ra, err := store.ReaderAt(ctx, blobDigest)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
r := io.NewSectionReader(ra, 0, readSize)
|
||||||
|
b, err := ioutil.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := ra.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
d := digest.FromBytes(b)
|
||||||
|
if blobDigest != d {
|
||||||
|
t.Fatalf("expected %s (%q), got %s (%q)", blobDigest, string(blob),
|
||||||
|
d, string(b))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func checkCrossNSShare(ctx context.Context, t *testing.T, cs content.Store) {
|
func checkCrossNSShare(ctx context.Context, t *testing.T, cs content.Store) {
|
||||||
wrap, ok := ctx.Value(wrapperKey{}).(ContextWrapper)
|
wrap, ok := ctx.Value(wrapperKey{}).(ContextWrapper)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -187,7 +187,9 @@ func (s *service) Read(req *api.ReadContentRequest, session api.Content_ReadServ
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
offset = req.Offset
|
offset = req.Offset
|
||||||
size = req.Size_
|
// size is read size, not the expected size of the blob (oi.Size), which the caller might not be aware of.
|
||||||
|
// offset+size can be larger than oi.Size.
|
||||||
|
size = req.Size_
|
||||||
|
|
||||||
// TODO(stevvooe): Using the global buffer pool. At 32KB, it is probably
|
// TODO(stevvooe): Using the global buffer pool. At 32KB, it is probably
|
||||||
// little inefficient for work over a fast network. We can tune this later.
|
// little inefficient for work over a fast network. We can tune this later.
|
||||||
@ -199,12 +201,12 @@ func (s *service) Read(req *api.ReadContentRequest, session api.Content_ReadServ
|
|||||||
offset = 0
|
offset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if size <= 0 {
|
if offset > oi.Size {
|
||||||
size = oi.Size - offset
|
return status.Errorf(codes.OutOfRange, "read past object length %v bytes", oi.Size)
|
||||||
}
|
}
|
||||||
|
|
||||||
if offset+size > oi.Size {
|
if size <= 0 || offset+size > oi.Size {
|
||||||
return status.Errorf(codes.OutOfRange, "read past object length %v bytes", oi.Size)
|
size = oi.Size - offset
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = io.CopyBuffer(
|
_, err = io.CopyBuffer(
|
||||||
|
Loading…
Reference in New Issue
Block a user