opaque_data_tuple_unittest.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. // Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <config.h>
  7. #include <dhcp/opaque_data_tuple.h>
  8. #include <util/buffer.h>
  9. #include <gtest/gtest.h>
  10. #include <algorithm>
  11. #include <sstream>
  12. #include <vector>
  13. using namespace isc;
  14. using namespace isc::dhcp;
  15. using namespace isc::util;
  16. namespace {
  17. // This test checks that when the default constructor is called, the data buffer
  18. // is empty.
  19. TEST(OpaqueDataTuple, constructor) {
  20. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  21. // There should be no data in the tuple.
  22. EXPECT_EQ(0, tuple.getLength());
  23. EXPECT_TRUE(tuple.getData().empty());
  24. EXPECT_TRUE(tuple.getText().empty());
  25. }
  26. // Test that the constructor which takes the buffer as argument parses the
  27. // wire data.
  28. TEST(OpaqueDataTuple, constructorParse1Byte) {
  29. const char wire_data[] = {
  30. 0x0B, // Length is 11
  31. 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, // Hello<space>
  32. 0x77, 0x6F, 0x72, 0x6C, 0x64 // world
  33. };
  34. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_1_BYTE, wire_data,
  35. wire_data + sizeof(wire_data));
  36. EXPECT_EQ(11, tuple.getLength());
  37. EXPECT_EQ("Hello world", tuple.getText());
  38. }
  39. // Test that the constructor which takes the buffer as argument parses the
  40. // wire data.
  41. TEST(OpaqueDataTuple, constructorParse2Bytes) {
  42. const char wire_data[] = {
  43. 0x00, 0x0B, // Length is 11
  44. 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, // Hello<space>
  45. 0x77, 0x6F, 0x72, 0x6C, 0x64 // world
  46. };
  47. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES, wire_data,
  48. wire_data + sizeof(wire_data));
  49. EXPECT_EQ(11, tuple.getLength());
  50. EXPECT_EQ("Hello world", tuple.getText());
  51. }
  52. // This test checks that it is possible to set the tuple data using raw buffer.
  53. TEST(OpaqueDataTuple, assignData) {
  54. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  55. // Initially the tuple buffer should be empty.
  56. OpaqueDataTuple::Buffer buf = tuple.getData();
  57. ASSERT_TRUE(buf.empty());
  58. // Prepare some input data and assign to the tuple.
  59. const uint8_t data1[] = {
  60. 0xCA, 0xFE, 0xBE, 0xEF
  61. };
  62. tuple.assign(data1, sizeof(data1));
  63. // Tuple should now hold the data we assigned.
  64. ASSERT_EQ(sizeof(data1), tuple.getLength());
  65. buf = tuple.getData();
  66. EXPECT_TRUE(std::equal(buf.begin(), buf.end(), data1));
  67. // Prepare the other set of data and assign to the tuple.
  68. const uint8_t data2[] = {
  69. 1, 2, 3, 4, 5, 6
  70. };
  71. tuple.assign(data2, sizeof(data2));
  72. // The new data should have replaced the old data.
  73. ASSERT_EQ(sizeof(data2), tuple.getLength());
  74. buf = tuple.getData();
  75. EXPECT_TRUE(std::equal(buf.begin(), buf.end(), data2));
  76. }
  77. // This test checks that it is possible to append the data to the tuple using
  78. // raw buffer.
  79. TEST(OpaqueDataTuple, appendData) {
  80. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  81. // Initially the tuple buffer should be empty.
  82. OpaqueDataTuple::Buffer buf = tuple.getData();
  83. ASSERT_TRUE(buf.empty());
  84. // Prepare some input data and append to the empty tuple.
  85. const uint8_t data1[] = {
  86. 0xCA, 0xFE, 0xBE, 0xEF
  87. };
  88. tuple.append(data1, sizeof(data1));
  89. // The tuple should now hold only the data we appended.
  90. ASSERT_EQ(sizeof(data1), tuple.getLength());
  91. buf = tuple.getData();
  92. EXPECT_TRUE(std::equal(buf.begin(), buf.end(), data1));
  93. // Prepare the new set of data and append.
  94. const uint8_t data2[] = {
  95. 1, 2, 3, 4, 5, 6
  96. };
  97. tuple.append(data2, sizeof(data2));
  98. // We expect that the tuple now has both sets of data we appended. In order
  99. // to verify that, we have to concatenate the input data1 and data2.
  100. std::vector<uint8_t> data12(data1, data1 + sizeof(data1));
  101. data12.insert(data12.end(), data2, data2 + sizeof(data2));
  102. // The size of the tuple should be a sum of data1 and data2 lengths.
  103. ASSERT_EQ(sizeof(data1) + sizeof(data2), tuple.getLength());
  104. buf = tuple.getData();
  105. EXPECT_TRUE(std::equal(buf.begin(), buf.end(), data12.begin()));
  106. }
  107. // This test checks that it is possible to assign the string to the tuple.
  108. TEST(OpaqueDataTuple, assignString) {
  109. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  110. // Initially, the tuple should be empty.
  111. ASSERT_EQ(0, tuple.getLength());
  112. // Assign some string data.
  113. tuple.assign("Some string");
  114. // Verify that the data has been assigned.
  115. EXPECT_EQ(11, tuple.getLength());
  116. EXPECT_EQ("Some string", tuple.getText());
  117. // Assign some other string.
  118. tuple.assign("Different string");
  119. // The new string should have replaced the old string.
  120. EXPECT_EQ(16, tuple.getLength());
  121. EXPECT_EQ("Different string", tuple.getText());
  122. }
  123. // This test checks that it is possible to append the string to the tuple.
  124. TEST(OpaqueDataTuple, appendString) {
  125. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  126. // Initially the tuple should be empty.
  127. ASSERT_EQ(0, tuple.getLength());
  128. // Append the string to it.
  129. tuple.append("First part");
  130. ASSERT_EQ(10, tuple.getLength());
  131. ASSERT_EQ("First part", tuple.getText());
  132. // Now append the other string.
  133. tuple.append(" and second part");
  134. EXPECT_EQ(26, tuple.getLength());
  135. // The resulting data in the tuple should be a concatenation of both
  136. // strings.
  137. EXPECT_EQ("First part and second part", tuple.getText());
  138. }
  139. // This test verifies that equals function correctly checks that the tuple
  140. // holds a given string but it doesn't hold the other. This test also
  141. // checks the assignment operator for the tuple.
  142. TEST(OpaqueDataTuple, equals) {
  143. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  144. // Tuple is supposed to be empty so it is not equal xyz.
  145. EXPECT_FALSE(tuple.equals("xyz"));
  146. // Assign xyz.
  147. EXPECT_NO_THROW(tuple = "xyz");
  148. // The tuple should be equal xyz, but not abc.
  149. EXPECT_FALSE(tuple.equals("abc"));
  150. EXPECT_TRUE(tuple.equals("xyz"));
  151. // Assign abc to the tuple.
  152. EXPECT_NO_THROW(tuple = "abc");
  153. // It should be now opposite.
  154. EXPECT_TRUE(tuple.equals("abc"));
  155. EXPECT_FALSE(tuple.equals("xyz"));
  156. }
  157. // This test checks that the conversion of the data in the tuple to the string
  158. // is performed correctly.
  159. TEST(OpaqueDataTuple, getText) {
  160. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  161. // Initially the tuple should be empty.
  162. ASSERT_TRUE(tuple.getText().empty());
  163. // ASCII representation of 'Hello world'.
  164. const char as_ascii[] = {
  165. 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, // Hello<space>
  166. 0x77, 0x6F, 0x72, 0x6C, 0x64 // world
  167. };
  168. // Assign it to the tuple.
  169. tuple.assign(as_ascii, sizeof(as_ascii));
  170. // Conversion to string should give as the original text.
  171. EXPECT_EQ("Hello world", tuple.getText());
  172. }
  173. // This test verifies the behavior of (in)equality and assignment operators.
  174. TEST(OpaqueDataTuple, operators) {
  175. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  176. // Tuple should be empty initially.
  177. ASSERT_EQ(0, tuple.getLength());
  178. // Check assignment.
  179. EXPECT_NO_THROW(tuple = "Hello World");
  180. EXPECT_EQ(11, tuple.getLength());
  181. EXPECT_TRUE(tuple == "Hello World");
  182. EXPECT_TRUE(tuple != "Something else");
  183. // Assign something else to make sure it affects the tuple.
  184. EXPECT_NO_THROW(tuple = "Something else");
  185. EXPECT_EQ(14, tuple.getLength());
  186. EXPECT_TRUE(tuple == "Something else");
  187. EXPECT_TRUE(tuple != "Hello World");
  188. }
  189. // This test verifies that the tuple is inserted in the textual format to the
  190. // output stream.
  191. TEST(OpaqueDataTuple, operatorOutputStream) {
  192. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  193. // The tuple should be empty initially.
  194. ASSERT_EQ(0, tuple.getLength());
  195. // The tuple is empty, so assigning its content to the output stream should
  196. // be no-op and result in the same text in the stream.
  197. std::ostringstream s;
  198. s << "Some text";
  199. EXPECT_NO_THROW(s << tuple);
  200. EXPECT_EQ("Some text", s.str());
  201. // Now, let's assign some text to the tuple and call operator again.
  202. // The new text should be added to the stream.
  203. EXPECT_NO_THROW(tuple = " and some other text");
  204. EXPECT_NO_THROW(s << tuple);
  205. EXPECT_EQ(s.str(), "Some text and some other text");
  206. }
  207. // This test verifies that the value of the tuple can be initialized from the
  208. // input stream.
  209. TEST(OpaqueDataTuple, operatorInputStream) {
  210. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  211. // The tuple should be empty initially.
  212. ASSERT_EQ(0, tuple.getLength());
  213. // The input stream has some text. This text should be appended to the
  214. // tuple.
  215. std::istringstream s;
  216. s.str("Some text");
  217. EXPECT_NO_THROW(s >> tuple);
  218. EXPECT_EQ("Some text", tuple.getText());
  219. // Now, let's assign some other text to the stream. This new text should be
  220. // assigned to the tuple.
  221. s.str("And some other");
  222. EXPECT_NO_THROW(s >> tuple);
  223. EXPECT_EQ("And some other", tuple.getText());
  224. }
  225. // This test checks that the tuple is correctly encoded in the wire format when
  226. // the size of the length field is 1 byte.
  227. TEST(OpaqueDataTuple, pack1Byte) {
  228. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_1_BYTE);
  229. // Initially, the tuple should be empty.
  230. ASSERT_EQ(0, tuple.getLength());
  231. // The empty data doesn't make much sense, so the pack() should not
  232. // allow it.
  233. OutputBuffer out_buf(10);
  234. EXPECT_THROW(tuple.pack(out_buf), OpaqueDataTupleError);
  235. // Set the data for tuple.
  236. std::vector<uint8_t> data;
  237. for (uint8_t i = 0; i < 100; ++i) {
  238. data.push_back(i);
  239. }
  240. tuple.assign(data.begin(), data.size());
  241. // The pack should now succeed.
  242. ASSERT_NO_THROW(tuple.pack(out_buf));
  243. // The rendered buffer should be 101 bytes long - 1 byte for length,
  244. // 100 bytes for the actual data.
  245. ASSERT_EQ(101, out_buf.getLength());
  246. // Get the rendered data into the vector for convenience.
  247. std::vector<uint8_t>
  248. render_data(static_cast<const uint8_t*>(out_buf.getData()),
  249. static_cast<const uint8_t*>(out_buf.getData()) + 101);
  250. // The first byte is a length byte. It should hold the length of 100.
  251. EXPECT_EQ(100, render_data[0]);
  252. // Verify that the rendered data is correct.
  253. EXPECT_TRUE(std::equal(render_data.begin() + 1, render_data.end(),
  254. data.begin()));
  255. // Reset the output buffer for another test.
  256. out_buf.clear();
  257. // Fill in the tuple buffer so as it reaches maximum allowed length. The
  258. // maximum length is 255 when the size of the length field is one byte.
  259. for (uint8_t i = 100; i < 255; ++i) {
  260. data.push_back(i);
  261. }
  262. ASSERT_EQ(255, data.size());
  263. tuple.assign(data.begin(), data.size());
  264. // The pack() should be successful again.
  265. ASSERT_NO_THROW(tuple.pack(out_buf));
  266. // The rendered buffer should be 256 bytes long. The first byte holds the
  267. // opaque data length, the remaining bytes hold the actual data.
  268. ASSERT_EQ(256, out_buf.getLength());
  269. // Check that the data is correct.
  270. render_data.assign(static_cast<const uint8_t*>(out_buf.getData()),
  271. static_cast<const uint8_t*>(out_buf.getData()) + 256);
  272. EXPECT_EQ(255, render_data[0]);
  273. EXPECT_TRUE(std::equal(render_data.begin() + 1, render_data.end(),
  274. data.begin()));
  275. // Clear output buffer for another test.
  276. out_buf.clear();
  277. // Add one more value to the tuple. Now, the resulting buffer should exceed
  278. // the maximum length. An attempt to pack() should fail.
  279. data.push_back(255);
  280. tuple.assign(data.begin(), data.size());
  281. EXPECT_THROW(tuple.pack(out_buf), OpaqueDataTupleError);
  282. }
  283. // This test checks that the tuple is correctly encoded in the wire format when
  284. // the size of the length field is 2 bytes.
  285. TEST(OpaqueDataTuple, pack2Bytes) {
  286. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  287. // Initially, the tuple should be empty.
  288. ASSERT_EQ(0, tuple.getLength());
  289. // The empty data doesn't make much sense, so the pack() should not
  290. // allow it.
  291. OutputBuffer out_buf(10);
  292. EXPECT_THROW(tuple.pack(out_buf), OpaqueDataTupleError);
  293. // Set the data for tuple.
  294. std::vector<uint8_t> data;
  295. for (unsigned i = 0; i < 512; ++i) {
  296. data.push_back(i & 0xff);
  297. }
  298. tuple.assign(data.begin(), data.size());
  299. // The pack should now succeed.
  300. ASSERT_NO_THROW(tuple.pack(out_buf));
  301. // The rendered buffer should be 514 bytes long - 2 bytes for length,
  302. // 512 bytes for the actual data.
  303. ASSERT_EQ(514, out_buf.getLength());
  304. // Get the rendered data into the vector for convenience.
  305. std::vector<uint8_t>
  306. render_data(static_cast<const uint8_t*>(out_buf.getData()),
  307. static_cast<const uint8_t*>(out_buf.getData()) + 514);
  308. // The first two bytes hold the length of 512.
  309. uint16_t len = (render_data[0] << 8) + render_data[1];
  310. EXPECT_EQ(512, len);
  311. // Verify that the rendered data is correct.
  312. EXPECT_TRUE(std::equal(render_data.begin() + 2, render_data.end(),
  313. data.begin()));
  314. // Without clearing the output buffer, try to do it again. The pack should
  315. // append the data to the current buffer.
  316. ASSERT_NO_THROW(tuple.pack(out_buf));
  317. EXPECT_EQ(1028, out_buf.getLength());
  318. // Check that we can render the buffer of the maximal allowed size.
  319. data.assign(65535, 1);
  320. ASSERT_NO_THROW(tuple.assign(data.begin(), data.size()));
  321. ASSERT_NO_THROW(tuple.pack(out_buf));
  322. out_buf.clear();
  323. // Append one additional byte. The total length of the tuple now exceeds
  324. // the maximal value. An attempt to render it should throw an exception.
  325. data.assign(1, 1);
  326. ASSERT_NO_THROW(tuple.append(data.begin(), data.size()));
  327. EXPECT_THROW(tuple.pack(out_buf), OpaqueDataTupleError);
  328. }
  329. // This test verifies that the tuple is decoded from the wire format.
  330. TEST(OpaqueDataTuple, unpack1Byte) {
  331. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_1_BYTE);
  332. const char wire_data[] = {
  333. 0x0B, // Length is 11
  334. 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, // Hello<space>
  335. 0x77, 0x6F, 0x72, 0x6C, 0x64 // world
  336. };
  337. ASSERT_NO_THROW(tuple.unpack(wire_data, wire_data + sizeof(wire_data)));
  338. EXPECT_EQ(11, tuple.getLength());
  339. EXPECT_EQ("Hello world", tuple.getText());
  340. }
  341. // This test verifies that the tuple having a length of 0, is decoded from
  342. // the wire format.
  343. TEST(OpaqueDataTuple, unpack1ByteZeroLength) {
  344. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_1_BYTE);
  345. EXPECT_NO_THROW(tuple = "Hello world");
  346. ASSERT_NE(tuple.getLength(), 0);
  347. const char wire_data[] = {
  348. 0
  349. };
  350. ASSERT_NO_THROW(tuple.unpack(wire_data, wire_data + sizeof(wire_data)));
  351. EXPECT_EQ(0, tuple.getLength());
  352. }
  353. // This test verifies that exception is thrown if the empty buffer is being
  354. // parsed.
  355. TEST(OpaqueDataTuple, unpack1ByteEmptyBuffer) {
  356. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_1_BYTE);
  357. const char wire_data[] = {
  358. 1, 2, 3
  359. };
  360. EXPECT_THROW(tuple.unpack(wire_data, wire_data), OpaqueDataTupleError);
  361. }
  362. // This test verifies that exception is thrown when parsing truncated buffer.
  363. TEST(OpaqueDataTuple, unpack1ByteTruncatedBuffer) {
  364. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_1_BYTE);
  365. const char wire_data[] = {
  366. 10, 2, 3
  367. };
  368. EXPECT_THROW(tuple.unpack(wire_data, wire_data + sizeof(wire_data)),
  369. OpaqueDataTupleError);
  370. }
  371. // This test verifies that the tuple is decoded from the wire format.
  372. TEST(OpaqueDataTuple, unpack2Byte) {
  373. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  374. std::vector<uint8_t> wire_data;
  375. // Set tuple length to 400 (0x190).
  376. wire_data.push_back(1);
  377. wire_data.push_back(0x90);
  378. // Fill in the buffer with some data.
  379. for (int i = 0; i < 400; ++i) {
  380. wire_data.push_back(i);
  381. }
  382. // The unpack should succeed.
  383. ASSERT_NO_THROW(tuple.unpack(wire_data.begin(), wire_data.end()));
  384. // The decoded length should be 400.
  385. ASSERT_EQ(400, tuple.getLength());
  386. // And the data should match.
  387. EXPECT_TRUE(std::equal(wire_data.begin() + 2, wire_data.end(),
  388. tuple.getData().begin()));
  389. }
  390. // This test verifies that the tuple having a length of 0, is decoded from
  391. // the wire format.
  392. TEST(OpaqueDataTuple, unpack2ByteZeroLength) {
  393. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  394. // Set some data for the tuple.
  395. EXPECT_NO_THROW(tuple = "Hello world");
  396. ASSERT_NE(tuple.getLength(), 0);
  397. // The buffer holds just a length field with the value of 0.
  398. const char wire_data[] = {
  399. 0, 0
  400. };
  401. // The empty tuple should be successfully decoded.
  402. ASSERT_NO_THROW(tuple.unpack(wire_data, wire_data + sizeof(wire_data)));
  403. // The data should be replaced with an empty buffer.
  404. EXPECT_EQ(0, tuple.getLength());
  405. }
  406. // This test verifies that exception is thrown if the empty buffer is being
  407. // parsed.
  408. TEST(OpaqueDataTuple, unpack2ByteEmptyBuffer) {
  409. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  410. // Initialize the input buffer with some data, just to avoid initializing
  411. // empty array.
  412. const char wire_data[] = {
  413. 1, 2, 3
  414. };
  415. // Pass empty buffer (first iterator equal to second iterator).
  416. // This should not be accepted.
  417. EXPECT_THROW(tuple.unpack(wire_data, wire_data), OpaqueDataTupleError);
  418. }
  419. // This test verifies that exception if thrown when parsing truncated buffer.
  420. TEST(OpaqueDataTuple, unpack2ByteTruncatedBuffer) {
  421. OpaqueDataTuple tuple(OpaqueDataTuple::LENGTH_2_BYTES);
  422. // Specify the data with the length of 10, but limit the buffer size to
  423. // 2 bytes.
  424. const char wire_data[] = {
  425. 0, 10, 2, 3
  426. };
  427. // This should fail because the buffer is truncated.
  428. EXPECT_THROW(tuple.unpack(wire_data, wire_data + sizeof(wire_data)),
  429. OpaqueDataTupleError);
  430. }
  431. } // anonymous namespace