rrttl_unittest.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. // Copyright (C) 2010 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 <gtest/gtest.h>
  15. #include <util/buffer.h>
  16. #include <dns/messagerenderer.h>
  17. #include <dns/rrttl.h>
  18. #include <dns/tests/unittest_util.h>
  19. #include <util/unittests/wiredata.h>
  20. #include <boost/scoped_ptr.hpp>
  21. using namespace std;
  22. using namespace isc;
  23. using namespace isc::dns;
  24. using namespace isc::util;
  25. using boost::scoped_ptr;
  26. using isc::util::unittests::matchWireData;
  27. namespace {
  28. class RRTTLTest : public ::testing::Test {
  29. protected:
  30. RRTTLTest() : obuffer(0) {}
  31. OutputBuffer obuffer;
  32. MessageRenderer renderer;
  33. static RRTTL rrttlFactoryFromWire(const char* datafile);
  34. static const RRTTL ttl_0, ttl_1h, ttl_1d, ttl_32bit, ttl_max;
  35. static const RRTTL ttl_small, ttl_large;
  36. static const uint8_t wiredata[20];
  37. };
  38. const RRTTL RRTTLTest::ttl_0(0);
  39. const RRTTL RRTTLTest::ttl_1h(3600);
  40. const RRTTL RRTTLTest::ttl_1d(86400);
  41. const RRTTL RRTTLTest::ttl_32bit(0x12345678);
  42. const RRTTL RRTTLTest::ttl_max(0xffffffff);
  43. const RRTTL RRTTLTest::ttl_small(1);
  44. const RRTTL RRTTLTest::ttl_large(0x80000001);
  45. // This is wire-format data for the above sample RRTTLs rendered in the
  46. // appearing order.
  47. const uint8_t RRTTLTest::wiredata[20] = { 0x00, 0x00, 0x00, 0x00,
  48. 0x00, 0x00, 0x0e, 0x10,
  49. 0x00, 0x01, 0x51, 0x80,
  50. 0x12, 0x34, 0x56, 0x78,
  51. 0xff, 0xff, 0xff, 0xff };
  52. RRTTL
  53. RRTTLTest::rrttlFactoryFromWire(const char* datafile) {
  54. std::vector<unsigned char> data;
  55. UnitTestUtil::readWireData(datafile, data);
  56. InputBuffer buffer(&data[0], data.size());
  57. return (RRTTL(buffer));
  58. }
  59. TEST_F(RRTTLTest, getValue) {
  60. EXPECT_EQ(0, ttl_0.getValue());
  61. EXPECT_EQ(3600, ttl_1h.getValue());
  62. EXPECT_EQ(86400, ttl_1d.getValue());
  63. EXPECT_EQ(0x12345678, ttl_32bit.getValue());
  64. EXPECT_EQ(0xffffffff, ttl_max.getValue());
  65. }
  66. TEST_F(RRTTLTest, copyConstruct) {
  67. const RRTTL ttl1(3600);
  68. const RRTTL ttl2(ttl1);
  69. EXPECT_EQ(ttl1.getValue(), ttl2.getValue());
  70. }
  71. TEST_F(RRTTLTest, fromText) {
  72. // Border cases
  73. EXPECT_EQ(0, RRTTL("0").getValue());
  74. EXPECT_EQ(4294967295U, RRTTL("4294967295").getValue());
  75. // Invalid cases
  76. EXPECT_THROW(RRTTL("0xdeadbeef"), InvalidRRTTL); // must be decimal
  77. EXPECT_THROW(RRTTL("-1"), InvalidRRTTL); // must be positive
  78. EXPECT_THROW(RRTTL("1.1"), InvalidRRTTL); // must be integer
  79. EXPECT_THROW(RRTTL("4294967296"), InvalidRRTTL); // must be 32-bit
  80. }
  81. TEST_F(RRTTLTest, createFromText) {
  82. // It returns an actual RRTTL iff the given text is recognized as a
  83. // valid RR TTL.
  84. scoped_ptr<RRTTL> good_ttl(RRTTL::createFromText("3600"));
  85. EXPECT_TRUE(good_ttl);
  86. EXPECT_EQ(RRTTL(3600), *good_ttl);
  87. scoped_ptr<RRTTL> bad_ttl(RRTTL::createFromText("bad"));
  88. EXPECT_FALSE(bad_ttl);
  89. }
  90. void
  91. checkUnit(unsigned multiply, char suffix) {
  92. SCOPED_TRACE(string("Unit check with suffix ") + suffix);
  93. const uint32_t value = 10 * multiply;
  94. const string num = "10";
  95. // Check both lower and upper version of the suffix
  96. EXPECT_EQ(value,
  97. RRTTL(num + static_cast<char>(tolower(suffix))).getValue());
  98. EXPECT_EQ(value,
  99. RRTTL(num + static_cast<char>(toupper(suffix))).getValue());
  100. }
  101. // Check parsing the unit form (1D, etc)
  102. TEST_F(RRTTLTest, fromTextUnit) {
  103. // Check each of the units separately
  104. checkUnit(1, 'S');
  105. checkUnit(60, 'M');
  106. checkUnit(60 * 60, 'H');
  107. checkUnit(24 * 60 * 60, 'D');
  108. checkUnit(7 * 24 * 60 * 60, 'W');
  109. // Some border cases (with units)
  110. EXPECT_EQ(4294967295U, RRTTL("4294967295S").getValue());
  111. EXPECT_EQ(0, RRTTL("0W0D0H0M0S").getValue());
  112. EXPECT_EQ(4294967295U, RRTTL("1193046H1695S").getValue());
  113. // Leading zeroes are accepted
  114. EXPECT_EQ(4294967295U, RRTTL("0000000000000004294967295S").getValue());
  115. // Now some compound ones. We allow any order (it would be much work to
  116. // check the order anyway).
  117. EXPECT_EQ(60 * 60 + 3, RRTTL("1H3S").getValue());
  118. // Awkward, but allowed case - the same unit used twice.
  119. EXPECT_EQ(20 * 3600, RRTTL("12H8H").getValue());
  120. // Negative number in part of the expression, but the total is positive.
  121. // Rejected.
  122. EXPECT_THROW(RRTTL("-1S1H"), InvalidRRTTL);
  123. // Some things out of range in the ttl, but it wraps to number in range
  124. // in int64_t. Should still not get fooled and reject it.
  125. // First part out of range
  126. EXPECT_THROW(RRTTL("9223372036854775807S9223372036854775807S2S"),
  127. InvalidRRTTL);
  128. // Second part out of range, but it immediately wraps (2S+2^64-2S)
  129. EXPECT_THROW(RRTTL("2S18446744073709551614S"), InvalidRRTTL);
  130. // The whole thing wraps right away (2^64S)
  131. EXPECT_THROW(RRTTL("18446744073709551616S"), InvalidRRTTL);
  132. // Second part out of range, and will become negative with the unit,
  133. EXPECT_THROW(RRTTL("256S307445734561825856M"), InvalidRRTTL);
  134. // Missing before unit.
  135. EXPECT_THROW(RRTTL("W5H"), InvalidRRTTL);
  136. EXPECT_THROW(RRTTL("5hW"), InvalidRRTTL);
  137. // Empty string is not allowed
  138. EXPECT_THROW(RRTTL(""), InvalidRRTTL);
  139. // Missing the last unit is not allowed
  140. EXPECT_THROW(RRTTL("3D5"), InvalidRRTTL);
  141. // There are some wrong units
  142. EXPECT_THROW(RRTTL("13X"), InvalidRRTTL);
  143. EXPECT_THROW(RRTTL("3D5F"), InvalidRRTTL);
  144. }
  145. TEST_F(RRTTLTest, fromWire) {
  146. EXPECT_EQ(0x12345678,
  147. rrttlFactoryFromWire("rrcode32_fromWire1").getValue());
  148. EXPECT_THROW(rrttlFactoryFromWire("rrcode32_fromWire2"),
  149. IncompleteRRTTL);
  150. }
  151. TEST_F(RRTTLTest, toText) {
  152. EXPECT_EQ("0", ttl_0.toText());
  153. EXPECT_EQ("3600", ttl_1h.toText());
  154. EXPECT_EQ("86400", ttl_1d.toText());
  155. EXPECT_EQ("305419896", ttl_32bit.toText());
  156. EXPECT_EQ("4294967295", ttl_max.toText());
  157. }
  158. TEST_F(RRTTLTest, toWireBuffer) {
  159. ttl_0.toWire(obuffer);
  160. ttl_1h.toWire(obuffer);
  161. ttl_1d.toWire(obuffer);
  162. ttl_32bit.toWire(obuffer);
  163. ttl_max.toWire(obuffer);
  164. matchWireData(wiredata, sizeof(wiredata),
  165. obuffer.getData(), obuffer.getLength());
  166. }
  167. TEST_F(RRTTLTest, toWireRenderer) {
  168. ttl_0.toWire(renderer);
  169. ttl_1h.toWire(renderer);
  170. ttl_1d.toWire(renderer);
  171. ttl_32bit.toWire(renderer);
  172. ttl_max.toWire(renderer);
  173. matchWireData(wiredata, sizeof(wiredata),
  174. renderer.getData(), renderer.getLength());
  175. }
  176. TEST_F(RRTTLTest, equal) {
  177. EXPECT_TRUE(RRTTL("3600") == ttl_1h);
  178. EXPECT_TRUE(RRTTL("86400").equals(ttl_1d));
  179. EXPECT_TRUE(ttl_1d != ttl_1h);
  180. EXPECT_TRUE(ttl_1d.nequals(ttl_max));
  181. }
  182. //
  183. // The following set of tests confirm the result of <=, <, >=, >
  184. // The test logic is simple, and all tests are just straightforward variations
  185. // of the first one.
  186. //
  187. TEST_F(RRTTLTest, leq) {
  188. // small <= large is true
  189. EXPECT_TRUE(ttl_small.leq(ttl_large));
  190. EXPECT_TRUE(ttl_small <= ttl_large);
  191. // small <= small is true
  192. EXPECT_TRUE(ttl_small.leq(ttl_small));
  193. EXPECT_LE(ttl_small, ttl_small);
  194. // large <= small is false
  195. EXPECT_FALSE(ttl_large.leq(ttl_small));
  196. EXPECT_FALSE(ttl_large <= ttl_small);
  197. }
  198. TEST_F(RRTTLTest, geq) {
  199. EXPECT_TRUE(ttl_large.geq(ttl_small));
  200. EXPECT_TRUE(ttl_large >= ttl_small);
  201. EXPECT_TRUE(ttl_large.geq(ttl_large));
  202. EXPECT_GE(ttl_large, ttl_large);
  203. EXPECT_FALSE(ttl_small.geq(ttl_large));
  204. EXPECT_FALSE(ttl_small >= ttl_large);
  205. }
  206. TEST_F(RRTTLTest, lthan) {
  207. EXPECT_TRUE(ttl_small.lthan(ttl_large));
  208. EXPECT_TRUE(ttl_small < ttl_large);
  209. EXPECT_FALSE(ttl_small.lthan(ttl_small));
  210. // cppcheck-suppress duplicateExpression
  211. EXPECT_FALSE(ttl_small < ttl_small);
  212. EXPECT_FALSE(ttl_large.lthan(ttl_small));
  213. EXPECT_FALSE(ttl_large < ttl_small);
  214. }
  215. TEST_F(RRTTLTest, gthan) {
  216. EXPECT_TRUE(ttl_large.gthan(ttl_small));
  217. EXPECT_TRUE(ttl_large > ttl_small);
  218. EXPECT_FALSE(ttl_large.gthan(ttl_large));
  219. // cppcheck-suppress duplicateExpression
  220. EXPECT_FALSE(ttl_large > ttl_large);
  221. EXPECT_FALSE(ttl_small.gthan(ttl_large));
  222. EXPECT_FALSE(ttl_small > ttl_large);
  223. }
  224. TEST_F(RRTTLTest, maxTTL) {
  225. EXPECT_EQ((1u << 31) - 1, RRTTL::MAX_TTL().getValue());
  226. }
  227. // test operator<<. We simply confirm it appends the result of toText().
  228. TEST_F(RRTTLTest, LeftShiftOperator) {
  229. ostringstream oss;
  230. oss << ttl_1h;
  231. EXPECT_EQ(ttl_1h.toText(), oss.str());
  232. }
  233. }