diff options
author | Sven Gothel <[email protected]> | 2021-10-31 17:08:15 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2021-10-31 17:08:15 +0100 |
commit | a847f3b0d7ba4465bde0d91fe534c9c0562c225b (patch) | |
tree | 5f24647b94660afbb54e44422af6e338ddb5e5db | |
parent | 573160dcc8e77c738410b9006ca27d5611a2eff1 (diff) |
test_lfringbuffer[00..04]: Unify non-threaded functional tests using template, testing multiple types and all parameter
-rw-r--r-- | test/CMakeLists.txt | 1 | ||||
-rw-r--r-- | test/test_lfringbuffer01.cpp | 565 | ||||
-rw-r--r-- | test/test_lfringbuffer02.cpp | 587 | ||||
-rw-r--r-- | test/test_lfringbuffer03.cpp | 564 | ||||
-rw-r--r-- | test/test_lfringbuffer04.cpp | 118 | ||||
-rw-r--r-- | test/test_lfringbuffer_a.hpp | 549 |
6 files changed, 876 insertions, 1508 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0468605..0f9f137 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -27,6 +27,7 @@ set( SOURCES_IDIOMATIC_EXAMPLES test_lfringbuffer01.cpp test_lfringbuffer02.cpp test_lfringbuffer03.cpp + test_lfringbuffer04.cpp test_lfringbuffer11.cpp test_lfringbuffer12.cpp test_lfringbuffer13.cpp diff --git a/test/test_lfringbuffer01.cpp b/test/test_lfringbuffer01.cpp index 68aeaf2..7eb0b88 100644 --- a/test/test_lfringbuffer01.cpp +++ b/test/test_lfringbuffer01.cpp @@ -33,510 +33,85 @@ #include <jau/ringbuffer.hpp> -using namespace jau; - -typedef uint8_t IntegralType; -typedef uint8_t TrivialType; -constexpr const TrivialType TrivialTypeNullElem(0xff); -typedef ringbuffer<TrivialType, jau::nsize_t> TrivialTypeRingbuffer; - -// Test examples. -class TestRingbuffer01 { - private: - - TrivialTypeRingbuffer createEmpty(jau::nsize_t initialCapacity) { - TrivialTypeRingbuffer rb(initialCapacity); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - return rb; - } - TrivialTypeRingbuffer createFull(const std::vector<TrivialType> & source) { - TrivialTypeRingbuffer rb(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - return rb; - } - - std::vector<TrivialType> createIntArray(const jau::nsize_t capacity, const IntegralType startValue) { - std::vector<TrivialType> array(capacity); - for(jau::nsize_t i=0; i<capacity; i++) { - array[i] = TrivialType(startValue+i); - } - return array; - } - - void readTestImpl(TrivialTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) { - (void) clearRef; - - jau::nsize_t preSize = rb.size(); - REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); - REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len); - REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - - for(jau::nsize_t i=0; i<len; i++) { - TrivialType svI; - REQUIRE_MSG("ringbuffer get", rb.get(svI)); - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(IntegralType)i == svI); - } - - REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size()); - REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - } - - void readRangeTestImpl(TrivialTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) { - (void) clearRef; - - jau::nsize_t preSize = rb.size(); - REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); - REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len); - REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - - std::vector<TrivialType> array(len); - REQUIRE_MSG("get-range of "+std::to_string(array.size())+" elem in "+rb.toString(), len==rb.get( &(*array.begin()), len, len) ); - - REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size()); - REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - - for(jau::nsize_t i=0; i<len; i++) { - TrivialType svI = array[i]; - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(IntegralType)i == svI); - } - } - - void writeTestImpl(TrivialTypeRingbuffer &rb, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) { - jau::nsize_t preSize = rb.size(); - - REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); - REQUIRE_MSG("capacity at write "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len); - REQUIRE_MSG("size at write "+std::to_string(len)+" elems: "+rb.toString(), preSize+len <= capacity); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - - for(jau::nsize_t i=0; i<len; i++) { - std::string m = "buffer put #"+std::to_string(i)+": "+rb.toString(); - REQUIRE_MSG(m, rb.put( TrivialType( startValue+i ) ) ); - } - - REQUIRE_MSG("size "+rb.toString(), preSize+len == rb.size()); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - } - - void writeRangeTestImpl(TrivialTypeRingbuffer &rb, jau::nsize_t capacity, const std::vector<TrivialType> & data) { - jau::nsize_t preSize = rb.size(); - jau::nsize_t postSize = preSize+data.size(); - - REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); - REQUIRE_MSG("capacity at write "+std::to_string(data.size())+" elems: "+rb.toString(), capacity >= data.size()); - REQUIRE_MSG("size at write "+std::to_string(data.size())+" elems: "+rb.toString(), postSize<= capacity); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - REQUIRE_MSG("data fits in RB capacity "+rb.toString(), rb.capacity() >= data.size()); - REQUIRE_MSG("data fits in RB free-slots "+rb.toString(), rb.freeSlots() >= data.size()); - - REQUIRE_MSG("put-range of "+std::to_string(data.size())+" elem in "+rb.toString(), rb.put( &(*data.begin()), &(*data.end()) ) ); - - REQUIRE_MSG("size "+rb.toString(), postSize == rb.size()); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - } - - void moveGetPutImpl(TrivialTypeRingbuffer &rb, jau::nsize_t pos) { - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - for(jau::nsize_t i=0; i<pos; i++) { - TrivialType svI; - REQUIRE_MSG("moveFull.get "+rb.toString(), rb.get(svI)); - REQUIRE_MSG("moveFull.get "+rb.toString(), (IntegralType)i == svI); - REQUIRE_MSG("moveFull.put "+rb.toString(), rb.put( TrivialType( (IntegralType)i ) ) ); - } - } - - void movePutGetImpl(TrivialTypeRingbuffer &rb, jau::nsize_t pos) { - REQUIRE_MSG("RB is full "+rb.toString(), !rb.isFull()); - for(jau::nsize_t i=0; i<pos; i++) { - REQUIRE_MSG("moveEmpty.put "+rb.toString(), rb.put( TrivialType( 600+(IntegralType)i ) ) ); - - TrivialType svI; - REQUIRE_MSG("moveEmpty.get "+rb.toString(), rb.get(svI)); - REQUIRE_MSG("moveEmpty.get "+rb.toString(), 600+(IntegralType)i == svI); - } - } - - public: - - void test00_PrintInfo() { - TrivialTypeRingbuffer rb = createEmpty(11); - - std::string msg("Ringbuffer: uses_memcpy "+std::to_string(TrivialTypeRingbuffer::uses_memcpy)+ - ", trivially_copyable "+std::to_string(std::is_trivially_copyable<typename TrivialTypeRingbuffer::value_type>::value)+ - ", size "+std::to_string(sizeof(rb))+" bytes"); - fprintf(stderr, "%s\n", msg.c_str()); - fprintf(stderr, "%s\n", rb.get_info().c_str()); - REQUIRE_MSG("Ringbuffer<T> using memcpy", TrivialTypeRingbuffer::uses_memcpy); - } - - void test01_FullRead() { - jau::nsize_t capacity = 11; - std::vector<TrivialType> source = createIntArray(capacity, 0); - TrivialTypeRingbuffer rb = createFull(source); - INFO_STR("test01_FullRead: Created / "+ rb.toString()); - REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, true, capacity, capacity, 0); - INFO_STR("test01_FullRead: PostRead / " + rb.toString()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - - void test02_EmptyWrite() { - jau::nsize_t capacity = 11; - TrivialTypeRingbuffer rb = createEmpty(capacity); - INFO( std::string("test02_EmptyWrite: Created / ") + rb.toString().c_str()); - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - writeTestImpl(rb, capacity, capacity, 0); - INFO( std::string("test02_EmptyWrite: PostWrite / ") + rb.toString().c_str()); - REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, true, capacity, capacity, 0); - INFO( std::string("test02_EmptyWrite: PostRead / ") + rb.toString().c_str()); - REQUIRE_MSG("empty1 "+rb.toString(), rb.isEmpty()); - } - - void test03_EmptyWriteRange() { - { - jau::nsize_t capacity = 11; - TrivialTypeRingbuffer rb = createEmpty(capacity); - INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str()); - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - /** - * Move R == W == 0 - * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start - */ - std::vector<TrivialType> new_data = createIntArray(capacity, 0); - writeRangeTestImpl(rb, capacity, new_data); - - INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str()); - REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readRangeTestImpl(rb, true, capacity, capacity, 0); - INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - { - jau::nsize_t capacity = 11; - - TrivialTypeRingbuffer rb = createEmpty(capacity); - INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str()); - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - /** - * Move R == W == 3 - * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start - * Empty [ ][ ][ ][RW][ ][ ][ ][ ][ ][ ][ ] - */ - TrivialType dummy(TrivialTypeNullElem); - rb.put(dummy); - rb.put(dummy); - rb.put(dummy); - rb.drop(3); - - std::vector<TrivialType> new_data = createIntArray(capacity, 0); - writeRangeTestImpl(rb, capacity, new_data); - // writeTestImpl(rb, capacity, capacity, 0); - - INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str()); - REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readRangeTestImpl(rb, true, capacity, capacity, 0); - // readTestImpl(rb, true, capacity, capacity, 0); - - INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - { - jau::nsize_t capacity = 11; - TrivialTypeRingbuffer rb = createEmpty(capacity); - INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str()); - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - /** - * Move R == 2, W == 4, size 2 - * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start - * Avail [ ][ ][R][.][W][ ][ ][ ][ ][ ][ ] ; W > R - */ - TrivialType dummy(TrivialTypeNullElem); - rb.put(dummy); // w idx 0 -> 1 - rb.put(dummy); - rb.put(dummy); - rb.put(dummy); // w idx 3 -> 4 - rb.drop(2); // r idx 0 -> 2 +#include "test_lfringbuffer_a.hpp" - // left = 11 - 2 - REQUIRE_MSG("size 2 "+rb.toString(), 2 == rb.size()); - REQUIRE_MSG("available 11-2 "+rb.toString(), capacity-2 == rb.freeSlots()); - - std::vector<TrivialType> new_data = createIntArray(capacity-2, 0); - writeRangeTestImpl(rb, capacity, new_data); - // writeTestImpl(rb, capacity, capacity-2, 0); - - INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str()); - REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - // take off 2 remaining dummies - rb.drop(2); - REQUIRE_MSG("size capacity-2 "+rb.toString(), capacity-2 == rb.size()); - - readRangeTestImpl(rb, true, capacity, capacity-2, 0); - // readTestImpl(rb, true, capacity, capacity-2, 0); - INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str()); - REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - { - jau::nsize_t capacity = 11; - TrivialTypeRingbuffer rb = createEmpty(capacity); - INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str()); - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - /** - * Move R == 9, W == 1, size 3 - * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start - * Avail [.][W][ ][ ][ ][ ][ ][ ][ ][R][.] ; W < R - 1 - */ - TrivialType dummy(TrivialTypeNullElem); - for(int i=0; i<11; i++) { rb.put(dummy); } // fill all - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - rb.drop(10); // pull - REQUIRE_MSG("size 1"+rb.toString(), 1 == rb.size()); - - for(int i=0; i<2; i++) { rb.put(dummy); } // fill 2 more - REQUIRE_MSG("size 3"+rb.toString(), 3 == rb.size()); - - // left = 11 - 3 - REQUIRE_MSG("available 11-3 "+rb.toString(), capacity-3 == rb.freeSlots()); - - std::vector<TrivialType> new_data = createIntArray(capacity-3, 0); - writeRangeTestImpl(rb, capacity, new_data); - // writeTestImpl(rb, capacity, capacity-3, 0); - - INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str()); - REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - // take off 3 remaining dummies - rb.drop(3); // pull - REQUIRE_MSG("size capacity-3 "+rb.toString(), capacity-3 == rb.size()); - - readRangeTestImpl(rb, true, capacity, capacity-3, 0); - // readTestImpl(rb, true, capacity, capacity-3, 0); - INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str()); - REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - } - - void test04_FullReadReset() { - jau::nsize_t capacity = 11; - std::vector<TrivialType> source = createIntArray(capacity, 0); - TrivialTypeRingbuffer rb = createFull(source); - INFO_STR("test04_FullReadReset: Created / " + rb.toString()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - rb.reset(source); - INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, capacity, 0); - INFO_STR("test04_FullReadReset: Post Read / " + rb.toString()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - rb.reset(source); - INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, capacity, 0); - INFO_STR("test04_FullReadReset: Post Read / " + rb.toString()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - - void test05_EmptyWriteClear() { - jau::nsize_t capacity = 11; - TrivialTypeRingbuffer rb = createEmpty(capacity); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - rb.clear(); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - writeTestImpl(rb, capacity, capacity, 0); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, capacity, 0); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - rb.clear(); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - writeTestImpl(rb, capacity, capacity, 0); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, capacity, 0); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - - void test06_ReadResetMid01() { - jau::nsize_t capacity = 11; - std::vector<TrivialType> source = createIntArray(capacity, 0); - TrivialTypeRingbuffer rb = createFull(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - rb.reset(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, 5, 0); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull()); - - rb.reset(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, capacity, 0); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - - void test07_ReadResetMid02() { - jau::nsize_t capacity = 11; - std::vector<TrivialType> source = createIntArray(capacity, 0); - TrivialTypeRingbuffer rb = createFull(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - rb.reset(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - moveGetPutImpl(rb, 5); - readTestImpl(rb, false, capacity, 5, 5); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull()); - - rb.reset(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, capacity, 0); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - - private: - - void test_GrowFullImpl(jau::nsize_t initialCapacity, jau::nsize_t pos) { - jau::nsize_t growAmount = 5; - jau::nsize_t grownCapacity = initialCapacity+growAmount; - std::vector<TrivialType> source = createIntArray(initialCapacity, 0); - TrivialTypeRingbuffer rb = createFull(source); - - for(jau::nsize_t i=0; i<initialCapacity; i++) { - TrivialType svI;; - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI)); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType((0+i)%initialCapacity) == svI); - } - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - - rb.reset(source); - REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.size()); - - moveGetPutImpl(rb, pos); - // PRINTM("X02 "+rb.toString()); - // rb.dump(stderr, "X02"); - - rb.recapacity(grownCapacity); - REQUIRE_MSG("capacity "+rb.toString(), grownCapacity == rb.capacity()); - REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.size()); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - // PRINTM("X03 "+rb.toString()); - // rb.dump(stderr, "X03"); - - for(jau::nsize_t i=0; i<growAmount; i++) { - REQUIRE_MSG("buffer not full at put #"+std::to_string(i)+": "+rb.toString(), rb.put( TrivialType( 100+i ) ) ); - } - REQUIRE_MSG("new size "+rb.toString(), grownCapacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); +using namespace jau; - for(jau::nsize_t i=0; i<initialCapacity; i++) { - TrivialType svI; - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI)); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType((pos+i)%initialCapacity) == svI); - } +typedef uint8_t Integral_type; +typedef uint8_t Value_type; - for(jau::nsize_t i=0; i<growAmount; i++) { - TrivialType svI; - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI)); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType(100+i) == svI); - } +template<> +Value_type getDefault() { return (Value_type)0xff; } - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); +template<> +Value_type createValue(const Integral_type& v) { return v; } - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - } +template<> +Integral_type getValue(const Value_type& e) { return e; } - public: +typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t, + true /* exp_memmove */, true /* exp_memcpy */, false /* exp_secmem */> TestRingbuffer01a; - void test20_GrowFull01_Begin() { - test_GrowFullImpl(11, 0); - } - void test21_GrowFull02_Begin1() { - test_GrowFullImpl(11, 0+1); - } - void test22_GrowFull03_Begin2() { - test_GrowFullImpl(11, 0+2); - } - void test23_GrowFull04_Begin3() { - test_GrowFullImpl(11, 0+3); - } - void test24_GrowFull05_End() { - test_GrowFullImpl(11, 11-1); - } - void test25_GrowFull11_End1() { - test_GrowFullImpl(11, 11-1-1); - } - void test26_GrowFull12_End2() { - test_GrowFullImpl(11, 11-1-2); - } - void test27_GrowFull13_End3() { - test_GrowFullImpl(11, 11-1-3); - } +typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t, + true /* exp_memmove */, true /* exp_memcpy */, true /* exp_secmem */, + true /* use_memmove */, true /* use_memcpy */, true /* use_secmem */> TestRingbuffer01b; -}; +typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t, + false /* exp_memmove */, false /* exp_memcpy */, true /* exp_secmem */, + false /* use_memmove */, false /* use_memcpy */, true /* use_secmem */> TestRingbuffer01c; #if 1 -METHOD_AS_TEST_CASE( TestRingbuffer01::test00_PrintInfo, "Test TestRingbuffer 01- 00"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test01_FullRead, "Test TestRingbuffer 01- 01"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test02_EmptyWrite, "Test TestRingbuffer 01- 02"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test03_EmptyWriteRange, "Test TestRingbuffer 01- 03"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test04_FullReadReset, "Test TestRingbuffer 01- 04"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test05_EmptyWriteClear, "Test TestRingbuffer 01- 05"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test06_ReadResetMid01, "Test TestRingbuffer 01- 06"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test07_ReadResetMid02, "Test TestRingbuffer 01- 07"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test20_GrowFull01_Begin, "Test TestRingbuffer 01- 20"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test21_GrowFull02_Begin1, "Test TestRingbuffer 01- 21"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test22_GrowFull03_Begin2, "Test TestRingbuffer 01- 22"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test23_GrowFull04_Begin3, "Test TestRingbuffer 01- 23"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test24_GrowFull05_End, "Test TestRingbuffer 01- 24"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test25_GrowFull11_End1, "Test TestRingbuffer 01- 25"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test26_GrowFull12_End2, "Test TestRingbuffer 01- 26"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test27_GrowFull13_End3, "Test TestRingbuffer 01- 27"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test00_PrintInfo, "Test TestRingbuffer 01a- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test01_FullRead, "Test TestRingbuffer 01a- 01"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test02_EmptyWrite, "Test TestRingbuffer 01a- 02"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test03_EmptyWriteRange, "Test TestRingbuffer 01a- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test04_FullReadReset, "Test TestRingbuffer 01a- 04"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test05_EmptyWriteClear, "Test TestRingbuffer 01a- 05"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test06_ReadResetMid01, "Test TestRingbuffer 01a- 06"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test07_ReadResetMid02, "Test TestRingbuffer 01a- 07"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test20_GrowFull01_Begin, "Test TestRingbuffer 01a- 20"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test21_GrowFull02_Begin1, "Test TestRingbuffer 01a- 21"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test22_GrowFull03_Begin2, "Test TestRingbuffer 01a- 22"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test23_GrowFull04_Begin3, "Test TestRingbuffer 01a- 23"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test24_GrowFull05_End, "Test TestRingbuffer 01a- 24"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test25_GrowFull11_End1, "Test TestRingbuffer 01a- 25"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test26_GrowFull12_End2, "Test TestRingbuffer 01a- 26"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test27_GrowFull13_End3, "Test TestRingbuffer 01a- 27"); #else -METHOD_AS_TEST_CASE( TestRingbuffer01::test00_PrintInfo, "Test TestRingbuffer 01- 00"); -METHOD_AS_TEST_CASE( TestRingbuffer01::test03_EmptyWriteRange, "Test TestRingbuffer 01- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test00_PrintInfo, "Test TestRingbuffer 01a- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer01a::test03_EmptyWriteRange, "Test TestRingbuffer 01a- 03"); #endif + +METHOD_AS_TEST_CASE( TestRingbuffer01b::test00_PrintInfo, "Test TestRingbuffer 01b- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test01_FullRead, "Test TestRingbuffer 01b- 01"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test02_EmptyWrite, "Test TestRingbuffer 01b- 02"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test03_EmptyWriteRange, "Test TestRingbuffer 01b- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test04_FullReadReset, "Test TestRingbuffer 01b- 04"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test05_EmptyWriteClear, "Test TestRingbuffer 01b- 05"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test06_ReadResetMid01, "Test TestRingbuffer 01b- 06"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test07_ReadResetMid02, "Test TestRingbuffer 01b- 07"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test20_GrowFull01_Begin, "Test TestRingbuffer 01b- 20"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test21_GrowFull02_Begin1, "Test TestRingbuffer 01b- 21"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test22_GrowFull03_Begin2, "Test TestRingbuffer 01b- 22"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test23_GrowFull04_Begin3, "Test TestRingbuffer 01b- 23"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test24_GrowFull05_End, "Test TestRingbuffer 01b- 24"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test25_GrowFull11_End1, "Test TestRingbuffer 01b- 25"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test26_GrowFull12_End2, "Test TestRingbuffer 01b- 26"); +METHOD_AS_TEST_CASE( TestRingbuffer01b::test27_GrowFull13_End3, "Test TestRingbuffer 01b- 27"); + +METHOD_AS_TEST_CASE( TestRingbuffer01c::test00_PrintInfo, "Test TestRingbuffer 01c- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test01_FullRead, "Test TestRingbuffer 01c- 01"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test02_EmptyWrite, "Test TestRingbuffer 01c- 02"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test03_EmptyWriteRange, "Test TestRingbuffer 01c- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test04_FullReadReset, "Test TestRingbuffer 01c- 04"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test05_EmptyWriteClear, "Test TestRingbuffer 01c- 05"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test06_ReadResetMid01, "Test TestRingbuffer 01c- 06"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test07_ReadResetMid02, "Test TestRingbuffer 01c- 07"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test20_GrowFull01_Begin, "Test TestRingbuffer 01c- 20"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test21_GrowFull02_Begin1, "Test TestRingbuffer 01c- 21"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test22_GrowFull03_Begin2, "Test TestRingbuffer 01c- 22"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test23_GrowFull04_Begin3, "Test TestRingbuffer 01c- 23"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test24_GrowFull05_End, "Test TestRingbuffer 01c- 24"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test25_GrowFull11_End1, "Test TestRingbuffer 01c- 25"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test26_GrowFull12_End2, "Test TestRingbuffer 01c- 26"); +METHOD_AS_TEST_CASE( TestRingbuffer01c::test27_GrowFull13_End3, "Test TestRingbuffer 01c- 27"); diff --git a/test/test_lfringbuffer02.cpp b/test/test_lfringbuffer02.cpp index 35953e7..f9fccca 100644 --- a/test/test_lfringbuffer02.cpp +++ b/test/test_lfringbuffer02.cpp @@ -33,540 +33,105 @@ #include <jau/ringbuffer.hpp> +#include "test_lfringbuffer_a.hpp" + using namespace jau; -typedef jau::snsize_t IntegralType; +typedef jau::snsize_t Integral_type; class Integer { public: - IntegralType value; + Integral_type value; - Integer(IntegralType v) : value(v) {} + Integer(Integral_type v) : value(v) {} - Integer() noexcept : value(0) { } + Integer() noexcept : value(-1) { } Integer(const Integer &o) noexcept = default; Integer(Integer &&o) noexcept = default; Integer& operator=(const Integer &o) noexcept = default; Integer& operator=(Integer &&o) noexcept = default; - operator IntegralType() const { + operator Integral_type() const { return value; } - IntegralType intValue() const { return value; } - static Integer valueOf(const IntegralType i) { return Integer(i); } + constexpr Integral_type getValue() const { return value; } + static Integer valueOf(const Integral_type i) { return Integer(i); } }; +typedef Integer Value_type; -typedef Integer TrivialType; -static const TrivialType TrivialTypeNullElem(-1); -typedef ringbuffer<TrivialType, jau::nsize_t> TrivialTypeRingbuffer; - -// Test examples. -class TestRingbuffer02 { - private: - - TrivialTypeRingbuffer createEmpty(jau::nsize_t initialCapacity) { - TrivialTypeRingbuffer rb(initialCapacity); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - return rb; - } - TrivialTypeRingbuffer createFull(const std::vector<TrivialType> & source) { - TrivialTypeRingbuffer rb(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - return rb; - } - - std::vector<TrivialType> createIntArray(const jau::nsize_t capacity, const IntegralType startValue) { - std::vector<TrivialType> array(capacity); - for(jau::nsize_t i=0; i<capacity; i++) { - array[i] = TrivialType(startValue+i); - } - return array; - } - - void readTestImpl(TrivialTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) { - (void) clearRef; - - jau::nsize_t preSize = rb.size(); - REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); - REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len); - REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - - for(jau::nsize_t i=0; i<len; i++) { - TrivialType svI; - REQUIRE_MSG("ringbuffer get", rb.get(svI)); - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(IntegralType)i == svI.intValue()); - } - - REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size()); - REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - } - - void readRangeTestImpl(TrivialTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) { - (void) clearRef; - - jau::nsize_t preSize = rb.size(); - REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); - REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len); - REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - - std::vector<TrivialType> array(len); - REQUIRE_MSG("get-range of "+std::to_string(array.size())+" elem in "+rb.toString(), len==rb.get( &(*array.begin()), len, len) ); - - REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size()); - REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - - for(jau::nsize_t i=0; i<len; i++) { - TrivialType svI = array[i]; - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=TrivialTypeNullElem); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(IntegralType)i == svI.intValue()); - } - } - - void writeTestImpl(TrivialTypeRingbuffer &rb, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) { - jau::nsize_t preSize = rb.size(); - - REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); - REQUIRE_MSG("capacity at write "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len); - REQUIRE_MSG("size at write "+std::to_string(len)+" elems: "+rb.toString(), preSize+len <= capacity); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - - for(jau::nsize_t i=0; i<len; i++) { - std::string m = "buffer put #"+std::to_string(i)+": "+rb.toString(); - REQUIRE_MSG(m, rb.put( TrivialType( startValue+i ) ) ); - } - - REQUIRE_MSG("size "+rb.toString(), preSize+len == rb.size()); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - } - - void writeRangeTestImpl(TrivialTypeRingbuffer &rb, jau::nsize_t capacity, const std::vector<TrivialType> & data) { - jau::nsize_t preSize = rb.size(); - jau::nsize_t postSize = preSize+data.size(); - - REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); - REQUIRE_MSG("capacity at write "+std::to_string(data.size())+" elems: "+rb.toString(), capacity >= data.size()); - REQUIRE_MSG("size at write "+std::to_string(data.size())+" elems: "+rb.toString(), postSize<= capacity); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - REQUIRE_MSG("data fits in RB capacity "+rb.toString(), rb.capacity() >= data.size()); - REQUIRE_MSG("data fits in RB free-slots "+rb.toString(), rb.freeSlots() >= data.size()); - - REQUIRE_MSG("put-range of "+std::to_string(data.size())+" elem in "+rb.toString(), rb.put( &(*data.begin()), &(*data.end()) ) ); - - REQUIRE_MSG("size "+rb.toString(), postSize == rb.size()); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - } - - void moveGetPutImpl(TrivialTypeRingbuffer &rb, jau::nsize_t pos) { - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - for(jau::nsize_t i=0; i<pos; i++) { - TrivialType svI; - REQUIRE_MSG("moveFull.get "+rb.toString(), rb.get(svI)); - REQUIRE_MSG("moveFull.get "+rb.toString(), (IntegralType)i == svI.intValue()); - REQUIRE_MSG("moveFull.put "+rb.toString(), rb.put( TrivialType( (IntegralType)i ) ) ); - } - } - - void movePutGetImpl(TrivialTypeRingbuffer &rb, jau::nsize_t pos) { - REQUIRE_MSG("RB is full "+rb.toString(), !rb.isFull()); - for(jau::nsize_t i=0; i<pos; i++) { - REQUIRE_MSG("moveEmpty.put "+rb.toString(), rb.put( TrivialType( 600+(IntegralType)i ) ) ); - TrivialType svI; - REQUIRE_MSG("moveEmpty.get "+rb.toString(), rb.get(svI)); - REQUIRE_MSG("moveEmpty.get "+rb.toString(), 600+(IntegralType)i == svI.intValue()); - } - } - - public: - - void test00_PrintInfo() { - TrivialTypeRingbuffer rb = createEmpty(11); - - std::string msg("Ringbuffer: uses_memcpy "+std::to_string(TrivialTypeRingbuffer::uses_memcpy)+ - ", trivially_copyable "+std::to_string(std::is_trivially_copyable<typename TrivialTypeRingbuffer::value_type>::value)+ - ", size "+std::to_string(sizeof(rb))+" bytes"); - fprintf(stderr, "%s\n", msg.c_str()); - fprintf(stderr, "%s\n", rb.get_info().c_str()); - REQUIRE_MSG("Ringbuffer<T> using memcpy", TrivialTypeRingbuffer::uses_memcpy); - } - - void test01_FullRead() { - jau::nsize_t capacity = 11; - std::vector<TrivialType> source = createIntArray(capacity, 0); - TrivialTypeRingbuffer rb = createFull(source); - INFO_STR("test01_FullRead: Created / "+ rb.toString()); - REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, true, capacity, capacity, 0); - INFO_STR("test01_FullRead: PostRead / " + rb.toString()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - - void test02_EmptyWrite() { - jau::nsize_t capacity = 11; - TrivialTypeRingbuffer rb = createEmpty(capacity); - INFO( std::string("test02_EmptyWrite: Created / ") + rb.toString().c_str()); - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - writeTestImpl(rb, capacity, capacity, 0); - INFO( std::string("test02_EmptyWrite: PostWrite / ") + rb.toString().c_str()); - REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, true, capacity, capacity, 0); - INFO( std::string("test02_EmptyWrite: PostRead / ") + rb.toString().c_str()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - - void test03_EmptyWriteRange() { -#if 1 - { - jau::nsize_t capacity = 11; - TrivialTypeRingbuffer rb = createEmpty(capacity); - INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str()); - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - /** - * Move R == W == 0 - * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start - */ - std::vector<TrivialType> new_data = createIntArray(capacity, 0); - writeRangeTestImpl(rb, capacity, new_data); - - INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str()); - REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readRangeTestImpl(rb, true, capacity, capacity, 0); - INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } -#endif -#if 1 - { - jau::nsize_t capacity = 11; - - TrivialTypeRingbuffer rb = createEmpty(capacity); - INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str()); - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - /** - * Move R == W == 3 - * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start - * Empty [ ][ ][ ][RW][ ][ ][ ][ ][ ][ ][ ] - */ - TrivialType dummy(TrivialTypeNullElem); - rb.put(dummy); - rb.put(dummy); - rb.put(dummy); - rb.drop(3); - - std::vector<TrivialType> new_data = createIntArray(capacity, 0); - writeRangeTestImpl(rb, capacity, new_data); - // writeTestImpl(rb, capacity, capacity, 0); - - INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str()); - REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readRangeTestImpl(rb, true, capacity, capacity, 0); - // readTestImpl(rb, true, capacity, capacity, 0); - - INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } -#endif -#if 1 - { - jau::nsize_t capacity = 11; - TrivialTypeRingbuffer rb = createEmpty(capacity); - INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str()); - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - /** - * Move R == 2, W == 4, size 2 - * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start - * Avail [ ][ ][R][.][W][ ][ ][ ][ ][ ][ ] ; W > R - */ - TrivialType dummy(TrivialTypeNullElem); - rb.put(dummy); // r idx 0 -> 1 - rb.put(dummy); - rb.put(dummy); - rb.put(dummy); // r idx 3 -> 4 - rb.drop(2); // r idx 0 -> 2 +template<> +Value_type getDefault() { return Integer(); } - // left = 11 - 2 - REQUIRE_MSG("size 2 "+rb.toString(), 2 == rb.size()); - REQUIRE_MSG("available 11-2 "+rb.toString(), capacity-2 == rb.freeSlots()); +template<> +Value_type createValue(const Integral_type& v) { return Integer(v); } - std::vector<TrivialType> new_data = createIntArray(capacity-2, 0); - writeRangeTestImpl(rb, capacity, new_data); - // writeTestImpl(rb, capacity, capacity-2, 0); +template<> +Integral_type getValue(const Value_type& e) { return e.getValue(); } - INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str()); - REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); +typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t, + true /* exp_memmove */, true /* exp_memcpy */, false /* exp_secmem */> TestRingbuffer02a; - // take off 2 remaining dummies - rb.drop(2); - REQUIRE_MSG("size capacity-2 "+rb.toString(), capacity-2 == rb.size()); +typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t, + true /* exp_memmove */, true /* exp_memcpy */, true /* exp_secmem */, + true /* use_memmove */, true /* use_memcpy */, true /* use_secmem */> TestRingbuffer02b; - readRangeTestImpl(rb, true, capacity, capacity-2, 0); - // readTestImpl(rb, true, capacity, capacity-2, 0); - INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str()); - REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } -#endif -#if 1 - { - jau::nsize_t capacity = 11; - TrivialTypeRingbuffer rb = createEmpty(capacity); - INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str()); - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - /** - * Move R == 9, W == 1, size 3 - * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start - * Avail [.][W][ ][ ][ ][ ][ ][ ][ ][R][.] ; W < R - 1 - */ - TrivialType dummy(TrivialTypeNullElem); - for(int i=0; i<11; i++) { rb.put(dummy); } // fill all - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - // for(int i=0; i<10; i++) { rb.get(); } // pull - rb.drop(10); // pull - REQUIRE_MSG("size 1"+rb.toString(), 1 == rb.size()); - - for(int i=0; i<2; i++) { rb.put(dummy); } // fill 2 more - REQUIRE_MSG("size 3"+rb.toString(), 3 == rb.size()); - - // left = 11 - 3 - REQUIRE_MSG("available 11-3 "+rb.toString(), capacity-3 == rb.freeSlots()); - - std::vector<TrivialType> new_data = createIntArray(capacity-3, 0); - writeRangeTestImpl(rb, capacity, new_data); - // writeTestImpl(rb, capacity, capacity-3, 0); - - INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str()); - REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - // take off 3 remaining dummies - rb.drop(3); // pull - // for(int i=0; i<3; i++) { rb.get(); } // pull - REQUIRE_MSG("size capacity-3 "+rb.toString(), capacity-3 == rb.size()); - - readRangeTestImpl(rb, true, capacity, capacity-3, 0); - // readTestImpl(rb, true, capacity, capacity-3, 0); - INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb.toString().c_str()); - REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } -#endif - } - - void test04_FullReadReset() { - jau::nsize_t capacity = 11; - std::vector<TrivialType> source = createIntArray(capacity, 0); - TrivialTypeRingbuffer rb = createFull(source); - INFO_STR("test04_FullReadReset: Created / " + rb.toString()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - rb.reset(source); - INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, capacity, 0); - INFO_STR("test04_FullReadReset: Post Read / " + rb.toString()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - rb.reset(source); - INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, capacity, 0); - INFO_STR("test04_FullReadReset: Post Read / " + rb.toString()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - - void test05_EmptyWriteClear() { - jau::nsize_t capacity = 11; - TrivialTypeRingbuffer rb = createEmpty(capacity); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - rb.clear(); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - writeTestImpl(rb, capacity, capacity, 0); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, capacity, 0); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - rb.clear(); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - writeTestImpl(rb, capacity, capacity, 0); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, capacity, 0); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - - void test06_ReadResetMid01() { - jau::nsize_t capacity = 11; - std::vector<TrivialType> source = createIntArray(capacity, 0); - TrivialTypeRingbuffer rb = createFull(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - rb.reset(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, 5, 0); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull()); - - rb.reset(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, capacity, 0); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - - void test07_ReadResetMid02() { - jau::nsize_t capacity = 11; - std::vector<TrivialType> source = createIntArray(capacity, 0); - TrivialTypeRingbuffer rb = createFull(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - rb.reset(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - moveGetPutImpl(rb, 5); - readTestImpl(rb, false, capacity, 5, 5); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull()); - - rb.reset(source); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - readTestImpl(rb, false, capacity, capacity, 0); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - } - - private: - - void test_GrowFullImpl(jau::nsize_t initialCapacity, jau::nsize_t pos) { - jau::nsize_t growAmount = 5; - jau::nsize_t grownCapacity = initialCapacity+growAmount; - std::vector<TrivialType> source = createIntArray(initialCapacity, 0); - TrivialTypeRingbuffer rb = createFull(source); - - for(jau::nsize_t i=0; i<initialCapacity; i++) { - TrivialType svI; - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI)); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType((0+i)%initialCapacity) == svI.intValue()); - } - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - - rb.reset(source); - REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.size()); - - moveGetPutImpl(rb, pos); - // PRINTM("X02 "+rb.toString()); - // rb.dump(stderr, "X02"); - - rb.recapacity(grownCapacity); - REQUIRE_MSG("capacity "+rb.toString(), grownCapacity == rb.capacity()); - REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.size()); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - // PRINTM("X03 "+rb.toString()); - // rb.dump(stderr, "X03"); - - for(jau::nsize_t i=0; i<growAmount; i++) { - REQUIRE_MSG("buffer not full at put #"+std::to_string(i)+": "+rb.toString(), rb.put( TrivialType( 100+i ) ) ); - } - REQUIRE_MSG("new size "+rb.toString(), grownCapacity == rb.size()); - REQUIRE_MSG("full "+rb.toString(), rb.isFull()); - - for(jau::nsize_t i=0; i<initialCapacity; i++) { - TrivialType svI; - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI)); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType((pos+i)%initialCapacity) == svI.intValue()); - } - - for(jau::nsize_t i=0; i<growAmount; i++) { - TrivialType svI; - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI)); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType(100+i) == svI.intValue()); - } - - REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); - REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); - - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - } - - public: - - void test20_GrowFull01_Begin() { - test_GrowFullImpl(11, 0); - } - void test21_GrowFull02_Begin1() { - test_GrowFullImpl(11, 0+1); - } - void test22_GrowFull03_Begin2() { - test_GrowFullImpl(11, 0+2); - } - void test23_GrowFull04_Begin3() { - test_GrowFullImpl(11, 0+3); - } - void test24_GrowFull05_End() { - test_GrowFullImpl(11, 11-1); - } - void test25_GrowFull11_End1() { - test_GrowFullImpl(11, 11-1-1); - } - void test26_GrowFull12_End2() { - test_GrowFullImpl(11, 11-1-2); - } - void test27_GrowFull13_End3() { - test_GrowFullImpl(11, 11-1-3); - } - -}; +typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t, + false /* exp_memmove */, false /* exp_memcpy */, true /* exp_secmem */, + false /* use_memmove */, false /* use_memcpy */, true /* use_secmem */> TestRingbuffer02c; #if 1 -METHOD_AS_TEST_CASE( TestRingbuffer02::test00_PrintInfo, "Test TestRingbuffer 02- 00"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test01_FullRead, "Test TestRingbuffer 02- 01"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test02_EmptyWrite, "Test TestRingbuffer 02- 02"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test03_EmptyWriteRange, "Test TestRingbuffer 02- 03"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test04_FullReadReset, "Test TestRingbuffer 02- 04"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test05_EmptyWriteClear, "Test TestRingbuffer 02- 05"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test06_ReadResetMid01, "Test TestRingbuffer 02- 06"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test07_ReadResetMid02, "Test TestRingbuffer 02- 07"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test20_GrowFull01_Begin, "Test TestRingbuffer 02- 20"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test21_GrowFull02_Begin1, "Test TestRingbuffer 02- 21"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test22_GrowFull03_Begin2, "Test TestRingbuffer 02- 22"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test23_GrowFull04_Begin3, "Test TestRingbuffer 02- 23"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test24_GrowFull05_End, "Test TestRingbuffer 02- 24"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test25_GrowFull11_End1, "Test TestRingbuffer 02- 25"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test26_GrowFull12_End2, "Test TestRingbuffer 02- 26"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test27_GrowFull13_End3, "Test TestRingbuffer 02- 27"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test00_PrintInfo, "Test TestRingbuffer 02a- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test01_FullRead, "Test TestRingbuffer 02a- 01"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test02_EmptyWrite, "Test TestRingbuffer 02a- 02"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test03_EmptyWriteRange, "Test TestRingbuffer 02a- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test04_FullReadReset, "Test TestRingbuffer 02a- 04"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test05_EmptyWriteClear, "Test TestRingbuffer 02a- 05"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test06_ReadResetMid01, "Test TestRingbuffer 02a- 06"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test07_ReadResetMid02, "Test TestRingbuffer 02a- 07"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test20_GrowFull01_Begin, "Test TestRingbuffer 02a- 20"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test21_GrowFull02_Begin1, "Test TestRingbuffer 02a- 21"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test22_GrowFull03_Begin2, "Test TestRingbuffer 02a- 22"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test23_GrowFull04_Begin3, "Test TestRingbuffer 02a- 23"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test24_GrowFull05_End, "Test TestRingbuffer 02a- 24"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test25_GrowFull11_End1, "Test TestRingbuffer 02a- 25"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test26_GrowFull12_End2, "Test TestRingbuffer 02a- 26"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test27_GrowFull13_End3, "Test TestRingbuffer 02a- 27"); #else -METHOD_AS_TEST_CASE( TestRingbuffer02::test00_PrintInfo, "Test TestRingbuffer 02- 00"); -METHOD_AS_TEST_CASE( TestRingbuffer02::test03_EmptyWriteRange, "Test TestRingbuffer 02- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test00_PrintInfo, "Test TestRingbuffer 02a- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test03_EmptyWriteRange, "Test TestRingbuffer 02a- 03"); #endif + +METHOD_AS_TEST_CASE( TestRingbuffer02b::test00_PrintInfo, "Test TestRingbuffer 02b- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test01_FullRead, "Test TestRingbuffer 02b- 01"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test02_EmptyWrite, "Test TestRingbuffer 02b- 02"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test03_EmptyWriteRange, "Test TestRingbuffer 02b- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test04_FullReadReset, "Test TestRingbuffer 02b- 04"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test05_EmptyWriteClear, "Test TestRingbuffer 02b- 05"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test06_ReadResetMid01, "Test TestRingbuffer 02b- 06"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test07_ReadResetMid02, "Test TestRingbuffer 02b- 07"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test20_GrowFull01_Begin, "Test TestRingbuffer 02b- 20"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test21_GrowFull02_Begin1, "Test TestRingbuffer 02b- 21"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test22_GrowFull03_Begin2, "Test TestRingbuffer 02b- 22"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test23_GrowFull04_Begin3, "Test TestRingbuffer 02b- 23"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test24_GrowFull05_End, "Test TestRingbuffer 02b- 24"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test25_GrowFull11_End1, "Test TestRingbuffer 02b- 25"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test26_GrowFull12_End2, "Test TestRingbuffer 02b- 26"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test27_GrowFull13_End3, "Test TestRingbuffer 02b- 27"); + +METHOD_AS_TEST_CASE( TestRingbuffer02c::test00_PrintInfo, "Test TestRingbuffer 02c- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test01_FullRead, "Test TestRingbuffer 02c- 01"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test02_EmptyWrite, "Test TestRingbuffer 02c- 02"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test03_EmptyWriteRange, "Test TestRingbuffer 02c- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test04_FullReadReset, "Test TestRingbuffer 02c- 04"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test05_EmptyWriteClear, "Test TestRingbuffer 02c- 05"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test06_ReadResetMid01, "Test TestRingbuffer 02c- 06"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test07_ReadResetMid02, "Test TestRingbuffer 02c- 07"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test20_GrowFull01_Begin, "Test TestRingbuffer 02c- 20"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test21_GrowFull02_Begin1, "Test TestRingbuffer 02c- 21"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test22_GrowFull03_Begin2, "Test TestRingbuffer 02c- 22"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test23_GrowFull04_Begin3, "Test TestRingbuffer 02c- 23"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test24_GrowFull05_End, "Test TestRingbuffer 02c- 24"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test25_GrowFull11_End1, "Test TestRingbuffer 02c- 25"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test26_GrowFull12_End2, "Test TestRingbuffer 02c- 26"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test27_GrowFull13_End3, "Test TestRingbuffer 02c- 27"); diff --git a/test/test_lfringbuffer03.cpp b/test/test_lfringbuffer03.cpp index 5e6f7bc..7ca785e 100644 --- a/test/test_lfringbuffer03.cpp +++ b/test/test_lfringbuffer03.cpp @@ -33,520 +33,80 @@ #include <jau/ringbuffer.hpp> +#include "test_lfringbuffer_a.hpp" + using namespace jau; -typedef jau::snsize_t IntegralType; +typedef jau::snsize_t Integral_type; class Integer { public: - IntegralType value; + Integral_type value; + + Integer(Integral_type v) : value(v) {} - Integer(IntegralType v) : value(v) {} + Integer() noexcept : value(-1) { } Integer(const Integer &o) noexcept = default; Integer(Integer &&o) noexcept = default; Integer& operator=(const Integer &o) noexcept = default; Integer& operator=(Integer &&o) noexcept = default; - operator IntegralType() const { + operator Integral_type() const { return value; } - IntegralType intValue() const { return value; } - static Integer valueOf(const IntegralType i) { return Integer(i); } -}; - -std::shared_ptr<Integer> NullInteger = nullptr; - -typedef std::shared_ptr<Integer> SharedType; -typedef ringbuffer<SharedType, jau::nsize_t> SharedTypeRingbuffer; - -// Test examples. -class TestRingbuffer03 { - private: - - std::shared_ptr<SharedTypeRingbuffer> createEmpty(jau::nsize_t initialCapacity) { - std::shared_ptr<SharedTypeRingbuffer> rb = std::shared_ptr<SharedTypeRingbuffer>(new SharedTypeRingbuffer(initialCapacity)); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - return rb; - } - std::shared_ptr<SharedTypeRingbuffer> createFull(const std::vector<std::shared_ptr<Integer>> & source) { - std::shared_ptr<SharedTypeRingbuffer> rb = std::shared_ptr<SharedTypeRingbuffer>(new SharedTypeRingbuffer(source)); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - return rb; - } - - std::vector<SharedType> createIntArray(const jau::nsize_t capacity, const IntegralType startValue) { - std::vector<SharedType> array(capacity); - for(jau::nsize_t i=0; i<capacity; i++) { - array[i] = SharedType(new Integer(startValue+i)); - } - return array; - } - - void readTestImpl(SharedTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) { - (void) clearRef; - - jau::nsize_t preSize = rb.size(); - REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); - REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len); - REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - - for(jau::nsize_t i=0; i<len; i++) { - SharedType svI; - REQUIRE_MSG("ringbuffer get", rb.get(svI)); - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=nullptr); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType(startValue+i) == svI->intValue()); - } - - REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size()); - REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - } - - void readRangeTestImpl(SharedTypeRingbuffer &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) { - (void) clearRef; - - jau::nsize_t preSize = rb.size(); - REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); - REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len); - REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - - std::vector<SharedType> array(len); - REQUIRE_MSG("get-range of "+std::to_string(array.size())+" elem in "+rb.toString(), len==rb.get( &(*array.begin()), len, len) ); - - REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size()); - REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - - for(jau::nsize_t i=0; i<len; i++) { - SharedType svI = array[i]; - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), svI!=nullptr); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), IntegralType(startValue+i) == svI->intValue()); - } - } - - void writeTestImpl(SharedTypeRingbuffer &rb, jau::nsize_t capacity, jau::nsize_t len, IntegralType startValue) { - jau::nsize_t preSize = rb.size(); - - REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); - REQUIRE_MSG("capacity at write "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len); - REQUIRE_MSG("size at write "+std::to_string(len)+" elems: "+rb.toString(), preSize+len <= capacity); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - - for(jau::nsize_t i=0; i<len; i++) { - std::string m = "buffer put #"+std::to_string(i)+": "+rb.toString(); - REQUIRE_MSG(m, rb.put( SharedType( new Integer(startValue+i) ) ) ); - } - - REQUIRE_MSG("size "+rb.toString(), preSize+len == rb.size()); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - } - - void writeRangeTestImpl(SharedTypeRingbuffer &rb, jau::nsize_t capacity, const std::vector<std::shared_ptr<Integer>> & data) { - jau::nsize_t preSize = rb.size(); - jau::nsize_t postSize = preSize+data.size(); - - REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); - REQUIRE_MSG("capacity at write "+std::to_string(data.size())+" elems: "+rb.toString(), capacity >= data.size()); - REQUIRE_MSG("size at write "+std::to_string(data.size())+" elems: "+rb.toString(), postSize<= capacity); - REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); - REQUIRE_MSG("data fits in RB capacity "+rb.toString(), rb.capacity() >= data.size()); - REQUIRE_MSG("data fits in RB free-slots "+rb.toString(), rb.freeSlots() >= data.size()); - - REQUIRE_MSG("put-range of "+std::to_string(data.size())+" elem in "+rb.toString(), rb.put( &(*data.begin()), &(*data.end()) ) ); - - REQUIRE_MSG("size "+rb.toString(), postSize == rb.size()); - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - } - - void moveGetPutImpl(SharedTypeRingbuffer &rb, jau::nsize_t pos) { - REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); - for(jau::nsize_t i=0; i<pos; i++) { - SharedType svI; - REQUIRE_MSG("moveFull.get "+rb.toString(), rb.get(svI)); - REQUIRE_MSG("moveFull.get "+rb.toString(), IntegralType(i) == svI->intValue()); - REQUIRE_MSG("moveFull.put "+rb.toString(), rb.put( SharedType( new Integer(i) ) ) ); - } - } - - void movePutGetImpl(SharedTypeRingbuffer &rb, jau::nsize_t pos) { - REQUIRE_MSG("RB is full "+rb.toString(), !rb.isFull()); - for(jau::nsize_t i=0; i<pos; i++) { - REQUIRE_MSG("moveEmpty.put "+rb.toString(), rb.put( SharedType( new Integer(600+i) ) ) ); - SharedType svI; - REQUIRE_MSG("moveEmpty.get "+rb.toString(), rb.get(svI)); - REQUIRE_MSG("moveEmpty.get "+rb.toString(), IntegralType(600+i) == svI->intValue()); - } - } - - public: - - void test00_PrintInfo() { - std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(11); - - std::string msg("Ringbuffer: uses_memcpy "+std::to_string(SharedTypeRingbuffer::uses_memcpy)+ - ", trivially_copyable "+std::to_string(std::is_trivially_copyable<typename SharedTypeRingbuffer::value_type>::value)+ - ", size "+std::to_string(sizeof(*rb))+" bytes"); - fprintf(stderr, "%s\n", msg.c_str()); - fprintf(stderr, "%s\n", rb->get_info().c_str()); - REQUIRE_MSG("Ringbuffer<shared_ptr<T>> not using memcpy", !SharedTypeRingbuffer::uses_memcpy); - } - - void test01_FullRead() { - jau::nsize_t capacity = 11; - std::vector<SharedType> source = createIntArray(capacity, 0); - std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source); - INFO_STR("test01_FullRead: Created / "+ rb->toString()); - REQUIRE_MSG("full size "+rb->toString(), capacity == rb->size()); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - readTestImpl(*rb, true, capacity, capacity, 0); - INFO_STR("test01_FullRead: PostRead / " + rb->toString()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - } - - void test02_EmptyWrite() { - jau::nsize_t capacity = 11; - std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity); - INFO( std::string("test02_EmptyWrite: Created / ") + rb->toString().c_str()); - REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - - writeTestImpl(*rb, capacity, capacity, 0); - INFO( std::string("test02_EmptyWrite: PostWrite / ") + rb->toString().c_str()); - REQUIRE_MSG("full size "+rb->toString(), capacity == rb->size()); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - readTestImpl(*rb, true, capacity, capacity, 0); - INFO( std::string("test02_EmptyWrite: PostRead / ") + rb->toString().c_str()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - } - - void test03_EmptyWriteRange() { - { - jau::nsize_t capacity = 11; - std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity); - INFO( std::string("test03_EmptyWriteRange: Created / ") + rb->toString().c_str()); - REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - - /** - * Move R == W == 0 - * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start - */ - std::vector<SharedType> new_data = createIntArray(capacity, 0); - writeRangeTestImpl(*rb, capacity, new_data); - - INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb->toString().c_str()); - REQUIRE_MSG("full size "+rb->toString(), capacity == rb->size()); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - readRangeTestImpl(*rb, true, capacity, capacity, 0); - INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb->toString().c_str()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - } - { - jau::nsize_t capacity = 11; - std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity); - INFO( std::string("test03_EmptyWriteRange: Created / ") + rb->toString().c_str()); - REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - - /** - * Move R == W == 3 - * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start - * Empty [ ][ ][ ][RW][ ][ ][ ][ ][ ][ ][ ] - */ - SharedType dummy(new Integer(-1)); - rb->put(dummy); - rb->put(dummy); - rb->put(dummy); - rb->drop(3); - - std::vector<SharedType> new_data = createIntArray(capacity, 0); - writeRangeTestImpl(*rb, capacity, new_data); - - INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb->toString().c_str()); - REQUIRE_MSG("full size "+rb->toString(), capacity == rb->size()); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - readRangeTestImpl(*rb, true, capacity, capacity, 0); - INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb->toString().c_str()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - } - { - jau::nsize_t capacity = 11; - std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity); - INFO( std::string("test03_EmptyWriteRange: Created / ") + rb->toString().c_str()); - REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - - /** - * Move R == 2, W == 4, size 2 - * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start - * Avail [ ][ ][R][.][W][ ][ ][ ][ ][ ][ ] ; W > R - */ - SharedType dummy(new Integer(-1)); - rb->put(dummy); // w idx 0 -> 1 - rb->put(dummy); - rb->put(dummy); - rb->put(dummy); // w idx 3 -> 4 - rb->drop(2); // r idx 0 -> 2 - - // left = 11 - 2 - REQUIRE_MSG("size 2 "+rb->toString(), 2 == rb->size()); - REQUIRE_MSG("available 11-2 "+rb->toString(), capacity-2 == rb->freeSlots()); - - std::vector<SharedType> new_data = createIntArray(capacity-2, 0); - writeRangeTestImpl(*rb, capacity, new_data); - // writeTestImpl(*rb, capacity, capacity-2, 0); - - INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb->toString().c_str()); - REQUIRE_MSG("full size "+rb->toString(), capacity == rb->size()); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - // take off 2 remaining dummies - rb->drop(2); - REQUIRE_MSG("size capacity-2 "+rb->toString(), capacity-2 == rb->size()); - - readRangeTestImpl(*rb, true, capacity, capacity-2, 0); - // readTestImpl(*rb, true, capacity, capacity-2, 0); - INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb->toString().c_str()); - REQUIRE_MSG("size 0 "+rb->toString(), 0 == rb->size()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - } - { - jau::nsize_t capacity = 11; - std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity); - INFO( std::string("test03_EmptyWriteRange: Created / ") + rb->toString().c_str()); - REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - - /** - * Move R == 9, W == 1, size 3 - * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start - * Avail [.][W][ ][ ][ ][ ][ ][ ][ ][R][.] ; W < R - 1 - */ - SharedType dummy(new Integer(-1)); - for(int i=0; i<11; i++) { rb->put(dummy); } // fill all - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - rb->drop(10); // pull - REQUIRE_MSG("size 1"+rb->toString(), 1 == rb->size()); - - for(int i=0; i<2; i++) { rb->put(dummy); } // fill 2 more - REQUIRE_MSG("size 3"+rb->toString(), 3 == rb->size()); - - // left = 11 - 3 - REQUIRE_MSG("available 11-3 "+rb->toString(), capacity-3 == rb->freeSlots()); - - std::vector<SharedType> new_data = createIntArray(capacity-3, 0); - writeRangeTestImpl(*rb, capacity, new_data); - // writeTestImpl(*rb, capacity, capacity-3, 0); - - INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb->toString().c_str()); - REQUIRE_MSG("full size "+rb->toString(), capacity == rb->size()); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - // take off 3 remaining dummies - rb->drop(3); // pull - REQUIRE_MSG("size capacity-3 "+rb->toString(), capacity-3 == rb->size()); - - readRangeTestImpl(*rb, true, capacity, capacity-3, 0); - // readTestImpl(*rb, true, capacity, capacity-3, 0); - INFO( std::string("test03_EmptyWriteRange: PostRead / ") + rb->toString().c_str()); - REQUIRE_MSG("size 0 "+rb->toString(), 0 == rb->size()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - } - } - - void test04_FullReadReset() { - jau::nsize_t capacity = 11; - std::vector<SharedType> source = createIntArray(capacity, 0); - std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source); - INFO_STR("test04_FullReadReset: Created / " + rb->toString()); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - rb->reset(source); - INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb->toString()); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - readTestImpl(*rb, false, capacity, capacity, 0); - INFO_STR("test04_FullReadReset: Post Read / " + rb->toString()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - - rb->reset(source); - INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb->toString()); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - readTestImpl(*rb, false, capacity, capacity, 0); - INFO_STR("test04_FullReadReset: Post Read / " + rb->toString()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - } - - void test05_EmptyWriteClear() { - jau::nsize_t capacity = 11; - std::shared_ptr<SharedTypeRingbuffer> rb = createEmpty(capacity); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - - rb->clear(); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - - writeTestImpl(*rb, capacity, capacity, 0); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - readTestImpl(*rb, false, capacity, capacity, 0); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - - rb->clear(); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - - writeTestImpl(*rb, capacity, capacity, 0); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - readTestImpl(*rb, false, capacity, capacity, 0); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - } - - void test06_ReadResetMid01() { - jau::nsize_t capacity = 11; - std::vector<SharedType> source = createIntArray(capacity, 0); - std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - rb->reset(source); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - readTestImpl(*rb, false, capacity, 5, 0); - REQUIRE_MSG("not empty "+rb->toString(), !rb->isEmpty()); - REQUIRE_MSG("not Full "+rb->toString(), !rb->isFull()); - - rb->reset(source); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - readTestImpl(*rb, false, capacity, capacity, 0); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - } - - void test07_ReadResetMid02() { - jau::nsize_t capacity = 11; - std::vector<SharedType> source = createIntArray(capacity, 0); - std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - rb->reset(source); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - moveGetPutImpl(*rb, 5); - readTestImpl(*rb, false, capacity, 5, 5); - REQUIRE_MSG("not empty "+rb->toString(), !rb->isEmpty()); - REQUIRE_MSG("not Full "+rb->toString(), !rb->isFull()); - - rb->reset(source); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - readTestImpl(*rb, false, capacity, capacity, 0); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - } - - private: - - void test_GrowFullImpl(jau::nsize_t initialCapacity, jau::nsize_t pos) { - jau::nsize_t growAmount = 5; - jau::nsize_t grownCapacity = initialCapacity+growAmount; - std::vector<SharedType> source = createIntArray(initialCapacity, 0); - std::shared_ptr<SharedTypeRingbuffer> rb = createFull(source); - - for(jau::nsize_t i=0; i<initialCapacity; i++) { - SharedType svI; - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb->toString(), rb->get(svI)); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb->toString(), IntegralType((0+i)%initialCapacity) == svI->intValue()); - } - REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size()); - - rb->reset(source); - REQUIRE_MSG("orig size "+rb->toString(), initialCapacity == rb->size()); - - moveGetPutImpl(*rb, pos); - // PRINTM("X02 "+rb->toString()); - // rb->dump(stderr, "X02"); - - rb->recapacity(grownCapacity); - REQUIRE_MSG("capacity "+rb->toString(), grownCapacity == rb->capacity()); - REQUIRE_MSG("orig size "+rb->toString(), initialCapacity == rb->size()); - REQUIRE_MSG("not full "+rb->toString(), !rb->isFull()); - REQUIRE_MSG("not empty "+rb->toString(), !rb->isEmpty()); - // PRINTM("X03 "+rb->toString()); - // rb->dump(stderr, "X03"); - - for(jau::nsize_t i=0; i<growAmount; i++) { - REQUIRE_MSG("buffer not full at put #"+std::to_string(i)+": "+rb->toString(), rb->put( SharedType( new Integer(100+i) ) ) ); - } - REQUIRE_MSG("new size "+rb->toString(), grownCapacity == rb->size()); - REQUIRE_MSG("full "+rb->toString(), rb->isFull()); - - for(jau::nsize_t i=0; i<initialCapacity; i++) { - SharedType svI; - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb->toString(), rb->get(svI)); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb->toString(), IntegralType((pos+i)%initialCapacity) == svI->intValue()); - } - - for(jau::nsize_t i=0; i<growAmount; i++) { - SharedType svI; - REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb->toString(), rb->get(svI)); - REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb->toString(), IntegralType(100+i) == svI->intValue()); - } - - REQUIRE_MSG("zero size "+rb->toString(), 0 == rb->size()); - REQUIRE_MSG("empty "+rb->toString(), rb->isEmpty()); - - REQUIRE_MSG("not full "+rb->toString(), !rb->isFull()); - } - - public: - - void test20_GrowFull01_Begin() { - test_GrowFullImpl(11, 0); - } - void test21_GrowFull02_Begin1() { - test_GrowFullImpl(11, 0+1); - } - void test22_GrowFull03_Begin2() { - test_GrowFullImpl(11, 0+2); - } - void test23_GrowFull04_Begin3() { - test_GrowFullImpl(11, 0+3); - } - void test24_GrowFull05_End() { - test_GrowFullImpl(11, 11-1); - } - void test25_GrowFull11_End1() { - test_GrowFullImpl(11, 11-1-1); - } - void test26_GrowFull12_End2() { - test_GrowFullImpl(11, 11-1-2); - } - void test27_GrowFull13_End3() { - test_GrowFullImpl(11, 11-1-3); - } - + Integral_type getValue() const { return value; } + static Integer valueOf(const Integral_type i) { return Integer(i); } }; - -METHOD_AS_TEST_CASE( TestRingbuffer03::test00_PrintInfo, "Test TestRingbuffer 03- 00"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test01_FullRead, "Test TestRingbuffer 03- 01"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test02_EmptyWrite, "Test TestRingbuffer 03- 02"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test03_EmptyWriteRange, "Test TestRingbuffer 03- 03"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test04_FullReadReset, "Test TestRingbuffer 03- 04"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test05_EmptyWriteClear, "Test TestRingbuffer 03- 05"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test06_ReadResetMid01, "Test TestRingbuffer 03- 06"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test07_ReadResetMid02, "Test TestRingbuffer 03- 07"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test20_GrowFull01_Begin, "Test TestRingbuffer 03- 20"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test21_GrowFull02_Begin1, "Test TestRingbuffer 03- 21"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test22_GrowFull03_Begin2, "Test TestRingbuffer 03- 22"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test23_GrowFull04_Begin3, "Test TestRingbuffer 03- 23"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test24_GrowFull05_End, "Test TestRingbuffer 03- 24"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test25_GrowFull11_End1, "Test TestRingbuffer 03- 25"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test26_GrowFull12_End2, "Test TestRingbuffer 03- 26"); -METHOD_AS_TEST_CASE( TestRingbuffer03::test27_GrowFull13_End3, "Test TestRingbuffer 03- 27"); +typedef std::shared_ptr<Integer> Value_type; + +template<> +Value_type getDefault() { return std::make_shared<Integer>(); } + +template<> +Value_type createValue(const Integral_type& v) { return std::make_shared<Integer>(v); } + +template<> +Integral_type getValue(const Value_type& e) { return e->getValue(); } + +typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t, + false /* exp_memmove */, false /* exp_memcpy */, false /* exp_secmem */> TestRingbuffer03a; + +typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t, + false /* exp_memmove */, false /* exp_memcpy */, true /* exp_secmem */, + false /* use_memmove */, false /* use_memcpy */, true /* use_secmem */> TestRingbuffer03b; + + +METHOD_AS_TEST_CASE( TestRingbuffer03a::test00_PrintInfo, "Test TestRingbuffer 03a- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test01_FullRead, "Test TestRingbuffer 03a- 01"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test02_EmptyWrite, "Test TestRingbuffer 03a- 02"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test03_EmptyWriteRange, "Test TestRingbuffer 03a- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test04_FullReadReset, "Test TestRingbuffer 03a- 04"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test05_EmptyWriteClear, "Test TestRingbuffer 03a- 05"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test06_ReadResetMid01, "Test TestRingbuffer 03a- 06"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test07_ReadResetMid02, "Test TestRingbuffer 03a- 07"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test20_GrowFull01_Begin, "Test TestRingbuffer 03a- 20"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test21_GrowFull02_Begin1, "Test TestRingbuffer 03a- 21"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test22_GrowFull03_Begin2, "Test TestRingbuffer 03a- 22"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test23_GrowFull04_Begin3, "Test TestRingbuffer 03a- 23"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test24_GrowFull05_End, "Test TestRingbuffer 03a- 24"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test25_GrowFull11_End1, "Test TestRingbuffer 03a- 25"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test26_GrowFull12_End2, "Test TestRingbuffer 03a- 26"); +METHOD_AS_TEST_CASE( TestRingbuffer03a::test27_GrowFull13_End3, "Test TestRingbuffer 03a- 27"); + +METHOD_AS_TEST_CASE( TestRingbuffer03b::test00_PrintInfo, "Test TestRingbuffer 03b- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test01_FullRead, "Test TestRingbuffer 03b- 01"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test02_EmptyWrite, "Test TestRingbuffer 03b- 02"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test03_EmptyWriteRange, "Test TestRingbuffer 03b- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test04_FullReadReset, "Test TestRingbuffer 03b- 04"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test05_EmptyWriteClear, "Test TestRingbuffer 03b- 05"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test06_ReadResetMid01, "Test TestRingbuffer 03b- 06"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test07_ReadResetMid02, "Test TestRingbuffer 03b- 07"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test20_GrowFull01_Begin, "Test TestRingbuffer 03b- 20"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test21_GrowFull02_Begin1, "Test TestRingbuffer 03b- 21"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test22_GrowFull03_Begin2, "Test TestRingbuffer 03b- 22"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test23_GrowFull04_Begin3, "Test TestRingbuffer 03b- 23"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test24_GrowFull05_End, "Test TestRingbuffer 03b- 24"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test25_GrowFull11_End1, "Test TestRingbuffer 03b- 25"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test26_GrowFull12_End2, "Test TestRingbuffer 03b- 26"); +METHOD_AS_TEST_CASE( TestRingbuffer03b::test27_GrowFull13_End3, "Test TestRingbuffer 03b- 27"); diff --git a/test/test_lfringbuffer04.cpp b/test/test_lfringbuffer04.cpp new file mode 100644 index 0000000..61b1315 --- /dev/null +++ b/test/test_lfringbuffer04.cpp @@ -0,0 +1,118 @@ +/* + * Author: Sven Gothel <[email protected]> + * Copyright (c) 2020 Gothel Software e.K. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include <iostream> +#include <cassert> +#include <cinttypes> +#include <cstring> +#include <memory> + +#define CATCH_CONFIG_MAIN +#include <catch2/catch_amalgamated.hpp> +#include <jau/test/catch2_ext.hpp> + +#include <jau/ringbuffer.hpp> + +#include "test_lfringbuffer_a.hpp" + +using namespace jau; + +typedef jau::snsize_t Integral_type; + +typedef std::array<Integral_type, 6> Value_type; + +template<> +Value_type getDefault() { return Value_type{-1, -1, -1, -1, -1, -1}; } + +template<> +Value_type createValue(const Integral_type& v) { return Value_type{v, v+1, v+2, v+3, v+4, v+5}; } + +template<> +Integral_type getValue(const Value_type& e) { return e[0]; } + +typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t, + true /* exp_memmove */, true /* exp_memcpy */, false /* exp_secmem */> TestRingbuffer02a; + +typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t, + true /* exp_memmove */, true /* exp_memcpy */, true /* exp_secmem */, + true /* use_memmove */, true /* use_memcpy */, true /* use_secmem */> TestRingbuffer02b; + +typedef TestRingbuffer_A<Integral_type, Value_type, jau::nsize_t, + false /* exp_memmove */, false /* exp_memcpy */, true /* exp_secmem */, + false /* use_memmove */, false /* use_memcpy */, true /* use_secmem */> TestRingbuffer02c; + +#if 1 +METHOD_AS_TEST_CASE( TestRingbuffer02a::test00_PrintInfo, "Test TestRingbuffer 02a- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test01_FullRead, "Test TestRingbuffer 02a- 01"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test02_EmptyWrite, "Test TestRingbuffer 02a- 02"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test03_EmptyWriteRange, "Test TestRingbuffer 02a- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test04_FullReadReset, "Test TestRingbuffer 02a- 04"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test05_EmptyWriteClear, "Test TestRingbuffer 02a- 05"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test06_ReadResetMid01, "Test TestRingbuffer 02a- 06"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test07_ReadResetMid02, "Test TestRingbuffer 02a- 07"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test20_GrowFull01_Begin, "Test TestRingbuffer 02a- 20"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test21_GrowFull02_Begin1, "Test TestRingbuffer 02a- 21"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test22_GrowFull03_Begin2, "Test TestRingbuffer 02a- 22"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test23_GrowFull04_Begin3, "Test TestRingbuffer 02a- 23"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test24_GrowFull05_End, "Test TestRingbuffer 02a- 24"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test25_GrowFull11_End1, "Test TestRingbuffer 02a- 25"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test26_GrowFull12_End2, "Test TestRingbuffer 02a- 26"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test27_GrowFull13_End3, "Test TestRingbuffer 02a- 27"); +#else +METHOD_AS_TEST_CASE( TestRingbuffer02a::test00_PrintInfo, "Test TestRingbuffer 02a- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer02a::test03_EmptyWriteRange, "Test TestRingbuffer 02a- 03"); +#endif + +METHOD_AS_TEST_CASE( TestRingbuffer02b::test00_PrintInfo, "Test TestRingbuffer 02b- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test01_FullRead, "Test TestRingbuffer 02b- 01"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test02_EmptyWrite, "Test TestRingbuffer 02b- 02"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test03_EmptyWriteRange, "Test TestRingbuffer 02b- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test04_FullReadReset, "Test TestRingbuffer 02b- 04"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test05_EmptyWriteClear, "Test TestRingbuffer 02b- 05"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test06_ReadResetMid01, "Test TestRingbuffer 02b- 06"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test07_ReadResetMid02, "Test TestRingbuffer 02b- 07"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test20_GrowFull01_Begin, "Test TestRingbuffer 02b- 20"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test21_GrowFull02_Begin1, "Test TestRingbuffer 02b- 21"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test22_GrowFull03_Begin2, "Test TestRingbuffer 02b- 22"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test23_GrowFull04_Begin3, "Test TestRingbuffer 02b- 23"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test24_GrowFull05_End, "Test TestRingbuffer 02b- 24"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test25_GrowFull11_End1, "Test TestRingbuffer 02b- 25"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test26_GrowFull12_End2, "Test TestRingbuffer 02b- 26"); +METHOD_AS_TEST_CASE( TestRingbuffer02b::test27_GrowFull13_End3, "Test TestRingbuffer 02b- 27"); + +METHOD_AS_TEST_CASE( TestRingbuffer02c::test00_PrintInfo, "Test TestRingbuffer 02c- 00"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test01_FullRead, "Test TestRingbuffer 02c- 01"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test02_EmptyWrite, "Test TestRingbuffer 02c- 02"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test03_EmptyWriteRange, "Test TestRingbuffer 02c- 03"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test04_FullReadReset, "Test TestRingbuffer 02c- 04"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test05_EmptyWriteClear, "Test TestRingbuffer 02c- 05"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test06_ReadResetMid01, "Test TestRingbuffer 02c- 06"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test07_ReadResetMid02, "Test TestRingbuffer 02c- 07"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test20_GrowFull01_Begin, "Test TestRingbuffer 02c- 20"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test21_GrowFull02_Begin1, "Test TestRingbuffer 02c- 21"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test22_GrowFull03_Begin2, "Test TestRingbuffer 02c- 22"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test23_GrowFull04_Begin3, "Test TestRingbuffer 02c- 23"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test24_GrowFull05_End, "Test TestRingbuffer 02c- 24"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test25_GrowFull11_End1, "Test TestRingbuffer 02c- 25"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test26_GrowFull12_End2, "Test TestRingbuffer 02c- 26"); +METHOD_AS_TEST_CASE( TestRingbuffer02c::test27_GrowFull13_End3, "Test TestRingbuffer 02c- 27"); diff --git a/test/test_lfringbuffer_a.hpp b/test/test_lfringbuffer_a.hpp new file mode 100644 index 0000000..1d128b1 --- /dev/null +++ b/test/test_lfringbuffer_a.hpp @@ -0,0 +1,549 @@ +/* + * Author: Sven Gothel <[email protected]> + * Copyright (c) 2020 Gothel Software e.K. + * Copyright (c) 2021 Gothel Software e.K. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include <iostream> +#include <cassert> +#include <cinttypes> +#include <cstring> +#include <memory> + +#define CATCH_CONFIG_MAIN +#include <catch2/catch_amalgamated.hpp> +#include <jau/test/catch2_ext.hpp> + +#include <jau/ringbuffer.hpp> + +using namespace jau; + +template<typename Value_type> +Value_type getDefault(); + +template<typename Integral_type, typename Value_type> +Value_type createValue(const Integral_type& v); + +template<typename Integral_type, typename Value_type> +Integral_type getValue(const Value_type& e); + +template <typename Integral_type, typename Value_type, typename Size_type, + bool exp_memmove, bool exp_memcpy, bool exp_secmem, + + bool use_memmove = std::is_trivially_copyable_v<Value_type> || is_container_memmove_compliant_v<Value_type>, + bool use_memcpy = std::is_trivially_copyable_v<Value_type>, + bool use_secmem = is_enforcing_secmem_v<Value_type> + > +class TestRingbuffer_A { + public: + typedef ringbuffer<Value_type, Size_type, use_memmove, use_memcpy, use_secmem> ringbuffer_t; + + private: + + ringbuffer_t createEmpty(jau::nsize_t initialCapacity) { + ringbuffer_t rb(initialCapacity); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + return rb; + } + ringbuffer_t createFull(const std::vector<Value_type> & source) { + ringbuffer_t rb(source); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + return rb; + } + + std::vector<Value_type> createIntArray(const jau::nsize_t capacity, const Integral_type startValue) { + std::vector<Value_type> array(capacity); + for(jau::nsize_t i=0; i<capacity; i++) { + array[i] = createValue<Integral_type, Value_type>( (Integral_type)( startValue+i )); + } + return array; + } + + void readTestImpl(ringbuffer_t &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, Integral_type startValue) { + (void) clearRef; + + jau::nsize_t preSize = rb.size(); + REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); + REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len); + REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len); + REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); + + for(jau::nsize_t i=0; i<len; i++) { + Value_type svI = getDefault<Value_type>(); + REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI)); + REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(Integral_type)i == getValue<Integral_type, Value_type>(svI)); + } + + REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size()); + REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len); + REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); + } + + void readRangeTestImpl(ringbuffer_t &rb, bool clearRef, jau::nsize_t capacity, jau::nsize_t len, Integral_type startValue) { + (void) clearRef; + + jau::nsize_t preSize = rb.size(); + REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); + REQUIRE_MSG("capacity at read "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len); + REQUIRE_MSG("size at read "+std::to_string(len)+" elems: "+rb.toString(), preSize >= len); + REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); + + std::vector<Value_type> array(len); + REQUIRE_MSG("get-range of "+std::to_string(array.size())+" elem in "+rb.toString(), len==rb.get( &(*array.begin()), len, len) ); + + REQUIRE_MSG("size "+rb.toString(), preSize-len == rb.size()); + REQUIRE_MSG("free slots after reading "+std::to_string(len)+": "+rb.toString(), rb.freeSlots()>= len); + REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); + + for(jau::nsize_t i=0; i<len; i++) { + Value_type svI = array[i]; + REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), startValue+(Integral_type)i == getValue<Integral_type, Value_type>(svI)); + } + } + + void writeTestImpl(ringbuffer_t &rb, jau::nsize_t capacity, jau::nsize_t len, Integral_type startValue) { + jau::nsize_t preSize = rb.size(); + + REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); + REQUIRE_MSG("capacity at write "+std::to_string(len)+" elems: "+rb.toString(), capacity >= len); + REQUIRE_MSG("size at write "+std::to_string(len)+" elems: "+rb.toString(), preSize+len <= capacity); + REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); + + for(jau::nsize_t i=0; i<len; i++) { + std::string m = "buffer put #"+std::to_string(i)+": "+rb.toString(); + REQUIRE_MSG(m, rb.put( createValue<Integral_type, Value_type>( (Integral_type)( startValue+i ) ) ) ); + } + + REQUIRE_MSG("size "+rb.toString(), preSize+len == rb.size()); + REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); + } + + void writeRangeTestImpl(ringbuffer_t &rb, jau::nsize_t capacity, const std::vector<Value_type> & data) { + jau::nsize_t preSize = rb.size(); + jau::nsize_t postSize = preSize+data.size(); + + REQUIRE_MSG("capacity "+rb.toString(), capacity == rb.capacity()); + REQUIRE_MSG("capacity at write "+std::to_string(data.size())+" elems: "+rb.toString(), capacity >= data.size()); + REQUIRE_MSG("size at write "+std::to_string(data.size())+" elems: "+rb.toString(), postSize<= capacity); + REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); + REQUIRE_MSG("data fits in RB capacity "+rb.toString(), rb.capacity() >= data.size()); + REQUIRE_MSG("data fits in RB free-slots "+rb.toString(), rb.freeSlots() >= data.size()); + + REQUIRE_MSG("put-range of "+std::to_string(data.size())+" elem in "+rb.toString(), rb.put( &(*data.begin()), &(*data.end()) ) ); + + REQUIRE_MSG("size "+rb.toString(), postSize == rb.size()); + REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); + } + + void moveGetPutImpl(ringbuffer_t &rb, jau::nsize_t pos) { + REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); + for(jau::nsize_t i=0; i<pos; i++) { + Value_type svI = getDefault<Value_type>(); + REQUIRE_MSG("moveFull.get "+rb.toString(), rb.get(svI)); + REQUIRE_MSG("moveFull.get "+rb.toString(), (Integral_type)i == getValue<Integral_type, Value_type>(svI)); + REQUIRE_MSG("moveFull.put "+rb.toString(), rb.put( createValue<Integral_type, Value_type>( (Integral_type)i ) ) ); + } + } + + void movePutGetImpl(ringbuffer_t &rb, jau::nsize_t pos) { + REQUIRE_MSG("RB is full "+rb.toString(), !rb.isFull()); + for(jau::nsize_t i=0; i<pos; i++) { + REQUIRE_MSG("moveEmpty.put "+rb.toString(), rb.put( createValue<Integral_type, Value_type>( (Integral_type)( 600+i ) ) ) ); + Value_type svI = getDefault<Value_type>(); + REQUIRE_MSG("moveEmpty.get "+rb.toString(), rb.get(svI)); + REQUIRE_MSG("moveEmpty.get "+rb.toString(), 600+(Integral_type)i == getValue<Integral_type, Value_type>(svI)); + } + } + + public: + + void test00_PrintInfo() { + ringbuffer_t rb = createEmpty(11); + + std::string msg("Ringbuffer: uses_memcpy "+std::to_string(ringbuffer_t::uses_memcpy)+ + ", trivially_copyable "+std::to_string(std::is_trivially_copyable<typename ringbuffer_t::value_type>::value)+ + ", size "+std::to_string(sizeof(rb))+" bytes"); + fprintf(stderr, "%s\n", msg.c_str()); + fprintf(stderr, "%s\n", rb.get_info().c_str()); + REQUIRE_MSG("Ringbuffer<T> memmove", ringbuffer_t::uses_memmove == exp_memmove); + REQUIRE_MSG("Ringbuffer<T> memcpy", ringbuffer_t::uses_memcpy == exp_memcpy); + REQUIRE_MSG("Ringbuffer<T> secmem", ringbuffer_t::uses_secmem == exp_secmem); + } + + void test01_FullRead() { + jau::nsize_t capacity = 11; + std::vector<Value_type> source = createIntArray(capacity, 0); + ringbuffer_t rb = createFull(source); + INFO_STR("test01_FullRead: Created / "+ rb.toString()); + REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + readTestImpl(rb, true, capacity, capacity, 0); + INFO_STR("test01_FullRead: PostRead / " + rb.toString()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + } + + void test02_EmptyWrite() { + jau::nsize_t capacity = 11; + ringbuffer_t rb = createEmpty(capacity); + INFO( std::string("test02_EmptyWrite: Created / ") + rb.toString().c_str()); + REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + + writeTestImpl(rb, capacity, capacity, 0); + INFO( std::string("test02_EmptyWrite: PostWrite / ") + rb.toString().c_str()); + REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + readTestImpl(rb, true, capacity, capacity, 0); + INFO( std::string("test02_EmptyWrite: PostRead / ") + rb.toString().c_str()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + } + + void test03_EmptyWriteRange() { + { + jau::nsize_t capacity = 2*11; + ringbuffer_t rb = createEmpty(capacity); + INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str()); + REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + + /** + * Move R == W == 0 + * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start + */ + std::vector<Value_type> new_data = createIntArray(capacity, 0); + writeRangeTestImpl(rb, capacity, new_data); + + INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str()); + REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + readRangeTestImpl(rb, true, capacity, capacity/2, 0); + INFO( std::string("test03_EmptyWriteRange: PostRead-1 / ") + rb.toString().c_str()); + REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); + + readRangeTestImpl(rb, true, capacity, capacity/2, capacity/2); + INFO( std::string("test03_EmptyWriteRange: PostRead-2 / ") + rb.toString().c_str()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + } + { + jau::nsize_t capacity = 2*11; + + ringbuffer_t rb = createEmpty(capacity); + INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str()); + REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + + /** + * Move R == W == 3 + * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start + * Empty [ ][ ][ ][RW][ ][ ][ ][ ][ ][ ][ ] + */ + Value_type dummy; + rb.put(dummy); + rb.put(dummy); + rb.put(dummy); + rb.drop(3); + + std::vector<Value_type> new_data = createIntArray(capacity, 0); + writeRangeTestImpl(rb, capacity, new_data); + // writeTestImpl(rb, capacity, capacity, 0); + + INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str()); + REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + readRangeTestImpl(rb, true, capacity, capacity/2, 0); + INFO( std::string("test03_EmptyWriteRange: PostRead-1 / ") + rb.toString().c_str()); + REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); + + readRangeTestImpl(rb, true, capacity, capacity/2, capacity/2); + INFO( std::string("test03_EmptyWriteRange: PostRead-2 / ") + rb.toString().c_str()); + REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + } + { + jau::nsize_t capacity = 2*11; + ringbuffer_t rb = createEmpty(capacity); + INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str()); + REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + + /** + * Move R == 2, W == 4, size 2 + * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start + * Avail [ ][ ][R][.][W][ ][ ][ ][ ][ ][ ] ; W > R + */ + Value_type dummy; + rb.put(dummy); // r idx 0 -> 1 + rb.put(dummy); + rb.put(dummy); + rb.put(dummy); // r idx 3 -> 4 + rb.drop(2); // r idx 0 -> 2 + + // left = 22 - 2 + REQUIRE_MSG("size 2 "+rb.toString(), 2 == rb.size()); + REQUIRE_MSG("available 11-2 "+rb.toString(), capacity-2 == rb.freeSlots()); + + std::vector<Value_type> new_data = createIntArray(capacity-2, 0); + writeRangeTestImpl(rb, capacity, new_data); + // writeTestImpl(rb, capacity, capacity-2, 0); + + INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str()); + REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + // take off 2 remaining dummies + rb.drop(2); + REQUIRE_MSG("size capacity-2 "+rb.toString(), capacity-2 == rb.size()); + + readRangeTestImpl(rb, true, capacity, capacity/2-2, 0); + INFO( std::string("test03_EmptyWriteRange: PostRead-1 / ") + rb.toString().c_str()); + REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); + + readRangeTestImpl(rb, true, capacity, capacity/2, capacity/2-2); + INFO( std::string("test03_EmptyWriteRange: PostRead-2 / ") + rb.toString().c_str()); + REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + } + { + jau::nsize_t capacity = 2*11; + ringbuffer_t rb = createEmpty(capacity); + INFO( std::string("test03_EmptyWriteRange: Created / ") + rb.toString().c_str()); + REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + + /** + * Move R == 9, W == 1, size 3 + * Empty [RW][][ ][ ][ ][ ][ ][ ][ ][ ][ ] ; start + * Avail [.][W][ ][ ][ ][ ][ ][ ][ ][R][.] ; W < R - 1 + */ + Value_type dummy; + for(jau::nsize_t i=0; i<capacity; i++) { rb.put(dummy); } // fill all + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + // for(int i=0; i<10; i++) { rb.get(); } // pull + rb.drop(capacity-1); // pull + REQUIRE_MSG("size 1"+rb.toString(), 1 == rb.size()); + + for(int i=0; i<2; i++) { rb.put(dummy); } // fill 2 more + REQUIRE_MSG("size 3"+rb.toString(), 3 == rb.size()); + + // left = 22 - 3 + REQUIRE_MSG("available 22-3 "+rb.toString(), capacity-3 == rb.freeSlots()); + + std::vector<Value_type> new_data = createIntArray(capacity-3, 0); + writeRangeTestImpl(rb, capacity, new_data); + // writeTestImpl(rb, capacity, capacity-3, 0); + + INFO( std::string("test03_EmptyWriteRange: PostWrite / ") + rb.toString().c_str()); + REQUIRE_MSG("full size "+rb.toString(), capacity == rb.size()); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + // take off 3 remaining dummies + rb.drop(3); // pull + // for(int i=0; i<3; i++) { rb.get(); } // pull + REQUIRE_MSG("size capacity-3 "+rb.toString(), capacity-3 == rb.size()); + + readRangeTestImpl(rb, true, capacity, capacity/2-3, 0); + INFO( std::string("test03_EmptyWriteRange: PostRead-1 / ") + rb.toString().c_str()); + REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); + + readRangeTestImpl(rb, true, capacity, capacity/2, capacity/2-3); + INFO( std::string("test03_EmptyWriteRange: PostRead-2 / ") + rb.toString().c_str()); + REQUIRE_MSG("size 0 "+rb.toString(), 0 == rb.size()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + } + } + + void test04_FullReadReset() { + jau::nsize_t capacity = 11; + std::vector<Value_type> source = createIntArray(capacity, 0); + ringbuffer_t rb = createFull(source); + INFO_STR("test04_FullReadReset: Created / " + rb.toString()); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + rb.reset(source); + INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString()); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + readTestImpl(rb, false, capacity, capacity, 0); + INFO_STR("test04_FullReadReset: Post Read / " + rb.toString()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + + rb.reset(source); + INFO_STR("test04_FullReadReset: Post Reset w/ source / " + rb.toString()); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + readTestImpl(rb, false, capacity, capacity, 0); + INFO_STR("test04_FullReadReset: Post Read / " + rb.toString()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + } + + void test05_EmptyWriteClear() { + jau::nsize_t capacity = 11; + ringbuffer_t rb = createEmpty(capacity); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + + rb.clear(); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + + writeTestImpl(rb, capacity, capacity, 0); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + readTestImpl(rb, false, capacity, capacity, 0); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + + rb.clear(); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + + writeTestImpl(rb, capacity, capacity, 0); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + readTestImpl(rb, false, capacity, capacity, 0); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + } + + void test06_ReadResetMid01() { + jau::nsize_t capacity = 11; + std::vector<Value_type> source = createIntArray(capacity, 0); + ringbuffer_t rb = createFull(source); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + rb.reset(source); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + readTestImpl(rb, false, capacity, 5, 0); + REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); + REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull()); + + rb.reset(source); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + readTestImpl(rb, false, capacity, capacity, 0); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + } + + void test07_ReadResetMid02() { + jau::nsize_t capacity = 11; + std::vector<Value_type> source = createIntArray(capacity, 0); + ringbuffer_t rb = createFull(source); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + rb.reset(source); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + moveGetPutImpl(rb, 5); + readTestImpl(rb, false, capacity, 5, 5); + REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); + REQUIRE_MSG("not Full "+rb.toString(), !rb.isFull()); + + rb.reset(source); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + readTestImpl(rb, false, capacity, capacity, 0); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + } + + private: + + void test_GrowFullImpl(jau::nsize_t initialCapacity, jau::nsize_t pos) { + jau::nsize_t growAmount = 5; + jau::nsize_t grownCapacity = initialCapacity+growAmount; + std::vector<Value_type> source = createIntArray(initialCapacity, 0); + ringbuffer_t rb = createFull(source); + + for(jau::nsize_t i=0; i<initialCapacity; i++) { + Value_type svI = getDefault<Value_type>(); + REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI)); + REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), Integral_type((0+i)%initialCapacity) == getValue<Integral_type, Value_type>(svI)); + } + REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); + + rb.reset(source); + REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.size()); + + moveGetPutImpl(rb, pos); + // PRINTM("X02 "+rb.toString()); + // rb.dump(stderr, "X02"); + + rb.recapacity(grownCapacity); + REQUIRE_MSG("capacity "+rb.toString(), grownCapacity == rb.capacity()); + REQUIRE_MSG("orig size "+rb.toString(), initialCapacity == rb.size()); + REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); + REQUIRE_MSG("not empty "+rb.toString(), !rb.isEmpty()); + // PRINTM("X03 "+rb.toString()); + // rb.dump(stderr, "X03"); + + for(jau::nsize_t i=0; i<growAmount; i++) { + REQUIRE_MSG("buffer not full at put #"+std::to_string(i)+": "+rb.toString(), rb.put( createValue<Integral_type, Value_type>( (Integral_type)(100+i) ) ) ); + } + REQUIRE_MSG("new size "+rb.toString(), grownCapacity == rb.size()); + REQUIRE_MSG("full "+rb.toString(), rb.isFull()); + + for(jau::nsize_t i=0; i<initialCapacity; i++) { + Value_type svI = getDefault<Value_type>(); + REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI)); + REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), Integral_type((pos+i)%initialCapacity) == getValue<Integral_type, Value_type>(svI)); + } + + for(jau::nsize_t i=0; i<growAmount; i++) { + Value_type svI = getDefault<Value_type>(); + REQUIRE_MSG("not empty at read #"+std::to_string(i+1)+": "+rb.toString(), rb.get(svI)); + REQUIRE_MSG("value at read #"+std::to_string(i+1)+": "+rb.toString(), Integral_type(100+i) == getValue<Integral_type, Value_type>(svI)); + } + + REQUIRE_MSG("zero size "+rb.toString(), 0 == rb.size()); + REQUIRE_MSG("empty "+rb.toString(), rb.isEmpty()); + + REQUIRE_MSG("not full "+rb.toString(), !rb.isFull()); + } + + public: + + void test20_GrowFull01_Begin() { + test_GrowFullImpl(11, 0); + } + void test21_GrowFull02_Begin1() { + test_GrowFullImpl(11, 0+1); + } + void test22_GrowFull03_Begin2() { + test_GrowFullImpl(11, 0+2); + } + void test23_GrowFull04_Begin3() { + test_GrowFullImpl(11, 0+3); + } + void test24_GrowFull05_End() { + test_GrowFullImpl(11, 11-1); + } + void test25_GrowFull11_End1() { + test_GrowFullImpl(11, 11-1-1); + } + void test26_GrowFull12_End2() { + test_GrowFullImpl(11, 11-1-2); + } + void test27_GrowFull13_End3() { + test_GrowFullImpl(11, 11-1-3); + } + +}; + |