From f660d30138e07afe81e6cbcedb1aab2a4fc36b41 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 15 Mar 2014 17:30:08 +0100 Subject: util/CircularBuffer: new buffer class --- test/TestCircularBuffer.hxx | 141 ++++++++++++++++++++++++++++++++++++++++++++ test/test_util.cxx | 2 + 2 files changed, 143 insertions(+) create mode 100644 test/TestCircularBuffer.hxx (limited to 'test') diff --git a/test/TestCircularBuffer.hxx b/test/TestCircularBuffer.hxx new file mode 100644 index 000000000..e4285484b --- /dev/null +++ b/test/TestCircularBuffer.hxx @@ -0,0 +1,141 @@ +/* + * Unit tests for class CircularBuffer. + */ + +#include "config.h" +#include "util/CircularBuffer.hxx" + +#include +#include +#include +#include + +#include +#include + +class TestCircularBuffer : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(TestCircularBuffer); + CPPUNIT_TEST(TestIt); + CPPUNIT_TEST_SUITE_END(); + +public: + void TestIt() { + static size_t N = 8; + int data[N]; + CircularBuffer buffer(data, N); + + /* '.' = empty; 'O' = occupied; 'X' = blocked */ + + /* checks on empty buffer */ + /* [.......X] */ + CPPUNIT_ASSERT_EQUAL(true, buffer.IsEmpty()); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsFull()); + CPPUNIT_ASSERT_EQUAL(true, buffer.Read().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(false, buffer.Write().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(&data[0], buffer.Write().data); + CPPUNIT_ASSERT_EQUAL(size_t(7), buffer.Write().size); + + /* append one element */ + /* [O......X] */ + buffer.Append(1); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsEmpty()); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsFull()); + CPPUNIT_ASSERT_EQUAL(false, buffer.Read().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(size_t(1), buffer.Read().size); + CPPUNIT_ASSERT_EQUAL(&data[0], buffer.Read().data); + CPPUNIT_ASSERT_EQUAL(false, buffer.Write().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(&data[1], buffer.Write().data); + CPPUNIT_ASSERT_EQUAL(size_t(6), buffer.Write().size); + + /* append 6 elements, buffer is now full */ + /* [OOOOOOOX] */ + buffer.Append(6); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsEmpty()); + CPPUNIT_ASSERT_EQUAL(true, buffer.IsFull()); + CPPUNIT_ASSERT_EQUAL(false, buffer.Read().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(size_t(7), buffer.Read().size); + CPPUNIT_ASSERT_EQUAL(&data[0], buffer.Read().data); + CPPUNIT_ASSERT_EQUAL(true, buffer.Write().IsEmpty()); + + /* consume [0]; can append one at [7] */ + /* [XOOOOOO.] */ + buffer.Consume(1); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsEmpty()); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsFull()); + CPPUNIT_ASSERT_EQUAL(false, buffer.Read().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(size_t(6), buffer.Read().size); + CPPUNIT_ASSERT_EQUAL(&data[1], buffer.Read().data); + CPPUNIT_ASSERT_EQUAL(false, buffer.Write().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(&data[7], buffer.Write().data); + CPPUNIT_ASSERT_EQUAL(size_t(1), buffer.Write().size); + + /* append one element; [0] is still empty but cannot + be written to because head==1 */ + /* [XOOOOOOO] */ + buffer.Append(1); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsEmpty()); + CPPUNIT_ASSERT_EQUAL(true, buffer.IsFull()); + CPPUNIT_ASSERT_EQUAL(false, buffer.Read().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(size_t(7), buffer.Read().size); + CPPUNIT_ASSERT_EQUAL(&data[1], buffer.Read().data); + CPPUNIT_ASSERT_EQUAL(true, buffer.Write().IsEmpty()); + + /* consume [1..3]; can append [0..2] */ + /* [...XOOOO] */ + buffer.Consume(3); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsEmpty()); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsFull()); + CPPUNIT_ASSERT_EQUAL(false, buffer.Read().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(size_t(4), buffer.Read().size); + CPPUNIT_ASSERT_EQUAL(&data[4], buffer.Read().data); + CPPUNIT_ASSERT_EQUAL(false, buffer.Write().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(&data[0], buffer.Write().data); + CPPUNIT_ASSERT_EQUAL(size_t(3), buffer.Write().size); + + /* append [0..1] */ + /* [OO.XOOOO] */ + buffer.Append(2); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsEmpty()); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsFull()); + CPPUNIT_ASSERT_EQUAL(false, buffer.Read().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(size_t(4), buffer.Read().size); + CPPUNIT_ASSERT_EQUAL(&data[4], buffer.Read().data); + CPPUNIT_ASSERT_EQUAL(false, buffer.Write().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(&data[2], buffer.Write().data); + CPPUNIT_ASSERT_EQUAL(size_t(1), buffer.Write().size); + + /* append [2] */ + /* [OOOXOOOO] */ + buffer.Append(1); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsEmpty()); + CPPUNIT_ASSERT_EQUAL(true, buffer.IsFull()); + CPPUNIT_ASSERT_EQUAL(false, buffer.Read().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(size_t(4), buffer.Read().size); + CPPUNIT_ASSERT_EQUAL(&data[4], buffer.Read().data); + CPPUNIT_ASSERT_EQUAL(true, buffer.Write().IsEmpty()); + + /* consume [4..7] */ + /* [OOO....X] */ + buffer.Consume(4); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsEmpty()); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsFull()); + CPPUNIT_ASSERT_EQUAL(false, buffer.Read().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(size_t(3), buffer.Read().size); + CPPUNIT_ASSERT_EQUAL(&data[0], buffer.Read().data); + CPPUNIT_ASSERT_EQUAL(false, buffer.Write().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(&data[3], buffer.Write().data); + CPPUNIT_ASSERT_EQUAL(size_t(4), buffer.Write().size); + + /* consume [0..2]; after that, we can only write 5, + because the CircularBuffer class doesn't have + special code to rewind/reset an empty buffer */ + /* [..X.....] */ + buffer.Consume(3); + CPPUNIT_ASSERT_EQUAL(true, buffer.IsEmpty()); + CPPUNIT_ASSERT_EQUAL(false, buffer.IsFull()); + CPPUNIT_ASSERT_EQUAL(true, buffer.Read().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(false, buffer.Write().IsEmpty()); + CPPUNIT_ASSERT_EQUAL(&data[3], buffer.Write().data); + CPPUNIT_ASSERT_EQUAL(size_t(5), buffer.Write().size); + } +}; diff --git a/test/test_util.cxx b/test/test_util.cxx index 07bcacbe9..aaadec68f 100644 --- a/test/test_util.cxx +++ b/test/test_util.cxx @@ -4,6 +4,7 @@ #include "config.h" #include "util/UriUtil.hxx" +#include "TestCircularBuffer.hxx" #include #include @@ -50,6 +51,7 @@ public: }; CPPUNIT_TEST_SUITE_REGISTRATION(UriUtilTest); +CPPUNIT_TEST_SUITE_REGISTRATION(TestCircularBuffer); int main(gcc_unused int argc, gcc_unused char **argv) -- cgit v1.2.3