cfgmgr_unittest.cc 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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 <dhcpsrv/cfgmgr.h>
  16. #include <exceptions/exceptions.h>
  17. #include <gtest/gtest.h>
  18. #include <iostream>
  19. #include <sstream>
  20. #include <arpa/inet.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. class CfgMgrTest : public ::testing::Test {
  31. public:
  32. CfgMgrTest() {
  33. }
  34. ~CfgMgrTest() {
  35. CfgMgr::instance().deleteSubnets6();
  36. CfgMgr::instance().deleteOptionDefs();
  37. }
  38. };
  39. // This test verifies that multiple option definitions can be added
  40. // under different option spaces.
  41. TEST_F(CfgMgrTest, getOptionDefs) {
  42. CfgMgr& cfg_mgr = CfgMgr::instance();
  43. // Create a set of option definitions with codes between 100 and 109.
  44. for (uint16_t code = 100; code < 110; ++code) {
  45. std::ostringstream option_name;
  46. // Option name is unique, e.g. option-100, option-101 etc.
  47. option_name << "option-" << code;
  48. OptionDefinitionPtr def(new OptionDefinition(option_name.str(), code,
  49. "uint16"));
  50. // Add option definition to "isc" option space.
  51. // Option codes are not duplicated so expect no error
  52. // when adding them.
  53. ASSERT_NO_THROW(cfg_mgr.addOptionDef(def, "isc"));
  54. }
  55. // Create a set of option definitions with codes between 105 and 114 and
  56. // add them to the different option space.
  57. for (uint16_t code = 105; code < 115; ++code) {
  58. std::ostringstream option_name;
  59. option_name << "option-" << code;
  60. OptionDefinitionPtr def(new OptionDefinition(option_name.str(), code,
  61. "uint16"));
  62. ASSERT_NO_THROW(cfg_mgr.addOptionDef(def, "abcde"));
  63. }
  64. // Sanity check that all 10 option definitions are there.
  65. const OptionDefContainer& option_defs1 = cfg_mgr.getOptionDefs("isc");
  66. ASSERT_EQ(10, option_defs1.size());
  67. // Iterate over all option definitions and check that they have
  68. // valid codes. Also, their order should be the same as they
  69. // were added (codes 100-109).
  70. uint16_t code = 100;
  71. for (OptionDefContainer::const_iterator it = option_defs1.begin();
  72. it != option_defs1.end(); ++it, ++code) {
  73. OptionDefinitionPtr def(*it);
  74. ASSERT_TRUE(def);
  75. EXPECT_EQ(code, def->getCode());
  76. }
  77. // Sanity check that all 10 option definitions are there.
  78. const OptionDefContainer& option_defs2 = cfg_mgr.getOptionDefs("abcde");
  79. ASSERT_EQ(10, option_defs2.size());
  80. // Check that the option codes are valid.
  81. code = 105;
  82. for (OptionDefContainer::const_iterator it = option_defs2.begin();
  83. it != option_defs2.end(); ++it, ++code) {
  84. OptionDefinitionPtr def(*it);
  85. ASSERT_TRUE(def);
  86. EXPECT_EQ(code, def->getCode());
  87. }
  88. // Let's make one more check that the empty set is returned when
  89. // invalid option space is used.
  90. const OptionDefContainer& option_defs3 = cfg_mgr.getOptionDefs("non-existing");
  91. ASSERT_TRUE(option_defs3.empty());
  92. }
  93. // This test verifies that single option definition is correctly
  94. // returned with getOptionDef function.
  95. TEST_F(CfgMgrTest, getOptionDef) {
  96. CfgMgr& cfg_mgr = CfgMgr::instance();
  97. // Create a set of option definitions with codes between 100 and 109.
  98. for (uint16_t code = 100; code < 110; ++code) {
  99. std::ostringstream option_name;
  100. // Option name is unique, e.g. option-100, option-101 etc.
  101. option_name << "option-" << code;
  102. OptionDefinitionPtr def(new OptionDefinition(option_name.str(), code,
  103. "uint16"));
  104. // Add option definition to "isc" option space.
  105. // Option codes are not duplicated so expect no error
  106. // when adding them.
  107. ASSERT_NO_THROW(cfg_mgr.addOptionDef(def, "isc"));
  108. }
  109. // Create a set of option definitions with codes between 105 and 114 and
  110. // add them to the different option space.
  111. for (uint16_t code = 105; code < 115; ++code) {
  112. std::ostringstream option_name;
  113. option_name << "option-" << code;
  114. OptionDefinitionPtr def(new OptionDefinition(option_name.str(), code,
  115. "uint16"));
  116. ASSERT_NO_THROW(cfg_mgr.addOptionDef(def, "abcde"));
  117. }
  118. // Try to get option definitions one by one using all codes
  119. // that we expect to be there.
  120. for (uint16_t code = 100; code < 110; ++code) {
  121. OptionDefinitionPtr def = cfg_mgr.getOptionDef("isc", code);
  122. ASSERT_TRUE(def);
  123. EXPECT_EQ(code, def->getCode());
  124. }
  125. // Check that the option codes are valid.
  126. for (uint16_t code = 105; code < 115; ++code) {
  127. OptionDefinitionPtr def = cfg_mgr.getOptionDef("abcde", code);
  128. ASSERT_TRUE(def);
  129. EXPECT_EQ(code, def->getCode());
  130. }
  131. // Try to query the option definition from an non-existing
  132. // option space and expect NULL pointer.
  133. OptionDefinitionPtr def = cfg_mgr.getOptionDef("non-existing", 56);
  134. ASSERT_FALSE(def);
  135. }
  136. // This test verifies if the configuration manager is able to hold and return
  137. // valid leases
  138. TEST_F(CfgMgrTest, subnet4) {
  139. CfgMgr& cfg_mgr = CfgMgr::instance();
  140. Subnet4Ptr subnet1(new Subnet4(IOAddress("192.0.2.0"), 26, 1, 2, 3));
  141. Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.64"), 26, 1, 2, 3));
  142. Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.2.128"), 26, 1, 2, 3));
  143. // there shouldn't be any subnet configured at this stage
  144. EXPECT_EQ( Subnet4Ptr(), cfg_mgr.getSubnet4(IOAddress("192.0.2.0")));
  145. cfg_mgr.addSubnet4(subnet1);
  146. // Now we have only one subnet, any request will be served from it
  147. EXPECT_EQ(subnet1, cfg_mgr.getSubnet4(IOAddress("192.0.2.63")));
  148. // Now we add more subnets and check that both old and new subnets
  149. // are accessible.
  150. cfg_mgr.addSubnet4(subnet2);
  151. cfg_mgr.addSubnet4(subnet3);
  152. EXPECT_EQ(subnet3, cfg_mgr.getSubnet4(IOAddress("192.0.2.191")));
  153. EXPECT_EQ(subnet1, cfg_mgr.getSubnet4(IOAddress("192.0.2.15")));
  154. EXPECT_EQ(subnet2, cfg_mgr.getSubnet4(IOAddress("192.0.2.85")));
  155. // Try to find an address that does not belong to any subnet
  156. EXPECT_EQ(Subnet4Ptr(), cfg_mgr.getSubnet4(IOAddress("192.0.2.192")));
  157. }
  158. // This test verifies if the configuration manager is able to hold and return
  159. // valid leases
  160. TEST_F(CfgMgrTest, subnet6) {
  161. CfgMgr& cfg_mgr = CfgMgr::instance();
  162. Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"), 48, 1, 2, 3, 4));
  163. Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 48, 1, 2, 3, 4));
  164. Subnet6Ptr subnet3(new Subnet6(IOAddress("4000::"), 48, 1, 2, 3, 4));
  165. // there shouldn't be any subnet configured at this stage
  166. EXPECT_EQ( Subnet6Ptr(), cfg_mgr.getSubnet6(IOAddress("2000::1")));
  167. cfg_mgr.addSubnet6(subnet1);
  168. // Now we have only one subnet, any request will be served from it
  169. EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(IOAddress("2000::1")));
  170. // If we have only a single subnet and the request came from a local
  171. // address, let's use that subnet
  172. EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(IOAddress("fe80::dead:beef")));
  173. cfg_mgr.addSubnet6(subnet2);
  174. cfg_mgr.addSubnet6(subnet3);
  175. EXPECT_EQ(subnet3, cfg_mgr.getSubnet6(IOAddress("4000::123")));
  176. EXPECT_EQ(subnet2, cfg_mgr.getSubnet6(IOAddress("3000::dead:beef")));
  177. EXPECT_EQ(Subnet6Ptr(), cfg_mgr.getSubnet6(IOAddress("5000::1")));
  178. cfg_mgr.deleteSubnets6();
  179. EXPECT_EQ(Subnet6Ptr(), cfg_mgr.getSubnet6(IOAddress("200::123")));
  180. EXPECT_EQ(Subnet6Ptr(), cfg_mgr.getSubnet6(IOAddress("3000::123")));
  181. EXPECT_EQ(Subnet6Ptr(), cfg_mgr.getSubnet6(IOAddress("4000::123")));
  182. }
  183. } // end of anonymous namespace