diff options
author | Christopher Friedt <chrisfriedt@gmail.com> | 2020-06-18 21:50:54 -0400 |
---|---|---|
committer | Jens Geyer <Jens-G@users.noreply.github.com> | 2022-04-19 18:51:18 +0200 |
commit | edcad983d9896adc559f7305549492db85629f4c (patch) | |
tree | 05bf6dbddaaac0e09ec66156e6916b6f6c044192 /lib/cpp | |
parent | 5d220eb3321aa571b316da942feb72c29c7386c1 (diff) | |
download | thrift-edcad983d9896adc559f7305549492db85629f4c.tar.gz |
THRIFT-5093: lib: cpp: test: clarify effect of MemoryPolicy on TMemoryBuffer
Client: cpp
Tests to clarify the effect of each MemoryPolicy on TMemoryBuffer.
Signed-off-by: Christopher Friedt <chrisfriedt@gmail.com>
Diffstat (limited to 'lib/cpp')
-rw-r--r-- | lib/cpp/test/TMemoryBufferTest.cpp | 252 |
1 files changed, 249 insertions, 3 deletions
diff --git a/lib/cpp/test/TMemoryBufferTest.cpp b/lib/cpp/test/TMemoryBufferTest.cpp index 759aa0c9b..0ae4dc9ad 100644 --- a/lib/cpp/test/TMemoryBufferTest.cpp +++ b/lib/cpp/test/TMemoryBufferTest.cpp @@ -17,13 +17,17 @@ * under the License. */ +#include <array> #include <boost/test/unit_test.hpp> -#include <iostream> #include <climits> -#include <vector> -#include <thrift/protocol/TBinaryProtocol.h> +#include <cstdlib> +#include <iostream> #include <memory> +#include <numeric> +#include <thrift/protocol/TBinaryProtocol.h> #include <thrift/transport/TBufferTransports.h> +#include <vector> + #include "gen-cpp/ThriftTest_types.h" BOOST_AUTO_TEST_SUITE(TMemoryBufferTest) @@ -125,6 +129,248 @@ BOOST_AUTO_TEST_CASE(test_error_set_max_buffer_size_too_small) BOOST_CHECK_THROW(buf.setMaxBufferSize(buf.getBufferSize() - 1), TTransportException); } +BOOST_AUTO_TEST_CASE(test_observe) { +#ifdef _MSC_VER + #define N 73 +#else + constexpr size_t N = 73; +#endif + constexpr size_t M = 42; + uint8_t one_byte = 42; + std::vector<uint8_t> scratch; + auto filler = [=]() { + std::array<uint8_t, N> x; + // Fill buf_mem with a sequence from 0 to N - 1 + std::iota(x.begin(), x.end(), 0); + return x; + }; + static const std::array<uint8_t, N> buf_mem = filler(); + + BOOST_STATIC_ASSERT(M < N); + + TMemoryBuffer buf((uint8_t*)&buf_mem.front(), N, TMemoryBuffer::MemoryPolicy::OBSERVE); + + // Readable + BOOST_CHECK_EQUAL(N, buf.available_read()); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + // Not writeable + BOOST_CHECK_THROW(buf.write(&one_byte, 1), TTransportException); + + // Read some but not all + scratch.resize(M); + BOOST_CHECK_EQUAL(M, buf.read(&scratch[0], M)); + // Check remaining + BOOST_CHECK_EQUAL(N - M, buf.available_read()); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + // Not writeable + BOOST_CHECK_THROW(buf.write(&one_byte, 1), TTransportException); + // Contents + BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), buf_mem.begin(), + buf_mem.begin() + M); + + // Readable (drain remaining) + scratch.resize(N); + BOOST_CHECK_EQUAL(N - M, buf.read(&scratch[M], N - M)); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + // Not writeable + BOOST_CHECK_THROW(buf.write(&one_byte, 1), TTransportException); + // Contents + BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), buf_mem.begin(), buf_mem.end()); + + // Not readable + BOOST_CHECK_EQUAL(0, buf.read(&one_byte, 1)); + BOOST_CHECK_EQUAL(0, buf.available_read()); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + // Not writeable + BOOST_CHECK_THROW(buf.write(&one_byte, 1), TTransportException); + + /* OBSERVE buffer cannot be reread with the default reset */ + + buf.resetBuffer(); + // Not Readable + BOOST_CHECK_EQUAL(0, buf.available_read()); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + // Not writeable + BOOST_CHECK_THROW(buf.write(&one_byte, 1), TTransportException); + + /* OBSERVE buffers do not auto-resize when written to (implicit) */ + /* OBSERVE buffers can be appended-to (implicit) */ +} + +BOOST_AUTO_TEST_CASE(test_copy) { +#ifdef _MSC_VER + #define N 73 +#else + constexpr size_t N = 73; +#endif + constexpr size_t M = 42; + uint8_t one_byte = 42; + std::vector<uint8_t> scratch; + auto filler = [&]() { + std::array<uint8_t, N> x; + // Fill buf_mem with a sequence from 0 to N - 1 + std::iota(x.begin(), x.end(), 0); + return x; + }; + static const std::array<uint8_t, N> buf_mem = filler(); + + BOOST_STATIC_ASSERT(M < N); + + TMemoryBuffer buf((uint8_t*)&buf_mem.front(), N, TMemoryBuffer::MemoryPolicy::COPY); + + // Readable + BOOST_CHECK_EQUAL(N, buf.available_read()); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + + // Read some but not all + scratch.resize(M); + BOOST_CHECK_EQUAL(M, buf.read(&scratch[0], M)); + // Check remaining + BOOST_CHECK_EQUAL(N - M, buf.available_read()); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + // Contents + BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), buf_mem.begin(), + buf_mem.begin() + M); + + // Readable (drain remaining) + scratch.resize(N); + BOOST_CHECK_EQUAL(N - M, buf.read(&scratch[M], N - M)); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + // Contents + BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), buf_mem.begin(), buf_mem.end()); + + // Not readable + BOOST_CHECK_EQUAL(0, buf.read(&one_byte, 1)); + BOOST_CHECK_EQUAL(0, buf.available_read()); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + + /* COPY buffer cannot be reread with the default reset */ + + buf.resetBuffer(); + // Not readable + BOOST_CHECK_EQUAL(0, buf.available_read()); + // Has available write space + BOOST_CHECK_EQUAL(N, buf.available_write()); + + /* COPY buffers auto-resize when written to */ + + // Not readable + BOOST_CHECK_EQUAL(0, buf.read(&one_byte, 1)); + BOOST_CHECK_EQUAL(0, buf.available_read()); + // No available write space + BOOST_CHECK_GT(buf.available_write(), 0); + // Writeable + one_byte = M; + BOOST_CHECK_NO_THROW(buf.write(&one_byte, 1)); + // Readable + one_byte = 0xff; + BOOST_CHECK_EQUAL(1, buf.read(&one_byte, 1)); + BOOST_CHECK_EQUAL(one_byte, M); + + /* COPY buffers can be appended-to (and auto-resize) */ + + buf.resetBuffer((uint8_t*)&buf_mem.front(), N, TMemoryBuffer::MemoryPolicy::COPY); + // Appendable + one_byte = N + 1; + BOOST_CHECK_NO_THROW(buf.write(&one_byte, 1)); + BOOST_CHECK_EQUAL(N, buf.read(&scratch[0], N)); + BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), buf_mem.begin(), + buf_mem.begin() + N); + one_byte = 0xff; + BOOST_CHECK_EQUAL(1, buf.read(&one_byte, 1)); + BOOST_CHECK_EQUAL(one_byte, N + 1); +} + +BOOST_AUTO_TEST_CASE(test_take_ownership) +{ +#ifdef _MSC_VER + #define N 73 +#else + constexpr size_t N = 73; +#endif + constexpr size_t M = 42; + uint8_t one_byte = 42; + std::vector<uint8_t> scratch; + auto filler = [&]() { + /* TAKE_OWNERSHIP buffers MUST be malloc'ed */ + uint8_t* x = static_cast<uint8_t*>(malloc(N)); + // Fill buf_mem with a sequence from 0 to N - 1 + std::iota(&x[0], &x[N], 0); + return x; + }; + uint8_t* buf_mem = filler(); + + BOOST_STATIC_ASSERT(M < N); + + TMemoryBuffer buf(buf_mem, N, TMemoryBuffer::MemoryPolicy::TAKE_OWNERSHIP); + + // Readable + BOOST_CHECK_EQUAL(N, buf.available_read()); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + + // Read some but not all + scratch.resize(M); + BOOST_CHECK_EQUAL(M, buf.read(&scratch[0], M)); + // Check remaining + BOOST_CHECK_EQUAL(N - M, buf.available_read()); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + // Contents + BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), &buf_mem[0], &buf_mem[M]); + + // Readable (drain remaining) + scratch.resize(N); + BOOST_CHECK_EQUAL(N - M, buf.read(&scratch[M], N - M)); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + // Contents + BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), &buf_mem[0], &buf_mem[N]); + + // Not readable + BOOST_CHECK_EQUAL(0, buf.read(&one_byte, 1)); + BOOST_CHECK_EQUAL(0, buf.available_read()); + // No available write space + BOOST_CHECK_EQUAL(0, buf.available_write()); + + /* TAKE_OWNERSHIP buffers auto-resize when written to */ + + // Not readable + BOOST_CHECK_EQUAL(0, buf.read(&one_byte, 1)); + BOOST_CHECK_EQUAL(0, buf.available_read()); + // No available write space + BOOST_CHECK_EQUAL(buf.available_write(), 0); + // Writeable + one_byte = M; + BOOST_CHECK_NO_THROW(buf.write(&one_byte, 1)); + // Readable + one_byte = 0xff; + BOOST_CHECK_EQUAL(1, buf.read(&one_byte, 1)); + BOOST_CHECK_EQUAL(one_byte, M); + + /* TAKE_OWNERSHIP buffers can be appended-to (and auto-resize) */ + + buf_mem = filler(); + buf.resetBuffer(buf_mem, N, TMemoryBuffer::MemoryPolicy::COPY); + // Appendable + one_byte = N + 1; + BOOST_CHECK_NO_THROW(buf.write(&one_byte, 1)); + BOOST_CHECK_EQUAL(N, buf.read(&scratch[0], N)); + BOOST_CHECK_EQUAL_COLLECTIONS(scratch.begin(), scratch.end(), &buf_mem[0], &buf_mem[N]); + one_byte = 0xff; + BOOST_CHECK_EQUAL(1, buf.read(&one_byte, 1)); + BOOST_CHECK_EQUAL(one_byte, N + 1); +} + BOOST_AUTO_TEST_CASE(test_maximum_buffer_size) { TMemoryBuffer buf; |