buffer_unittest.cc 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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. #ifdef EXPECT_DEATH
  153. // We use assert now, so we check it dies
  154. EXPECT_DEATH({
  155. try {
  156. obuffer[sizeof(testdata)];
  157. } catch (...) {
  158. // Prevent exceptions killing the application, we need
  159. // to make sure it dies the real hard way
  160. }
  161. }, "");
  162. #endif
  163. }
  164. TEST_F(BufferTest, outputBufferClear) {
  165. obuffer.writeData(testdata, sizeof(testdata));
  166. obuffer.clear();
  167. EXPECT_EQ(0, obuffer.getLength());
  168. }
  169. TEST_F(BufferTest, outputBufferCopy) {
  170. obuffer.writeData(testdata, sizeof(testdata));
  171. EXPECT_NO_THROW({
  172. OutputBuffer copy(obuffer);
  173. ASSERT_EQ(sizeof(testdata), copy.getLength());
  174. for (int i = 0; i < sizeof(testdata); i ++) {
  175. EXPECT_EQ(testdata[i], copy[i]);
  176. if (i + 1 < sizeof(testdata)) {
  177. obuffer.writeUint16At(0, i);
  178. }
  179. EXPECT_EQ(testdata[i], copy[i]);
  180. }
  181. obuffer.clear();
  182. ASSERT_EQ(sizeof(testdata), copy.getLength());
  183. });
  184. }
  185. TEST_F(BufferTest, outputBufferAssign) {
  186. OutputBuffer another(0);
  187. another.clear();
  188. obuffer.writeData(testdata, sizeof(testdata));
  189. EXPECT_NO_THROW({
  190. another = obuffer;
  191. ASSERT_EQ(sizeof(testdata), another.getLength());
  192. for (int i = 0; i < sizeof(testdata); i ++) {
  193. EXPECT_EQ(testdata[i], another[i]);
  194. if (i + 1 < sizeof(testdata)) {
  195. obuffer.writeUint16At(0, i);
  196. }
  197. EXPECT_EQ(testdata[i], another[i]);
  198. }
  199. obuffer.clear();
  200. ASSERT_EQ(sizeof(testdata), another.getLength());
  201. });
  202. }
  203. TEST_F(BufferTest, outputBufferZeroSize) {
  204. // Some OSes might return NULL on malloc for 0 size, so check it works
  205. EXPECT_NO_THROW({
  206. OutputBuffer first(0);
  207. OutputBuffer copy(first);
  208. OutputBuffer second(0);
  209. second = first;
  210. });
  211. }
  212. TEST_F(BufferTest, readVectorAll) {
  213. std::vector<uint8_t> vec;
  214. // check that vector can read the whole buffer
  215. ibuffer.readVector(vec, 5);
  216. ASSERT_EQ(5, vec.size());
  217. EXPECT_EQ(0, memcmp(&vec[0], testdata, 5));
  218. // ibuffer is 5 bytes long. Can't read past it.
  219. EXPECT_THROW(
  220. ibuffer.readVector(vec, 1),
  221. isc::util::InvalidBufferPosition
  222. );
  223. }
  224. TEST_F(BufferTest, readVectorChunks) {
  225. std::vector<uint8_t> vec;
  226. // check that vector can read the whole buffer
  227. ibuffer.readVector(vec, 3);
  228. EXPECT_EQ(3, vec.size());
  229. EXPECT_EQ(0, memcmp(&vec[0], testdata, 3));
  230. EXPECT_NO_THROW(
  231. ibuffer.readVector(vec, 2)
  232. );
  233. EXPECT_EQ(0, memcmp(&vec[0], testdata+3, 2));
  234. }
  235. }