buffer: expand test coverage.

In preparation for changing the public API.
geesefs-0-30-9
Aaron Jacobs 2016-12-19 12:40:00 +11:00
commit 40b516328e
1 changed files with 173 additions and 15 deletions

View File

@ -1,12 +1,16 @@
package buffer
import (
"bytes"
"crypto/rand"
"fmt"
"io"
"reflect"
"testing"
"unsafe"
"github.com/jacobsa/fuse/internal/fusekernel"
"github.com/kylelemons/godebug/pretty"
)
func toByteSlice(p unsafe.Pointer, n int) []byte {
@ -86,18 +90,154 @@ func TestMemclr(t *testing.T) {
}
}
func TestOutMessageAppend(t *testing.T) {
var om OutMessage
om.Reset()
// Append some payload.
const wantPayloadStr = "tacoburrito"
wantPayload := []byte(wantPayloadStr)
om.Append(wantPayload[:4])
om.Append(wantPayload[4:])
// The result should be a zeroed header followed by the desired payload.
const wantLen = int(OutMessageInitialSize) + len(wantPayloadStr)
if got, want := om.Len(), wantLen; got != want {
t.Errorf("om.Len() = %d, want %d", got, want)
}
b := om.Bytes()
if got, want := len(b), wantLen; got != want {
t.Fatalf("len(om.Bytes()) = %d, want %d", got, want)
}
want := append(
make([]byte, OutMessageInitialSize),
wantPayload...)
if !bytes.Equal(b, want) {
t.Error("messages differ")
}
}
func TestOutMessageAppendString(t *testing.T) {
var om OutMessage
om.Reset()
// Append some payload.
const wantPayload = "tacoburrito"
om.AppendString(wantPayload[:4])
om.AppendString(wantPayload[4:])
// The result should be a zeroed header followed by the desired payload.
const wantLen = int(OutMessageInitialSize) + len(wantPayload)
if got, want := om.Len(), wantLen; got != want {
t.Errorf("om.Len() = %d, want %d", got, want)
}
b := om.Bytes()
if got, want := len(b), wantLen; got != want {
t.Fatalf("len(om.Bytes()) = %d, want %d", got, want)
}
want := append(
make([]byte, OutMessageInitialSize),
wantPayload...)
if !bytes.Equal(b, want) {
t.Error("messages differ")
}
}
func TestOutMessageShrinkTo(t *testing.T) {
// Set up a buffer with some payload.
var om OutMessage
om.Reset()
om.AppendString("taco")
om.AppendString("burrito")
// Shrink it.
om.ShrinkTo(OutMessageInitialSize + uintptr(len("taco")))
// The result should be a zeroed header followed by "taco".
const wantLen = int(OutMessageInitialSize) + len("taco")
if got, want := om.Len(), wantLen; got != want {
t.Errorf("om.Len() = %d, want %d", got, want)
}
b := om.Bytes()
if got, want := len(b), wantLen; got != want {
t.Fatalf("len(om.Bytes()) = %d, want %d", got, want)
}
want := append(
make([]byte, OutMessageInitialSize),
"taco"...)
if !bytes.Equal(b, want) {
t.Error("messages differ")
}
}
func TestOutMessageHeader(t *testing.T) {
var om OutMessage
om.Reset()
// Fill in the header.
want := fusekernel.OutHeader{
Len: 0xdeadbeef,
Error: -31231917,
Unique: 0xcafebabeba5eba11,
}
h := om.OutHeader()
if h == nil {
t.Fatal("OutHeader returned nil")
}
*h = want
// Check that the result is as expected.
b := om.Bytes()
if len(b) != int(unsafe.Sizeof(want)) {
t.Fatalf("unexpected length %d; want %d", len(b), unsafe.Sizeof(want))
}
got := *(*fusekernel.OutHeader)(unsafe.Pointer(&b[0]))
if diff := pretty.Compare(got, want); diff != "" {
t.Errorf("diff -got +want:\n%s", diff)
}
}
func TestOutMessageReset(t *testing.T) {
var om OutMessage
h := om.OutHeader()
const trials = 100
const trials = 10
for i := 0; i < trials; i++ {
// Fill the header with garbage.
err := fillWithGarbage(unsafe.Pointer(h), int(unsafe.Sizeof(*h)))
if err != nil {
t.Fatalf("fillWithGarbage: %v", err)
}
// Ensure a non-zero payload length.
if p := om.GrowNoZero(128); p == nil {
t.Fatal("GrowNoZero failed")
}
// Reset.
om.Reset()
// Check that the length was updated.
if got, want := int(om.Len()), int(OutMessageInitialSize); got != want {
t.Fatalf("om.Len() = %d, want %d", got, want)
}
// Check that the header was zeroed.
if h.Len != 0 {
t.Fatalf("non-zero Len %v", h.Len)
}
@ -114,26 +254,44 @@ func TestOutMessageReset(t *testing.T) {
func TestOutMessageGrow(t *testing.T) {
var om OutMessage
// Overwrite with garbage.
err := fillWithGarbage(unsafe.Pointer(&om), int(unsafe.Sizeof(om)))
if err != nil {
t.Fatalf("fillWithGarbage: %v", err)
}
// Zero the header.
om.Reset()
// Grow to the max size. This should zero the message.
if p := om.Grow(MaxReadSize); p == nil {
t.Fatal("Grow returned nil")
// Set up garbage where the payload will soon be.
const payloadSize = 1234
{
p := om.GrowNoZero(payloadSize)
if p == nil {
t.Fatal("GrowNoZero failed")
}
err := fillWithGarbage(p, payloadSize)
if err != nil {
t.Fatalf("fillWithGarbage: %v", err)
}
om.ShrinkTo(OutMessageInitialSize)
}
// Call Grow.
if p := om.Grow(payloadSize); p == nil {
t.Fatal("Grow failed")
}
// Check the resulting length in two ways.
const wantLen = int(payloadSize + OutMessageInitialSize)
if got, want := om.Len(), wantLen; got != want {
t.Errorf("om.Len() = %d, want %d", got)
}
// Check that everything has been zeroed.
b := om.Bytes()
for i, x := range b {
if got, want := len(b), wantLen; got != want {
t.Fatalf("len(om.Len()) = %d, want %d", got)
}
// Check that the payload was zeroed.
for i, x := range b[OutMessageInitialSize:] {
if x != 0 {
t.Fatalf("non-zero byte 0x%02x at offset %d", x, i)
t.Fatalf("non-zero byte 0x%02x at payload offset %d", x, i)
}
}
}