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 (
|
2017-12-05 12:48:48 +03:00
|
|
|
"fmt"
|
2017-12-02 08:24:34 +03:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2017-12-05 12:48:48 +03:00
|
|
|
// Parameters used over the testing
|
2017-12-03 12:35:46 +03:00
|
|
|
const (
|
2017-12-03 12:37:45 +03:00
|
|
|
testBufferSize = 10
|
|
|
|
testElementSize = 1
|
2017-12-05 12:48:48 +03:00
|
|
|
testOverFlowSize = 2
|
2017-12-03 12:37:45 +03:00
|
|
|
testDataSize = 1
|
|
|
|
testConcurrencyBufferSize = 1000
|
2017-12-03 12:35:46 +03:00
|
|
|
)
|
|
|
|
|
2017-12-05 12:52:34 +03:00
|
|
|
// Types of actions, assertions and test ends
|
2017-12-05 12:48:48 +03:00
|
|
|
const (
|
|
|
|
testWrite = 0
|
|
|
|
testDoneWriting = 1
|
|
|
|
testRead = 2
|
|
|
|
testDoneReading = 3
|
|
|
|
testEnd = 4
|
|
|
|
assertNoError = 5
|
|
|
|
assertError = 6
|
|
|
|
)
|
2017-12-03 10:37:15 +03:00
|
|
|
|
2017-12-05 12:52:34 +03:00
|
|
|
// Strings to help with test fail messages
|
2017-12-05 12:48:48 +03:00
|
|
|
const (
|
|
|
|
noErrorFailMessage = "Should have got error!"
|
|
|
|
falseErrorFailMessage = "Should not have got error: %v"
|
2017-12-05 12:52:34 +03:00
|
|
|
atMessage = " Series: %v"
|
2017-12-05 12:48:48 +03:00
|
|
|
)
|
2017-12-02 08:24:34 +03:00
|
|
|
|
2017-12-05 12:52:34 +03:00
|
|
|
// Pointer to the ringbuffer we will be testing
|
2017-12-05 12:48:48 +03:00
|
|
|
var rb *ringBuffer
|
|
|
|
|
|
|
|
// Call when the a test array has the wrong format
|
|
|
|
func wrongFmt() {
|
|
|
|
fmt.Println("Test has wrong format!")
|
2017-12-02 08:24:34 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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) {
|
2017-12-03 12:35:46 +03:00
|
|
|
rb = NewRingBuffer(testBufferSize, testElementSize)
|
|
|
|
if len(rb.dataMemory) != testBufferSize {
|
2017-12-02 08:24:34 +03:00
|
|
|
t.Errorf("Len of buffer is wrong!")
|
|
|
|
}
|
2017-12-03 12:35:46 +03:00
|
|
|
if len(rb.dataMemory[0]) != testElementSize {
|
2017-12-02 08:24:34 +03:00
|
|
|
t.Errorf("Len of individual element is wrong!")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-05 12:48:48 +03:00
|
|
|
// Format: { <size of uffer>, <type of check>, <action>, ..., <action>, <test end> }
|
|
|
|
var tests = [][]int{
|
|
|
|
{testBufferSize, assertError, testDoneWriting, testEnd},
|
|
|
|
{testBufferSize, assertNoError, testWrite, testDoneWriting, testEnd},
|
|
|
|
{testBufferSize, assertError, testDoneReading, testEnd},
|
|
|
|
{testBufferSize, assertError, testRead, testEnd},
|
|
|
|
{testBufferSize, assertError, testWrite, testWrite, testEnd},
|
|
|
|
{testBufferSize, assertNoError, testWrite, testDoneWriting, testRead,
|
|
|
|
testDoneReading, testEnd},
|
|
|
|
{testBufferSize, assertNoError, testWrite, testDoneWriting, testWrite,
|
|
|
|
testDoneWriting, testRead, testDoneReading, testRead, testDoneReading,
|
|
|
|
testEnd},
|
|
|
|
{testBufferSize, assertError, testWrite, testDoneWriting, testRead,
|
|
|
|
testDoneReading, testRead, testDoneReading, testEnd},
|
|
|
|
{testOverFlowSize, assertError, testWrite, testDoneWriting, testWrite, testDoneWriting,
|
|
|
|
testWrite, testDoneWriting, testEnd},
|
|
|
|
{testOverFlowSize, assertNoError, testWrite, testDoneWriting, testWrite, testDoneWriting,
|
|
|
|
testRead, testDoneReading, testWrite, testDoneWriting, testEnd},
|
|
|
|
{testOverFlowSize, assertError, testWrite, testDoneWriting, testWrite, testDoneWriting,
|
|
|
|
testRead, testDoneReading, testWrite, testDoneWriting, testWrite,
|
|
|
|
testDoneWriting, testEnd},
|
|
|
|
{testBufferSize, assertError, testWrite, testDoneWriting, testWrite,
|
|
|
|
testDoneWriting, testRead, testRead, testEnd},
|
|
|
|
}
|
|
|
|
|
2017-12-05 12:52:34 +03:00
|
|
|
// Tests series of actions performed by the ring buffer defined in array tests
|
2017-12-05 12:48:48 +03:00
|
|
|
func TestAllSorts(t *testing.T) {
|
|
|
|
for i := range tests {
|
|
|
|
rb = NewRingBuffer(tests[i][0], testElementSize)
|
|
|
|
var err error
|
|
|
|
for j := 2; tests[i][j] != testEnd; j++ {
|
|
|
|
var newErr error
|
|
|
|
switch tests[i][j] {
|
|
|
|
case testWrite:
|
|
|
|
_, newErr = rb.Get()
|
|
|
|
case testDoneWriting:
|
|
|
|
newErr = rb.DoneWriting(testDataSize)
|
|
|
|
case testRead:
|
|
|
|
_, newErr = rb.Read()
|
|
|
|
case testDoneReading:
|
|
|
|
newErr = rb.DoneReading()
|
|
|
|
default:
|
|
|
|
wrongFmt()
|
|
|
|
}
|
|
|
|
if err == nil {
|
|
|
|
err = newErr
|
|
|
|
}
|
2017-12-02 08:24:34 +03:00
|
|
|
}
|
2017-12-05 12:48:48 +03:00
|
|
|
switch tests[i][1] {
|
|
|
|
case assertError:
|
|
|
|
if err == nil {
|
|
|
|
t.Errorf(noErrorFailMessage+atMessage, i)
|
|
|
|
}
|
|
|
|
case assertNoError:
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf(falseErrorFailMessage+atMessage, err, i)
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
wrongFmt()
|
2017-12-02 08:24:34 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Let's see if we can do concurrency. (tip: run as: go test -race) to see
|
2017-12-03 01:41:48 +03:00
|
|
|
// any data race issues. We will continously write and read at concurrently
|
|
|
|
// time for a second
|
2017-12-02 08:24:34 +03:00
|
|
|
func TestConcurrency1(t *testing.T) {
|
2017-12-03 12:35:46 +03:00
|
|
|
rb = NewRingBuffer(testConcurrencyBufferSize, testElementSize)
|
2017-12-02 08:24:34 +03:00
|
|
|
go func() {
|
|
|
|
for i := 0; i < 100; i++ {
|
2017-12-03 11:43:29 +03:00
|
|
|
if data, err1 := rb.Read(); data != nil {
|
2017-12-03 10:37:15 +03:00
|
|
|
err2 := rb.DoneReading()
|
2017-12-02 08:24:34 +03:00
|
|
|
if err1 != nil {
|
2017-12-05 12:48:48 +03:00
|
|
|
t.Errorf(falseErrorFailMessage, err1)
|
2017-12-02 08:24:34 +03:00
|
|
|
}
|
|
|
|
if err2 != nil {
|
2017-12-05 12:48:48 +03:00
|
|
|
t.Errorf(falseErrorFailMessage, err2)
|
2017-12-02 08:24:34 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
go func() {
|
|
|
|
for i := 0; i < 100; i++ {
|
2017-12-03 10:37:15 +03:00
|
|
|
_, err1 := rb.Get()
|
2017-12-03 12:35:46 +03:00
|
|
|
err2 := rb.DoneWriting(testDataSize)
|
2017-12-02 08:24:34 +03:00
|
|
|
if err1 != nil {
|
2017-12-05 12:48:48 +03:00
|
|
|
t.Errorf(falseErrorFailMessage, err1)
|
2017-12-02 08:24:34 +03:00
|
|
|
}
|
|
|
|
if err2 != nil {
|
2017-12-05 12:48:48 +03:00
|
|
|
t.Errorf(falseErrorFailMessage, err2)
|
2017-12-02 08:24:34 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
time.Sleep(1000 * time.Millisecond)
|
|
|
|
}
|