lnd.xprv/queue/circular_buf_test.go
carla a223e4eedb
queue: add fixed size circular buffer
This commit introduces a fixed size circular buffer  which stores
elements in a fixed size underlying array, wrapping to overwrite items
when the buffer gets full.
2020-03-17 08:22:23 +02:00

199 lines
3.7 KiB
Go

package queue
import (
"reflect"
"testing"
)
// TestNewCircularBuffer tests the size parameter check when creating a circular
// buffer.
func TestNewCircularBuffer(t *testing.T) {
tests := []struct {
name string
size int
expectedError error
}{
{
name: "zero size",
size: 0,
expectedError: errInvalidSize,
},
{
name: "negative size",
size: -1,
expectedError: errInvalidSize,
},
{
name: "ok size",
size: 1,
expectedError: nil,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
_, err := NewCircularBuffer(test.size)
if err != test.expectedError {
t.Fatalf("expected: %v, got: %v",
test.expectedError, err)
}
})
}
}
// TestCircularBuffer tests the adding and listing of items in a circular
// buffer.
func TestCircularBuffer(t *testing.T) {
tests := []struct {
name string
size int
itemCount int
expectedItems []interface{}
}{
{
name: "no elements",
size: 5,
itemCount: 0,
expectedItems: nil,
},
{
name: "single element",
size: 5,
itemCount: 1,
expectedItems: []interface{}{
0,
},
},
{
name: "no wrap, not full",
size: 5,
itemCount: 4,
expectedItems: []interface{}{
0, 1, 2, 3,
},
},
{
name: "no wrap, exactly full",
size: 5,
itemCount: 5,
expectedItems: []interface{}{
0, 1, 2, 3, 4,
},
},
{
// The underlying array should contain {5, 1, 2, 3, 4}.
name: "wrap, one over",
size: 5,
itemCount: 6,
expectedItems: []interface{}{
1, 2, 3, 4, 5,
},
},
{
// The underlying array should contain {5, 6, 2, 3, 4}.
name: "wrap, two over",
size: 5,
itemCount: 7,
expectedItems: []interface{}{
2, 3, 4, 5, 6,
},
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
buffer, err := NewCircularBuffer(test.size)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
for i := 0; i < test.itemCount; i++ {
buffer.Add(i)
}
// List the items in the buffer and check that the list
// is as expected.
list := buffer.List()
if !reflect.DeepEqual(test.expectedItems, list) {
t.Fatalf("expected %v, got: %v",
test.expectedItems, list)
}
})
}
}
// TestLatest tests fetching of the last item added to a circular buffer.
func TestLatest(t *testing.T) {
tests := []struct {
name string
size int
// items is the number of items to add to the buffer.
items int
// expectedItem is the value we expect from Latest().
expectedItem interface{}
}{
{
name: "no items",
size: 3,
items: 0,
expectedItem: nil,
},
{
name: "one item",
size: 3,
items: 1,
expectedItem: 0,
},
{
name: "exactly full",
size: 3,
items: 3,
expectedItem: 2,
},
{
name: "overflow to index 0",
size: 3,
items: 4,
expectedItem: 3,
},
{
name: "overflow twice to index 0",
size: 3,
items: 7,
expectedItem: 6,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
//t.Parallel()
buffer, err := NewCircularBuffer(test.size)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
for i := 0; i < test.items; i++ {
buffer.Add(i)
}
latest := buffer.Latest()
if !reflect.DeepEqual(latest, test.expectedItem) {
t.Fatalf("expected: %v, got: %v",
test.expectedItem, latest)
}
})
}
}