generic_host_data_source_unittest.cc 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378
  1. // Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <dhcp/dhcp6.h>
  7. #include <dhcp/libdhcp++.h>
  8. #include <dhcp/option4_addrlst.h>
  9. #include <dhcp/option6_addrlst.h>
  10. #include <dhcp/option_space.h>
  11. #include <dhcp/option_string.h>
  12. #include <dhcp/option_int.h>
  13. #include <dhcp/option_vendor.h>
  14. #include <dhcpsrv/tests/generic_host_data_source_unittest.h>
  15. #include <dhcpsrv/tests/test_utils.h>
  16. #include <dhcpsrv/database_connection.h>
  17. #include <asiolink/io_address.h>
  18. #include <util/buffer.h>
  19. #include <boost/foreach.hpp>
  20. #include <gtest/gtest.h>
  21. #include <cstring>
  22. #include <list>
  23. #include <string>
  24. #include <sstream>
  25. #include <typeinfo>
  26. using namespace std;
  27. using namespace isc::asiolink;
  28. using namespace isc::util;
  29. namespace isc {
  30. namespace dhcp {
  31. namespace test {
  32. GenericHostDataSourceTest::GenericHostDataSourceTest()
  33. :hdsptr_() {
  34. LibDHCP::clearRuntimeOptionDefs();
  35. }
  36. GenericHostDataSourceTest::~GenericHostDataSourceTest() {
  37. LibDHCP::clearRuntimeOptionDefs();
  38. }
  39. std::vector<uint8_t>
  40. GenericHostDataSourceTest::generateHWAddr(const bool new_identifier) {
  41. /// @todo: Consider moving this somewhere to lib/testutils.
  42. // Let's use something that is easily printable. That's convenient
  43. // if you need to enter MySQL queries by hand.
  44. static uint8_t hwaddr[] = {65, 66, 67, 68, 69, 70};
  45. if (new_identifier) {
  46. // Increase the address for the next time we use it.
  47. // This is primitive, but will work for 65k unique
  48. // addresses.
  49. hwaddr[sizeof(hwaddr) - 1]++;
  50. if (hwaddr[sizeof(hwaddr) - 1] == 0) {
  51. hwaddr[sizeof(hwaddr) - 2]++;
  52. }
  53. }
  54. return (std::vector<uint8_t>(hwaddr, hwaddr + sizeof(hwaddr)));
  55. }
  56. std::vector<uint8_t>
  57. GenericHostDataSourceTest::generateIdentifier(const bool new_identifier) {
  58. /// @todo: Consider moving this somewhere to lib/testutils.
  59. // Let's use something that is easily printable. That's convenient
  60. // if you need to enter MySQL queries by hand.
  61. static uint8_t ident[] = { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74 };
  62. // Increase the identifier for the next time we use it.
  63. // This is primitive, but will work for 65k unique
  64. // identifiers.
  65. if (new_identifier) {
  66. ident[sizeof(ident) - 1]++;
  67. if (ident[sizeof(ident) - 1] == 0) {
  68. ident[sizeof(ident) - 2]++;
  69. }
  70. }
  71. return (std::vector<uint8_t>(ident, ident + sizeof(ident)));
  72. }
  73. HostPtr
  74. GenericHostDataSourceTest::initializeHost4(const std::string& address,
  75. const Host::IdentifierType& id) {
  76. std::vector<uint8_t> ident;
  77. if (id == Host::IDENT_HWADDR) {
  78. ident = generateHWAddr();
  79. } else {
  80. ident = generateIdentifier();
  81. }
  82. // Let's create ever increasing subnet-ids. Let's keep those different,
  83. // so subnet4 != subnet6. Useful for catching cases if the code confuses
  84. // subnet4 with subnet6.
  85. static SubnetID subnet4 = 0;
  86. static SubnetID subnet6 = 100;
  87. ++subnet4;
  88. ++subnet6;
  89. IOAddress addr(address);
  90. HostPtr host(new Host(&ident[0], ident.size(), id, subnet4, subnet6, addr));
  91. return (host);
  92. }
  93. HostPtr GenericHostDataSourceTest::initializeHost6(std::string address,
  94. Host::IdentifierType identifier,
  95. bool prefix,
  96. bool new_identifier) {
  97. std::vector<uint8_t> ident;
  98. switch (identifier) {
  99. case Host::IDENT_HWADDR:
  100. ident = generateHWAddr(new_identifier);
  101. break;
  102. case Host::IDENT_DUID:
  103. ident = generateIdentifier(new_identifier);
  104. break;
  105. default:
  106. ADD_FAILURE() << "Unknown IdType: " << identifier;
  107. return HostPtr();
  108. }
  109. // Let's create ever increasing subnet-ids. Let's keep those different,
  110. // so subnet4 != subnet6. Useful for catching cases if the code confuses
  111. // subnet4 with subnet6.
  112. static SubnetID subnet4 = 0;
  113. static SubnetID subnet6 = 100;
  114. subnet4++;
  115. subnet6++;
  116. HostPtr host(new Host(&ident[0], ident.size(), identifier, subnet4,
  117. subnet6, IOAddress("0.0.0.0")));
  118. if (!prefix) {
  119. // Create IPv6 reservation (for an address)
  120. IPv6Resrv resv(IPv6Resrv::TYPE_NA, IOAddress(address), 128);
  121. host->addReservation(resv);
  122. } else {
  123. // Create IPv6 reservation for a /64 prefix
  124. IPv6Resrv resv(IPv6Resrv::TYPE_PD, IOAddress(address), 64);
  125. host->addReservation(resv);
  126. }
  127. return (host);
  128. }
  129. void
  130. GenericHostDataSourceTest::compareHwaddrs(const ConstHostPtr& host1,
  131. const ConstHostPtr& host2,
  132. bool expect_match) {
  133. ASSERT_TRUE(host1);
  134. ASSERT_TRUE(host2);
  135. // Compare if both have or have not HWaddress set.
  136. if ((host1->getHWAddress() && !host2->getHWAddress()) ||
  137. (!host1->getHWAddress() && host2->getHWAddress())) {
  138. // One host has hardware address set while the other has not.
  139. // Let's see if it's a problem.
  140. if (expect_match) {
  141. ADD_FAILURE() << "Host comparison failed: host1 hwaddress="
  142. << host1->getHWAddress() << ", host2 hwaddress="
  143. << host2->getHWAddress();
  144. }
  145. return;
  146. }
  147. // Now we know that either both or neither have hw address set.
  148. // If host1 has it, we can proceed to value comparison.
  149. if (host1->getHWAddress()) {
  150. if (expect_match) {
  151. // Compare the actual address if they match.
  152. EXPECT_TRUE(*host1->getHWAddress() == *host2->getHWAddress());
  153. } else {
  154. EXPECT_FALSE(*host1->getHWAddress() == *host2->getHWAddress());
  155. }
  156. if (*host1->getHWAddress() != *host2->getHWAddress()) {
  157. cout << host1->getHWAddress()->toText(true) << endl;
  158. cout << host2->getHWAddress()->toText(true) << endl;
  159. }
  160. }
  161. }
  162. void
  163. GenericHostDataSourceTest::compareDuids(const ConstHostPtr& host1,
  164. const ConstHostPtr& host2,
  165. bool expect_match) {
  166. ASSERT_TRUE(host1);
  167. ASSERT_TRUE(host2);
  168. // compare if both have or have not DUID set
  169. if ((host1->getDuid() && !host2->getDuid()) ||
  170. (!host1->getDuid() && host2->getDuid())) {
  171. // One host has a DUID and the other doesn't.
  172. // Let's see if it's a problem.
  173. if (expect_match) {
  174. ADD_FAILURE() << "DUID comparison failed: host1 duid="
  175. << host1->getDuid() << ", host2 duid="
  176. << host2->getDuid();
  177. }
  178. return;
  179. }
  180. // Now we know that either both or neither have DUID set.
  181. // If host1 has it, we can proceed to value comparison.
  182. if (host1->getDuid()) {
  183. if (expect_match) {
  184. EXPECT_TRUE(*host1->getDuid() == *host2->getDuid());
  185. } else {
  186. EXPECT_FALSE(*host1->getDuid() == *host2->getDuid());
  187. }
  188. if (*host1->getDuid() != *host2->getDuid()) {
  189. cout << host1->getDuid()->toText() << endl;
  190. cout << host2->getDuid()->toText() << endl;
  191. }
  192. }
  193. }
  194. void GenericHostDataSourceTest::compareHosts(const ConstHostPtr& host1,
  195. const ConstHostPtr& host2) {
  196. // Let's compare HW addresses and expect match.
  197. compareHwaddrs(host1, host2, true);
  198. // Now compare DUIDs
  199. compareDuids(host1, host2, true);
  200. // Now check that the identifiers returned as vectors are the same
  201. EXPECT_EQ(host1->getIdentifierType(), host2->getIdentifierType());
  202. EXPECT_TRUE(host1->getIdentifier() == host2->getIdentifier());
  203. // Check host parameters
  204. EXPECT_EQ(host1->getIPv4SubnetID(), host2->getIPv4SubnetID());
  205. EXPECT_EQ(host1->getIPv6SubnetID(), host2->getIPv6SubnetID());
  206. EXPECT_EQ(host1->getIPv4Reservation(), host2->getIPv4Reservation());
  207. EXPECT_EQ(host1->getHostname(), host2->getHostname());
  208. EXPECT_EQ(host1->getNextServer(), host2->getNextServer());
  209. EXPECT_EQ(host1->getServerHostname(), host2->getServerHostname());
  210. EXPECT_EQ(host1->getBootFileName(), host2->getBootFileName());
  211. // Compare IPv6 reservations
  212. compareReservations6(host1->getIPv6Reservations(),
  213. host2->getIPv6Reservations());
  214. // Compare client classification details
  215. compareClientClasses(host1->getClientClasses4(),
  216. host2->getClientClasses4());
  217. compareClientClasses(host1->getClientClasses6(),
  218. host2->getClientClasses6());
  219. // Compare DHCPv4 and DHCPv6 options.
  220. compareOptions(host1->getCfgOption4(), host2->getCfgOption4());
  221. compareOptions(host1->getCfgOption6(), host2->getCfgOption6());
  222. }
  223. DuidPtr
  224. GenericHostDataSourceTest::HWAddrToDuid(const HWAddrPtr& hwaddr) {
  225. if (!hwaddr) {
  226. return (DuidPtr());
  227. }
  228. return (DuidPtr(new DUID(hwaddr->hwaddr_)));
  229. }
  230. HWAddrPtr
  231. GenericHostDataSourceTest::DuidToHWAddr(const DuidPtr& duid) {
  232. if (!duid) {
  233. return (HWAddrPtr());
  234. }
  235. return (HWAddrPtr(new HWAddr(duid->getDuid(), HTYPE_ETHER)));
  236. }
  237. void
  238. GenericHostDataSourceTest::compareReservations6(IPv6ResrvRange resrv1,
  239. IPv6ResrvRange resrv2) {
  240. // Compare number of reservations for both hosts
  241. if (std::distance(resrv1.first, resrv1.second) !=
  242. std::distance(resrv2.first, resrv2.second)){
  243. ADD_FAILURE()<< "Reservation comparison failed, "
  244. "hosts got different number of reservations.";
  245. return;
  246. }
  247. // Iterate over the range of reservations to find a match in the
  248. // reference range.
  249. for (IPv6ResrvIterator r1 = resrv1.first; r1 != resrv1.second; ++r1) {
  250. IPv6ResrvIterator r2 = resrv2.first;
  251. for (; r2 != resrv2.second; ++r2) {
  252. // IPv6Resrv object implements equality operator.
  253. if (r1->second == r2->second) {
  254. break;
  255. }
  256. }
  257. // If r2 iterator reached the end of the range it means that there
  258. // is no match.
  259. if (r2 == resrv2.second) {
  260. ADD_FAILURE() << "No match found for reservation: "
  261. << resrv1.first->second.getPrefix().toText();
  262. }
  263. }
  264. if (std::distance(resrv1.first, resrv1.second) > 0) {
  265. for (; resrv1.first != resrv1.second; resrv1.first++) {
  266. IPv6ResrvIterator iter = resrv2.first;
  267. while (iter != resrv2.second) {
  268. if((resrv1.first->second.getType() == iter->second.getType()) &&
  269. (resrv1.first->second.getPrefixLen() == iter->second.getPrefixLen()) &&
  270. (resrv1.first->second.getPrefix() == iter->second.getPrefix())) {
  271. break;
  272. }
  273. iter++;
  274. if (iter == resrv2.second) {
  275. ADD_FAILURE()<< "Reservation comparison failed, "
  276. "no match for reservation: "
  277. << resrv1.first->second.getPrefix().toText();
  278. }
  279. }
  280. }
  281. }
  282. }
  283. void
  284. GenericHostDataSourceTest::compareClientClasses(const ClientClasses& classes1,
  285. const ClientClasses& classes2) {
  286. EXPECT_TRUE(std::equal(classes1.begin(), classes1.end(), classes2.begin()));
  287. }
  288. void
  289. GenericHostDataSourceTest::compareOptions(const ConstCfgOptionPtr& cfg1,
  290. const ConstCfgOptionPtr& cfg2) const {
  291. ASSERT_TRUE(cfg1);
  292. ASSERT_TRUE(cfg2);
  293. // Combine option space names with vendor space names in a single list.
  294. std::list<std::string> option_spaces = cfg2->getOptionSpaceNames();
  295. std::list<std::string> vendor_spaces = cfg2->getVendorIdsSpaceNames();
  296. option_spaces.insert(option_spaces.end(), vendor_spaces.begin(),
  297. vendor_spaces.end());
  298. // Make sure that the number of option spaces is equal in both
  299. // configurations.
  300. EXPECT_EQ(option_spaces.size(), cfg1->getOptionSpaceNames().size());
  301. EXPECT_EQ(vendor_spaces.size(), cfg1->getVendorIdsSpaceNames().size());
  302. // Iterate over all option spaces existing in cfg2.
  303. BOOST_FOREACH(std::string space, option_spaces) {
  304. // Retrieve options belonging to the current option space.
  305. OptionContainerPtr options1 = cfg1->getAll(space);
  306. OptionContainerPtr options2 = cfg2->getAll(space);
  307. ASSERT_TRUE(options1) << "failed for option space " << space;
  308. ASSERT_TRUE(options2) << "failed for option space " << space;
  309. // If number of options doesn't match, the test fails.
  310. ASSERT_EQ(options1->size(), options2->size())
  311. << "failed for option space " << space;
  312. // Iterate over all options within this option space.
  313. BOOST_FOREACH(OptionDescriptor desc1, *options1) {
  314. OptionDescriptor desc2 = cfg2->get(space, desc1.option_->getType());
  315. // Compare persistent flag.
  316. EXPECT_EQ(desc1.persistent_, desc2.persistent_)
  317. << "failed for option " << space << "." << desc1.option_->getType();
  318. // Compare formatted value.
  319. EXPECT_EQ(desc1.formatted_value_, desc2.formatted_value_)
  320. << "failed for option " << space << "." << desc1.option_->getType();
  321. // Retrieve options.
  322. Option* option1 = desc1.option_.get();
  323. Option* option2 = desc2.option_.get();
  324. // Options must be represented by the same C++ class derived from
  325. // the Option class.
  326. EXPECT_TRUE(typeid(*option1) == typeid(*option2))
  327. << "Comapared DHCP options, having option code "
  328. << desc1.option_->getType() << " and belonging to the "
  329. << space << " option space, are represented "
  330. "by different C++ classes: "
  331. << typeid(*option1).name() << " vs "
  332. << typeid(*option2).name();
  333. // Because we use different C++ classes to represent different
  334. // options, the simplest way to make sure that the options are
  335. // equal is to simply compare them in wire format.
  336. OutputBuffer buf1(option1->len());
  337. ASSERT_NO_THROW(option1->pack(buf1));
  338. OutputBuffer buf2(option2->len());
  339. ASSERT_NO_THROW(option2->pack(buf2));
  340. ASSERT_EQ(buf1.getLength(), buf2.getLength())
  341. << "failed for option " << space << "." << desc1.option_->getType();
  342. EXPECT_EQ(0, memcmp(buf1.getData(), buf2.getData(), buf1.getLength()))
  343. << "failed for option " << space << "." << desc1.option_->getType();
  344. }
  345. }
  346. }
  347. OptionDescriptor
  348. GenericHostDataSourceTest::createEmptyOption(const Option::Universe& universe,
  349. const uint16_t option_type,
  350. const bool persist) const {
  351. OptionPtr option(new Option(universe, option_type));
  352. OptionDescriptor desc(option, persist);
  353. return (desc);
  354. }
  355. OptionDescriptor
  356. GenericHostDataSourceTest::createVendorOption(const Option::Universe& universe,
  357. const bool persist,
  358. const bool formatted,
  359. const uint32_t vendor_id) const {
  360. OptionVendorPtr option(new OptionVendor(universe, vendor_id));
  361. std::ostringstream s;
  362. if (formatted) {
  363. // Vendor id comprises vendor-id field, for which we need to
  364. // assign a value in the textual (formatted) format.
  365. s << vendor_id;
  366. }
  367. OptionDescriptor desc(option, persist, s.str());
  368. return (desc);
  369. }
  370. void
  371. GenericHostDataSourceTest::addTestOptions(const HostPtr& host,
  372. const bool formatted,
  373. const AddedOptions& added_options) const {
  374. OptionDefSpaceContainer defs;
  375. if ((added_options == DHCP4_ONLY) || (added_options == DHCP4_AND_DHCP6)) {
  376. // Add DHCPv4 options.
  377. CfgOptionPtr opts = host->getCfgOption4();
  378. opts->add(createOption<OptionString>(Option::V4, DHO_BOOT_FILE_NAME,
  379. true, formatted, "my-boot-file"),
  380. DHCP4_OPTION_SPACE);
  381. opts->add(createOption<OptionUint8>(Option::V4, DHO_DEFAULT_IP_TTL,
  382. false, formatted, 64),
  383. DHCP4_OPTION_SPACE);
  384. opts->add(createOption<OptionUint32>(Option::V4, 1, false, formatted, 312131),
  385. "vendor-encapsulated-options");
  386. opts->add(createAddressOption<Option4AddrLst>(254, false, formatted, "192.0.2.3"),
  387. DHCP4_OPTION_SPACE);
  388. opts->add(createEmptyOption(Option::V4, 1, true), "isc");
  389. opts->add(createAddressOption<Option4AddrLst>(2, false, formatted, "10.0.0.5",
  390. "10.0.0.3", "10.0.3.4"),
  391. "isc");
  392. // Add definitions for DHCPv4 non-standard options.
  393. defs.addItem(OptionDefinitionPtr(new OptionDefinition("vendor-encapsulated-1",
  394. 1, "uint32")),
  395. "vendor-encapsulated-options");
  396. defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-254", 254,
  397. "ipv4-address", true)),
  398. DHCP4_OPTION_SPACE);
  399. defs.addItem(OptionDefinitionPtr(new OptionDefinition("isc-1", 1, "empty")),
  400. "isc");
  401. defs.addItem(OptionDefinitionPtr(new OptionDefinition("isc-2", 2,
  402. "ipv4-address", true)),
  403. "isc");
  404. }
  405. if ((added_options == DHCP6_ONLY) || (added_options == DHCP4_AND_DHCP6)) {
  406. // Add DHCPv6 options.
  407. CfgOptionPtr opts = host->getCfgOption6();
  408. opts->add(createOption<OptionString>(Option::V6, D6O_BOOTFILE_URL,
  409. true, formatted, "my-boot-file"),
  410. DHCP6_OPTION_SPACE);
  411. opts->add(createOption<OptionUint32>(Option::V6, D6O_INFORMATION_REFRESH_TIME,
  412. false, formatted, 3600),
  413. DHCP6_OPTION_SPACE);
  414. opts->add(createVendorOption(Option::V6, false, formatted, 2495),
  415. DHCP6_OPTION_SPACE);
  416. opts->add(createAddressOption<Option6AddrLst>(1024, false, formatted,
  417. "2001:db8:1::1"),
  418. DHCP6_OPTION_SPACE);
  419. opts->add(createEmptyOption(Option::V6, 1, true), "isc2");
  420. opts->add(createAddressOption<Option6AddrLst>(2, false, formatted, "3000::1",
  421. "3000::2", "3000::3"),
  422. "isc2");
  423. // Add definitions for DHCPv6 non-standard options.
  424. defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-1024", 1024,
  425. "ipv6-address", true)),
  426. DHCP6_OPTION_SPACE);
  427. defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-1", 1, "empty")),
  428. "isc2");
  429. defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-2", 2,
  430. "ipv6-address", true)),
  431. "isc2");
  432. }
  433. // Register created "runtime" option definitions. They will be used by a
  434. // host data source to convert option data into the appropriate option
  435. // classes when the options are retrieved.
  436. LibDHCP::setRuntimeOptionDefs(defs);
  437. }
  438. void GenericHostDataSourceTest::testBasic4(const Host::IdentifierType& id) {
  439. // Make sure we have the pointer to the host data source.
  440. ASSERT_TRUE(hdsptr_);
  441. // Create a host reservation.
  442. HostPtr host = initializeHost4("192.0.2.1", id);
  443. ASSERT_TRUE(host); // Make sure the host is generate properly.
  444. SubnetID subnet = host->getIPv4SubnetID();
  445. // Try to add it to the host data source.
  446. ASSERT_NO_THROW(hdsptr_->add(host));
  447. // This should not return anything
  448. ConstHostPtr from_hds = hdsptr_->get4(subnet, IOAddress("10.10.10.10"));
  449. ASSERT_FALSE(from_hds);
  450. // This time it should return a host
  451. from_hds = hdsptr_->get4(subnet, IOAddress("192.0.2.1"));
  452. ASSERT_TRUE(from_hds);
  453. // Finally, let's check if what we got makes any sense.
  454. compareHosts(host, from_hds);
  455. }
  456. void GenericHostDataSourceTest::testGetByIPv4(const Host::IdentifierType& id) {
  457. // Make sure we have a pointer to the host data source.
  458. ASSERT_TRUE(hdsptr_);
  459. // Let's create a couple of hosts...
  460. HostPtr host1 = initializeHost4("192.0.2.1", id);
  461. HostPtr host2 = initializeHost4("192.0.2.2", id);
  462. HostPtr host3 = initializeHost4("192.0.2.3", id);
  463. HostPtr host4 = initializeHost4("192.0.2.4", id);
  464. // ... and add them to the data source.
  465. ASSERT_NO_THROW(hdsptr_->add(host1));
  466. ASSERT_NO_THROW(hdsptr_->add(host2));
  467. ASSERT_NO_THROW(hdsptr_->add(host3));
  468. ASSERT_NO_THROW(hdsptr_->add(host4));
  469. SubnetID subnet1 = host1->getIPv4SubnetID();
  470. SubnetID subnet2 = host2->getIPv4SubnetID();
  471. SubnetID subnet3 = host3->getIPv4SubnetID();
  472. SubnetID subnet4 = host4->getIPv4SubnetID();
  473. // And then try to retrieve them back.
  474. ConstHostPtr from_hds1 = hdsptr_->get4(subnet1, IOAddress("192.0.2.1"));
  475. ConstHostPtr from_hds2 = hdsptr_->get4(subnet2, IOAddress("192.0.2.2"));
  476. ConstHostPtr from_hds3 = hdsptr_->get4(subnet3, IOAddress("192.0.2.3"));
  477. ConstHostPtr from_hds4 = hdsptr_->get4(subnet4, IOAddress("192.0.2.4"));
  478. // Make sure we got something back.
  479. ASSERT_TRUE(from_hds1);
  480. ASSERT_TRUE(from_hds2);
  481. ASSERT_TRUE(from_hds3);
  482. ASSERT_TRUE(from_hds4);
  483. // Then let's check that what we got seems correct.
  484. compareHosts(host1, from_hds1);
  485. compareHosts(host2, from_hds2);
  486. compareHosts(host3, from_hds3);
  487. compareHosts(host4, from_hds4);
  488. // Ok, finally let's check that getting by a different address
  489. // will not work.
  490. EXPECT_FALSE(hdsptr_->get4(subnet1, IOAddress("192.0.1.5")));
  491. }
  492. void
  493. GenericHostDataSourceTest::testGet4ByIdentifier(const Host::IdentifierType& identifier_type) {
  494. // Make sure we have a pointer to the host data source.
  495. ASSERT_TRUE(hdsptr_);
  496. HostPtr host1 = initializeHost4("192.0.2.1", identifier_type);
  497. HostPtr host2 = initializeHost4("192.0.2.2", identifier_type);
  498. // Sanity check: make sure the hosts have different identifiers..
  499. ASSERT_FALSE(host1->getIdentifier() == host2->getIdentifier());
  500. // Try to add both of them to the host data source.
  501. ASSERT_NO_THROW(hdsptr_->add(host1));
  502. ASSERT_NO_THROW(hdsptr_->add(host2));
  503. SubnetID subnet1 = host1->getIPv4SubnetID();
  504. SubnetID subnet2 = host2->getIPv4SubnetID();
  505. ConstHostPtr from_hds1 = hdsptr_->get4(subnet1,
  506. identifier_type,
  507. &host1->getIdentifier()[0],
  508. host1->getIdentifier().size());
  509. ConstHostPtr from_hds2 = hdsptr_->get4(subnet2,
  510. identifier_type,
  511. &host2->getIdentifier()[0],
  512. host2->getIdentifier().size());
  513. // Now let's check if we got what we expected.
  514. ASSERT_TRUE(from_hds1);
  515. ASSERT_TRUE(from_hds2);
  516. compareHosts(host1, from_hds1);
  517. compareHosts(host2, from_hds2);
  518. }
  519. void GenericHostDataSourceTest::testHWAddrNotClientId() {
  520. // Make sure we have a pointer to the host data source.
  521. ASSERT_TRUE(hdsptr_);
  522. // Create a host with HW address
  523. HostPtr host = initializeHost4("192.0.2.1", Host::IDENT_HWADDR);
  524. ASSERT_TRUE(host->getHWAddress());
  525. ASSERT_FALSE(host->getDuid());
  526. // Try to add it to the host data source.
  527. ASSERT_NO_THROW(hdsptr_->add(host));
  528. SubnetID subnet = host->getIPv4SubnetID();
  529. DuidPtr duid = HWAddrToDuid(host->getHWAddress());
  530. // Get the host by HW address (should succeed)
  531. ConstHostPtr by_hwaddr = hdsptr_->get4(subnet, Host::IDENT_HWADDR,
  532. &host->getIdentifier()[0],
  533. host->getIdentifier().size());
  534. // Get the host by DUID (should fail)
  535. ConstHostPtr by_duid = hdsptr_->get4(subnet, Host::IDENT_DUID,
  536. &host->getIdentifier()[0],
  537. host->getIdentifier().size());
  538. // Now let's check if we got what we expected.
  539. EXPECT_TRUE(by_hwaddr);
  540. EXPECT_FALSE(by_duid);
  541. }
  542. void GenericHostDataSourceTest::testClientIdNotHWAddr() {
  543. // Make sure we have a pointer to the host data source.
  544. ASSERT_TRUE(hdsptr_);
  545. // Create a host with client-id
  546. HostPtr host = initializeHost4("192.0.2.1", Host::IDENT_DUID);
  547. ASSERT_FALSE(host->getHWAddress());
  548. ASSERT_TRUE(host->getDuid());
  549. // Try to add it to the host data source.
  550. ASSERT_NO_THROW(hdsptr_->add(host));
  551. SubnetID subnet = host->getIPv4SubnetID();
  552. HWAddrPtr hwaddr = DuidToHWAddr(host->getDuid());
  553. // Get the host by DUID (should succeed)
  554. ConstHostPtr by_duid = hdsptr_->get4(subnet, Host::IDENT_DUID,
  555. &host->getIdentifier()[0],
  556. host->getIdentifier().size());
  557. // Get the host by HW address (should fail)
  558. ConstHostPtr by_hwaddr = hdsptr_->get4(subnet, Host::IDENT_HWADDR,
  559. &host->getIdentifier()[0],
  560. host->getIdentifier().size());
  561. // Now let's check if we got what we expected.
  562. EXPECT_TRUE(by_duid);
  563. EXPECT_FALSE(by_hwaddr);
  564. }
  565. void
  566. GenericHostDataSourceTest::testHostname(std::string name, int num) {
  567. // Make sure we have a pointer to the host data source.
  568. ASSERT_TRUE(hdsptr_);
  569. // Initialize the address to 192.0.2.0 (this will be bumped
  570. // up to 192.0.2.1 in the first iteration)
  571. IOAddress addr("192.0.2.0");
  572. vector<HostPtr> hosts;
  573. // Prepare a vector of hosts with unique hostnames
  574. for (int i = 0; i < num; ++i) {
  575. addr = IOAddress::increase(addr);
  576. HostPtr host = initializeHost4(addr.toText(), Host::IDENT_DUID);
  577. stringstream hostname;
  578. hostname.str("");
  579. if (num > 1) {
  580. hostname << i;
  581. }
  582. hostname << name;
  583. host->setHostname(hostname.str());
  584. hosts.push_back(host);
  585. }
  586. // Now add them all to the host data source.
  587. for (vector<HostPtr>::const_iterator it = hosts.begin();
  588. it != hosts.end(); ++it) {
  589. // Try to add both of the to the host data source.
  590. ASSERT_NO_THROW(hdsptr_->add(*it));
  591. }
  592. // And finally retrieve them one by one and check
  593. // if the hostname was preserved.
  594. for (vector<HostPtr>::const_iterator it = hosts.begin();
  595. it != hosts.end(); ++it) {
  596. ConstHostPtr from_hds;
  597. ASSERT_NO_THROW(from_hds = hdsptr_->get4(
  598. (*it)->getIPv4SubnetID(),
  599. (*it)->getIPv4Reservation()));
  600. ASSERT_TRUE(from_hds);
  601. EXPECT_EQ((*it)->getHostname(), from_hds->getHostname());
  602. }
  603. }
  604. void
  605. GenericHostDataSourceTest::testMultipleSubnets(int subnets,
  606. const Host::IdentifierType& id) {
  607. // Make sure we have a pointer to the host data source.
  608. ASSERT_TRUE(hdsptr_);
  609. HostPtr host = initializeHost4("192.0.2.1", id);
  610. for (int i = 0; i < subnets; ++i) {
  611. host->setIPv4SubnetID(i + 1000);
  612. host->setIPv6SubnetID(i + 1000);
  613. // Check that the same host can have reservations in multiple subnets.
  614. EXPECT_NO_THROW(hdsptr_->add(host));
  615. }
  616. // Now check that the reservations can be retrieved by IPv4 address from
  617. // each subnet separately.
  618. for (int i = 0; i < subnets; ++i) {
  619. // Try to retrieve the host by IPv4 address.
  620. ConstHostPtr from_hds = hdsptr_->get4(i + 1000, host->getIPv4Reservation());
  621. ASSERT_TRUE(from_hds);
  622. EXPECT_EQ(i + 1000, from_hds->getIPv4SubnetID());
  623. // Try to retrieve the host by either HW address of client-id
  624. from_hds = hdsptr_->get4(i + 1000,
  625. id, &host->getIdentifier()[0],
  626. host->getIdentifier().size());
  627. ASSERT_TRUE(from_hds);
  628. EXPECT_EQ(i + 1000, from_hds->getIPv4SubnetID());
  629. }
  630. // Now check that they can be retrieved all at once, by IPv4 address.
  631. ConstHostCollection all_by_addr = hdsptr_->getAll4(IOAddress("192.0.2.1"));
  632. ASSERT_EQ(subnets, all_by_addr.size());
  633. // Verify that the values returned are proper.
  634. int i = 0;
  635. for (ConstHostCollection::const_iterator it = all_by_addr.begin();
  636. it != all_by_addr.end(); ++it) {
  637. EXPECT_EQ(IOAddress("192.0.2.1"), (*it)->getIPv4Reservation());
  638. EXPECT_EQ(1000 + i++, (*it)->getIPv4SubnetID());
  639. }
  640. // Finally, check that the hosts can be retrived by HW address or DUID
  641. ConstHostCollection all_by_id =
  642. hdsptr_->getAll(id, &host->getIdentifier()[0],
  643. host->getIdentifier().size());
  644. ASSERT_EQ(subnets, all_by_id.size());
  645. // Check that the returned values are as expected.
  646. i = 0;
  647. for (ConstHostCollection::const_iterator it = all_by_id.begin();
  648. it != all_by_id.end(); ++it) {
  649. EXPECT_EQ(IOAddress("192.0.2.1"), (*it)->getIPv4Reservation());
  650. EXPECT_EQ(1000 + i++, (*it)->getIPv4SubnetID());
  651. }
  652. }
  653. void GenericHostDataSourceTest::testGet6ByHWAddr() {
  654. // Make sure we have the pointer to the host data source.
  655. ASSERT_TRUE(hdsptr_);
  656. // Create a host reservations.
  657. HostPtr host1 = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, false);
  658. HostPtr host2 = initializeHost6("2001:db8::2", Host::IDENT_HWADDR, false);
  659. // Sanity check: make sure the hosts have different HW addresses.
  660. ASSERT_TRUE(host1->getHWAddress());
  661. ASSERT_TRUE(host2->getHWAddress());
  662. compareHwaddrs(host1, host2, false);
  663. // Try to add both of them to the host data source.
  664. ASSERT_NO_THROW(hdsptr_->add(host1));
  665. ASSERT_NO_THROW(hdsptr_->add(host2));
  666. SubnetID subnet1 = host1->getIPv6SubnetID();
  667. SubnetID subnet2 = host2->getIPv6SubnetID();
  668. ConstHostPtr from_hds1 = hdsptr_->get6(subnet1, Host::IDENT_HWADDR,
  669. &host1->getIdentifier()[0],
  670. host1->getIdentifier().size());
  671. ConstHostPtr from_hds2 = hdsptr_->get6(subnet2, Host::IDENT_HWADDR,
  672. &host2->getIdentifier()[0],
  673. host2->getIdentifier().size());
  674. // Now let's check if we got what we expected.
  675. ASSERT_TRUE(from_hds1);
  676. ASSERT_TRUE(from_hds2);
  677. compareHosts(host1, from_hds1);
  678. compareHosts(host2, from_hds2);
  679. }
  680. void GenericHostDataSourceTest::testGet6ByClientId() {
  681. // Make sure we have the pointer to the host data source.
  682. ASSERT_TRUE(hdsptr_);
  683. // Create a host reservations.
  684. HostPtr host1 = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
  685. HostPtr host2 = initializeHost6("2001:db8::2", Host::IDENT_DUID, false);
  686. // Sanity check: make sure the hosts have different HW addresses.
  687. ASSERT_TRUE(host1->getDuid());
  688. ASSERT_TRUE(host2->getDuid());
  689. compareDuids(host1, host2, false);
  690. // Try to add both of them to the host data source.
  691. ASSERT_NO_THROW(hdsptr_->add(host1));
  692. ASSERT_NO_THROW(hdsptr_->add(host2));
  693. SubnetID subnet1 = host1->getIPv6SubnetID();
  694. SubnetID subnet2 = host2->getIPv6SubnetID();
  695. ConstHostPtr from_hds1 = hdsptr_->get6(subnet1, Host::IDENT_DUID,
  696. &host1->getIdentifier()[0],
  697. host1->getIdentifier().size());
  698. ConstHostPtr from_hds2 = hdsptr_->get6(subnet2, Host::IDENT_DUID,
  699. &host2->getIdentifier()[0],
  700. host2->getIdentifier().size());
  701. // Now let's check if we got what we expected.
  702. ASSERT_TRUE(from_hds1);
  703. ASSERT_TRUE(from_hds2);
  704. compareHosts(host1, from_hds1);
  705. compareHosts(host2, from_hds2);
  706. }
  707. void
  708. GenericHostDataSourceTest::testSubnetId6(int subnets, Host::IdentifierType id) {
  709. // Make sure we have a pointer to the host data source.
  710. ASSERT_TRUE(hdsptr_);
  711. HostPtr host;
  712. IOAddress current_address("2001:db8::0");
  713. for (int i = 0; i < subnets; ++i) {
  714. // Last boolean value set to false indicates that the same identifier
  715. // must be used for each generated host.
  716. host = initializeHost6(current_address.toText(), id, true, false);
  717. host->setIPv4SubnetID(i + 1000);
  718. host->setIPv6SubnetID(i + 1000);
  719. // Check that the same host can have reservations in multiple subnets.
  720. EXPECT_NO_THROW(hdsptr_->add(host));
  721. // Increase address to make sure we don't assign the same address
  722. // in different subnets.
  723. current_address = IOAddress::increase(current_address);
  724. }
  725. // Check that the reservations can be retrieved from each subnet separately.
  726. for (int i = 0; i < subnets; ++i) {
  727. // Try to retrieve the host
  728. ConstHostPtr from_hds = hdsptr_->get6(i + 1000, id, &host->getIdentifier()[0],
  729. host->getIdentifier().size());
  730. ASSERT_TRUE(from_hds) << "failed for i=" << i;
  731. EXPECT_EQ(i + 1000, from_hds->getIPv6SubnetID());
  732. }
  733. // Check that the hosts can all be retrived by HW address or DUID
  734. ConstHostCollection all_by_id = hdsptr_->getAll(id, &host->getIdentifier()[0],
  735. host->getIdentifier().size());
  736. ASSERT_EQ(subnets, all_by_id.size());
  737. // Check that the returned values are as expected.
  738. int i = 0;
  739. for (ConstHostCollection::const_iterator it = all_by_id.begin();
  740. it != all_by_id.end(); ++it) {
  741. EXPECT_EQ(IOAddress("0.0.0.0"), (*it)->getIPv4Reservation());
  742. EXPECT_EQ(1000 + i++, (*it)->getIPv6SubnetID());
  743. }
  744. }
  745. void GenericHostDataSourceTest::testGetByIPv6(Host::IdentifierType id,
  746. bool prefix) {
  747. // Make sure we have a pointer to the host data source.
  748. ASSERT_TRUE(hdsptr_);
  749. // Let's create a couple of hosts...
  750. HostPtr host1 = initializeHost6("2001:db8::1", id, prefix);
  751. HostPtr host2 = initializeHost6("2001:db8::2", id, prefix);
  752. HostPtr host3 = initializeHost6("2001:db8::3", id, prefix);
  753. HostPtr host4 = initializeHost6("2001:db8::4", id, prefix);
  754. // ... and add them to the data source.
  755. ASSERT_NO_THROW(hdsptr_->add(host1));
  756. ASSERT_NO_THROW(hdsptr_->add(host2));
  757. ASSERT_NO_THROW(hdsptr_->add(host3));
  758. ASSERT_NO_THROW(hdsptr_->add(host4));
  759. // Are we talking about addresses or prefixes?
  760. uint8_t len = prefix ? 64 : 128;
  761. // And then try to retrieve them back.
  762. ConstHostPtr from_hds1 = hdsptr_->get6(IOAddress("2001:db8::1"), len);
  763. ConstHostPtr from_hds2 = hdsptr_->get6(IOAddress("2001:db8::2"), len);
  764. ConstHostPtr from_hds3 = hdsptr_->get6(IOAddress("2001:db8::3"), len);
  765. ConstHostPtr from_hds4 = hdsptr_->get6(IOAddress("2001:db8::4"), len);
  766. // Make sure we got something back.
  767. ASSERT_TRUE(from_hds1);
  768. ASSERT_TRUE(from_hds2);
  769. ASSERT_TRUE(from_hds3);
  770. ASSERT_TRUE(from_hds4);
  771. // Then let's check that what we got seems correct.
  772. compareHosts(host1, from_hds1);
  773. compareHosts(host2, from_hds2);
  774. compareHosts(host3, from_hds3);
  775. compareHosts(host4, from_hds4);
  776. // Ok, finally let's check that getting by a different address
  777. // will not work.
  778. EXPECT_FALSE(hdsptr_->get6(IOAddress("2001:db8::5"), len));
  779. }
  780. void GenericHostDataSourceTest::testAddDuplicate6WithSameDUID() {
  781. // Make sure we have the pointer to the host data source.
  782. ASSERT_TRUE(hdsptr_);
  783. // Create a host reservations.
  784. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, true);
  785. // Add this reservation once.
  786. ASSERT_NO_THROW(hdsptr_->add(host));
  787. // Then try to add it again, it should throw an exception.
  788. ASSERT_THROW(hdsptr_->add(host), DuplicateEntry);
  789. }
  790. void GenericHostDataSourceTest::testAddDuplicate6WithSameHWAddr() {
  791. // Make sure we have the pointer to the host data source.
  792. ASSERT_TRUE(hdsptr_);
  793. // Create a host reservations.
  794. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, true);
  795. // Add this reservation once.
  796. ASSERT_NO_THROW(hdsptr_->add(host));
  797. // Then try to add it again, it should throw an exception.
  798. ASSERT_THROW(hdsptr_->add(host), DuplicateEntry);
  799. }
  800. void GenericHostDataSourceTest::testAddDuplicate4() {
  801. // Make sure we have the pointer to the host data source.
  802. ASSERT_TRUE(hdsptr_);
  803. // Create a host reservations.
  804. HostPtr host = initializeHost4("192.0.2.1", Host::IDENT_DUID);
  805. // Add this reservation once.
  806. ASSERT_NO_THROW(hdsptr_->add(host));
  807. // Then try to add it again, it should throw an exception.
  808. ASSERT_THROW(hdsptr_->add(host), DuplicateEntry);
  809. // This time use a different host identifier and try again.
  810. // This update should be rejected because of duplicated
  811. // address.
  812. ASSERT_NO_THROW(host->setIdentifier("01:02:03:04:05:06", "hw-address"));
  813. ASSERT_THROW(hdsptr_->add(host), DuplicateEntry);
  814. // Modify address to avoid its duplication and make sure
  815. // we can now add the host.
  816. ASSERT_NO_THROW(host->setIPv4Reservation(IOAddress("192.0.2.3")));
  817. EXPECT_NO_THROW(hdsptr_->add(host));
  818. }
  819. void GenericHostDataSourceTest::testAddr6AndPrefix(){
  820. // Make sure we have the pointer to the host data source.
  821. ASSERT_TRUE(hdsptr_);
  822. // Create a host reservations with prefix reservation (prefix = true)
  823. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, true);
  824. // Create IPv6 reservation (for an address) and add it to the host
  825. IPv6Resrv resv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::2"), 128);
  826. host->addReservation(resv);
  827. // Add this reservation
  828. ASSERT_NO_THROW(hdsptr_->add(host));
  829. // Get this host by DUID
  830. ConstHostPtr from_hds = hdsptr_->get6(host->getIPv6SubnetID(),
  831. Host::IDENT_DUID,
  832. &host->getIdentifier()[0],
  833. host->getIdentifier().size());
  834. // Make sure we got something back
  835. ASSERT_TRUE(from_hds);
  836. // Check if reservations are the same
  837. compareReservations6(host->getIPv6Reservations(),
  838. from_hds->getIPv6Reservations());
  839. }
  840. void GenericHostDataSourceTest::testMultipleReservations(){
  841. // Make sure we have the pointer to the host data source.
  842. ASSERT_TRUE(hdsptr_);
  843. uint8_t len = 128;
  844. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
  845. // Add some reservations
  846. IPv6Resrv resv1(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::6"), len);
  847. IPv6Resrv resv2(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::7"), len);
  848. IPv6Resrv resv3(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::8"), len);
  849. IPv6Resrv resv4(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::9"), len);
  850. host->addReservation(resv1);
  851. host->addReservation(resv2);
  852. host->addReservation(resv3);
  853. host->addReservation(resv4);
  854. ASSERT_NO_THROW(hdsptr_->add(host));
  855. ConstHostPtr from_hds = hdsptr_->get6(IOAddress("2001:db8::1"), len);
  856. // Make sure we got something back
  857. ASSERT_TRUE(from_hds);
  858. // Check if hosts are the same
  859. compareHosts(host, from_hds);
  860. }
  861. void GenericHostDataSourceTest::testMultipleReservationsDifferentOrder(){
  862. // Make sure we have the pointer to the host data source.
  863. ASSERT_TRUE(hdsptr_);
  864. uint8_t len = 128;
  865. HostPtr host1 = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
  866. HostPtr host2 = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
  867. // Add some reservations
  868. IPv6Resrv resv1(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::6"), len);
  869. IPv6Resrv resv2(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::7"), len);
  870. IPv6Resrv resv3(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::8"), len);
  871. IPv6Resrv resv4(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::9"), len);
  872. host1->addReservation(resv1);
  873. host1->addReservation(resv2);
  874. host1->addReservation(resv3);
  875. host1->addReservation(resv4);
  876. host2->addReservation(resv4);
  877. host2->addReservation(resv3);
  878. host2->addReservation(resv2);
  879. host2->addReservation(resv1);
  880. // Check if reservations are the same
  881. compareReservations6(host1->getIPv6Reservations(), host2->getIPv6Reservations());
  882. }
  883. void GenericHostDataSourceTest::testOptionsReservations4(const bool formatted) {
  884. HostPtr host = initializeHost4("192.0.2.5", Host::IDENT_HWADDR);
  885. // Add a bunch of DHCPv4 and DHCPv6 options for the host.
  886. ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP4_ONLY));
  887. // Insert host and the options into respective tables.
  888. ASSERT_NO_THROW(hdsptr_->add(host));
  889. // Subnet id will be used in quries to the database.
  890. SubnetID subnet_id = host->getIPv4SubnetID();
  891. // getAll4(address)
  892. ConstHostCollection hosts_by_addr = hdsptr_->getAll4(host->getIPv4Reservation());
  893. ASSERT_EQ(1, hosts_by_addr.size());
  894. ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_addr.begin()));
  895. // get4(subnet_id, identifier_type, identifier, identifier_size)
  896. ConstHostPtr host_by_id = hdsptr_->get4(subnet_id,
  897. host->getIdentifierType(),
  898. &host->getIdentifier()[0],
  899. host->getIdentifier().size());
  900. ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_id));
  901. // get4(subnet_id, address)
  902. ConstHostPtr host_by_addr = hdsptr_->get4(subnet_id, IOAddress("192.0.2.5"));
  903. ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_addr));
  904. }
  905. void GenericHostDataSourceTest::testOptionsReservations6(const bool formatted) {
  906. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
  907. // Add a bunch of DHCPv4 and DHCPv6 options for the host.
  908. ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP6_ONLY));
  909. // Insert host, options and IPv6 reservations into respective tables.
  910. ASSERT_NO_THROW(hdsptr_->add(host));
  911. // Subnet id will be used in queries to the database.
  912. SubnetID subnet_id = host->getIPv6SubnetID();
  913. // get6(subnet_id, identifier_type, identifier, identifier_size)
  914. ConstHostPtr host_by_id = hdsptr_->get6(subnet_id, host->getIdentifierType(),
  915. &host->getIdentifier()[0],
  916. host->getIdentifier().size());
  917. ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_id));
  918. // get6(address, prefix_len)
  919. ConstHostPtr host_by_addr = hdsptr_->get6(IOAddress("2001:db8::1"), 128);
  920. ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_addr));
  921. }
  922. void GenericHostDataSourceTest::testOptionsReservations46(const bool formatted) {
  923. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, false);
  924. // Add a bunch of DHCPv4 and DHCPv6 options for the host.
  925. ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP4_AND_DHCP6));
  926. // Insert host, options and IPv6 reservations into respective tables.
  927. ASSERT_NO_THROW(hdsptr_->add(host));
  928. // getAll(identifier_type, identifier, identifier_size)
  929. ConstHostCollection hosts_by_id = hdsptr_->getAll(host->getIdentifierType(),
  930. &host->getIdentifier()[0],
  931. host->getIdentifier().size());
  932. ASSERT_EQ(1, hosts_by_id.size());
  933. ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
  934. }
  935. void
  936. GenericHostDataSourceTest::testMultipleClientClasses4() {
  937. ASSERT_TRUE(hdsptr_);
  938. // Create the Host object.
  939. HostPtr host = initializeHost4("192.0.2.5", Host::IDENT_HWADDR);
  940. // Add v4 classes to the host.
  941. for (int i = 0; i < 4; ++i) {
  942. std::ostringstream os;
  943. os << "class4_" << i;
  944. host->addClientClass4(os.str());
  945. }
  946. // Add the host.
  947. ASSERT_NO_THROW(hdsptr_->add(host));
  948. // Subnet id will be used in quries to the database.
  949. SubnetID subnet_id = host->getIPv4SubnetID();
  950. // Fetch the host via:
  951. // getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid = DuidPtr()) const;
  952. ConstHostCollection hosts_by_id = hdsptr_->getAll(host->getHWAddress());
  953. ASSERT_EQ(1, hosts_by_id.size());
  954. ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
  955. // Fetch the host via:
  956. // getAll(const Host::IdentifierType, const uint8_t* identifier_begin,
  957. // const size_t identifier_len) const;
  958. hosts_by_id = hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
  959. host->getIdentifier().size());
  960. ASSERT_EQ(1, hosts_by_id.size());
  961. ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
  962. // Fetch the host via
  963. // getAll4(const asiolink::IOAddress& address) const;
  964. hosts_by_id = hdsptr_->getAll4(IOAddress("192.0.2.5"));
  965. ASSERT_EQ(1, hosts_by_id.size());
  966. ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
  967. // Fetch the host via
  968. // get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
  969. // const DuidPtr& duid = DuidPtr()) const;
  970. ConstHostPtr from_hds = hdsptr_->get4(subnet_id, host->getHWAddress());
  971. ASSERT_TRUE(from_hds);
  972. ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
  973. // Fetch the host via
  974. // get4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
  975. // const uint8_t* identifier_begin, const size_t identifier_len) const;
  976. from_hds = hdsptr_->get4(subnet_id, host->getIdentifierType(), &host->getIdentifier()[0],
  977. host->getIdentifier().size());
  978. ASSERT_TRUE(from_hds);
  979. ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
  980. // Fetch the host via:
  981. // get4(const SubnetID& subnet_id, const asiolink::IOAddress& address) const;
  982. from_hds = hdsptr_->get4(subnet_id, IOAddress("192.0.2.5"));
  983. ASSERT_TRUE(from_hds);
  984. ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
  985. }
  986. void
  987. GenericHostDataSourceTest::testMultipleClientClasses6() {
  988. ASSERT_TRUE(hdsptr_);
  989. // Create the Host object.
  990. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, false);
  991. // Add v6 classes to the host.
  992. for (int i = 0; i < 4; ++i) {
  993. std::ostringstream os;
  994. os << "class6_" << i;
  995. host->addClientClass6(os.str());
  996. }
  997. // Add the host.
  998. ASSERT_NO_THROW(hdsptr_->add(host));
  999. // Subnet id will be used in quries to the database.
  1000. SubnetID subnet_id = host->getIPv6SubnetID();
  1001. // Fetch the host via:
  1002. // getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid = DuidPtr()) const;
  1003. ConstHostCollection hosts_by_id = hdsptr_->getAll(host->getHWAddress());
  1004. ASSERT_EQ(1, hosts_by_id.size());
  1005. ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
  1006. // getAll(const Host::IdentifierType& identifier_type,
  1007. // const uint8_t* identifier_begin,
  1008. // const size_t identifier_len) const;
  1009. hosts_by_id = hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
  1010. host->getIdentifier().size());
  1011. ASSERT_EQ(1, hosts_by_id.size());
  1012. ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
  1013. // get6(const SubnetID& subnet_id, const DuidPtr& duid,
  1014. // const HWAddrPtr& hwaddr = HWAddrPtr()) const;
  1015. ConstHostPtr from_hds = hdsptr_->get6(subnet_id, DuidPtr(), host->getHWAddress());
  1016. ASSERT_TRUE(from_hds);
  1017. ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
  1018. // Fetch the host via:
  1019. // get6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
  1020. // const uint8_t* identifier_begin, const size_t identifier_len) const;
  1021. from_hds = hdsptr_->get6(subnet_id, Host::IDENT_HWADDR,
  1022. &host->getIdentifier()[0],
  1023. host->getIdentifier().size());
  1024. ASSERT_TRUE(from_hds);
  1025. ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
  1026. // Fetch the host via:
  1027. // get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len) const;
  1028. from_hds = hdsptr_->get6(IOAddress("2001:db8::1"), 128);
  1029. ASSERT_TRUE(from_hds);
  1030. ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
  1031. }
  1032. void
  1033. GenericHostDataSourceTest::testMultipleClientClassesBoth() {
  1034. /// Add host reservation with a multiple v4 and v6 client-classes,
  1035. /// retrieve it and make sure that all client classes are retrieved
  1036. /// properly.
  1037. ASSERT_TRUE(hdsptr_);
  1038. // Create the Host object.
  1039. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, false);
  1040. // Add v4 classes to the host.
  1041. for (int i = 0; i < 4; ++i) {
  1042. std::ostringstream os;
  1043. os << "class4_" << i;
  1044. host->addClientClass4(os.str());
  1045. }
  1046. // Add v6 classes to the host.
  1047. for (int i = 0; i < 4; ++i) {
  1048. std::ostringstream os;
  1049. os << "class6_" << i;
  1050. host->addClientClass6(os.str());
  1051. }
  1052. // Add the host.
  1053. ASSERT_NO_THROW(hdsptr_->add(host));
  1054. // Subnet id will be used in quries to the database.
  1055. SubnetID subnet_id = host->getIPv6SubnetID();
  1056. // Fetch the host from the source.
  1057. ConstHostPtr from_hds = hdsptr_->get6(subnet_id, Host::IDENT_HWADDR,
  1058. &host->getIdentifier()[0],
  1059. host->getIdentifier().size());
  1060. ASSERT_TRUE(from_hds);
  1061. // Verify they match.
  1062. ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
  1063. }
  1064. void
  1065. GenericHostDataSourceTest::testMessageFields4() {
  1066. ASSERT_TRUE(hdsptr_);
  1067. // Create the Host object.
  1068. HostPtr host = initializeHost4("192.0.2.5", Host::IDENT_HWADDR);
  1069. // And assign values for DHCPv4 message fields.
  1070. ASSERT_NO_THROW({
  1071. host->setNextServer(IOAddress("10.1.1.1"));
  1072. host->setServerHostname("server-name.example.org");
  1073. host->setBootFileName("bootfile.efi");
  1074. });
  1075. // Add the host.
  1076. ASSERT_NO_THROW(hdsptr_->add(host));
  1077. // Subnet id will be used in quries to the database.
  1078. SubnetID subnet_id = host->getIPv4SubnetID();
  1079. // Fetch the host via:
  1080. // getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid = DuidPtr()) const;
  1081. ConstHostCollection hosts_by_id = hdsptr_->getAll(host->getHWAddress());
  1082. ASSERT_EQ(1, hosts_by_id.size());
  1083. ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
  1084. // Fetch the host via:
  1085. // getAll(const Host::IdentifierType, const uint8_t* identifier_begin,
  1086. // const size_t identifier_len) const;
  1087. hosts_by_id = hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
  1088. host->getIdentifier().size());
  1089. ASSERT_EQ(1, hosts_by_id.size());
  1090. ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
  1091. // Fetch the host via
  1092. // getAll4(const asiolink::IOAddress& address) const;
  1093. hosts_by_id = hdsptr_->getAll4(IOAddress("192.0.2.5"));
  1094. ASSERT_EQ(1, hosts_by_id.size());
  1095. ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
  1096. // Fetch the host via
  1097. // get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
  1098. // const DuidPtr& duid = DuidPtr()) const;
  1099. ConstHostPtr from_hds = hdsptr_->get4(subnet_id, host->getHWAddress());
  1100. ASSERT_TRUE(from_hds);
  1101. ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
  1102. // Fetch the host via
  1103. // get4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
  1104. // const uint8_t* identifier_begin, const size_t identifier_len) const;
  1105. from_hds = hdsptr_->get4(subnet_id, host->getIdentifierType(), &host->getIdentifier()[0],
  1106. host->getIdentifier().size());
  1107. ASSERT_TRUE(from_hds);
  1108. ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
  1109. // Fetch the host via:
  1110. // get4(const SubnetID& subnet_id, const asiolink::IOAddress& address) const;
  1111. from_hds = hdsptr_->get4(subnet_id, IOAddress("192.0.2.5"));
  1112. ASSERT_TRUE(from_hds);
  1113. ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
  1114. }
  1115. }; // namespace test
  1116. }; // namespace dhcp
  1117. }; // namespace isc