diff --git a/internal/storage/minio_chunk_manager.go b/internal/storage/minio_chunk_manager.go index 1e0f6ec834..9977c3cf8d 100644 --- a/internal/storage/minio_chunk_manager.go +++ b/internal/storage/minio_chunk_manager.go @@ -412,10 +412,6 @@ func (mcm *MinioChunkManager) ListWithPrefix(ctx context.Context, prefix string, func Read(r io.Reader, size int64) ([]byte, error) { data := make([]byte, 0, size) for { - if len(data) >= cap(data) { - d := append(data[:cap(data)], 0) - data = d[:len(data)] - } n, err := r.Read(data[len(data):cap(data)]) data = data[:len(data)+n] if err != nil { @@ -424,5 +420,8 @@ func Read(r io.Reader, size int64) ([]byte, error) { } return data, err } + if len(data) == cap(data) { + return data, nil + } } } diff --git a/internal/storage/minio_chunk_manager_test.go b/internal/storage/minio_chunk_manager_test.go index 95140f6889..58bd72e3c9 100644 --- a/internal/storage/minio_chunk_manager_test.go +++ b/internal/storage/minio_chunk_manager_test.go @@ -19,6 +19,8 @@ package storage import ( "context" "errors" + "io" + "math/rand" "path" "strconv" "strings" @@ -571,3 +573,63 @@ func TestMinioChunkManager_normalizeRootPath(t *testing.T) { }) } } + +func TestMinioChunkManager_Read(t *testing.T) { + var reader MockReader + reader.offset = new(int) + reader.value = make([]byte, 10) + reader.lastEOF = true + for i := 0; i < 10; i++ { + reader.value[i] = byte(i) + } + value, err := Read(reader, 10) + assert.Equal(t, len(value), 10) + for i := 0; i < 10; i++ { + assert.Equal(t, value[i], byte(i)) + } + + assert.Nil(t, err) +} + +func TestMinioChunkManager_ReadEOF(t *testing.T) { + var reader MockReader + reader.offset = new(int) + reader.value = make([]byte, 10) + reader.lastEOF = false + for i := 0; i < 10; i++ { + reader.value[i] = byte(i) + } + value, err := Read(reader, 10) + assert.Equal(t, len(value), 10) + for i := 0; i < 10; i++ { + assert.Equal(t, value[i], byte(i)) + } + assert.Nil(t, err) +} + +type MockReader struct { + value []byte + offset *int + lastEOF bool +} + +func (r MockReader) Read(p []byte) (n int, err error) { + if len(r.value) == *r.offset { + return 0, io.EOF + } + + cap := len(r.value) - *r.offset + if cap < 5 { + copy(p, r.value[*r.offset:]) + *r.offset = len(r.value) + if r.lastEOF { + return cap, io.EOF + } + return cap, nil + } + + n = rand.Intn(5) + copy(p, r.value[*r.offset:(*r.offset+n)]) + *r.offset += n + return n, nil +}