1
0
buffer/writeto_test.go

289 lines
5.6 KiB
Go

package buffer_test
import (
"bytes"
"code.squareroundforest.org/arpio/buffer"
"errors"
"io"
"testing"
)
func TestWriteTo(t *testing.T) {
for title, cr := range map[string]createReader{"reader": buffer.BufferedReader, "content": testContent} {
t.Run(title, func(t *testing.T) {
t.Run("write out from zero", func(t *testing.T) {
g := &gen{max: 1 << 15}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := cr(g, o)
var b bytes.Buffer
n, err := r.WriteTo(&b)
if err != nil {
t.Fatal(err)
}
if n != 1<<15 {
t.Fatal("write count")
}
if !bytes.Equal(b.Bytes(), generate(1<<15)) {
t.Fatal("content")
}
})
t.Run("write out from started", func(t *testing.T) {
g := &gen{max: 1 << 15}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := cr(g, o)
p := make([]byte, 256)
n, err := r.Read(p)
if err != nil {
t.Fatal(err)
}
if n != 256 {
t.Fatal("invalid read count")
}
if !bytes.Equal(p, generate(256)) {
t.Fatal("invalid content")
}
var b bytes.Buffer
n64, err := r.WriteTo(&b)
if err != nil {
t.Fatal(err)
}
if n64 != 1<<15-256 {
t.Fatal("write count")
}
if !bytes.Equal(b.Bytes(), generate(1 << 15)[256:]) {
t.Fatal("content")
}
})
t.Run("after EOF", func(t *testing.T) {
g := &gen{max: 256}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := cr(g, o)
b, err := r.Peek(512)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(b, generate(256)) {
t.Fatal("invalid content")
}
var buf bytes.Buffer
n, err := r.WriteTo(&buf)
if err != nil {
t.Fatal(err)
}
if n != 256 {
t.Fatal("write count")
}
if !bytes.Equal(buf.Bytes(), generate(256)) {
t.Fatal("invalid content")
}
})
t.Run("after eof empty", func(t *testing.T) {
g := &gen{max: 256}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := cr(g, o)
p := make([]byte, 512)
n, err := r.Read(p)
if err != nil {
t.Fatal(err)
}
if n != 256 {
t.Fatal("invalid length")
}
if !bytes.Equal(p[:n], generate(256)) {
t.Fatal("invalid content 1")
}
var buf bytes.Buffer
n64, err := r.WriteTo(&buf)
if err != nil {
t.Fatal(err)
}
if n64 != 0 {
t.Fatal("write count")
}
if buf.Len() != 0 {
t.Fatal("invalid content 2")
}
})
t.Run("write error", func(t *testing.T) {
g := &gen{max: 1 << 15}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := cr(g, o)
w := &writer{errAfter: []int{256}}
n, err := r.WriteTo(w)
if !errors.Is(err, errTest) {
t.Fatal("failed to fail with the right error", err)
}
if n < 256 {
t.Fatal("not enough written")
}
if !bytes.Equal(w.written, generate(1 << 15)[:n]) {
t.Fatal("invalid content")
}
})
t.Run("short write", func(t *testing.T) {
g := &gen{max: 1 << 15}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := cr(g, o)
w := &writer{shortAfter: []int{256}}
n, err := r.WriteTo(w)
if !errors.Is(err, io.ErrShortWrite) {
t.Fatal("failed to fail with the right error", err)
}
if n < 256 {
t.Fatal("not enough written")
}
if !bytes.Equal(w.written, generate(1 << 15)[:n]) {
t.Fatal("invalid content")
}
})
})
}
t.Run("reader only", func(t *testing.T) {
cr := buffer.BufferedReader
t.Run("after err", func(t *testing.T) {
g := &gen{
max: 1 << 15,
errAfter: []int{256},
fastErr: true,
}
o := buffer.Options{Pool: buffer.NoPool(64)}
r := cr(g, o)
b, err := r.Peek(512)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(b, generate(256)) {
t.Fatal("invalid content", 1)
}
var buf bytes.Buffer
n, err := r.WriteTo(&buf)
if !errors.Is(err, errTest) {
t.Fatal("failed to test with the right error", err)
}
if n != 256 {
t.Fatal("write count")
}
if !bytes.Equal(buf.Bytes(), generate(256)) {
t.Fatal("invalid content", 2)
}
})
t.Run("after error empty", func(t *testing.T) {
g := &gen{
max: 1 << 15,
errAfter: []int{256},
}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := cr(g, o)
p := make([]byte, 1<<15)
n, err := r.Read(p)
if err != nil {
t.Fatal(err)
}
if n < 256 {
t.Fatal("invalid length")
}
if !bytes.Equal(p[:n], generate(1 << 15)[:n]) {
t.Fatal("invalid content 1")
}
var buf bytes.Buffer
n64, err := r.WriteTo(&buf)
if !errors.Is(err, errTest) {
t.Fatal(err)
}
if n64 != 0 {
t.Fatal("write count")
}
if buf.Len() != 0 {
t.Fatal("invalid content 2")
}
})
t.Run("null read on fill", func(t *testing.T) {
g := &gen{
max: 1 << 15,
nullReadAfter: []int{256, 256},
}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := cr(g, o)
var b bytes.Buffer
n, err := r.WriteTo(&b)
if !errors.Is(err, io.ErrNoProgress) {
t.Fatal("failed to fail with the right error")
}
if n < 256 {
t.Fatal("not enough written")
}
if !bytes.Equal(b.Bytes(), generate(1 << 15)[:n]) {
t.Fatal("invalid content")
}
})
t.Run("err during fill", func(t *testing.T) {
g := &gen{
max: 1 << 15,
errAfter: []int{256},
}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := cr(g, o)
var b bytes.Buffer
n, err := r.WriteTo(&b)
if !errors.Is(err, errTest) {
t.Fatal("failed to fail with the right error")
}
if n < 256 {
t.Fatal("not enough written")
}
if !bytes.Equal(b.Bytes(), generate(1 << 15)[:n]) {
t.Fatal("invalid content")
}
})
})
}