You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gosuv/vendor/github.com/glycerine/rbuf/rbuf_test.go

192 lines
5.1 KiB

package rbuf
import (
"bytes"
"fmt"
"io"
"testing"
cv "github.com/smartystreets/goconvey/convey"
)
func TestRingBufReadWrite(t *testing.T) {
b := NewFixedSizeRingBuf(5)
data := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
cv.Convey("Given a FixedSizeRingBuf of size 5", t, func() {
cv.Convey("Write(), Bytes(), and Read() should put and get bytes", func() {
n, err := b.Write(data[0:5])
cv.So(n, cv.ShouldEqual, 5)
cv.So(err, cv.ShouldEqual, nil)
cv.So(b.Readable, cv.ShouldEqual, 5)
if n != 5 {
fmt.Printf("should have been able to write 5 bytes.\n")
}
if err != nil {
panic(err)
}
cv.So(b.Bytes(), cv.ShouldResemble, data[0:5])
sink := make([]byte, 3)
n, err = b.Read(sink)
cv.So(n, cv.ShouldEqual, 3)
cv.So(b.Bytes(), cv.ShouldResemble, data[3:5])
cv.So(sink, cv.ShouldResemble, data[0:3])
})
cv.Convey("Write() more than 5 should give back ErrShortWrite", func() {
b.Reset()
cv.So(b.Readable, cv.ShouldEqual, 0)
n, err := b.Write(data[0:10])
cv.So(n, cv.ShouldEqual, 5)
cv.So(err, cv.ShouldEqual, io.ErrShortWrite)
cv.So(b.Readable, cv.ShouldEqual, 5)
if n != 5 {
fmt.Printf("should have been able to write 5 bytes.\n")
}
cv.So(b.Bytes(), cv.ShouldResemble, data[0:5])
sink := make([]byte, 3)
n, err = b.Read(sink)
cv.So(n, cv.ShouldEqual, 3)
cv.So(b.Bytes(), cv.ShouldResemble, data[3:5])
cv.So(sink, cv.ShouldResemble, data[0:3])
})
cv.Convey("we should be able to wrap data and then get it back in Bytes()", func() {
b.Reset()
n, err := b.Write(data[0:3])
cv.So(n, cv.ShouldEqual, 3)
cv.So(err, cv.ShouldEqual, nil)
sink := make([]byte, 3)
n, err = b.Read(sink) // put b.beg at 3
cv.So(n, cv.ShouldEqual, 3)
cv.So(err, cv.ShouldEqual, nil)
cv.So(b.Readable, cv.ShouldEqual, 0)
n, err = b.Write(data[3:8]) // wrap 3 bytes around to the front
cv.So(n, cv.ShouldEqual, 5)
cv.So(err, cv.ShouldEqual, nil)
by := b.Bytes()
cv.So(by, cv.ShouldResemble, data[3:8]) // but still get them back from the ping-pong buffering
})
cv.Convey("FixedSizeRingBuf::WriteTo() should work with wrapped data", func() {
b.Reset()
n, err := b.Write(data[0:3])
cv.So(n, cv.ShouldEqual, 3)
cv.So(err, cv.ShouldEqual, nil)
sink := make([]byte, 3)
n, err = b.Read(sink) // put b.beg at 3
cv.So(n, cv.ShouldEqual, 3)
cv.So(err, cv.ShouldEqual, nil)
cv.So(b.Readable, cv.ShouldEqual, 0)
n, err = b.Write(data[3:8]) // wrap 3 bytes around to the front
var bb bytes.Buffer
m, err := b.WriteTo(&bb)
cv.So(m, cv.ShouldEqual, 5)
cv.So(err, cv.ShouldEqual, nil)
by := bb.Bytes()
cv.So(by, cv.ShouldResemble, data[3:8]) // but still get them back from the ping-pong buffering
})
cv.Convey("FixedSizeRingBuf::ReadFrom() should work with wrapped data", func() {
b.Reset()
var bb bytes.Buffer
n, err := b.ReadFrom(&bb)
cv.So(n, cv.ShouldEqual, 0)
cv.So(err, cv.ShouldEqual, nil)
// write 4, then read 4 bytes
m, err := b.Write(data[0:4])
cv.So(m, cv.ShouldEqual, 4)
cv.So(err, cv.ShouldEqual, nil)
sink := make([]byte, 4)
k, err := b.Read(sink) // put b.beg at 4
cv.So(k, cv.ShouldEqual, 4)
cv.So(err, cv.ShouldEqual, nil)
cv.So(b.Readable, cv.ShouldEqual, 0)
cv.So(b.Beg, cv.ShouldEqual, 4)
bbread := bytes.NewBuffer(data[4:9])
n, err = b.ReadFrom(bbread) // wrap 4 bytes around to the front, 5 bytes total.
by := b.Bytes()
cv.So(by, cv.ShouldResemble, data[4:9]) // but still get them back continguous from the ping-pong buffering
})
cv.Convey("FixedSizeRingBuf::WriteAndMaybeOverwriteOldestData() should auto advance", func() {
b.Reset()
n, err := b.WriteAndMaybeOverwriteOldestData(data[:5])
cv.So(err, cv.ShouldEqual, nil)
cv.So(n, cv.ShouldEqual, 5)
n, err = b.WriteAndMaybeOverwriteOldestData(data[5:7])
cv.So(n, cv.ShouldEqual, 2)
cv.So(b.Bytes(), cv.ShouldResemble, data[2:7])
n, err = b.WriteAndMaybeOverwriteOldestData(data[0:9])
cv.So(err, cv.ShouldEqual, nil)
cv.So(n, cv.ShouldEqual, 9)
cv.So(b.Bytes(), cv.ShouldResemble, data[4:9])
})
})
}
func TestNextPrev(t *testing.T) {
b := NewFixedSizeRingBuf(6)
data := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
cv.Convey("Given a FixedSizeRingBuf of size 6, filled with 4 elements at various begin points, then Nextpos() and Prev() should return the correct positions or <0 if done", t, func() {
k := b.N
for i := 0; i < b.N; i++ {
b.Reset()
b.Beg = i
_, err := b.Write(data[0:k])
panicOn(err)
// cannot go prev to first
cv.So(b.Prevpos(i), cv.ShouldEqual, -1)
// cannot go after last
cv.So(b.Nextpos((i+k-1)%b.N), cv.ShouldEqual, -1)
// in the middle we should be okay
for j := 1; j < k-1; j++ {
r := (i + j) % b.N
prev := b.Prevpos(r)
next := b.Nextpos(r)
cv.So(prev >= 0, cv.ShouldBeTrue)
cv.So(next >= 0, cv.ShouldBeTrue)
if next > r {
cv.So(next, cv.ShouldEqual, r+1)
} else {
cv.So(next, cv.ShouldEqual, 0)
}
if prev < r {
cv.So(prev, cv.ShouldEqual, r-1)
} else {
cv.So(prev, cv.ShouldEqual, b.N-1)
}
}
}
})
}
func panicOn(err error) {
if err != nil {
panic(err)
}
}