2017-12-02 08:24:34 +03:00
|
|
|
/*
|
|
|
|
NAME
|
|
|
|
RingBuffer_test.go - a test suite adopting the golang testing library to test functionality of the
|
|
|
|
RingBuffer structure
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
See Readme.md
|
|
|
|
|
|
|
|
AUTHOR
|
|
|
|
Saxon Nelson-Milton <saxon.milton@gmail.com>
|
|
|
|
|
|
|
|
LICENSE
|
2017-12-03 01:21:02 +03:00
|
|
|
RingBuffer_test.go is Copyright (C) 2017 the Australian Ocean Lab (AusOcean)
|
2017-12-02 08:24:34 +03:00
|
|
|
|
|
|
|
It is free software: you can redistribute it and/or modify them
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
Free Software Foundation, either version 3 of the License, or (at your
|
|
|
|
option) any later version.
|
|
|
|
|
|
|
|
It is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with revid in gpl.txt. If not, see [GNU licenses](http://www.gnu.org/licenses).
|
|
|
|
*/
|
|
|
|
|
|
|
|
package ringbuffer
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Call when we get an error we shouldn't have
|
|
|
|
func falseErrorFail(t *testing.T, err error) {
|
|
|
|
t.Errorf("Should not have got error: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Call when we should have got an error but didnt
|
|
|
|
func noErrorFail(t *testing.T) {
|
|
|
|
t.Errorf("Should have got error!")
|
|
|
|
}
|
|
|
|
|
|
|
|
// RingBuffer object used over testing funcs
|
|
|
|
var ringBuffer = RingBuffer{}
|
|
|
|
|
|
|
|
// Test that the Make method correctly allocates memory for arbitrary buffer
|
|
|
|
// size of 10 and arbitrary element size of 10
|
|
|
|
func TestMake(t *testing.T) {
|
|
|
|
ringBuffer.Make(10, 10)
|
|
|
|
if len(ringBuffer.Memory) != 10 {
|
|
|
|
t.Errorf("Len of buffer is wrong!")
|
|
|
|
}
|
|
|
|
if len(ringBuffer.Memory[0]) != 10 {
|
|
|
|
t.Errorf("Len of individual element is wrong!")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test call to done writing when no writing has occured.
|
|
|
|
// We pass arbitrary clipSize.
|
|
|
|
func TestDoneWriting1(t *testing.T) {
|
|
|
|
if ringBuffer.DoneWriting(1) == nil {
|
|
|
|
noErrorFail(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test call to done writing when there has been some 'writing'
|
|
|
|
func TestDoneWriting2(t *testing.T) {
|
|
|
|
if _, err := ringBuffer.Get(); err != nil {
|
|
|
|
t.Errorf("Shouldn't have got error: %v", err)
|
|
|
|
}
|
|
|
|
if err := ringBuffer.DoneWriting(1); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to 'write' to the buffer when full. Set buffer size to arbitrary number of 3.
|
|
|
|
// We write over buffer size of 3 (write 4 times)
|
|
|
|
func TestWritingWhenFull(t *testing.T) {
|
|
|
|
ringBuffer.Make(3, 10)
|
|
|
|
var err error
|
|
|
|
for i := 0; i < 4; i++ {
|
|
|
|
_, err = ringBuffer.Get()
|
|
|
|
ringBuffer.DoneWriting(1)
|
|
|
|
}
|
|
|
|
if err == nil {
|
|
|
|
noErrorFail(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test call to done reading when there hasn't been any reading
|
|
|
|
func TestDoneReading1(t *testing.T) {
|
|
|
|
ringBuffer.Make(10, 10)
|
|
|
|
if ringBuffer.DoneReading() == nil {
|
|
|
|
noErrorFail(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test read when there hasn't been anything written to buffer
|
|
|
|
func TestReadingWithoutWrite(t *testing.T) {
|
|
|
|
ringBuffer.Make(10, 10)
|
|
|
|
_, _, err := ringBuffer.Read()
|
|
|
|
if err == nil {
|
|
|
|
noErrorFail(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try Writing twice without calling DoneWriting
|
|
|
|
func TestWritingTwice(t *testing.T) {
|
|
|
|
ringBuffer.Make(10, 10)
|
|
|
|
_, err := ringBuffer.Get()
|
|
|
|
_, err = ringBuffer.Get()
|
|
|
|
if err == nil {
|
|
|
|
noErrorFail(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test call to done reading when there has been some reading
|
|
|
|
func TestDoneReading2(t *testing.T) {
|
|
|
|
ringBuffer.Make(10, 10)
|
|
|
|
_, err := ringBuffer.Get()
|
|
|
|
ringBuffer.DoneWriting(1)
|
|
|
|
_, _, err = ringBuffer.Read()
|
|
|
|
if err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
ringBuffer.DoneReading()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Testing writing then reading for single 'write' and single read with routines
|
|
|
|
func TestWritingAndReading1(t *testing.T) {
|
|
|
|
ringBuffer.Make(10, 10)
|
|
|
|
if _, err := ringBuffer.Get(); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
if err := ringBuffer.DoneWriting(1); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
if _, _, err := ringBuffer.Read(); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
if err := ringBuffer.DoneReading(); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Testing two 'write's and two 'reads'
|
|
|
|
func TestWritingAndReading2(t *testing.T) {
|
|
|
|
ringBuffer.Make(10, 10)
|
|
|
|
for i := 0; i < 2; i++ {
|
|
|
|
if _, err := ringBuffer.Get(); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
if err := ringBuffer.DoneWriting(1); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for i := 0; i < 2; i++ {
|
|
|
|
if _, _, err := ringBuffer.Read(); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
if err := ringBuffer.DoneReading(); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Testing one 'write' and two reads
|
|
|
|
func TestWritingAndReading3(t *testing.T) {
|
|
|
|
ringBuffer.Make(10, 10)
|
|
|
|
if _, err := ringBuffer.Get(); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
if err := ringBuffer.DoneWriting(1); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
var err1 error
|
|
|
|
var err2 error
|
|
|
|
for i := 0; i < 2; i++ {
|
|
|
|
_, _, err1 = ringBuffer.Read()
|
|
|
|
err2 = ringBuffer.DoneReading()
|
|
|
|
}
|
|
|
|
if err1 == nil {
|
|
|
|
noErrorFail(t)
|
|
|
|
}
|
|
|
|
if err2 == nil {
|
|
|
|
noErrorFail(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test two 'write's and one read
|
|
|
|
func TestWritingAndReading4(t *testing.T) {
|
|
|
|
ringBuffer.Make(10, 10)
|
|
|
|
for i := 0; i < 2; i++ {
|
|
|
|
if _, err := ringBuffer.Get(); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
if err := ringBuffer.DoneWriting(1); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if _, _, err := ringBuffer.Read(); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
if err := ringBuffer.DoneReading(); err != nil {
|
|
|
|
falseErrorFail(t, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test writing past size
|
|
|
|
func TestWritingAndReading5(t *testing.T) {
|
|
|
|
ringBuffer.Make(4, 10)
|
|
|
|
var err1 error
|
|
|
|
var err2 error
|
|
|
|
for i := 0; i < 5; i++ {
|
|
|
|
_, err1 = ringBuffer.Get()
|
|
|
|
err2 = ringBuffer.DoneWriting(1)
|
|
|
|
}
|
|
|
|
if err1 == nil {
|
|
|
|
noErrorFail(t)
|
|
|
|
}
|
|
|
|
if err2 == nil {
|
|
|
|
noErrorFail(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test writing to size, then read some, then 'write' past size to go back to start
|
|
|
|
func TestWritingAndReading6(t *testing.T) {
|
|
|
|
ringBuffer.Make(4, 10)
|
|
|
|
var err1 error
|
|
|
|
var err2 error
|
|
|
|
for i := 0; i < 4; i++ {
|
|
|
|
_, err1 = ringBuffer.Get()
|
|
|
|
err2 = ringBuffer.DoneWriting(1)
|
|
|
|
}
|
|
|
|
if err1 != nil {
|
|
|
|
falseErrorFail(t, err1)
|
|
|
|
}
|
|
|
|
if err2 != nil {
|
|
|
|
falseErrorFail(t, err2)
|
|
|
|
}
|
|
|
|
for i := 0; i < 2; i++ {
|
|
|
|
_, _, err1 = ringBuffer.Read()
|
|
|
|
err2 = ringBuffer.DoneReading()
|
|
|
|
}
|
|
|
|
if err1 != nil {
|
|
|
|
falseErrorFail(t, err1)
|
|
|
|
}
|
|
|
|
if err2 != nil {
|
|
|
|
falseErrorFail(t, err2)
|
|
|
|
}
|
|
|
|
_, err1 = ringBuffer.Get()
|
|
|
|
err2 = ringBuffer.DoneWriting(1)
|
|
|
|
if err1 != nil {
|
|
|
|
falseErrorFail(t, err1)
|
|
|
|
}
|
|
|
|
if err2 != nil {
|
|
|
|
falseErrorFail(t, err2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now let's do the previous test again, but this time we will try to write
|
|
|
|
// past capacity
|
|
|
|
func TestWritingAndReading7(t *testing.T) {
|
|
|
|
ringBuffer.Make(4, 10)
|
|
|
|
var err1 error
|
|
|
|
var err2 error
|
|
|
|
for i := 0; i < 4; i++ {
|
|
|
|
_, err1 = ringBuffer.Get()
|
|
|
|
err2 = ringBuffer.DoneWriting(1)
|
|
|
|
}
|
|
|
|
if err1 != nil {
|
|
|
|
falseErrorFail(t, err1)
|
|
|
|
}
|
|
|
|
if err2 != nil {
|
|
|
|
falseErrorFail(t, err2)
|
|
|
|
}
|
|
|
|
for i := 0; i < 2; i++ {
|
|
|
|
_, _, err1 = ringBuffer.Read()
|
|
|
|
err2 = ringBuffer.DoneReading()
|
|
|
|
}
|
|
|
|
if err1 != nil {
|
|
|
|
falseErrorFail(t, err1)
|
|
|
|
}
|
|
|
|
if err2 != nil {
|
|
|
|
falseErrorFail(t, err2)
|
|
|
|
}
|
|
|
|
for i := 0; i < 3; i++ {
|
|
|
|
_, err1 = ringBuffer.Get()
|
|
|
|
err2 = ringBuffer.DoneWriting(1)
|
|
|
|
}
|
|
|
|
if err1 == nil {
|
|
|
|
noErrorFail(t)
|
|
|
|
}
|
|
|
|
if err2 == nil {
|
|
|
|
noErrorFail(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test reading twice without call to DoneReading
|
|
|
|
func TestWritingAndReading8(t *testing.T) {
|
|
|
|
ringBuffer.Make(4, 10)
|
|
|
|
var err1 error
|
|
|
|
var err2 error
|
|
|
|
for i := 0; i < 4; i++ {
|
|
|
|
_, err1 = ringBuffer.Get()
|
|
|
|
err2 = ringBuffer.DoneWriting(1)
|
|
|
|
}
|
|
|
|
if err1 != nil {
|
|
|
|
falseErrorFail(t, err1)
|
|
|
|
}
|
|
|
|
if err2 != nil {
|
|
|
|
falseErrorFail(t, err2)
|
|
|
|
}
|
|
|
|
for i := 0; i < 2; i++ {
|
|
|
|
_, _, err1 = ringBuffer.Read()
|
|
|
|
}
|
|
|
|
if err1 == nil {
|
|
|
|
noErrorFail(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Let's see if we can do concurrency. (tip: run as: go test -race) to see
|
|
|
|
// an data race issues. We will continously write and read at the same time for
|
|
|
|
// a second
|
|
|
|
func TestConcurrency1(t *testing.T) {
|
|
|
|
ringBuffer.Make(1000, 10)
|
|
|
|
go func() {
|
|
|
|
for i := 0; i < 100; i++ {
|
|
|
|
if data, _, err1 := ringBuffer.Read(); data != nil {
|
|
|
|
err2 := ringBuffer.DoneReading()
|
|
|
|
if err1 != nil {
|
|
|
|
falseErrorFail(t, err1)
|
|
|
|
}
|
|
|
|
if err2 != nil {
|
|
|
|
falseErrorFail(t, err2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
go func() {
|
|
|
|
for i := 0; i < 100; i++ {
|
|
|
|
_, err1 := ringBuffer.Get()
|
|
|
|
err2 := ringBuffer.DoneWriting(1)
|
|
|
|
if err1 != nil {
|
|
|
|
falseErrorFail(t, err1)
|
|
|
|
}
|
|
|
|
if err2 != nil {
|
|
|
|
falseErrorFail(t, err2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
time.Sleep(1000 * time.Millisecond)
|
|
|
|
}
|