summaryrefslogtreecommitdiff
path: root/lib/cpp
diff options
context:
space:
mode:
authorChristopher Friedt <chrisfriedt@gmail.com>2020-06-18 21:50:54 -0400
committerJens Geyer <Jens-G@users.noreply.github.com>2022-04-19 18:51:18 +0200
commitedcad983d9896adc559f7305549492db85629f4c (patch)
tree05bf6dbddaaac0e09ec66156e6916b6f6c044192 /lib/cpp
parent5d220eb3321aa571b316da942feb72c29c7386c1 (diff)
downloadthrift-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.cpp252
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;