messagerenderer_unittest.cc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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 <dns/name.h>
  17. #include <dns/messagerenderer.h>
  18. #include <dns/tests/unittest_util.h>
  19. #include <gtest/gtest.h>
  20. #include <vector>
  21. using isc::UnitTestUtil;
  22. using isc::dns::Name;
  23. using isc::dns::MessageRenderer;
  24. using isc::util::OutputBuffer;
  25. namespace {
  26. class MessageRendererTest : public ::testing::Test {
  27. protected:
  28. MessageRendererTest() : expected_size(0) {
  29. data16 = (2 << 8) | 3;
  30. data32 = (4 << 24) | (5 << 16) | (6 << 8) | 7;
  31. }
  32. size_t expected_size;
  33. uint16_t data16;
  34. uint32_t data32;
  35. MessageRenderer renderer;
  36. std::vector<unsigned char> data;
  37. static const uint8_t testdata[5];
  38. };
  39. const uint8_t MessageRendererTest::testdata[5] = {1, 2, 3, 4, 5};
  40. // The test cases are borrowed from those for the OutputBuffer class.
  41. TEST_F(MessageRendererTest, writeIntger) {
  42. renderer.writeUint16(data16);
  43. expected_size += sizeof(data16);
  44. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
  45. renderer.getLength(), &testdata[1], sizeof(data16));
  46. }
  47. TEST_F(MessageRendererTest, writeName) {
  48. UnitTestUtil::readWireData("name_toWire1", data);
  49. renderer.writeName(Name("a.example.com."));
  50. renderer.writeName(Name("b.example.com."));
  51. renderer.writeName(Name("a.example.org."));
  52. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
  53. renderer.getLength(), &data[0], data.size());
  54. }
  55. TEST_F(MessageRendererTest, writeNameInLargeBuffer) {
  56. size_t offset = 0x3fff;
  57. renderer.skip(offset);
  58. UnitTestUtil::readWireData("name_toWire2", data);
  59. renderer.writeName(Name("a.example.com."));
  60. renderer.writeName(Name("a.example.com."));
  61. renderer.writeName(Name("b.example.com."));
  62. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  63. static_cast<const uint8_t*>(renderer.getData()) +
  64. offset,
  65. renderer.getLength() - offset,
  66. &data[0], data.size());
  67. }
  68. TEST_F(MessageRendererTest, writeNameWithUncompressed) {
  69. UnitTestUtil::readWireData("name_toWire3", data);
  70. renderer.writeName(Name("a.example.com."));
  71. renderer.writeName(Name("b.example.com."), false);
  72. renderer.writeName(Name("b.example.com."));
  73. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
  74. renderer.getLength(), &data[0], data.size());
  75. }
  76. TEST_F(MessageRendererTest, writeNamePointerChain) {
  77. UnitTestUtil::readWireData("name_toWire4", data);
  78. renderer.writeName(Name("a.example.com."));
  79. renderer.writeName(Name("b.example.com."));
  80. renderer.writeName(Name("b.example.com."));
  81. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
  82. renderer.getLength(), &data[0], data.size());
  83. }
  84. TEST_F(MessageRendererTest, compressMode) {
  85. // By default the render performs case insensitive compression.
  86. EXPECT_EQ(MessageRenderer::CASE_INSENSITIVE, renderer.getCompressMode());
  87. // The mode can be explicitly changed.
  88. renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
  89. EXPECT_EQ(MessageRenderer::CASE_SENSITIVE, renderer.getCompressMode());
  90. renderer.setCompressMode(MessageRenderer::CASE_INSENSITIVE);
  91. EXPECT_EQ(MessageRenderer::CASE_INSENSITIVE, renderer.getCompressMode());
  92. // The clear() method resets the mode to the default.
  93. renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
  94. renderer.clear();
  95. EXPECT_EQ(MessageRenderer::CASE_INSENSITIVE, renderer.getCompressMode());
  96. }
  97. TEST_F(MessageRendererTest, writeNameCaseCompress) {
  98. // By default MessageRenderer performs case insensitive compression.
  99. UnitTestUtil::readWireData("name_toWire1", data);
  100. renderer.writeName(Name("a.example.com."));
  101. // this should match the first name in terms of compression:
  102. renderer.writeName(Name("b.exAmple.CoM."));
  103. renderer.writeName(Name("a.example.org."));
  104. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
  105. renderer.getLength(), &data[0], data.size());
  106. }
  107. TEST_F(MessageRendererTest, writeNameCaseSensitiveCompress) {
  108. // name compression in case sensitive manner. See the data file
  109. // description for details.
  110. renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
  111. UnitTestUtil::readWireData("name_toWire5.wire", data);
  112. renderer.writeName(Name("a.example.com."));
  113. renderer.writeName(Name("b.eXample.com."));
  114. renderer.writeName(Name("c.eXample.com."));
  115. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
  116. renderer.getLength(), &data[0], data.size());
  117. }
  118. TEST_F(MessageRendererTest, writeNameMixedCaseCompress) {
  119. renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
  120. UnitTestUtil::readWireData("name_toWire6.wire", data);
  121. renderer.writeName(Name("a.example.com."));
  122. renderer.writeName(Name("b.eXample.com."));
  123. // Change the compression mode in the middle of rendering. This is not
  124. // allowed in this implementation.
  125. EXPECT_THROW(renderer.setCompressMode(MessageRenderer::CASE_INSENSITIVE),
  126. isc::InvalidParameter);
  127. // Once the renderer is cleared, it's okay again.
  128. renderer.clear();
  129. EXPECT_NO_THROW(renderer.setCompressMode(
  130. MessageRenderer::CASE_INSENSITIVE));
  131. }
  132. TEST_F(MessageRendererTest, writeRootName) {
  133. // root name is special: it never causes compression or can (reasonably)
  134. // be a compression pointer. So it makes sense to check this case
  135. // explicitly.
  136. Name example_name = Name("www.example.com");
  137. OutputBuffer expected(0);
  138. expected.writeUint8(0); // root name
  139. example_name.toWire(expected);
  140. renderer.writeName(Name("."));
  141. renderer.writeName(example_name);
  142. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  143. static_cast<const uint8_t*>(renderer.getData()),
  144. renderer.getLength(),
  145. static_cast<const uint8_t*>(expected.getData()),
  146. expected.getLength());
  147. }
  148. TEST_F(MessageRendererTest, setBuffer) {
  149. OutputBuffer new_buffer(0);
  150. renderer.setBuffer(&new_buffer);
  151. EXPECT_EQ(0, new_buffer.getLength()); // the buffer should be still empty
  152. renderer.writeUint32(42);
  153. EXPECT_EQ(sizeof(uint32_t), new_buffer.getLength());
  154. EXPECT_EQ(sizeof(uint32_t), renderer.getLength());
  155. // Change some other internal state for the reset test below.
  156. EXPECT_EQ(512, renderer.getLengthLimit());
  157. renderer.setLengthLimit(4096);
  158. EXPECT_EQ(4096, renderer.getLengthLimit());
  159. // Reset the buffer to the default again. Other internal states and
  160. // resources should be cleared. The used buffer should be intact.
  161. renderer.setBuffer(NULL);
  162. EXPECT_EQ(sizeof(uint32_t), new_buffer.getLength());
  163. EXPECT_EQ(0, renderer.getLength());
  164. EXPECT_EQ(512, renderer.getLengthLimit());
  165. }
  166. TEST_F(MessageRendererTest, setBufferErrors) {
  167. OutputBuffer new_buffer(0);
  168. // Buffer cannot be reset when the renderer is in use.
  169. renderer.writeUint32(10);
  170. EXPECT_THROW(renderer.setBuffer(&new_buffer), isc::InvalidParameter);
  171. renderer.clear();
  172. renderer.setBuffer(&new_buffer);
  173. renderer.writeUint32(10);
  174. EXPECT_THROW(renderer.setBuffer(&new_buffer), isc::InvalidParameter);
  175. // Resetting the buffer isn't allowed for the default buffer.
  176. renderer.setBuffer(NULL);
  177. EXPECT_THROW(renderer.setBuffer(NULL), isc::InvalidParameter);
  178. // It's okay to reset a temporary buffer without using it.
  179. renderer.setBuffer(&new_buffer);
  180. EXPECT_NO_THROW(renderer.setBuffer(NULL));
  181. }
  182. }