mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2026-05-17 08:36:55 +03:00
266 lines
5.7 KiB
Go
266 lines
5.7 KiB
Go
package chunkedbuffer
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"testing"
|
|
)
|
|
|
|
func TestBuffer(t *testing.T) {
|
|
cb := Get()
|
|
defer Put(cb)
|
|
|
|
for range 10 {
|
|
cb.Reset()
|
|
|
|
// Write data to chunked buffer
|
|
totalSize := 0
|
|
for j := 1; j < 1000; j++ {
|
|
b := make([]byte, j)
|
|
for k := range b {
|
|
b[k] = byte(k)
|
|
}
|
|
cb.MustWrite(b)
|
|
totalSize += len(b)
|
|
}
|
|
|
|
cbLen := cb.Len()
|
|
if cbLen != totalSize {
|
|
t.Fatalf("unexpected Buffer.Len value; got %d; want %d", cbLen, totalSize)
|
|
}
|
|
|
|
size := cb.SizeBytes()
|
|
if size < totalSize {
|
|
t.Fatalf("too small SizeBytes; got %d; want at least %d", size, totalSize)
|
|
}
|
|
|
|
// Read the data from chunked buffer via MustReadAt.
|
|
off := 0
|
|
for j := 1; j < 1000; j++ {
|
|
b := make([]byte, j)
|
|
cb.MustReadAt(b, int64(off))
|
|
off += j
|
|
|
|
// Verify the data is read correctly
|
|
for k := range b {
|
|
if b[k] != byte(k) {
|
|
t.Fatalf("unexpected byte read; got %d; want %d", b[k], k)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Read the data from chunked buffer via NewReader.
|
|
r := cb.NewReader()
|
|
var bb bytes.Buffer
|
|
n, err := bb.ReadFrom(r)
|
|
if err != nil {
|
|
t.Fatalf("error when reading data from chunked buffer: %s", err)
|
|
}
|
|
if n != int64(off) {
|
|
t.Fatalf("unexpected amounts of data read from chunked buffer; got %d; want %d", n, off)
|
|
}
|
|
|
|
// Verify that reader path is equivalent to cb path
|
|
cbPath := cb.Path()
|
|
rPath := r.Path()
|
|
if cbPath != rPath {
|
|
t.Fatalf("unexpected path; got %q; want %q", rPath, cbPath)
|
|
}
|
|
|
|
r.MustClose()
|
|
|
|
// Verify the read data
|
|
off = 0
|
|
data := bb.Bytes()
|
|
for j := 1; j < 1000; j++ {
|
|
b := data[off : off+j]
|
|
off += j
|
|
|
|
// Verify the data is read correctly
|
|
for k := range b {
|
|
if b[k] != byte(k) {
|
|
t.Fatalf("unexpected byte read; got %d; want %d", b[k], k)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Copy the data to another chunked buffer via WriteTo.
|
|
cb2 := Get()
|
|
n, err = cb.WriteTo(cb2)
|
|
if err != nil {
|
|
t.Fatalf("error when writing data to another chunked buffer: %s", err)
|
|
}
|
|
if n != int64(off) {
|
|
t.Fatalf("unexpected amounts of data written to chunked buffer; got %d; want %d", n, off)
|
|
}
|
|
|
|
// Verify that the data at cb is equivalent to the data at cb2
|
|
var bb2 bytes.Buffer
|
|
r2 := cb2.NewReader()
|
|
n, err = bb2.ReadFrom(r2)
|
|
if err != nil {
|
|
t.Fatalf("cannot read data from chunked buffer: %s", err)
|
|
}
|
|
if n != int64(off) {
|
|
t.Fatalf("unexpected amounts of data read from the chunked buffer; got %d; want %d", n, off)
|
|
}
|
|
data2 := bb2.Bytes()
|
|
|
|
if !bytes.Equal(data, data2) {
|
|
t.Fatalf("unexpected data at the second chunked buffer\ngot\n%q\nwant\n%q", data2, data)
|
|
}
|
|
|
|
// Verify MustClose at chunked buffer
|
|
cb2.MustClose()
|
|
|
|
Put(cb2)
|
|
}
|
|
}
|
|
|
|
func TestBuffer_ReadFrom(t *testing.T) {
|
|
cb := Get()
|
|
defer Put(cb)
|
|
|
|
bb := bytes.NewBufferString("foo")
|
|
n, err := cb.ReadFrom(bb)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %s", err)
|
|
}
|
|
if n != 3 {
|
|
t.Fatalf("unexpected number of bytes written: %d; want 3", n)
|
|
}
|
|
|
|
bb = bytes.NewBufferString("bar")
|
|
n, err = cb.ReadFrom(bb)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %s", err)
|
|
}
|
|
if n != 3 {
|
|
t.Fatalf("unexpected number of bytes written: %d; want 3", n)
|
|
}
|
|
|
|
var bbResult bytes.Buffer
|
|
cb.MustWriteTo(&bbResult)
|
|
|
|
result := bbResult.String()
|
|
resultExpected := "foobar"
|
|
if result != resultExpected {
|
|
t.Fatalf("unexpected result; got %q; want %q", result, resultExpected)
|
|
}
|
|
}
|
|
|
|
func TestBuffer_MustReadAtZeroData(_ *testing.T) {
|
|
var cb Buffer
|
|
cb.MustReadAt(nil, 0)
|
|
}
|
|
|
|
func TestBuffer_ReaderZeroData(t *testing.T) {
|
|
var cb Buffer
|
|
r := cb.NewReader()
|
|
data, err := io.ReadAll(r)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %s", err)
|
|
}
|
|
if len(data) != 0 {
|
|
t.Fatalf("unexpected data read with len=%d; data=%q", len(data), data)
|
|
}
|
|
}
|
|
|
|
func TestBuffer_ReaderSingleChunk(t *testing.T) {
|
|
var cb Buffer
|
|
|
|
fmt.Fprintf(&cb, "foo bar baz")
|
|
r := cb.NewReader()
|
|
b := make([]byte, 4)
|
|
|
|
if _, err := io.ReadFull(r, b); err != nil {
|
|
t.Fatalf("unexpected error: %s", err)
|
|
}
|
|
if string(b) != "foo " {
|
|
t.Fatalf("unexpected data read; got %q; want %q", b, "foo ")
|
|
}
|
|
|
|
if _, err := io.ReadFull(r, b); err != nil {
|
|
t.Fatalf("unexpected error: %s", err)
|
|
}
|
|
if string(b) != "bar " {
|
|
t.Fatalf("unexpected data read; got %q; want %q", b, "bar ")
|
|
}
|
|
|
|
data, err := io.ReadAll(r)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %s", err)
|
|
}
|
|
if string(data) != "baz" {
|
|
t.Fatalf("unexpected data read; got %q; want %q", b, "baz")
|
|
}
|
|
}
|
|
|
|
func TestBuffer_WriteToZeroData(t *testing.T) {
|
|
var cb Buffer
|
|
var bb bytes.Buffer
|
|
cb.MustWriteTo(&bb)
|
|
if bbLen := bb.Len(); bbLen != 0 {
|
|
t.Fatalf("unexpected data written to bb with len=%d; data=%q", bbLen, bb.Bytes())
|
|
}
|
|
}
|
|
|
|
func TestBuffer_WriteToBrokenWriter(t *testing.T) {
|
|
var cb Buffer
|
|
|
|
fmt.Fprintf(&cb, "foo bar baz")
|
|
|
|
w := &faultyWriter{}
|
|
n, err := cb.WriteTo(w)
|
|
if err == nil {
|
|
t.Fatalf("expecting non-nil error")
|
|
}
|
|
if n != 0 {
|
|
t.Fatalf("expecting zero bytes written; got %d bytes", n)
|
|
}
|
|
|
|
w = &faultyWriter{
|
|
bytesToAccept: 5,
|
|
}
|
|
n, err = cb.WriteTo(w)
|
|
if err == nil {
|
|
t.Fatalf("expecting non-nil error")
|
|
}
|
|
if n != int64(w.bytesToAccept) {
|
|
t.Fatalf("unexpected number of bytes written; got %d; want %d", n, w.bytesToAccept)
|
|
}
|
|
|
|
w = &faultyWriter{
|
|
returnInvalidBytesRead: true,
|
|
}
|
|
n, err = cb.WriteTo(w)
|
|
if err == nil {
|
|
t.Fatalf("expecting non-nil error")
|
|
}
|
|
if n != 0 {
|
|
t.Fatalf("unexpected number of bytes written; got %d; want %d", n, 0)
|
|
}
|
|
}
|
|
|
|
type faultyWriter struct {
|
|
bytesToAccept int
|
|
returnInvalidBytesRead bool
|
|
|
|
bytesRead int
|
|
}
|
|
|
|
func (fw *faultyWriter) Write(p []byte) (int, error) {
|
|
if fw.returnInvalidBytesRead {
|
|
return 0, nil
|
|
}
|
|
|
|
if fw.bytesRead+len(p) > fw.bytesToAccept {
|
|
n := fw.bytesToAccept - fw.bytesRead
|
|
fw.bytesRead = fw.bytesToAccept
|
|
return n, fmt.Errorf("some error")
|
|
}
|
|
fw.bytesRead += len(p)
|
|
return len(p), nil
|
|
}
|