cfgmgr_unittest.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. // Copyright (C) 2012-2013 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 <dhcpsrv/dhcp_parsers.h>
  17. #include <exceptions/exceptions.h>
  18. #include <dhcp/dhcp6.h>
  19. #include <gtest/gtest.h>
  20. #include <iostream>
  21. #include <sstream>
  22. #include <arpa/inet.h>
  23. using namespace std;
  24. using namespace isc::asiolink;
  25. using namespace isc::dhcp;
  26. using namespace isc::util;
  27. using namespace isc;
  28. // don't import the entire boost namespace. It will unexpectedly hide uint8_t
  29. // for some systems.
  30. using boost::scoped_ptr;
  31. namespace {
  32. // This test verifies that BooleanStorage functions properly.
  33. TEST(ValueStorageTest, BooleanTesting) {
  34. BooleanStorage testStore;
  35. // Verify that we can add and retrieve parameters.
  36. testStore.setParam("firstBool", false);
  37. testStore.setParam("secondBool", true);
  38. EXPECT_FALSE(testStore.getParam("firstBool"));
  39. EXPECT_TRUE(testStore.getParam("secondBool"));
  40. // Verify that we can update parameters.
  41. testStore.setParam("firstBool", true);
  42. testStore.setParam("secondBool", false);
  43. EXPECT_TRUE(testStore.getParam("firstBool"));
  44. EXPECT_FALSE(testStore.getParam("secondBool"));
  45. // Verify that we can delete a parameter and it will no longer be found.
  46. testStore.delParam("firstBool");
  47. EXPECT_THROW(testStore.getParam("firstBool"), isc::dhcp::DhcpConfigError);
  48. // Verify that the delete was safe and the store still operates.
  49. EXPECT_FALSE(testStore.getParam("secondBool"));
  50. // Verify that looking for a parameter that never existed throws.
  51. ASSERT_THROW(testStore.getParam("bogusBool"), isc::dhcp::DhcpConfigError);
  52. // Verify that attempting to delete a parameter that never existed does not throw.
  53. EXPECT_NO_THROW(testStore.delParam("bogusBool"));
  54. // Verify that we can empty the list.
  55. testStore.clear();
  56. EXPECT_THROW(testStore.getParam("secondBool"), isc::dhcp::DhcpConfigError);
  57. }
  58. // This test verifies that Uint32Storage functions properly.
  59. TEST(ValueStorageTest, Uint32Testing) {
  60. Uint32Storage testStore;
  61. uint32_t intOne = 77;
  62. uint32_t intTwo = 33;
  63. // Verify that we can add and retrieve parameters.
  64. testStore.setParam("firstInt", intOne);
  65. testStore.setParam("secondInt", intTwo);
  66. EXPECT_EQ(testStore.getParam("firstInt"), intOne);
  67. EXPECT_EQ(testStore.getParam("secondInt"), intTwo);
  68. // Verify that we can update parameters.
  69. testStore.setParam("firstInt", --intOne);
  70. testStore.setParam("secondInt", ++intTwo);
  71. EXPECT_EQ(testStore.getParam("firstInt"), intOne);
  72. EXPECT_EQ(testStore.getParam("secondInt"), intTwo);
  73. // Verify that we can delete a parameter and it will no longer be found.
  74. testStore.delParam("firstInt");
  75. EXPECT_THROW(testStore.getParam("firstInt"), isc::dhcp::DhcpConfigError);
  76. // Verify that the delete was safe and the store still operates.
  77. EXPECT_EQ(testStore.getParam("secondInt"), intTwo);
  78. // Verify that looking for a parameter that never existed throws.
  79. ASSERT_THROW(testStore.getParam("bogusInt"), isc::dhcp::DhcpConfigError);
  80. // Verify that attempting to delete a parameter that never existed does not throw.
  81. EXPECT_NO_THROW(testStore.delParam("bogusInt"));
  82. // Verify that we can empty the list.
  83. testStore.clear();
  84. EXPECT_THROW(testStore.getParam("secondInt"), isc::dhcp::DhcpConfigError);
  85. }
  86. // This test verifies that StringStorage functions properly.
  87. TEST(ValueStorageTest, StringTesting) {
  88. StringStorage testStore;
  89. std::string stringOne = "seventy-seven";
  90. std::string stringTwo = "thirty-three";
  91. // Verify that we can add and retrieve parameters.
  92. testStore.setParam("firstString", stringOne);
  93. testStore.setParam("secondString", stringTwo);
  94. EXPECT_EQ(testStore.getParam("firstString"), stringOne);
  95. EXPECT_EQ(testStore.getParam("secondString"), stringTwo);
  96. // Verify that we can update parameters.
  97. stringOne.append("-boo");
  98. stringTwo.append("-boo");
  99. testStore.setParam("firstString", stringOne);
  100. testStore.setParam("secondString", stringTwo);
  101. EXPECT_EQ(testStore.getParam("firstString"), stringOne);
  102. EXPECT_EQ(testStore.getParam("secondString"), stringTwo);
  103. // Verify that we can delete a parameter and it will no longer be found.
  104. testStore.delParam("firstString");
  105. EXPECT_THROW(testStore.getParam("firstString"), isc::dhcp::DhcpConfigError);
  106. // Verify that the delete was safe and the store still operates.
  107. EXPECT_EQ(testStore.getParam("secondString"), stringTwo);
  108. // Verify that looking for a parameter that never existed throws.
  109. ASSERT_THROW(testStore.getParam("bogusString"), isc::dhcp::DhcpConfigError);
  110. // Verify that attempting to delete a parameter that never existed does not throw.
  111. EXPECT_NO_THROW(testStore.delParam("bogusString"));
  112. // Verify that we can empty the list.
  113. testStore.clear();
  114. EXPECT_THROW(testStore.getParam("secondString"), isc::dhcp::DhcpConfigError);
  115. }
  116. class CfgMgrTest : public ::testing::Test {
  117. public:
  118. CfgMgrTest() {
  119. // make sure we start with a clean configuration
  120. CfgMgr::instance().deleteSubnets4();
  121. CfgMgr::instance().deleteSubnets6();
  122. CfgMgr::instance().deleteOptionDefs();
  123. CfgMgr::instance().deleteActiveIfaces();
  124. }
  125. /// @brief generates interface-id option based on provided text
  126. ///
  127. /// @param text content of the option to be created
  128. ///
  129. /// @return pointer to the option object created
  130. OptionPtr generateInterfaceId(const string& text) {
  131. OptionBuffer buffer(text.begin(), text.end());
  132. return OptionPtr(new Option(Option::V6, D6O_INTERFACE_ID, buffer));
  133. }
  134. ~CfgMgrTest() {
  135. // clean up after the test
  136. CfgMgr::instance().deleteSubnets4();
  137. CfgMgr::instance().deleteSubnets6();
  138. CfgMgr::instance().deleteOptionDefs();
  139. }
  140. };
  141. // This test verifies that multiple option definitions can be added
  142. // under different option spaces.
  143. TEST_F(CfgMgrTest, getOptionDefs) {
  144. CfgMgr& cfg_mgr = CfgMgr::instance();
  145. // Create a set of option definitions with codes between 100 and 109.
  146. for (uint16_t code = 100; code < 110; ++code) {
  147. std::ostringstream option_name;
  148. // Option name is unique, e.g. option-100, option-101 etc.
  149. option_name << "option-" << code;
  150. OptionDefinitionPtr def(new OptionDefinition(option_name.str(), code,
  151. "uint16"));
  152. // Add option definition to "isc" option space.
  153. // Option codes are not duplicated so expect no error
  154. // when adding them.
  155. ASSERT_NO_THROW(cfg_mgr.addOptionDef(def, "isc"));
  156. }
  157. // Create a set of option definitions with codes between 105 and 114 and
  158. // add them to the different option space.
  159. for (uint16_t code = 105; code < 115; ++code) {
  160. std::ostringstream option_name;
  161. option_name << "option-" << code;
  162. OptionDefinitionPtr def(new OptionDefinition(option_name.str(), code,
  163. "uint16"));
  164. ASSERT_NO_THROW(cfg_mgr.addOptionDef(def, "abcde"));
  165. }
  166. // Sanity check that all 10 option definitions are there.
  167. OptionDefContainerPtr option_defs1 = cfg_mgr.getOptionDefs("isc");
  168. ASSERT_TRUE(option_defs1);
  169. ASSERT_EQ(10, option_defs1->size());
  170. // Iterate over all option definitions and check that they have
  171. // valid codes. Also, their order should be the same as they
  172. // were added (codes 100-109).
  173. uint16_t code = 100;
  174. for (OptionDefContainer::const_iterator it = option_defs1->begin();
  175. it != option_defs1->end(); ++it, ++code) {
  176. OptionDefinitionPtr def(*it);
  177. ASSERT_TRUE(def);
  178. EXPECT_EQ(code, def->getCode());
  179. }
  180. // Sanity check that all 10 option definitions are there.
  181. OptionDefContainerPtr option_defs2 = cfg_mgr.getOptionDefs("abcde");
  182. ASSERT_TRUE(option_defs2);
  183. ASSERT_EQ(10, option_defs2->size());
  184. // Check that the option codes are valid.
  185. code = 105;
  186. for (OptionDefContainer::const_iterator it = option_defs2->begin();
  187. it != option_defs2->end(); ++it, ++code) {
  188. OptionDefinitionPtr def(*it);
  189. ASSERT_TRUE(def);
  190. EXPECT_EQ(code, def->getCode());
  191. }
  192. // Let's make one more check that the empty set is returned when
  193. // invalid option space is used.
  194. OptionDefContainerPtr option_defs3 = cfg_mgr.getOptionDefs("non-existing");
  195. ASSERT_TRUE(option_defs3);
  196. EXPECT_TRUE(option_defs3->empty());
  197. }
  198. // This test verifies that single option definition is correctly
  199. // returned with getOptionDef function.
  200. TEST_F(CfgMgrTest, getOptionDef) {
  201. CfgMgr& cfg_mgr = CfgMgr::instance();
  202. // Create a set of option definitions with codes between 100 and 109.
  203. for (uint16_t code = 100; code < 110; ++code) {
  204. std::ostringstream option_name;
  205. // Option name is unique, e.g. option-100, option-101 etc.
  206. option_name << "option-" << code;
  207. OptionDefinitionPtr def(new OptionDefinition(option_name.str(), code,
  208. "uint16"));
  209. // Add option definition to "isc" option space.
  210. // Option codes are not duplicated so expect no error
  211. // when adding them.
  212. ASSERT_NO_THROW(cfg_mgr.addOptionDef(def, "isc"));
  213. }
  214. // Create a set of option definitions with codes between 105 and 114 and
  215. // add them to the different option space.
  216. for (uint16_t code = 105; code < 115; ++code) {
  217. std::ostringstream option_name;
  218. option_name << "option-other-" << code;
  219. OptionDefinitionPtr def(new OptionDefinition(option_name.str(), code,
  220. "uint16"));
  221. ASSERT_NO_THROW(cfg_mgr.addOptionDef(def, "abcde"));
  222. }
  223. // Try to get option definitions one by one using all codes
  224. // that we expect to be there.
  225. for (uint16_t code = 100; code < 110; ++code) {
  226. OptionDefinitionPtr def = cfg_mgr.getOptionDef("isc", code);
  227. ASSERT_TRUE(def);
  228. // Check that the option name is in the format of 'option-[code]'.
  229. // That way we make sure that the options that have the same codes
  230. // within different option spaces are different.
  231. std::ostringstream option_name;
  232. option_name << "option-" << code;
  233. EXPECT_EQ(option_name.str(), def->getName());
  234. EXPECT_EQ(code, def->getCode());
  235. }
  236. // Check that the option codes are valid.
  237. for (uint16_t code = 105; code < 115; ++code) {
  238. OptionDefinitionPtr def = cfg_mgr.getOptionDef("abcde", code);
  239. ASSERT_TRUE(def);
  240. // Check that the option name is in the format of 'option-other-[code]'.
  241. // That way we make sure that the options that have the same codes
  242. // within different option spaces are different.
  243. std::ostringstream option_name;
  244. option_name << "option-other-" << code;
  245. EXPECT_EQ(option_name.str(), def->getName());
  246. EXPECT_EQ(code, def->getCode());
  247. }
  248. // Check that an option definition can be added to the standard
  249. // (dhcp4 and dhcp6) option spaces when the option code is not
  250. // reserved by the standard option.
  251. OptionDefinitionPtr def6(new OptionDefinition("option-foo", 79, "uint16"));
  252. EXPECT_NO_THROW(cfg_mgr.addOptionDef(def6, "dhcp6"));
  253. OptionDefinitionPtr def4(new OptionDefinition("option-foo", 222, "uint16"));
  254. EXPECT_NO_THROW(cfg_mgr.addOptionDef(def4, "dhcp4"));
  255. // Try to query the option definition from an non-existing
  256. // option space and expect NULL pointer.
  257. OptionDefinitionPtr def = cfg_mgr.getOptionDef("non-existing", 56);
  258. EXPECT_FALSE(def);
  259. // Try to get the non-existing option definition from an
  260. // existing option space.
  261. EXPECT_FALSE(cfg_mgr.getOptionDef("isc", 56));
  262. }
  263. // This test verifies that the function that adds new option definition
  264. // throws exceptions when arguments are invalid.
  265. TEST_F(CfgMgrTest, addOptionDefNegative) {
  266. CfgMgr& cfg_mgr = CfgMgr::instance();
  267. // The option code 65 is reserved for standard options either in
  268. // DHCPv4 or DHCPv6. Thus we expect that adding an option to this
  269. // option space fails.
  270. OptionDefinitionPtr def(new OptionDefinition("option-foo", 65, "uint16"));
  271. // Try reserved option space names.
  272. ASSERT_THROW(cfg_mgr.addOptionDef(def, "dhcp4"), isc::BadValue);
  273. ASSERT_THROW(cfg_mgr.addOptionDef(def, "dhcp6"), isc::BadValue);
  274. // Try empty option space name.
  275. ASSERT_THROW(cfg_mgr.addOptionDef(def, ""), isc::BadValue);
  276. // Try NULL option definition.
  277. ASSERT_THROW(cfg_mgr.addOptionDef(OptionDefinitionPtr(), "isc"),
  278. isc::dhcp::MalformedOptionDefinition);
  279. // Try adding option definition twice and make sure that it
  280. // fails on the second attempt.
  281. ASSERT_NO_THROW(cfg_mgr.addOptionDef(def, "isc"));
  282. EXPECT_THROW(cfg_mgr.addOptionDef(def, "isc"), DuplicateOptionDefinition);
  283. }
  284. // This test verifies if the configuration manager is able to hold and return
  285. // valid leases
  286. TEST_F(CfgMgrTest, subnet4) {
  287. CfgMgr& cfg_mgr = CfgMgr::instance();
  288. Subnet4Ptr subnet1(new Subnet4(IOAddress("192.0.2.0"), 26, 1, 2, 3));
  289. Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.64"), 26, 1, 2, 3));
  290. Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.2.128"), 26, 1, 2, 3));
  291. // There shouldn't be any subnet configured at this stage
  292. EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.0")));
  293. cfg_mgr.addSubnet4(subnet1);
  294. // Now we have only one subnet, any request will be served from it
  295. EXPECT_EQ(subnet1, cfg_mgr.getSubnet4(IOAddress("192.0.2.63")));
  296. // Now we add more subnets and check that both old and new subnets
  297. // are accessible.
  298. cfg_mgr.addSubnet4(subnet2);
  299. cfg_mgr.addSubnet4(subnet3);
  300. EXPECT_EQ(subnet3, cfg_mgr.getSubnet4(IOAddress("192.0.2.191")));
  301. EXPECT_EQ(subnet1, cfg_mgr.getSubnet4(IOAddress("192.0.2.15")));
  302. EXPECT_EQ(subnet2, cfg_mgr.getSubnet4(IOAddress("192.0.2.85")));
  303. // Try to find an address that does not belong to any subnet
  304. EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.192")));
  305. // Check that deletion of the subnets works.
  306. cfg_mgr.deleteSubnets4();
  307. EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.191")));
  308. EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.15")));
  309. EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.85")));
  310. }
  311. // This test verifies if the configuration manager is able to hold and return
  312. // valid leases
  313. TEST_F(CfgMgrTest, subnet6) {
  314. CfgMgr& cfg_mgr = CfgMgr::instance();
  315. Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"), 48, 1, 2, 3, 4));
  316. Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 48, 1, 2, 3, 4));
  317. Subnet6Ptr subnet3(new Subnet6(IOAddress("4000::"), 48, 1, 2, 3, 4));
  318. // There shouldn't be any subnet configured at this stage
  319. EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("2000::1")));
  320. cfg_mgr.addSubnet6(subnet1);
  321. // Now we have only one subnet, any request will be served from it
  322. EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(IOAddress("2000::1")));
  323. // If we have only a single subnet and the request came from a local
  324. // address, let's use that subnet
  325. EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(IOAddress("fe80::dead:beef")));
  326. cfg_mgr.addSubnet6(subnet2);
  327. cfg_mgr.addSubnet6(subnet3);
  328. EXPECT_EQ(subnet3, cfg_mgr.getSubnet6(IOAddress("4000::123")));
  329. EXPECT_EQ(subnet2, cfg_mgr.getSubnet6(IOAddress("3000::dead:beef")));
  330. EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("5000::1")));
  331. // Check that deletion of the subnets works.
  332. cfg_mgr.deleteSubnets6();
  333. EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("200::123")));
  334. EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("3000::123")));
  335. EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("4000::123")));
  336. }
  337. // This test verifies if the configuration manager is able to hold, select
  338. // and return valid subnets, based on interface names.
  339. TEST_F(CfgMgrTest, subnet6Interface) {
  340. CfgMgr& cfg_mgr = CfgMgr::instance();
  341. Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"), 48, 1, 2, 3, 4));
  342. Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 48, 1, 2, 3, 4));
  343. Subnet6Ptr subnet3(new Subnet6(IOAddress("4000::"), 48, 1, 2, 3, 4));
  344. subnet1->setIface("foo");
  345. subnet2->setIface("bar");
  346. subnet3->setIface("foobar");
  347. // There shouldn't be any subnet configured at this stage
  348. EXPECT_FALSE(cfg_mgr.getSubnet6("foo"));
  349. cfg_mgr.addSubnet6(subnet1);
  350. // Now we have only one subnet, any request will be served from it
  351. EXPECT_EQ(subnet1, cfg_mgr.getSubnet6("foo"));
  352. // Check that the interface name is checked even when there is
  353. // only one subnet defined.
  354. EXPECT_FALSE(cfg_mgr.getSubnet6("bar"));
  355. // If we have only a single subnet and the request came from a local
  356. // address, let's use that subnet
  357. EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(IOAddress("fe80::dead:beef")));
  358. cfg_mgr.addSubnet6(subnet2);
  359. cfg_mgr.addSubnet6(subnet3);
  360. EXPECT_EQ(subnet3, cfg_mgr.getSubnet6("foobar"));
  361. EXPECT_EQ(subnet2, cfg_mgr.getSubnet6("bar"));
  362. EXPECT_FALSE(cfg_mgr.getSubnet6("xyzzy")); // no such interface
  363. // Check that deletion of the subnets works.
  364. cfg_mgr.deleteSubnets6();
  365. EXPECT_FALSE(cfg_mgr.getSubnet6("foo"));
  366. EXPECT_FALSE(cfg_mgr.getSubnet6("bar"));
  367. EXPECT_FALSE(cfg_mgr.getSubnet6("foobar"));
  368. }
  369. // This test verifies if the configuration manager is able to hold, select
  370. // and return valid leases, based on interface-id option values
  371. TEST_F(CfgMgrTest, subnet6InterfaceId) {
  372. CfgMgr& cfg_mgr = CfgMgr::instance();
  373. Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"), 48, 1, 2, 3, 4));
  374. Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 48, 1, 2, 3, 4));
  375. Subnet6Ptr subnet3(new Subnet6(IOAddress("4000::"), 48, 1, 2, 3, 4));
  376. // interface-id options used in subnets 1,2, and 3
  377. OptionPtr ifaceid1 = generateInterfaceId("relay1.eth0");
  378. OptionPtr ifaceid2 = generateInterfaceId("VL32");
  379. // That's a strange interface-id, but this is a real life example
  380. OptionPtr ifaceid3 = generateInterfaceId("ISAM144|299|ipv6|nt:vp:1:110");
  381. // bogus interface-id
  382. OptionPtr ifaceid_bogus = generateInterfaceId("non-existent");
  383. subnet1->setInterfaceId(ifaceid1);
  384. subnet2->setInterfaceId(ifaceid2);
  385. subnet3->setInterfaceId(ifaceid3);
  386. // There shouldn't be any subnet configured at this stage
  387. EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid1));
  388. cfg_mgr.addSubnet6(subnet1);
  389. // If we have only a single subnet and the request came from a local
  390. // address, let's use that subnet
  391. EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(ifaceid1));
  392. EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid2));
  393. cfg_mgr.addSubnet6(subnet2);
  394. cfg_mgr.addSubnet6(subnet3);
  395. EXPECT_EQ(subnet3, cfg_mgr.getSubnet6(ifaceid3));
  396. EXPECT_EQ(subnet2, cfg_mgr.getSubnet6(ifaceid2));
  397. EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid_bogus));
  398. // Check that deletion of the subnets works.
  399. cfg_mgr.deleteSubnets6();
  400. EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid1));
  401. EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid2));
  402. EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid3));
  403. }
  404. // This test verifies that new DHCPv4 option spaces can be added to
  405. // the configuration manager and that duplicated option space is
  406. // rejected.
  407. TEST_F(CfgMgrTest, optionSpace4) {
  408. CfgMgr& cfg_mgr = CfgMgr::instance();
  409. // Create some option spaces.
  410. OptionSpacePtr space1(new OptionSpace("isc", false));
  411. OptionSpacePtr space2(new OptionSpace("xyz", true));
  412. // Add option spaces with different names and expect they
  413. // are accepted.
  414. ASSERT_NO_THROW(cfg_mgr.addOptionSpace4(space1));
  415. ASSERT_NO_THROW(cfg_mgr.addOptionSpace4(space2));
  416. // Validate that the option spaces have been added correctly.
  417. const OptionSpaceCollection& spaces = cfg_mgr.getOptionSpaces4();
  418. ASSERT_EQ(2, spaces.size());
  419. EXPECT_FALSE(spaces.find("isc") == spaces.end());
  420. EXPECT_FALSE(spaces.find("xyz") == spaces.end());
  421. // Create another option space with the name that duplicates
  422. // the existing option space.
  423. OptionSpacePtr space3(new OptionSpace("isc", true));
  424. // Expect that the duplicate option space is rejected.
  425. ASSERT_THROW(
  426. cfg_mgr.addOptionSpace4(space3), isc::dhcp::InvalidOptionSpace
  427. );
  428. // @todo decode if a duplicate vendor space is allowed.
  429. }
  430. // This test verifies that new DHCPv6 option spaces can be added to
  431. // the configuration manager and that duplicated option space is
  432. // rejected.
  433. TEST_F(CfgMgrTest, optionSpace6) {
  434. CfgMgr& cfg_mgr = CfgMgr::instance();
  435. // Create some option spaces.
  436. OptionSpacePtr space1(new OptionSpace("isc", false));
  437. OptionSpacePtr space2(new OptionSpace("xyz", true));
  438. // Add option spaces with different names and expect they
  439. // are accepted.
  440. ASSERT_NO_THROW(cfg_mgr.addOptionSpace6(space1));
  441. ASSERT_NO_THROW(cfg_mgr.addOptionSpace6(space2));
  442. // Validate that the option spaces have been added correctly.
  443. const OptionSpaceCollection& spaces = cfg_mgr.getOptionSpaces6();
  444. ASSERT_EQ(2, spaces.size());
  445. EXPECT_FALSE(spaces.find("isc") == spaces.end());
  446. EXPECT_FALSE(spaces.find("xyz") == spaces.end());
  447. // Create another option space with the name that duplicates
  448. // the existing option space.
  449. OptionSpacePtr space3(new OptionSpace("isc", true));
  450. // Expect that the duplicate option space is rejected.
  451. ASSERT_THROW(
  452. cfg_mgr.addOptionSpace6(space3), isc::dhcp::InvalidOptionSpace
  453. );
  454. // @todo decide if a duplicate vendor space is allowed.
  455. }
  456. // This test verifies that it is possible to specify interfaces that server
  457. // should listen on.
  458. TEST_F(CfgMgrTest, addActiveIface) {
  459. CfgMgr& cfg_mgr = CfgMgr::instance();
  460. cfg_mgr.addActiveIface("eth0");
  461. cfg_mgr.addActiveIface("eth1");
  462. EXPECT_TRUE(cfg_mgr.isActiveIface("eth0"));
  463. EXPECT_TRUE(cfg_mgr.isActiveIface("eth1"));
  464. EXPECT_FALSE(cfg_mgr.isActiveIface("eth2"));
  465. cfg_mgr.deleteActiveIfaces();
  466. EXPECT_FALSE(cfg_mgr.isActiveIface("eth0"));
  467. EXPECT_FALSE(cfg_mgr.isActiveIface("eth1"));
  468. EXPECT_FALSE(cfg_mgr.isActiveIface("eth2"));
  469. }
  470. // This test verifies that it is possible to specify interfaces that server
  471. // should listen on.
  472. TEST_F(CfgMgrTest, addUnicastAddresses) {
  473. CfgMgr& cfg_mgr = CfgMgr::instance();
  474. cfg_mgr.addActiveIface("eth1/2001:db8::1");
  475. cfg_mgr.addActiveIface("eth2/2001:db8::2");
  476. cfg_mgr.addActiveIface("eth3");
  477. EXPECT_TRUE(cfg_mgr.isActiveIface("eth1"));
  478. EXPECT_TRUE(cfg_mgr.isActiveIface("eth2"));
  479. EXPECT_TRUE(cfg_mgr.isActiveIface("eth3"));
  480. EXPECT_FALSE(cfg_mgr.isActiveIface("eth4"));
  481. ASSERT_TRUE(cfg_mgr.getUnicast("eth1"));
  482. EXPECT_EQ("2001:db8::1", cfg_mgr.getUnicast("eth1")->toText());
  483. EXPECT_EQ("2001:db8::2", cfg_mgr.getUnicast("eth2")->toText());
  484. EXPECT_FALSE(cfg_mgr.getUnicast("eth3"));
  485. EXPECT_FALSE(cfg_mgr.getUnicast("eth4"));
  486. cfg_mgr.deleteActiveIfaces();
  487. EXPECT_FALSE(cfg_mgr.isActiveIface("eth1"));
  488. EXPECT_FALSE(cfg_mgr.isActiveIface("eth2"));
  489. EXPECT_FALSE(cfg_mgr.isActiveIface("eth3"));
  490. EXPECT_FALSE(cfg_mgr.isActiveIface("eth4"));
  491. ASSERT_FALSE(cfg_mgr.getUnicast("eth1"));
  492. ASSERT_FALSE(cfg_mgr.getUnicast("eth2"));
  493. EXPECT_FALSE(cfg_mgr.getUnicast("eth3"));
  494. EXPECT_FALSE(cfg_mgr.getUnicast("eth4"));
  495. }
  496. // This test verifies that it is possible to set the flag which configures the
  497. // server to listen on all interfaces.
  498. TEST_F(CfgMgrTest, activateAllIfaces) {
  499. CfgMgr& cfg_mgr = CfgMgr::instance();
  500. cfg_mgr.addActiveIface("eth0");
  501. cfg_mgr.addActiveIface("eth1");
  502. ASSERT_TRUE(cfg_mgr.isActiveIface("eth0"));
  503. ASSERT_TRUE(cfg_mgr.isActiveIface("eth1"));
  504. ASSERT_FALSE(cfg_mgr.isActiveIface("eth2"));
  505. cfg_mgr.activateAllIfaces();
  506. EXPECT_TRUE(cfg_mgr.isActiveIface("eth0"));
  507. EXPECT_TRUE(cfg_mgr.isActiveIface("eth1"));
  508. EXPECT_TRUE(cfg_mgr.isActiveIface("eth2"));
  509. cfg_mgr.deleteActiveIfaces();
  510. EXPECT_FALSE(cfg_mgr.isActiveIface("eth0"));
  511. EXPECT_FALSE(cfg_mgr.isActiveIface("eth1"));
  512. EXPECT_FALSE(cfg_mgr.isActiveIface("eth2"));
  513. }
  514. // No specific tests for getSubnet6. That method (2 overloaded versions) is tested
  515. // in Dhcpv6SrvTest.selectSubnetAddr and Dhcpv6SrvTest.selectSubnetIface
  516. // (see src/bin/dhcp6/tests/dhcp6_srv_unittest.cc)
  517. } // end of anonymous namespace