cfgmgr_unittest.cc 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. // Copyright (C) 2012 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 <config.h>
  15. #include <iostream>
  16. #include <sstream>
  17. #include <arpa/inet.h>
  18. #include <gtest/gtest.h>
  19. #include <dhcp/cfgmgr.h>
  20. #include <exceptions/exceptions.h>
  21. using namespace std;
  22. using namespace isc::asiolink;
  23. using namespace isc::dhcp;
  24. using namespace isc::util;
  25. using namespace isc;
  26. // don't import the entire boost namespace. It will unexpectedly hide uint8_t
  27. // for some systems.
  28. using boost::scoped_ptr;
  29. namespace {
  30. // constructor validation
  31. TEST(TripletTest, constructor) {
  32. uint32_t min = 10;
  33. uint32_t value = 20;
  34. uint32_t max = 30;
  35. Triplet<uint32_t> x(min, value, max);
  36. EXPECT_EQ(10, x.getMin());
  37. EXPECT_EQ(20, x.get());
  38. EXPECT_EQ(30, x.getMax());
  39. // requested values below min should return allowed min value
  40. EXPECT_EQ(10, x.get(5));
  41. EXPECT_EQ(10, x.get(10));
  42. // requesting a value from within the range (min < x < max) should
  43. // return the requested value
  44. EXPECT_EQ(17, x.get(17));
  45. EXPECT_EQ(30, x.get(30));
  46. EXPECT_EQ(30, x.get(35));
  47. // this will be boring. It is expected to return 42 no matter what
  48. Triplet<uint32_t> y(42);
  49. EXPECT_EQ(42, y.getMin()); // min, default and max are equal to 42
  50. EXPECT_EQ(42, y.get()); // it returns ...
  51. EXPECT_EQ(42, y.getMax()); // the exact value...
  52. // requested values below or above are ignore
  53. EXPECT_EQ(42, y.get(5)); // all...
  54. EXPECT_EQ(42, y.get(42)); // the...
  55. EXPECT_EQ(42, y.get(80)); // time!
  56. }
  57. // Triplets must be easy to use.
  58. // Simple to/from int conversions must be done on the fly.
  59. TEST(TripletTest, operator) {
  60. uint32_t x = 47;
  61. // assignment operator: uint32_t => triplet
  62. Triplet<uint32_t> y = x;
  63. EXPECT_EQ(47, y.get());
  64. // let's try the other way around: triplet => uint32_t
  65. uint32_t z = y;
  66. EXPECT_EQ(47, z);
  67. }
  68. // check if specified values are sane
  69. TEST(TripletTest, sanity_check) {
  70. // min is larger than default
  71. EXPECT_THROW(Triplet<uint32_t>(6,5,5), BadValue);
  72. // max is smaller than default
  73. EXPECT_THROW(Triplet<uint32_t>(5,5,4), BadValue);
  74. }
  75. TEST(Pool6Test, constructor_first_last) {
  76. // let's construct 2001:db8:1:: - 2001:db8:1::ffff:ffff:ffff:ffff pool
  77. Pool6 pool1(Pool6::TYPE_IA, IOAddress("2001:db8:1::"),
  78. IOAddress("2001:db8:1::ffff:ffff:ffff:ffff"),
  79. 1000, 2000, 3000, 4000);
  80. EXPECT_EQ(Pool6::TYPE_IA, pool1.getType());
  81. EXPECT_EQ(IOAddress("2001:db8:1::"), pool1.getFirstAddress());
  82. EXPECT_EQ(IOAddress("2001:db8:1::ffff:ffff:ffff:ffff"),
  83. pool1.getLastAddress());
  84. EXPECT_EQ(1000, pool1.getT1());
  85. EXPECT_EQ(2000, pool1.getT2());
  86. EXPECT_EQ(3000, pool1.getPreferred());
  87. EXPECT_EQ(4000, pool1.getValid());
  88. // This is Pool6, IPv4 addresses do not belong here
  89. EXPECT_THROW(Pool6(Pool6::TYPE_IA, IOAddress("2001:db8::1"),
  90. IOAddress("192.168.0.5"),
  91. 1000, 2000, 3000, 4000), BadValue);
  92. EXPECT_THROW(Pool6(Pool6::TYPE_IA, IOAddress("192.168.0.2"),
  93. IOAddress("2001:db8::1"),
  94. 1000, 2000, 3000, 4000), BadValue);
  95. // Should throw. Range should be 2001:db8::1 - 2001:db8::2, not
  96. // the other way around.
  97. EXPECT_THROW(Pool6(Pool6::TYPE_IA, IOAddress("2001:db8::2"),
  98. IOAddress("2001:db8::1"),
  99. 1000, 2000, 3000, 4000), BadValue);
  100. }
  101. TEST(Pool6Test, constructor_prefix_len) {
  102. // let's construct 2001:db8:1::/96 pool
  103. Pool6 pool1(Pool6::TYPE_IA, IOAddress("2001:db8:1::"),
  104. 96, 1000, 2000, 3000, 4000);
  105. EXPECT_EQ(Pool6::TYPE_IA, pool1.getType());
  106. EXPECT_EQ("2001:db8:1::", pool1.getFirstAddress().toText());
  107. EXPECT_EQ("2001:db8:1::ffff:ffff", pool1.getLastAddress().toText());
  108. EXPECT_EQ(1000, pool1.getT1());
  109. EXPECT_EQ(2000, pool1.getT2());
  110. EXPECT_EQ(3000, pool1.getPreferred());
  111. EXPECT_EQ(4000, pool1.getValid());
  112. // This is Pool6, IPv4 addresses do not belong here
  113. EXPECT_THROW(Pool6(Pool6::TYPE_IA, IOAddress("192.168.0.2"),
  114. 96, 1000, 2000, 3000, 4000),
  115. BadValue);
  116. }
  117. TEST(Pool6Test, in_range) {
  118. Pool6 pool1(Pool6::TYPE_IA, IOAddress("2001:db8:1::1"),
  119. IOAddress("2001:db8:1::f"),
  120. 1000, 2000, 3000, 4000);
  121. EXPECT_FALSE(pool1.inRange(IOAddress("2001:db8:1::")));
  122. EXPECT_TRUE(pool1.inRange(IOAddress("2001:db8:1::1")));
  123. EXPECT_TRUE(pool1.inRange(IOAddress("2001:db8:1::7")));
  124. EXPECT_TRUE(pool1.inRange(IOAddress("2001:db8:1::f")));
  125. EXPECT_FALSE(pool1.inRange(IOAddress("2001:db8:1::10")));
  126. EXPECT_FALSE(pool1.inRange(IOAddress("::")));
  127. }
  128. // This test creates 100 pools and verifies that their IDs are unique.
  129. TEST(Pool6Test, unique_id) {
  130. const int num_pools = 100;
  131. vector<Pool6Ptr> pools;
  132. for (int i = 0; i < num_pools; ++i) {
  133. pools.push_back(Pool6Ptr(new Pool6(Pool6::TYPE_IA, IOAddress("2001:db8:1::"),
  134. IOAddress("2001:db8:1::ffff:ffff:ffff:ffff"),
  135. 1000, 2000, 3000, 4000)));
  136. }
  137. for (int i = 0; i < num_pools; ++i) {
  138. for (int j = i + 1; j < num_pools; ++j) {
  139. if (pools[i]->getId() == pools[j]->getId()) {
  140. FAIL() << "Pool-ids must be unique";
  141. }
  142. }
  143. }
  144. }
  145. TEST(Subnet6Test, constructor) {
  146. EXPECT_NO_THROW(Subnet6 subnet1(IOAddress("2001:db8:1::"), 64));
  147. EXPECT_THROW(Subnet6 subnet2(IOAddress("2001:db8:1::"), 129),
  148. BadValue); // invalid prefix length
  149. EXPECT_THROW(Subnet6 subnet3(IOAddress("192.168.0.0"), 32),
  150. BadValue); // IPv4 addresses are not allowed in Subnet6
  151. }
  152. TEST(Subnet6Test, in_range) {
  153. Subnet6 subnet(IOAddress("2001:db8:1::"), 64);
  154. EXPECT_FALSE(subnet.inRange(IOAddress("2001:db8:0:ffff:ffff:ffff:ffff:ffff")));
  155. EXPECT_TRUE(subnet.inRange(IOAddress("2001:db8:1::0")));
  156. EXPECT_TRUE(subnet.inRange(IOAddress("2001:db8:1::1")));
  157. EXPECT_TRUE(subnet.inRange(IOAddress("2001:db8:1::ffff:ffff:ffff:ffff")));
  158. EXPECT_FALSE(subnet.inRange(IOAddress("2001:db8:1:1::")));
  159. EXPECT_FALSE(subnet.inRange(IOAddress("::")));
  160. }
  161. TEST(Subnet6Test, Pool6InSubnet6) {
  162. Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56));
  163. Pool6Ptr pool1(new Pool6(Pool6::TYPE_IA, IOAddress("2001:db8:1:1::"),
  164. 64, 101, 102, 103, 104));
  165. Pool6Ptr pool2(new Pool6(Pool6::TYPE_IA, IOAddress("2001:db8:1:2::"),
  166. 64, 201, 202, 203, 204));
  167. Pool6Ptr pool3(new Pool6(Pool6::TYPE_IA, IOAddress("2001:db8:1:3::"),
  168. 64, 301, 302, 303, 304));
  169. subnet->addPool6(pool1);
  170. // If there's only one pool, get that pool
  171. Pool6Ptr mypool = subnet->getPool6();
  172. EXPECT_EQ(mypool, pool1);
  173. subnet->addPool6(pool2);
  174. subnet->addPool6(pool3);
  175. // If there are more than one pool and we didn't provide hint, we
  176. // should get the first pool
  177. mypool = subnet->getPool6();
  178. EXPECT_EQ(mypool, pool1);
  179. // If we provide a hint, we should get a pool that this hint belongs to
  180. mypool = subnet->getPool6(IOAddress("2001:db8:1:3::dead:beef"));
  181. EXPECT_EQ(mypool, pool3);
  182. }
  183. TEST(Subnet6Test, Subnet6_Pool6_checks) {
  184. Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56));
  185. // this one is in subnet
  186. Pool6Ptr pool1(new Pool6(Pool6::TYPE_IA, IOAddress("2001:db8:1:1::"),
  187. 64, 101, 102, 103, 104));
  188. subnet->addPool6(pool1);
  189. Pool6Ptr pool2(new Pool6(Pool6::TYPE_IA, IOAddress("2001:db8::"),
  190. 48, 201, 202, 203, 204)); // this one is larger than the subnet!
  191. EXPECT_THROW(subnet->addPool6(pool2), BadValue);
  192. // this one is totally out of blue
  193. Pool6Ptr pool3(new Pool6(Pool6::TYPE_IA, IOAddress("3000::"),
  194. 16, 301, 302, 303, 304));
  195. EXPECT_THROW(subnet->addPool6(pool3), BadValue);
  196. }
  197. // This test verifies if the configuration manager is able to hold and return
  198. // valid leases
  199. TEST(CfgMgrTest, subnet6) {
  200. CfgMgr& cfg_mgr = CfgMgr::instance();
  201. ASSERT_TRUE(&cfg_mgr != 0);
  202. Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"), 48));
  203. Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 48));
  204. Subnet6Ptr subnet3(new Subnet6(IOAddress("4000::"), 48));
  205. // there shouldn't be any subnet configured at this stage
  206. EXPECT_EQ( Subnet6Ptr(), cfg_mgr.getSubnet6(IOAddress("2000::1")));
  207. cfg_mgr.addSubnet6(subnet1);
  208. // Now we have only one subnet, any request will be served from it
  209. EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(IOAddress("2001:db8::1")));
  210. cfg_mgr.addSubnet6(subnet2);
  211. cfg_mgr.addSubnet6(subnet3);
  212. EXPECT_EQ(subnet3, cfg_mgr.getSubnet6(IOAddress("4000::123")));
  213. EXPECT_EQ(subnet2, cfg_mgr.getSubnet6(IOAddress("3000::dead:beef")));
  214. EXPECT_EQ(Subnet6Ptr(), cfg_mgr.getSubnet6(IOAddress("5000::1")));
  215. }
  216. } // end of anonymous namespace