240 lines
4.6 KiB
Go
240 lines
4.6 KiB
Go
package fwd
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"math/rand"
|
|
"testing"
|
|
)
|
|
|
|
type chunkedWriter struct {
|
|
w *Writer
|
|
}
|
|
|
|
// writes 'p' in randomly-sized chunks
|
|
func (c chunkedWriter) Write(p []byte) (int, error) {
|
|
l := len(p)
|
|
n := 0
|
|
for n < l {
|
|
amt := max(rand.Intn(l-n), 1) // number of bytes to write; at least 1
|
|
nn, err := c.w.Write(p[n : n+amt]) //
|
|
n += nn
|
|
if err == nil && nn < amt {
|
|
err = io.ErrShortWrite
|
|
}
|
|
if err != nil {
|
|
return n, err
|
|
}
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
// analogous to Write(), but w/ str
|
|
func (c chunkedWriter) WriteString(s string) (int, error) {
|
|
l := len(s)
|
|
n := 0
|
|
for n < l {
|
|
amt := max(rand.Intn(l-n), 1) // number of bytes to write; at least 1
|
|
nn, err := c.w.WriteString(s[n : n+amt]) //
|
|
n += nn
|
|
if err == nil && nn < amt {
|
|
err = io.ErrShortWrite
|
|
}
|
|
if err != nil {
|
|
return n, err
|
|
}
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
// writes via random calls to Next()
|
|
type nextWriter struct {
|
|
wr *Writer
|
|
}
|
|
|
|
func (c nextWriter) Write(p []byte) (int, error) {
|
|
l := len(p)
|
|
n := 0
|
|
for n < l {
|
|
amt := max(rand.Intn(l-n), 1) // at least 1 byte
|
|
fwd, err := c.wr.Next(amt) // get next (amt) bytes
|
|
if err != nil {
|
|
|
|
// this may happen occasionally
|
|
if err == io.ErrShortBuffer {
|
|
if cap(c.wr.buf) >= amt {
|
|
panic("bad io.ErrShortBuffer")
|
|
}
|
|
continue
|
|
}
|
|
|
|
return n, err
|
|
}
|
|
if len(fwd) != amt {
|
|
panic("bad Next() len")
|
|
}
|
|
n += copy(fwd, p[n:])
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
func TestWrite(t *testing.T) {
|
|
nbts := 4096
|
|
bts := randomBts(nbts)
|
|
var buf bytes.Buffer
|
|
wr := NewWriterSize(&buf, 512)
|
|
|
|
if wr.BufferSize() != 512 {
|
|
t.Fatalf("expected BufferSize() to be %d; found %d", 512, wr.BufferSize())
|
|
}
|
|
|
|
cwr := chunkedWriter{wr}
|
|
nb, err := cwr.Write(bts)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if nb != nbts {
|
|
t.Fatalf("expected to write %d bytes; wrote %d bytes", nbts, nb)
|
|
}
|
|
err = wr.Flush()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if wr.Buffered() != 0 {
|
|
t.Fatalf("expected 0 buffered bytes; found %d", wr.Buffered())
|
|
}
|
|
|
|
if buf.Len() != nbts {
|
|
t.Fatalf("wrote %d bytes, but buffer is %d bytes long", nbts, buf.Len())
|
|
}
|
|
if !bytes.Equal(bts, buf.Bytes()) {
|
|
t.Fatal("buf.Bytes() is not the same as the input bytes")
|
|
}
|
|
}
|
|
|
|
func TestWriteString(t *testing.T) {
|
|
nbts := 3998
|
|
str := string(randomBts(nbts))
|
|
var buf bytes.Buffer
|
|
wr := NewWriterSize(&buf, 1137)
|
|
|
|
if wr.BufferSize() != 1137 {
|
|
t.Fatalf("expected BufferSize() to return %d; returned %d", 1137, wr.BufferSize())
|
|
}
|
|
|
|
cwr := chunkedWriter{wr}
|
|
nb, err := cwr.WriteString(str)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if nb != nbts {
|
|
t.Fatalf("expected to write %d bytes; wrote %d bytes", nbts, nb)
|
|
}
|
|
|
|
err = wr.Flush()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if wr.Buffered() != 0 {
|
|
t.Fatalf("expected 0 buffered bytes; found %d", wr.Buffered())
|
|
}
|
|
|
|
if buf.Len() != nbts {
|
|
t.Fatalf("wrote %d bytes, buf buffer is %d bytes long", nbts, buf.Len())
|
|
}
|
|
if buf.String() != str {
|
|
t.Fatal("buf.String() is not the same as input string")
|
|
}
|
|
}
|
|
|
|
func TestWriteByte(t *testing.T) {
|
|
nbts := 3200
|
|
bts := randomBts(nbts)
|
|
var buf bytes.Buffer
|
|
wr := NewWriter(&buf)
|
|
|
|
if wr.BufferSize() != DefaultWriterSize {
|
|
t.Fatalf("expected BufferSize() to return %d; returned %d", DefaultWriterSize, wr.BufferSize())
|
|
}
|
|
|
|
// write byte-by-byte
|
|
for _, b := range bts {
|
|
if err := wr.WriteByte(b); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
err := wr.Flush()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if buf.Len() != nbts {
|
|
t.Fatalf("expected buf.Len() to be %d; got %d", nbts, buf.Len())
|
|
}
|
|
|
|
if !bytes.Equal(buf.Bytes(), bts) {
|
|
t.Fatal("buf.Bytes() and input are not equal")
|
|
}
|
|
}
|
|
|
|
func TestWriterNext(t *testing.T) {
|
|
nbts := 1871
|
|
bts := randomBts(nbts)
|
|
var buf bytes.Buffer
|
|
wr := NewWriterSize(&buf, 500)
|
|
nwr := nextWriter{wr}
|
|
|
|
nb, err := nwr.Write(bts)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if nb != nbts {
|
|
t.Fatalf("expected to write %d bytes; wrote %d", nbts, nb)
|
|
}
|
|
|
|
err = wr.Flush()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if buf.Len() != nbts {
|
|
t.Fatalf("expected buf.Len() to be %d; got %d", nbts, buf.Len())
|
|
}
|
|
|
|
if !bytes.Equal(buf.Bytes(), bts) {
|
|
t.Fatal("buf.Bytes() and input are not equal")
|
|
}
|
|
}
|
|
|
|
func TestReadFrom(t *testing.T) {
|
|
nbts := 2139
|
|
bts := randomBts(nbts)
|
|
var buf bytes.Buffer
|
|
wr := NewWriterSize(&buf, 987)
|
|
|
|
rd := partialReader{bytes.NewReader(bts)}
|
|
|
|
nb, err := wr.ReadFrom(rd)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if nb != int64(nbts) {
|
|
t.Fatalf("expeted to write %d bytes; wrote %d", nbts, nb)
|
|
}
|
|
err = wr.Flush()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if buf.Len() != nbts {
|
|
t.Fatalf("expected buf.Len() to be %d; got %d", nbts, buf.Len())
|
|
}
|
|
if !bytes.Equal(buf.Bytes(), bts) {
|
|
t.Fatal("buf.Bytes() and input are not equal")
|
|
}
|
|
|
|
}
|