diff options
Diffstat (limited to 'sax/tst/test_buffer.cc')
| -rw-r--r-- | sax/tst/test_buffer.cc | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/sax/tst/test_buffer.cc b/sax/tst/test_buffer.cc new file mode 100644 index 0000000..13bc6d4 --- /dev/null +++ b/sax/tst/test_buffer.cc @@ -0,0 +1,272 @@ +#include "buffer.hh" + +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +namespace { + +enum class BufferType { + FIXED, + DYNAMIC, +}; + +class BufferTest : public testing::TestWithParam<BufferType> { + protected: + std::unique_ptr<modxml::sax::Buffer> make_buffer(std::size_t size) { + switch (GetParam()) { + case BufferType::FIXED: + return modxml::sax::make_buffer(size, size); + case BufferType::DYNAMIC: + return modxml::sax::make_buffer(size / 2, size); + } + return nullptr; + } +}; + +std::array<uint8_t, 10> AAAAAAAAAA{ + 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'}; +std::array<uint8_t, 5> BBBBB{ + 'B', 'B', 'B', 'B', 'B'}; + +} // namespace + +TEST_P(BufferTest, sanity) { + auto buf = make_buffer(10); + EXPECT_TRUE(buf->empty()); + EXPECT_FALSE(buf->full()); + + EXPECT_TRUE(buf->write_all(AAAAAAAAAA)); + EXPECT_TRUE(buf->full()); + EXPECT_FALSE(buf->empty()); + + EXPECT_FALSE(buf->write_all(AAAAAAAAAA)); + + std::array<uint8_t, 10> tmp10; + EXPECT_TRUE(buf->read_all(tmp10)); + EXPECT_THAT(tmp10, testing::ContainerEq(AAAAAAAAAA)); + EXPECT_TRUE(buf->empty()); + EXPECT_FALSE(buf->full()); + + EXPECT_TRUE(buf->write_all(BBBBB)); + EXPECT_FALSE(buf->full()); + EXPECT_FALSE(buf->empty()); + + EXPECT_EQ(5u, buf->write(AAAAAAAAAA)); + EXPECT_TRUE(buf->full()); + EXPECT_FALSE(buf->empty()); + + std::array<uint8_t, 3> tmp3; + EXPECT_TRUE(buf->read_all(tmp3)); + EXPECT_THAT(tmp3, testing::ElementsAre('B', 'B', 'B')); + + EXPECT_EQ(3u, buf->write(BBBBB)); + + EXPECT_TRUE(buf->read_all(tmp3)); + EXPECT_THAT(tmp3, testing::ElementsAre('B', 'B', 'A')); + + std::array<uint8_t, 5> tmp5; + EXPECT_TRUE(buf->read_all(tmp5)); + EXPECT_THAT(tmp5, testing::ElementsAre('A', 'A', 'A', 'A', 'B')); + + EXPECT_FALSE(buf->read_all(tmp3)); + tmp3[2] = 'X'; + EXPECT_EQ(2u, buf->read(tmp3)); + EXPECT_THAT(tmp3, testing::ElementsAre('B', 'B', 'X')); +} + +TEST_P(BufferTest, noop) { + auto buf = make_buffer(10); + EXPECT_TRUE(buf->empty()); + + std::array<uint8_t, 0> empty; + EXPECT_EQ(0u, buf->write(empty)); + EXPECT_EQ(0u, buf->read(empty)); + + EXPECT_TRUE(buf->write_all(empty)); + EXPECT_TRUE(buf->read_all(empty)); + + buf->commit(0); + buf->consume(0); + + EXPECT_TRUE(buf->empty()); +} + +TEST_P(BufferTest, one_byte_filler) { + auto buf = make_buffer(10); + + std::array<uint8_t, 1> tmp1; + uint8_t out = 0; + for (uint8_t in = 0; in <= 20; ++in) { + tmp1[0] = in; + EXPECT_TRUE(buf->write_all(tmp1)); + if (in >= 9) { + EXPECT_TRUE(buf->read_all(tmp1)); + EXPECT_EQ(tmp1[0], out); + ++out; + } + } + for (; out <= 20; ++out) { + EXPECT_TRUE(buf->read_all(tmp1)); + EXPECT_EQ(tmp1[0], out); + } + EXPECT_TRUE(buf->empty()); +} + +TEST_P(BufferTest, read_wrap) { + auto buf = make_buffer(10); + + EXPECT_TRUE(buf->write_all(BBBBB)); + EXPECT_EQ(5u, buf->write(AAAAAAAAAA)); + + std::array<uint8_t, 5> tmp5; + EXPECT_TRUE(buf->read_all(tmp5)); + EXPECT_THAT(tmp5, testing::ContainerEq(BBBBB)); + + EXPECT_EQ(5u, buf->write(AAAAAAAAAA)); + + std::array<uint8_t, 10> tmp10; + EXPECT_TRUE(buf->read_all(tmp10)); + EXPECT_THAT(tmp10, testing::ContainerEq(AAAAAAAAAA)); +} + +TEST_P(BufferTest, skip_wrap) { + auto buf = make_buffer(10); + + EXPECT_TRUE(buf->write_all(BBBBB)); + EXPECT_EQ(5u, buf->write(AAAAAAAAAA)); + + buf->consume(5); + EXPECT_FALSE(buf->empty()); + + EXPECT_EQ(5u, buf->write(AAAAAAAAAA)); + + buf->consume(10); + EXPECT_TRUE(buf->empty()); +} + +TEST_P(BufferTest, write_wrap) { + auto buf = make_buffer(12); + + EXPECT_TRUE(buf->write_all(BBBBB)); + + std::array<uint8_t, 3> tmp3; + EXPECT_TRUE(buf->read_all(tmp3)); + EXPECT_THAT(tmp3, testing::ElementsAre('B', 'B', 'B')); + + EXPECT_TRUE(buf->write_all(AAAAAAAAAA)); + + std::array<uint8_t, 12> tmp12; + EXPECT_EQ(12u, buf->read(tmp12)); + EXPECT_THAT(tmp12, testing::ElementsAre( + 'B', 'B', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A')); +} + +TEST_P(BufferTest, read_wrap2) { + auto buf = make_buffer(12); + + EXPECT_TRUE(buf->write_all(AAAAAAAAAA)); + + std::array<uint8_t, 7> tmp7; + EXPECT_TRUE(buf->read_all(tmp7)); + EXPECT_THAT(tmp7, testing::ElementsAre('A', 'A', 'A', 'A', 'A', 'A', 'A')); + + EXPECT_EQ(5u, buf->write(BBBBB)); + EXPECT_EQ(4u, buf->write(BBBBB)); + + std::array<uint8_t, 12> tmp12; + EXPECT_TRUE(buf->read_all(tmp12)); + EXPECT_THAT(tmp12, testing::ElementsAre( + 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B')); +} + +TEST(Buffer, dynamic_resize) { + auto buf = modxml::sax::make_buffer(10, 1000); + + std::array<uint8_t, 30> tmp30; + for (uint8_t i = 0; i < 30; ++i) + tmp30[i] = i; + + EXPECT_TRUE(buf->write_all(tmp30)); + EXPECT_TRUE(buf->write_all(tmp30)); + + std::array<uint8_t, 60> tmp60; + EXPECT_TRUE(buf->read_all(tmp60)); + for (uint8_t i = 0; i < 60; ++i) + EXPECT_EQ(i % 30, tmp60[i]) << i; +} + +TEST(Buffer, dynamic_overalloc) { + // This test can fail, but in most configurations trying to allocate + // std::numeric_limits<std::size_t>::max() will fail. + auto buf = modxml::sax::make_buffer(10, std::numeric_limits<std::size_t>::max()); + EXPECT_FALSE(buf->wspan(10000).empty()); + EXPECT_TRUE(buf->wspan(std::numeric_limits<std::size_t>::max()).empty()); +} + +TEST_P(BufferTest, modify) { + auto buf = make_buffer(10); + + EXPECT_TRUE(buf->write_all(AAAAAAAAAA)); + + auto span = buf->mspan(5); + EXPECT_EQ(10u, span.size()); + auto len = std::min(static_cast<std::size_t>(5), span.size()); + for (uint8_t i = 0; i < len; ++i) + span[i] = 'C'; + + std::array<uint8_t, 10> tmp10; + EXPECT_TRUE(buf->read_all(tmp10)); + EXPECT_THAT(tmp10, testing::ElementsAre( + 'C', 'C', 'C', 'C', 'C', 'A', 'A', 'A', 'A', 'A')); +} + +TEST_P(BufferTest, uncommit) { + auto buf = make_buffer(10); + + EXPECT_TRUE(buf->write_all(BBBBB)); + + EXPECT_EQ(0u, buf->uncommit(0)); + + EXPECT_EQ(5u, buf->write(AAAAAAAAAA)); + + std::array<uint8_t, 2> tmp2; + EXPECT_TRUE(buf->read_all(tmp2)); + EXPECT_THAT(tmp2, testing::ElementsAre('B', 'B')); + + EXPECT_EQ(3u, buf->uncommit(3)); + std::array<uint8_t, 5> tmp5; + EXPECT_TRUE(buf->read_all(tmp5)); + EXPECT_THAT(tmp5, testing::ElementsAre('B', 'B', 'B', 'A', 'A')); + + EXPECT_EQ(0u, buf->uncommit(2)); +} + +TEST_P(BufferTest, uncommit_wrap) { + auto buf = make_buffer(10); + + EXPECT_TRUE(buf->write_all(AAAAAAAAAA)); + std::array<uint8_t, 5> tmp5; + EXPECT_TRUE(buf->read_all(tmp5)); + + EXPECT_TRUE(buf->write_all(BBBBB)); + + EXPECT_EQ(8u, buf->uncommit(8)); + std::array<uint8_t, 2> tmp2; + EXPECT_TRUE(buf->read_all(tmp2)); + EXPECT_THAT(tmp2, testing::ElementsAre('A', 'A')); +} + +INSTANTIATE_TEST_SUITE_P( + BufferTests, + BufferTest, + testing::Values(BufferType::FIXED, BufferType::DYNAMIC), + [](auto& info) { + switch (info.param) { + case BufferType::FIXED: + return "fixed"; + case BufferType::DYNAMIC: + return "dynamic"; + } + return ""; + } +); |
