generic_host_data_source_unittest.cc 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160
  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. // Compare IPv6 reservations
  209. compareReservations6(host1->getIPv6Reservations(),
  210. host2->getIPv6Reservations());
  211. // Compare client classification details
  212. compareClientClasses(host1->getClientClasses4(),
  213. host2->getClientClasses4());
  214. compareClientClasses(host1->getClientClasses6(),
  215. host2->getClientClasses6());
  216. // Compare DHCPv4 and DHCPv6 options.
  217. compareOptions(host1->getCfgOption4(), host2->getCfgOption4());
  218. compareOptions(host1->getCfgOption6(), host2->getCfgOption6());
  219. }
  220. DuidPtr
  221. GenericHostDataSourceTest::HWAddrToDuid(const HWAddrPtr& hwaddr) {
  222. if (!hwaddr) {
  223. return (DuidPtr());
  224. }
  225. return (DuidPtr(new DUID(hwaddr->hwaddr_)));
  226. }
  227. HWAddrPtr
  228. GenericHostDataSourceTest::DuidToHWAddr(const DuidPtr& duid) {
  229. if (!duid) {
  230. return (HWAddrPtr());
  231. }
  232. return (HWAddrPtr(new HWAddr(duid->getDuid(), HTYPE_ETHER)));
  233. }
  234. void
  235. GenericHostDataSourceTest::compareReservations6(IPv6ResrvRange resrv1,
  236. IPv6ResrvRange resrv2) {
  237. // Compare number of reservations for both hosts
  238. if (std::distance(resrv1.first, resrv1.second) !=
  239. std::distance(resrv2.first, resrv2.second)){
  240. ADD_FAILURE()<< "Reservation comparison failed, "
  241. "hosts got different number of reservations.";
  242. return;
  243. }
  244. // Iterate over the range of reservations to find a match in the
  245. // reference range.
  246. for (IPv6ResrvIterator r1 = resrv1.first; r1 != resrv1.second; ++r1) {
  247. IPv6ResrvIterator r2 = resrv2.first;
  248. for (; r2 != resrv2.second; ++r2) {
  249. // IPv6Resrv object implements equality operator.
  250. if (r1->second == r2->second) {
  251. break;
  252. }
  253. }
  254. // If r2 iterator reached the end of the range it means that there
  255. // is no match.
  256. if (r2 == resrv2.second) {
  257. ADD_FAILURE() << "No match found for reservation: "
  258. << resrv1.first->second.getPrefix().toText();
  259. }
  260. }
  261. if (std::distance(resrv1.first, resrv1.second) > 0) {
  262. for (; resrv1.first != resrv1.second; resrv1.first++) {
  263. IPv6ResrvIterator iter = resrv2.first;
  264. while (iter != resrv2.second) {
  265. if((resrv1.first->second.getType() == iter->second.getType()) &&
  266. (resrv1.first->second.getPrefixLen() == iter->second.getPrefixLen()) &&
  267. (resrv1.first->second.getPrefix() == iter->second.getPrefix())) {
  268. break;
  269. }
  270. iter++;
  271. if (iter == resrv2.second) {
  272. ADD_FAILURE()<< "Reservation comparison failed, "
  273. "no match for reservation: "
  274. << resrv1.first->second.getPrefix().toText();
  275. }
  276. }
  277. }
  278. }
  279. }
  280. void
  281. GenericHostDataSourceTest::compareClientClasses(const ClientClasses& /*classes1*/,
  282. const ClientClasses& /*classes2*/) {
  283. /// @todo: Implement client classes comparison.
  284. /// This is part of the work for #4213.
  285. }
  286. void
  287. GenericHostDataSourceTest::compareOptions(const ConstCfgOptionPtr& cfg1,
  288. const ConstCfgOptionPtr& cfg2) const {
  289. ASSERT_TRUE(cfg1);
  290. ASSERT_TRUE(cfg2);
  291. // Combine option space names with vendor space names in a single list.
  292. std::list<std::string> option_spaces = cfg2->getOptionSpaceNames();
  293. std::list<std::string> vendor_spaces = cfg2->getVendorIdsSpaceNames();
  294. option_spaces.insert(option_spaces.end(), vendor_spaces.begin(),
  295. vendor_spaces.end());
  296. // Make sure that the number of option spaces is equal in both
  297. // configurations.
  298. EXPECT_EQ(option_spaces.size(), cfg1->getOptionSpaceNames().size());
  299. EXPECT_EQ(vendor_spaces.size(), cfg1->getVendorIdsSpaceNames().size());
  300. // Iterate over all option spaces existing in cfg2.
  301. BOOST_FOREACH(std::string space, option_spaces) {
  302. // Retrieve options belonging to the current option space.
  303. OptionContainerPtr options1 = cfg1->getAll(space);
  304. OptionContainerPtr options2 = cfg2->getAll(space);
  305. ASSERT_TRUE(options1) << "failed for option space " << space;
  306. ASSERT_TRUE(options2) << "failed for option space " << space;
  307. // If number of options doesn't match, the test fails.
  308. ASSERT_EQ(options1->size(), options2->size())
  309. << "failed for option space " << space;
  310. // Iterate over all options within this option space.
  311. BOOST_FOREACH(OptionDescriptor desc1, *options1) {
  312. OptionDescriptor desc2 = cfg2->get(space, desc1.option_->getType());
  313. // Compare persistent flag.
  314. EXPECT_EQ(desc1.persistent_, desc2.persistent_)
  315. << "failed for option " << space << "." << desc1.option_->getType();
  316. // Compare formatted value.
  317. EXPECT_EQ(desc1.formatted_value_, desc2.formatted_value_)
  318. << "failed for option " << space << "." << desc1.option_->getType();
  319. // Retrieve options.
  320. Option* option1 = desc1.option_.get();
  321. Option* option2 = desc2.option_.get();
  322. // Options must be represented by the same C++ class derived from
  323. // the Option class.
  324. EXPECT_TRUE(typeid(*option1) == typeid(*option2))
  325. << "Comapared DHCP options, having option code "
  326. << desc1.option_->getType() << " and belonging to the "
  327. << space << " option space, are represented "
  328. "by different C++ classes: "
  329. << typeid(*option1).name() << " vs "
  330. << typeid(*option2).name();
  331. // Because we use different C++ classes to represent different
  332. // options, the simplest way to make sure that the options are
  333. // equal is to simply compare them in wire format.
  334. OutputBuffer buf1(option1->len());
  335. ASSERT_NO_THROW(option1->pack(buf1));
  336. OutputBuffer buf2(option2->len());
  337. ASSERT_NO_THROW(option2->pack(buf2));
  338. ASSERT_EQ(buf1.getLength(), buf2.getLength())
  339. << "failed for option " << space << "." << desc1.option_->getType();
  340. EXPECT_EQ(0, memcmp(buf1.getData(), buf2.getData(), buf1.getLength()))
  341. << "failed for option " << space << "." << desc1.option_->getType();
  342. }
  343. }
  344. }
  345. OptionDescriptor
  346. GenericHostDataSourceTest::createEmptyOption(const Option::Universe& universe,
  347. const uint16_t option_type,
  348. const bool persist) const {
  349. OptionPtr option(new Option(universe, option_type));
  350. OptionDescriptor desc(option, persist);
  351. return (desc);
  352. }
  353. OptionDescriptor
  354. GenericHostDataSourceTest::createVendorOption(const Option::Universe& universe,
  355. const bool persist,
  356. const bool formatted,
  357. const uint32_t vendor_id) const {
  358. OptionVendorPtr option(new OptionVendor(universe, vendor_id));
  359. std::ostringstream s;
  360. if (formatted) {
  361. // Vendor id comprises vendor-id field, for which we need to
  362. // assign a value in the textual (formatted) format.
  363. s << vendor_id;
  364. }
  365. OptionDescriptor desc(option, persist, s.str());
  366. return (desc);
  367. }
  368. void
  369. GenericHostDataSourceTest::addTestOptions(const HostPtr& host,
  370. const bool formatted,
  371. const AddedOptions& added_options) const {
  372. OptionDefSpaceContainer defs;
  373. if ((added_options == DHCP4_ONLY) || (added_options == DHCP4_AND_DHCP6)) {
  374. // Add DHCPv4 options.
  375. CfgOptionPtr opts = host->getCfgOption4();
  376. opts->add(createOption<OptionString>(Option::V4, DHO_BOOT_FILE_NAME,
  377. true, formatted, "my-boot-file"),
  378. DHCP4_OPTION_SPACE);
  379. opts->add(createOption<OptionUint8>(Option::V4, DHO_DEFAULT_IP_TTL,
  380. false, formatted, 64),
  381. DHCP4_OPTION_SPACE);
  382. opts->add(createOption<OptionUint32>(Option::V4, 1, false, formatted, 312131),
  383. "vendor-encapsulated-options");
  384. opts->add(createAddressOption<Option4AddrLst>(254, false, formatted, "192.0.2.3"),
  385. DHCP4_OPTION_SPACE);
  386. opts->add(createEmptyOption(Option::V4, 1, true), "isc");
  387. opts->add(createAddressOption<Option4AddrLst>(2, false, formatted, "10.0.0.5",
  388. "10.0.0.3", "10.0.3.4"),
  389. "isc");
  390. // Add definitions for DHCPv4 non-standard options.
  391. defs.addItem(OptionDefinitionPtr(new OptionDefinition("vendor-encapsulated-1",
  392. 1, "uint32")),
  393. "vendor-encapsulated-options");
  394. defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-254", 254,
  395. "ipv4-address", true)),
  396. DHCP4_OPTION_SPACE);
  397. defs.addItem(OptionDefinitionPtr(new OptionDefinition("isc-1", 1, "empty")),
  398. "isc");
  399. defs.addItem(OptionDefinitionPtr(new OptionDefinition("isc-2", 2,
  400. "ipv4-address", true)),
  401. "isc");
  402. }
  403. if ((added_options == DHCP6_ONLY) || (added_options == DHCP4_AND_DHCP6)) {
  404. // Add DHCPv6 options.
  405. CfgOptionPtr opts = host->getCfgOption6();
  406. opts->add(createOption<OptionString>(Option::V6, D6O_BOOTFILE_URL,
  407. true, formatted, "my-boot-file"),
  408. DHCP6_OPTION_SPACE);
  409. opts->add(createOption<OptionUint32>(Option::V6, D6O_INFORMATION_REFRESH_TIME,
  410. false, formatted, 3600),
  411. DHCP6_OPTION_SPACE);
  412. opts->add(createVendorOption(Option::V6, false, formatted, 2495),
  413. DHCP6_OPTION_SPACE);
  414. opts->add(createAddressOption<Option6AddrLst>(1024, false, formatted,
  415. "2001:db8:1::1"),
  416. DHCP6_OPTION_SPACE);
  417. opts->add(createEmptyOption(Option::V6, 1, true), "isc2");
  418. opts->add(createAddressOption<Option6AddrLst>(2, false, formatted, "3000::1",
  419. "3000::2", "3000::3"),
  420. "isc2");
  421. // Add definitions for DHCPv6 non-standard options.
  422. defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-1024", 1024,
  423. "ipv6-address", true)),
  424. DHCP6_OPTION_SPACE);
  425. defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-1", 1, "empty")),
  426. "isc2");
  427. defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-2", 2,
  428. "ipv6-address", true)),
  429. "isc2");
  430. }
  431. // Register created "runtime" option definitions. They will be used by a
  432. // host data source to convert option data into the appropriate option
  433. // classes when the options are retrieved.
  434. LibDHCP::setRuntimeOptionDefs(defs);
  435. }
  436. void GenericHostDataSourceTest::testBasic4(const Host::IdentifierType& id) {
  437. // Make sure we have the pointer to the host data source.
  438. ASSERT_TRUE(hdsptr_);
  439. // Create a host reservation.
  440. HostPtr host = initializeHost4("192.0.2.1", id);
  441. ASSERT_TRUE(host); // Make sure the host is generate properly.
  442. SubnetID subnet = host->getIPv4SubnetID();
  443. // Try to add it to the host data source.
  444. ASSERT_NO_THROW(hdsptr_->add(host));
  445. // This should not return anything
  446. ConstHostPtr from_hds = hdsptr_->get4(subnet, IOAddress("10.10.10.10"));
  447. ASSERT_FALSE(from_hds);
  448. // This time it should return a host
  449. from_hds = hdsptr_->get4(subnet, IOAddress("192.0.2.1"));
  450. ASSERT_TRUE(from_hds);
  451. // Finally, let's check if what we got makes any sense.
  452. compareHosts(host, from_hds);
  453. }
  454. void GenericHostDataSourceTest::testGetByIPv4(const Host::IdentifierType& id) {
  455. // Make sure we have a pointer to the host data source.
  456. ASSERT_TRUE(hdsptr_);
  457. // Let's create a couple of hosts...
  458. HostPtr host1 = initializeHost4("192.0.2.1", id);
  459. HostPtr host2 = initializeHost4("192.0.2.2", id);
  460. HostPtr host3 = initializeHost4("192.0.2.3", id);
  461. HostPtr host4 = initializeHost4("192.0.2.4", id);
  462. // ... and add them to the data source.
  463. ASSERT_NO_THROW(hdsptr_->add(host1));
  464. ASSERT_NO_THROW(hdsptr_->add(host2));
  465. ASSERT_NO_THROW(hdsptr_->add(host3));
  466. ASSERT_NO_THROW(hdsptr_->add(host4));
  467. SubnetID subnet1 = host1->getIPv4SubnetID();
  468. SubnetID subnet2 = host2->getIPv4SubnetID();
  469. SubnetID subnet3 = host3->getIPv4SubnetID();
  470. SubnetID subnet4 = host4->getIPv4SubnetID();
  471. // And then try to retrieve them back.
  472. ConstHostPtr from_hds1 = hdsptr_->get4(subnet1, IOAddress("192.0.2.1"));
  473. ConstHostPtr from_hds2 = hdsptr_->get4(subnet2, IOAddress("192.0.2.2"));
  474. ConstHostPtr from_hds3 = hdsptr_->get4(subnet3, IOAddress("192.0.2.3"));
  475. ConstHostPtr from_hds4 = hdsptr_->get4(subnet4, IOAddress("192.0.2.4"));
  476. // Make sure we got something back.
  477. ASSERT_TRUE(from_hds1);
  478. ASSERT_TRUE(from_hds2);
  479. ASSERT_TRUE(from_hds3);
  480. ASSERT_TRUE(from_hds4);
  481. // Then let's check that what we got seems correct.
  482. compareHosts(host1, from_hds1);
  483. compareHosts(host2, from_hds2);
  484. compareHosts(host3, from_hds3);
  485. compareHosts(host4, from_hds4);
  486. // Ok, finally let's check that getting by a different address
  487. // will not work.
  488. EXPECT_FALSE(hdsptr_->get4(subnet1, IOAddress("192.0.1.5")));
  489. }
  490. void
  491. GenericHostDataSourceTest::testGet4ByIdentifier(const Host::IdentifierType& identifier_type) {
  492. // Make sure we have a pointer to the host data source.
  493. ASSERT_TRUE(hdsptr_);
  494. HostPtr host1 = initializeHost4("192.0.2.1", identifier_type);
  495. HostPtr host2 = initializeHost4("192.0.2.2", identifier_type);
  496. // Sanity check: make sure the hosts have different identifiers..
  497. ASSERT_FALSE(host1->getIdentifier() == host2->getIdentifier());
  498. // Try to add both of them to the host data source.
  499. ASSERT_NO_THROW(hdsptr_->add(host1));
  500. ASSERT_NO_THROW(hdsptr_->add(host2));
  501. SubnetID subnet1 = host1->getIPv4SubnetID();
  502. SubnetID subnet2 = host2->getIPv4SubnetID();
  503. ConstHostPtr from_hds1 = hdsptr_->get4(subnet1,
  504. identifier_type,
  505. &host1->getIdentifier()[0],
  506. host1->getIdentifier().size());
  507. ConstHostPtr from_hds2 = hdsptr_->get4(subnet2,
  508. identifier_type,
  509. &host2->getIdentifier()[0],
  510. host2->getIdentifier().size());
  511. // Now let's check if we got what we expected.
  512. ASSERT_TRUE(from_hds1);
  513. ASSERT_TRUE(from_hds2);
  514. compareHosts(host1, from_hds1);
  515. compareHosts(host2, from_hds2);
  516. }
  517. void GenericHostDataSourceTest::testHWAddrNotClientId() {
  518. // Make sure we have a pointer to the host data source.
  519. ASSERT_TRUE(hdsptr_);
  520. // Create a host with HW address
  521. HostPtr host = initializeHost4("192.0.2.1", Host::IDENT_HWADDR);
  522. ASSERT_TRUE(host->getHWAddress());
  523. ASSERT_FALSE(host->getDuid());
  524. // Try to add it to the host data source.
  525. ASSERT_NO_THROW(hdsptr_->add(host));
  526. SubnetID subnet = host->getIPv4SubnetID();
  527. DuidPtr duid = HWAddrToDuid(host->getHWAddress());
  528. // Get the host by HW address (should succeed)
  529. ConstHostPtr by_hwaddr = hdsptr_->get4(subnet, Host::IDENT_HWADDR,
  530. &host->getIdentifier()[0],
  531. host->getIdentifier().size());
  532. // Get the host by DUID (should fail)
  533. ConstHostPtr by_duid = hdsptr_->get4(subnet, Host::IDENT_DUID,
  534. &host->getIdentifier()[0],
  535. host->getIdentifier().size());
  536. // Now let's check if we got what we expected.
  537. EXPECT_TRUE(by_hwaddr);
  538. EXPECT_FALSE(by_duid);
  539. }
  540. void GenericHostDataSourceTest::testClientIdNotHWAddr() {
  541. // Make sure we have a pointer to the host data source.
  542. ASSERT_TRUE(hdsptr_);
  543. // Create a host with client-id
  544. HostPtr host = initializeHost4("192.0.2.1", Host::IDENT_DUID);
  545. ASSERT_FALSE(host->getHWAddress());
  546. ASSERT_TRUE(host->getDuid());
  547. // Try to add it to the host data source.
  548. ASSERT_NO_THROW(hdsptr_->add(host));
  549. SubnetID subnet = host->getIPv4SubnetID();
  550. HWAddrPtr hwaddr = DuidToHWAddr(host->getDuid());
  551. // Get the host by DUID (should succeed)
  552. ConstHostPtr by_duid = hdsptr_->get4(subnet, Host::IDENT_DUID,
  553. &host->getIdentifier()[0],
  554. host->getIdentifier().size());
  555. // Get the host by HW address (should fail)
  556. ConstHostPtr by_hwaddr = hdsptr_->get4(subnet, Host::IDENT_HWADDR,
  557. &host->getIdentifier()[0],
  558. host->getIdentifier().size());
  559. // Now let's check if we got what we expected.
  560. EXPECT_TRUE(by_duid);
  561. EXPECT_FALSE(by_hwaddr);
  562. }
  563. void
  564. GenericHostDataSourceTest::testHostname(std::string name, int num) {
  565. // Make sure we have a pointer to the host data source.
  566. ASSERT_TRUE(hdsptr_);
  567. // Initialize the address to 192.0.2.0 (this will be bumped
  568. // up to 192.0.2.1 in the first iteration)
  569. IOAddress addr("192.0.2.0");
  570. vector<HostPtr> hosts;
  571. // Prepare a vector of hosts with unique hostnames
  572. for (int i = 0; i < num; ++i) {
  573. addr = IOAddress::increase(addr);
  574. HostPtr host = initializeHost4(addr.toText(), Host::IDENT_DUID);
  575. stringstream hostname;
  576. hostname.str("");
  577. if (num > 1) {
  578. hostname << i;
  579. }
  580. hostname << name;
  581. host->setHostname(hostname.str());
  582. hosts.push_back(host);
  583. }
  584. // Now add them all to the host data source.
  585. for (vector<HostPtr>::const_iterator it = hosts.begin();
  586. it != hosts.end(); ++it) {
  587. // Try to add both of the to the host data source.
  588. ASSERT_NO_THROW(hdsptr_->add(*it));
  589. }
  590. // And finally retrieve them one by one and check
  591. // if the hostname was preserved.
  592. for (vector<HostPtr>::const_iterator it = hosts.begin();
  593. it != hosts.end(); ++it) {
  594. ConstHostPtr from_hds;
  595. ASSERT_NO_THROW(from_hds = hdsptr_->get4(
  596. (*it)->getIPv4SubnetID(),
  597. (*it)->getIPv4Reservation()));
  598. ASSERT_TRUE(from_hds);
  599. EXPECT_EQ((*it)->getHostname(), from_hds->getHostname());
  600. }
  601. }
  602. void
  603. GenericHostDataSourceTest::testMultipleSubnets(int subnets,
  604. const Host::IdentifierType& id) {
  605. // Make sure we have a pointer to the host data source.
  606. ASSERT_TRUE(hdsptr_);
  607. HostPtr host = initializeHost4("192.0.2.1", id);
  608. for (int i = 0; i < subnets; ++i) {
  609. host->setIPv4SubnetID(i + 1000);
  610. host->setIPv6SubnetID(i + 1000);
  611. // Check that the same host can have reservations in multiple subnets.
  612. EXPECT_NO_THROW(hdsptr_->add(host));
  613. }
  614. // Now check that the reservations can be retrieved by IPv4 address from
  615. // each subnet separately.
  616. for (int i = 0; i < subnets; ++i) {
  617. // Try to retrieve the host by IPv4 address.
  618. ConstHostPtr from_hds = hdsptr_->get4(i + 1000, host->getIPv4Reservation());
  619. ASSERT_TRUE(from_hds);
  620. EXPECT_EQ(i + 1000, from_hds->getIPv4SubnetID());
  621. // Try to retrieve the host by either HW address of client-id
  622. from_hds = hdsptr_->get4(i + 1000,
  623. id, &host->getIdentifier()[0],
  624. host->getIdentifier().size());
  625. ASSERT_TRUE(from_hds);
  626. EXPECT_EQ(i + 1000, from_hds->getIPv4SubnetID());
  627. }
  628. // Now check that they can be retrieved all at once, by IPv4 address.
  629. ConstHostCollection all_by_addr = hdsptr_->getAll4(IOAddress("192.0.2.1"));
  630. ASSERT_EQ(subnets, all_by_addr.size());
  631. // Verify that the values returned are proper.
  632. int i = 0;
  633. for (ConstHostCollection::const_iterator it = all_by_addr.begin();
  634. it != all_by_addr.end(); ++it) {
  635. EXPECT_EQ(IOAddress("192.0.2.1"), (*it)->getIPv4Reservation());
  636. EXPECT_EQ(1000 + i++, (*it)->getIPv4SubnetID());
  637. }
  638. // Finally, check that the hosts can be retrived by HW address or DUID
  639. ConstHostCollection all_by_id =
  640. hdsptr_->getAll(id, &host->getIdentifier()[0],
  641. host->getIdentifier().size());
  642. ASSERT_EQ(subnets, all_by_id.size());
  643. // Check that the returned values are as expected.
  644. i = 0;
  645. for (ConstHostCollection::const_iterator it = all_by_id.begin();
  646. it != all_by_id.end(); ++it) {
  647. EXPECT_EQ(IOAddress("192.0.2.1"), (*it)->getIPv4Reservation());
  648. EXPECT_EQ(1000 + i++, (*it)->getIPv4SubnetID());
  649. }
  650. }
  651. void GenericHostDataSourceTest::testGet6ByHWAddr() {
  652. // Make sure we have the pointer to the host data source.
  653. ASSERT_TRUE(hdsptr_);
  654. // Create a host reservations.
  655. HostPtr host1 = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, "hw-address");
  656. HostPtr host2 = initializeHost6("2001:db8::2", Host::IDENT_HWADDR, "hw-address");
  657. // Sanity check: make sure the hosts have different HW addresses.
  658. ASSERT_TRUE(host1->getHWAddress());
  659. ASSERT_TRUE(host2->getHWAddress());
  660. compareHwaddrs(host1, host2, false);
  661. // Try to add both of them to the host data source.
  662. ASSERT_NO_THROW(hdsptr_->add(host1));
  663. ASSERT_NO_THROW(hdsptr_->add(host2));
  664. SubnetID subnet1 = host1->getIPv6SubnetID();
  665. SubnetID subnet2 = host2->getIPv6SubnetID();
  666. ConstHostPtr from_hds1 = hdsptr_->get6(subnet1, Host::IDENT_HWADDR,
  667. &host1->getIdentifier()[0],
  668. host1->getIdentifier().size());
  669. ConstHostPtr from_hds2 = hdsptr_->get6(subnet2, Host::IDENT_HWADDR,
  670. &host2->getIdentifier()[0],
  671. host2->getIdentifier().size());
  672. // Now let's check if we got what we expected.
  673. ASSERT_TRUE(from_hds1);
  674. ASSERT_TRUE(from_hds2);
  675. compareHosts(host1, from_hds1);
  676. compareHosts(host2, from_hds2);
  677. }
  678. void GenericHostDataSourceTest::testGet6ByClientId() {
  679. // Make sure we have the pointer to the host data source.
  680. ASSERT_TRUE(hdsptr_);
  681. // Create a host reservations.
  682. HostPtr host1 = initializeHost6("2001:db8::1", Host::IDENT_DUID, "hw-address");
  683. HostPtr host2 = initializeHost6("2001:db8::2", Host::IDENT_DUID, "hw-address");
  684. // Sanity check: make sure the hosts have different HW addresses.
  685. ASSERT_TRUE(host1->getDuid());
  686. ASSERT_TRUE(host2->getDuid());
  687. compareDuids(host1, host2, false);
  688. // Try to add both of them to the host data source.
  689. ASSERT_NO_THROW(hdsptr_->add(host1));
  690. ASSERT_NO_THROW(hdsptr_->add(host2));
  691. SubnetID subnet1 = host1->getIPv6SubnetID();
  692. SubnetID subnet2 = host2->getIPv6SubnetID();
  693. ConstHostPtr from_hds1 = hdsptr_->get6(subnet1, Host::IDENT_DUID,
  694. &host1->getIdentifier()[0],
  695. host1->getIdentifier().size());
  696. ConstHostPtr from_hds2 = hdsptr_->get6(subnet2, Host::IDENT_DUID,
  697. &host2->getIdentifier()[0],
  698. host2->getIdentifier().size());
  699. // Now let's check if we got what we expected.
  700. ASSERT_TRUE(from_hds1);
  701. ASSERT_TRUE(from_hds2);
  702. compareHosts(host1, from_hds1);
  703. compareHosts(host2, from_hds2);
  704. }
  705. void
  706. GenericHostDataSourceTest::testSubnetId6(int subnets, Host::IdentifierType id) {
  707. // Make sure we have a pointer to the host data source.
  708. ASSERT_TRUE(hdsptr_);
  709. HostPtr host;
  710. IOAddress current_address("2001:db8::0");
  711. for (int i = 0; i < subnets; ++i) {
  712. // Last boolean value set to false indicates that the same identifier
  713. // must be used for each generated host.
  714. host = initializeHost6(current_address.toText(), id, true, false);
  715. host->setIPv4SubnetID(i + 1000);
  716. host->setIPv6SubnetID(i + 1000);
  717. // Check that the same host can have reservations in multiple subnets.
  718. EXPECT_NO_THROW(hdsptr_->add(host));
  719. // Increase address to make sure we don't assign the same address
  720. // in different subnets.
  721. current_address = IOAddress::increase(current_address);
  722. }
  723. // Check that the reservations can be retrieved from each subnet separately.
  724. for (int i = 0; i < subnets; ++i) {
  725. // Try to retrieve the host
  726. ConstHostPtr from_hds = hdsptr_->get6(i + 1000, id, &host->getIdentifier()[0],
  727. host->getIdentifier().size());
  728. ASSERT_TRUE(from_hds) << "failed for i=" << i;
  729. EXPECT_EQ(i + 1000, from_hds->getIPv6SubnetID());
  730. }
  731. // Check that the hosts can all be retrived by HW address or DUID
  732. ConstHostCollection all_by_id = hdsptr_->getAll(id, &host->getIdentifier()[0],
  733. host->getIdentifier().size());
  734. ASSERT_EQ(subnets, all_by_id.size());
  735. // Check that the returned values are as expected.
  736. int i = 0;
  737. for (ConstHostCollection::const_iterator it = all_by_id.begin();
  738. it != all_by_id.end(); ++it) {
  739. EXPECT_EQ(IOAddress("0.0.0.0"), (*it)->getIPv4Reservation());
  740. EXPECT_EQ(1000 + i++, (*it)->getIPv6SubnetID());
  741. }
  742. }
  743. void GenericHostDataSourceTest::testGetByIPv6(Host::IdentifierType id,
  744. bool prefix) {
  745. // Make sure we have a pointer to the host data source.
  746. ASSERT_TRUE(hdsptr_);
  747. // Let's create a couple of hosts...
  748. HostPtr host1 = initializeHost6("2001:db8::1", id, prefix);
  749. HostPtr host2 = initializeHost6("2001:db8::2", id, prefix);
  750. HostPtr host3 = initializeHost6("2001:db8::3", id, prefix);
  751. HostPtr host4 = initializeHost6("2001:db8::4", id, prefix);
  752. // ... and add them to the data source.
  753. ASSERT_NO_THROW(hdsptr_->add(host1));
  754. ASSERT_NO_THROW(hdsptr_->add(host2));
  755. ASSERT_NO_THROW(hdsptr_->add(host3));
  756. ASSERT_NO_THROW(hdsptr_->add(host4));
  757. // Are we talking about addresses or prefixes?
  758. uint8_t len = prefix ? 64 : 128;
  759. // And then try to retrieve them back.
  760. ConstHostPtr from_hds1 = hdsptr_->get6(IOAddress("2001:db8::1"), len);
  761. ConstHostPtr from_hds2 = hdsptr_->get6(IOAddress("2001:db8::2"), len);
  762. ConstHostPtr from_hds3 = hdsptr_->get6(IOAddress("2001:db8::3"), len);
  763. ConstHostPtr from_hds4 = hdsptr_->get6(IOAddress("2001:db8::4"), len);
  764. // Make sure we got something back.
  765. ASSERT_TRUE(from_hds1);
  766. ASSERT_TRUE(from_hds2);
  767. ASSERT_TRUE(from_hds3);
  768. ASSERT_TRUE(from_hds4);
  769. // Then let's check that what we got seems correct.
  770. compareHosts(host1, from_hds1);
  771. compareHosts(host2, from_hds2);
  772. compareHosts(host3, from_hds3);
  773. compareHosts(host4, from_hds4);
  774. // Ok, finally let's check that getting by a different address
  775. // will not work.
  776. EXPECT_FALSE(hdsptr_->get6(IOAddress("2001:db8::5"), len));
  777. }
  778. void GenericHostDataSourceTest::testAddDuplicate6WithSameDUID() {
  779. // Make sure we have the pointer to the host data source.
  780. ASSERT_TRUE(hdsptr_);
  781. // Create a host reservations.
  782. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, true);
  783. // Add this reservation once.
  784. ASSERT_NO_THROW(hdsptr_->add(host));
  785. // Then try to add it again, it should throw an exception.
  786. ASSERT_THROW(hdsptr_->add(host), DuplicateEntry);
  787. }
  788. void GenericHostDataSourceTest::testAddDuplicate6WithSameHWAddr() {
  789. // Make sure we have the pointer to the host data source.
  790. ASSERT_TRUE(hdsptr_);
  791. // Create a host reservations.
  792. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, true);
  793. // Add this reservation once.
  794. ASSERT_NO_THROW(hdsptr_->add(host));
  795. // Then try to add it again, it should throw an exception.
  796. ASSERT_THROW(hdsptr_->add(host), DuplicateEntry);
  797. }
  798. void GenericHostDataSourceTest::testAddDuplicate4() {
  799. // Make sure we have the pointer to the host data source.
  800. ASSERT_TRUE(hdsptr_);
  801. // Create a host reservations.
  802. HostPtr host = initializeHost4("192.0.2.1", Host::IDENT_DUID);
  803. // Add this reservation once.
  804. ASSERT_NO_THROW(hdsptr_->add(host));
  805. // Then try to add it again, it should throw an exception.
  806. ASSERT_THROW(hdsptr_->add(host), DuplicateEntry);
  807. // This time use a different host identifier and try again.
  808. // This update should be rejected because of duplicated
  809. // address.
  810. ASSERT_NO_THROW(host->setIdentifier("01:02:03:04:05:06", "hw-address"));
  811. ASSERT_THROW(hdsptr_->add(host), DuplicateEntry);
  812. // Modify address to avoid its duplication and make sure
  813. // we can now add the host.
  814. ASSERT_NO_THROW(host->setIPv4Reservation(IOAddress("192.0.2.3")));
  815. EXPECT_NO_THROW(hdsptr_->add(host));
  816. }
  817. void GenericHostDataSourceTest::testAddr6AndPrefix(){
  818. // Make sure we have the pointer to the host data source.
  819. ASSERT_TRUE(hdsptr_);
  820. // Create a host reservations with prefix reservation (prefix = true)
  821. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, true);
  822. // Create IPv6 reservation (for an address) and add it to the host
  823. IPv6Resrv resv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::2"), 128);
  824. host->addReservation(resv);
  825. // Add this reservation
  826. ASSERT_NO_THROW(hdsptr_->add(host));
  827. // Get this host by DUID
  828. ConstHostPtr from_hds = hdsptr_->get6(host->getIPv6SubnetID(),
  829. Host::IDENT_DUID,
  830. &host->getIdentifier()[0],
  831. host->getIdentifier().size());
  832. // Make sure we got something back
  833. ASSERT_TRUE(from_hds);
  834. // Check if reservations are the same
  835. compareReservations6(host->getIPv6Reservations(),
  836. from_hds->getIPv6Reservations());
  837. }
  838. void GenericHostDataSourceTest::testMultipleReservations(){
  839. // Make sure we have the pointer to the host data source.
  840. ASSERT_TRUE(hdsptr_);
  841. uint8_t len = 128;
  842. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
  843. // Add some reservations
  844. IPv6Resrv resv1(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::6"), len);
  845. IPv6Resrv resv2(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::7"), len);
  846. IPv6Resrv resv3(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::8"), len);
  847. IPv6Resrv resv4(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::9"), len);
  848. host->addReservation(resv1);
  849. host->addReservation(resv2);
  850. host->addReservation(resv3);
  851. host->addReservation(resv4);
  852. ASSERT_NO_THROW(hdsptr_->add(host));
  853. ConstHostPtr from_hds = hdsptr_->get6(IOAddress("2001:db8::1"), len);
  854. // Make sure we got something back
  855. ASSERT_TRUE(from_hds);
  856. // Check if hosts are the same
  857. compareHosts(host, from_hds);
  858. }
  859. void GenericHostDataSourceTest::testMultipleReservationsDifferentOrder(){
  860. // Make sure we have the pointer to the host data source.
  861. ASSERT_TRUE(hdsptr_);
  862. uint8_t len = 128;
  863. HostPtr host1 = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
  864. HostPtr host2 = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
  865. // Add some reservations
  866. IPv6Resrv resv1(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::6"), len);
  867. IPv6Resrv resv2(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::7"), len);
  868. IPv6Resrv resv3(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::8"), len);
  869. IPv6Resrv resv4(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::9"), len);
  870. host1->addReservation(resv1);
  871. host1->addReservation(resv2);
  872. host1->addReservation(resv3);
  873. host1->addReservation(resv4);
  874. host2->addReservation(resv4);
  875. host2->addReservation(resv3);
  876. host2->addReservation(resv2);
  877. host2->addReservation(resv1);
  878. // Check if reservations are the same
  879. compareReservations6(host1->getIPv6Reservations(), host2->getIPv6Reservations());
  880. }
  881. void GenericHostDataSourceTest::testOptionsReservations4(const bool formatted) {
  882. HostPtr host = initializeHost4("192.0.2.5", Host::IDENT_HWADDR);
  883. // Add a bunch of DHCPv4 and DHCPv6 options for the host.
  884. ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP4_ONLY));
  885. // Insert host and the options into respective tables.
  886. ASSERT_NO_THROW(hdsptr_->add(host));
  887. // Subnet id will be used in quries to the database.
  888. SubnetID subnet_id = host->getIPv4SubnetID();
  889. // getAll4(address)
  890. ConstHostCollection hosts_by_addr = hdsptr_->getAll4(host->getIPv4Reservation());
  891. ASSERT_EQ(1, hosts_by_addr.size());
  892. ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_addr.begin()));
  893. // get4(subnet_id, identifier_type, identifier, identifier_size)
  894. ConstHostPtr host_by_id = hdsptr_->get4(subnet_id,
  895. host->getIdentifierType(),
  896. &host->getIdentifier()[0],
  897. host->getIdentifier().size());
  898. ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_id));
  899. // get4(subnet_id, address)
  900. ConstHostPtr host_by_addr = hdsptr_->get4(subnet_id, IOAddress("192.0.2.5"));
  901. ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_addr));
  902. }
  903. void GenericHostDataSourceTest::testOptionsReservations6(const bool formatted) {
  904. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
  905. // Add a bunch of DHCPv4 and DHCPv6 options for the host.
  906. ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP6_ONLY));
  907. // Insert host, options and IPv6 reservations into respective tables.
  908. ASSERT_NO_THROW(hdsptr_->add(host));
  909. // Subnet id will be used in queries to the database.
  910. SubnetID subnet_id = host->getIPv6SubnetID();
  911. // get6(subnet_id, identifier_type, identifier, identifier_size)
  912. ConstHostPtr host_by_id = hdsptr_->get6(subnet_id, host->getIdentifierType(),
  913. &host->getIdentifier()[0],
  914. host->getIdentifier().size());
  915. ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_id));
  916. // get6(address, prefix_len)
  917. ConstHostPtr host_by_addr = hdsptr_->get6(IOAddress("2001:db8::1"), 128);
  918. ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_addr));
  919. }
  920. void GenericHostDataSourceTest::testOptionsReservations46(const bool formatted) {
  921. HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, false);
  922. // Add a bunch of DHCPv4 and DHCPv6 options for the host.
  923. ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP4_AND_DHCP6));
  924. // Insert host, options and IPv6 reservations into respective tables.
  925. ASSERT_NO_THROW(hdsptr_->add(host));
  926. // Subnet id will be used in queries to the database.
  927. SubnetID subnet_id = host->getIPv6SubnetID();
  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. }; // namespace test
  936. }; // namespace dhcp
  937. }; // namespace isc