buffer_unittest.cc 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. // Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <exceptions/exceptions.h>
  15. #include <util/buffer.h>
  16. #include <gtest/gtest.h>
  17. using namespace isc;
  18. namespace {
  19. using isc::util::InputBuffer;
  20. using isc::util::OutputBuffer;
  21. class BufferTest : public ::testing::Test {
  22. protected:
  23. BufferTest() : ibuffer(testdata, sizeof(testdata)), obuffer(0),
  24. expected_size(0)
  25. {
  26. data16 = (2 << 8) | 3;
  27. data32 = (4 << 24) | (5 << 16) | (6 << 8) | 7;
  28. memset(vdata, 0, sizeof(testdata));
  29. }
  30. InputBuffer ibuffer;
  31. OutputBuffer obuffer;
  32. static const uint8_t testdata[5];
  33. uint8_t vdata[sizeof(testdata)];
  34. size_t expected_size;
  35. uint16_t data16;
  36. uint32_t data32;
  37. };
  38. const uint8_t BufferTest::testdata[5] = {1, 2, 3, 4, 5};
  39. TEST_F(BufferTest, inputBufferRead) {
  40. EXPECT_EQ(5, ibuffer.getLength());
  41. EXPECT_EQ(1, ibuffer.readUint8());
  42. EXPECT_EQ(1, ibuffer.getPosition());
  43. data16 = ibuffer.readUint16();
  44. EXPECT_EQ((2 << 8) | 3, data16);
  45. EXPECT_EQ(3, ibuffer.getPosition());
  46. ibuffer.setPosition(1);
  47. EXPECT_EQ(1, ibuffer.getPosition());
  48. data32 = ibuffer.readUint32();
  49. EXPECT_EQ((2 << 24) | (3 << 16) | (4 << 8) | 5, data32);
  50. ibuffer.setPosition(0);
  51. memset(vdata, 0, sizeof(vdata));
  52. ibuffer.readData(vdata, sizeof(vdata));
  53. EXPECT_EQ(0, memcmp(vdata, testdata, sizeof(testdata)));
  54. }
  55. TEST_F(BufferTest, inputBufferException) {
  56. EXPECT_THROW(ibuffer.setPosition(6), isc::util::InvalidBufferPosition);
  57. ibuffer.setPosition(sizeof(testdata));
  58. EXPECT_THROW(ibuffer.readUint8(), isc::util::InvalidBufferPosition);
  59. ibuffer.setPosition(sizeof(testdata) - 1);
  60. EXPECT_THROW(ibuffer.readUint16(), isc::util::InvalidBufferPosition);
  61. ibuffer.setPosition(sizeof(testdata) - 3);
  62. EXPECT_THROW(ibuffer.readUint32(), isc::util::InvalidBufferPosition);
  63. ibuffer.setPosition(sizeof(testdata) - 4);
  64. EXPECT_THROW(ibuffer.readData(vdata, sizeof(vdata)),
  65. isc::util::InvalidBufferPosition);
  66. }
  67. TEST_F(BufferTest, outputBufferExtend) {
  68. EXPECT_EQ(0, obuffer.getCapacity());
  69. EXPECT_EQ(0, obuffer.getLength());
  70. obuffer.writeUint8(10);
  71. EXPECT_LT(0, obuffer.getCapacity());
  72. EXPECT_EQ(1, obuffer.getLength());
  73. }
  74. TEST_F(BufferTest, outputBufferWrite) {
  75. const uint8_t* cp;
  76. obuffer.writeUint8(1);
  77. expected_size += sizeof(uint8_t);
  78. EXPECT_EQ(expected_size, obuffer.getLength());
  79. cp = static_cast<const uint8_t*>(obuffer.getData());
  80. EXPECT_EQ(1, *cp);
  81. obuffer.writeUint16(data16);
  82. expected_size += sizeof(data16);
  83. cp = static_cast<const uint8_t*>(obuffer.getData());
  84. EXPECT_EQ(expected_size, obuffer.getLength());
  85. EXPECT_EQ(2, *(cp + 1));
  86. EXPECT_EQ(3, *(cp + 2));
  87. obuffer.writeUint32(data32);
  88. expected_size += sizeof(data32);
  89. cp = static_cast<const uint8_t*>(obuffer.getData());
  90. EXPECT_EQ(expected_size, obuffer.getLength());
  91. EXPECT_EQ(4, *(cp + 3));
  92. EXPECT_EQ(5, *(cp + 4));
  93. EXPECT_EQ(6, *(cp + 5));
  94. EXPECT_EQ(7, *(cp + 6));
  95. obuffer.writeData(testdata, sizeof(testdata));
  96. expected_size += sizeof(testdata);
  97. EXPECT_EQ(expected_size, obuffer.getLength());
  98. cp = static_cast<const uint8_t*>(obuffer.getData());
  99. EXPECT_EQ(0, memcmp(cp + 7, testdata, sizeof(testdata)));
  100. }
  101. TEST_F(BufferTest, outputBufferWriteat) {
  102. obuffer.writeUint32(data32);
  103. expected_size += sizeof(data32);
  104. // overwrite 2nd byte
  105. obuffer.writeUint8At(4, 1);
  106. EXPECT_EQ(expected_size, obuffer.getLength()); // length shouldn't change
  107. const uint8_t* cp = static_cast<const uint8_t*>(obuffer.getData());
  108. EXPECT_EQ(4, *(cp + 1));
  109. // overwrite 2nd and 3rd bytes
  110. obuffer.writeUint16At(data16, 1);
  111. EXPECT_EQ(expected_size, obuffer.getLength()); // length shouldn't change
  112. cp = static_cast<const uint8_t*>(obuffer.getData());
  113. EXPECT_EQ(2, *(cp + 1));
  114. EXPECT_EQ(3, *(cp + 2));
  115. // overwrite 3rd and 4th bytes
  116. obuffer.writeUint16At(data16, 2);
  117. EXPECT_EQ(expected_size, obuffer.getLength());
  118. cp = static_cast<const uint8_t*>(obuffer.getData());
  119. EXPECT_EQ(2, *(cp + 2));
  120. EXPECT_EQ(3, *(cp + 3));
  121. EXPECT_THROW(obuffer.writeUint8At(data16, 5),
  122. isc::util::InvalidBufferPosition);
  123. EXPECT_THROW(obuffer.writeUint8At(data16, 4),
  124. isc::util::InvalidBufferPosition);
  125. EXPECT_THROW(obuffer.writeUint16At(data16, 3),
  126. isc::util::InvalidBufferPosition);
  127. EXPECT_THROW(obuffer.writeUint16At(data16, 4),
  128. isc::util::InvalidBufferPosition);
  129. EXPECT_THROW(obuffer.writeUint16At(data16, 5),
  130. isc::util::InvalidBufferPosition);
  131. }
  132. TEST_F(BufferTest, outputBufferSkip) {
  133. obuffer.skip(4);
  134. EXPECT_EQ(4, obuffer.getLength());
  135. obuffer.skip(2);
  136. EXPECT_EQ(6, obuffer.getLength());
  137. }
  138. TEST_F(BufferTest, outputBufferTrim) {
  139. obuffer.writeData(testdata, sizeof(testdata));
  140. EXPECT_EQ(5, obuffer.getLength());
  141. obuffer.trim(1);
  142. EXPECT_EQ(4, obuffer.getLength());
  143. obuffer.trim(2);
  144. EXPECT_EQ(2, obuffer.getLength());
  145. EXPECT_THROW(obuffer.trim(3), OutOfRange);
  146. }
  147. TEST_F(BufferTest, outputBufferReadat) {
  148. obuffer.writeData(testdata, sizeof(testdata));
  149. for (int i = 0; i < sizeof(testdata); i ++) {
  150. EXPECT_EQ(testdata[i], obuffer[i]);
  151. }
  152. EXPECT_THROW(obuffer[sizeof(testdata)], isc::util::InvalidBufferPosition);
  153. }
  154. TEST_F(BufferTest, outputBufferClear) {
  155. obuffer.writeData(testdata, sizeof(testdata));
  156. obuffer.clear();
  157. EXPECT_EQ(0, obuffer.getLength());
  158. }
  159. TEST_F(BufferTest, outputBufferCopy) {
  160. obuffer.writeData(testdata, sizeof(testdata));
  161. EXPECT_NO_THROW({
  162. OutputBuffer copy(obuffer);
  163. ASSERT_EQ(sizeof(testdata), copy.getLength());
  164. for (int i = 0; i < sizeof(testdata); i ++) {
  165. EXPECT_EQ(testdata[i], copy[i]);
  166. if (i + 1 < sizeof(testdata)) {
  167. obuffer.writeUint16At(0, i);
  168. }
  169. EXPECT_EQ(testdata[i], copy[i]);
  170. }
  171. obuffer.clear();
  172. ASSERT_EQ(sizeof(testdata), copy.getLength());
  173. });
  174. }
  175. TEST_F(BufferTest, outputBufferAssign) {
  176. OutputBuffer another(0);
  177. another.clear();
  178. obuffer.writeData(testdata, sizeof(testdata));
  179. EXPECT_NO_THROW({
  180. another = obuffer;
  181. ASSERT_EQ(sizeof(testdata), another.getLength());
  182. for (int i = 0; i < sizeof(testdata); i ++) {
  183. EXPECT_EQ(testdata[i], another[i]);
  184. if (i + 1 < sizeof(testdata)) {
  185. obuffer.writeUint16At(0, i);
  186. }
  187. EXPECT_EQ(testdata[i], another[i]);
  188. }
  189. obuffer.clear();
  190. ASSERT_EQ(sizeof(testdata), another.getLength());
  191. });
  192. }
  193. TEST_F(BufferTest, outputBufferZeroSize) {
  194. // Some OSes might return NULL on malloc for 0 size, so check it works
  195. EXPECT_NO_THROW({
  196. OutputBuffer first(0);
  197. OutputBuffer copy(first);
  198. OutputBuffer second(0);
  199. second = first;
  200. });
  201. }
  202. TEST_F(BufferTest, inputBufferReadVectorAll) {
  203. std::vector<uint8_t> vec;
  204. // check that vector can read the whole buffer
  205. ibuffer.readVector(vec, 5);
  206. ASSERT_EQ(5, vec.size());
  207. EXPECT_EQ(0, memcmp(&vec[0], testdata, 5));
  208. // ibuffer is 5 bytes long. Can't read past it.
  209. EXPECT_THROW(
  210. ibuffer.readVector(vec, 1),
  211. isc::util::InvalidBufferPosition
  212. );
  213. }
  214. TEST_F(BufferTest, inputBufferReadVectorChunks) {
  215. std::vector<uint8_t> vec;
  216. // check that vector can read the whole buffer
  217. ibuffer.readVector(vec, 3);
  218. EXPECT_EQ(3, vec.size());
  219. EXPECT_EQ(0, memcmp(&vec[0], testdata, 3));
  220. EXPECT_NO_THROW(
  221. ibuffer.readVector(vec, 2)
  222. );
  223. EXPECT_EQ(0, memcmp(&vec[0], testdata+3, 2));
  224. }
  225. TEST_F(BufferTest, inputBufferConstructorVector) {
  226. std::vector<uint8_t> vec(17);
  227. for (int i = 0; i < vec.size(); i++) {
  228. vec[i] = i;
  229. }
  230. InputBuffer buf(vec.begin(), vec.end());
  231. EXPECT_EQ(buf.getLength(), 17);
  232. std::vector<uint8_t> vec2;
  233. EXPECT_NO_THROW(buf.readVector(vec2, 17));
  234. EXPECT_EQ(vec, vec2);
  235. }
  236. }