host_mgr_unittest.cc 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <config.h>
  15. #include <dhcp/duid.h>
  16. #include <dhcp/hwaddr.h>
  17. #include <dhcpsrv/cfgmgr.h>
  18. #include <dhcpsrv/host.h>
  19. #include <dhcpsrv/host_mgr.h>
  20. #include <gtest/gtest.h>
  21. #include <vector>
  22. using namespace isc;
  23. using namespace isc::dhcp;
  24. using namespace isc::asiolink;
  25. namespace {
  26. /// @brief Test fixture class for @c HostMgr class.
  27. class HostMgrTest : public ::testing::Test {
  28. protected:
  29. /// @brief Prepares the class for a test.
  30. ///
  31. /// This method crates a handful of unique HW address and DUID objects
  32. /// for use in unit tests. These objects are held in the @c hwaddrs_ and
  33. /// @c duids_ members respectively.
  34. ///
  35. /// This method also resets the @c CfgMgr configuration and re-creates
  36. /// the @c HostMgr object.
  37. virtual void SetUp();
  38. /// @brief Convenience method returning a pointer to the @c CfgHosts object
  39. /// in the @c CfgMgr.
  40. CfgHostsPtr getCfgHosts() const;
  41. /// @brief HW addresses to be used by the tests.
  42. std::vector<HWAddrPtr> hwaddrs_;
  43. /// @brief DUIDs to be used by the tests.
  44. std::vector<DuidPtr> duids_;
  45. };
  46. void
  47. // cppcheck-suppress unusedFunction
  48. HostMgrTest::SetUp() {
  49. // Remove all configuration which may be dangling from the previous test.
  50. CfgMgr::instance().clear();
  51. // Recreate HostMgr instance. It drops any previous state.
  52. HostMgr::create();
  53. // Create HW addresses from the template.
  54. const uint8_t mac_template[] = {
  55. 0x01, 0x02, 0x0A, 0xBB, 0x03, 0x00
  56. };
  57. for (unsigned i = 0; i < 10; ++i) {
  58. std::vector<uint8_t> vec(mac_template,
  59. mac_template + sizeof(mac_template));
  60. vec[vec.size() - 1] = i;
  61. HWAddrPtr hwaddr(new HWAddr(vec, HTYPE_ETHER));
  62. hwaddrs_.push_back(hwaddr);
  63. }
  64. // Create DUIDs from the template.
  65. const uint8_t duid_template[] = {
  66. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x00
  67. };
  68. for (int i = 0; i < 10; ++i) {
  69. std::vector<uint8_t> vec(duid_template,
  70. duid_template + sizeof(mac_template));
  71. vec[vec.size() - 1] = i;
  72. DuidPtr duid(new DUID(vec));
  73. duids_.push_back(duid);
  74. }
  75. }
  76. CfgHostsPtr
  77. HostMgrTest::getCfgHosts() const {
  78. return (CfgMgr::instance().getStagingCfg()->getCfgHosts());
  79. }
  80. /// This test verifies that HostMgr returns all reservations for the
  81. /// specified HW address. The reservations are defined in the server's
  82. /// configuration.
  83. TEST_F(HostMgrTest, getAll) {
  84. // Initially, no reservations should be present.
  85. ConstHostCollection hosts = HostMgr::instance().getAll(hwaddrs_[0]);
  86. ASSERT_TRUE(hosts.empty());
  87. // Add two reservations for the same HW address. They differ by the IP
  88. // address reserved and the IPv4 subnet.
  89. getCfgHosts()->add(HostPtr(new Host(hwaddrs_[0]->toText(false),
  90. "hw-address", SubnetID(1), SubnetID(0),
  91. IOAddress("192.0.2.5"))));
  92. getCfgHosts()->add(HostPtr(new Host(hwaddrs_[0]->toText(false),
  93. "hw-address", SubnetID(10), SubnetID(0),
  94. IOAddress("192.0.3.10"))));
  95. CfgMgr::instance().commit();
  96. // If there non-matching HW address is specified, nothing should be
  97. // returned.
  98. ASSERT_TRUE(HostMgr::instance().getAll(hwaddrs_[1]).empty());
  99. // For the correct HW address, there should be two reservations.
  100. hosts = HostMgr::instance().getAll(hwaddrs_[0]);
  101. ASSERT_EQ(2, hosts.size());
  102. // We don't know the order in which the reservations are returned so
  103. // we have to match with any of the two reservations returned.
  104. // Look for the first reservation.
  105. bool found = false;
  106. for (int i = 0; i < 2; ++i) {
  107. if (hosts[0]->getIPv4Reservation() == IOAddress("192.0.2.5")) {
  108. ASSERT_EQ(1, hosts[0]->getIPv4SubnetID());
  109. found = true;
  110. }
  111. }
  112. if (!found) {
  113. ADD_FAILURE() << "Reservation for the IPv4 address 192.0.2.5"
  114. " not found using getAll method";
  115. }
  116. // Look for the second reservation.
  117. found = false;
  118. for (int i = 0; i < 2; ++i) {
  119. if (hosts[1]->getIPv4Reservation() == IOAddress("192.0.3.10")) {
  120. ASSERT_EQ(10, hosts[1]->getIPv4SubnetID());
  121. found = true;
  122. }
  123. }
  124. if (!found) {
  125. ADD_FAILURE() << "Reservation for the IPv4 address 192.0.3.10"
  126. " not found using getAll method";
  127. }
  128. }
  129. // This test verifies that it is possible to gather all reservations for the
  130. // specified IPv4 address from the HostMgr. The reservations are specified in
  131. // the server's configuration. Note: this test is currently disabled because the
  132. // getAll4 method is not implemented in the CfgHosts object.
  133. TEST_F(HostMgrTest, DISABLED_getAll4) {
  134. ConstHostCollection hosts =
  135. HostMgr::instance().getAll4(IOAddress("192.0.2.5"));
  136. ASSERT_TRUE(hosts.empty());
  137. getCfgHosts()->add(HostPtr(new Host(hwaddrs_[0]->toText(false),
  138. "hw-address", SubnetID(1), SubnetID(0),
  139. IOAddress("192.0.2.5"))));
  140. getCfgHosts()->add(HostPtr(new Host(hwaddrs_[1]->toText(false),
  141. "hw-address", SubnetID(10), SubnetID(0),
  142. IOAddress("192.0.2.5"))));
  143. CfgMgr::instance().commit();
  144. hosts = HostMgr::instance().getAll4(IOAddress("192.0.2.5"));
  145. ASSERT_EQ(2, hosts.size());
  146. /// @todo Extend this test to sanity check the hosts, once the test
  147. /// is enabled.
  148. }
  149. // This test verifies that it is possible to retrieve a reservation for the
  150. // particular host using HostMgr. The reservation is specified in the server's
  151. // configuration.
  152. TEST_F(HostMgrTest, get4) {
  153. ConstHostPtr host = HostMgr::instance().get4(SubnetID(1), hwaddrs_[0]);
  154. ASSERT_FALSE(host);
  155. getCfgHosts()->add(HostPtr(new Host(hwaddrs_[0]->toText(false),
  156. "hw-address",
  157. SubnetID(1), SubnetID(2),
  158. IOAddress("192.0.2.5"))));
  159. CfgMgr::instance().commit();
  160. host = HostMgr::instance().get4(SubnetID(1), hwaddrs_[0]);
  161. ASSERT_TRUE(host);
  162. EXPECT_EQ(1, host->getIPv4SubnetID());
  163. EXPECT_EQ("192.0.2.5", host->getIPv4Reservation().toText());
  164. }
  165. // This test verifies that it is possible to retrieve IPv6 reservations for
  166. // the particular host using HostMgr. The reservation is specified in the
  167. // server's configuration.
  168. TEST_F(HostMgrTest, get6) {
  169. ConstHostPtr host = HostMgr::instance().get6(SubnetID(2), duids_[0]);
  170. ASSERT_FALSE(host);
  171. HostPtr new_host(new Host(duids_[0]->toText(), "duid", SubnetID(1),
  172. SubnetID(2), IOAddress("0.0.0.0")));
  173. new_host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
  174. IOAddress("2001:db8:1::1")));
  175. getCfgHosts()->add(new_host);
  176. CfgMgr::instance().commit();
  177. host = HostMgr::instance().get6(SubnetID(2), duids_[0]);
  178. ASSERT_TRUE(host);
  179. EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
  180. IOAddress("2001:db8:1::1"))));
  181. }
  182. // This test verifies that it is possible to retrieve the reservation of the
  183. // particular IPv6 prefix using HostMgr. Note: this test is currently disabled
  184. // because the get6(prefix, prefix_len) method is not implemented in the
  185. // CfgHosts class.
  186. TEST_F(HostMgrTest, DISABLED_get6ByPrefix) {
  187. ConstHostPtr host = HostMgr::instance().get6(IOAddress("2001:db8:1::"), 64);
  188. ASSERT_FALSE(host);
  189. HostPtr new_host(new Host(duids_[0]->toText(), "duid", SubnetID(1),
  190. SubnetID(2), IOAddress("0.0.0.0")));
  191. new_host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
  192. IOAddress("2001:db8:1::"), 64));
  193. getCfgHosts()->add(new_host);
  194. CfgMgr::instance().commit();
  195. host = HostMgr::instance().get6(IOAddress("2001:db8:1::"), 64);
  196. ASSERT_TRUE(host);
  197. EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
  198. IOAddress("2001:db8:1::"), 64)));
  199. }
  200. } // end of anonymous namespace