lease_mgr_unittest.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. // Copyright (C) 2012-2017 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 <config.h>
  7. #include <asiolink/io_address.h>
  8. #include <dhcpsrv/lease_mgr.h>
  9. #include <dhcpsrv/memfile_lease_mgr.h>
  10. #include <dhcpsrv/tests/test_utils.h>
  11. #include <dhcpsrv/tests/generic_lease_mgr_unittest.h>
  12. #include <gtest/gtest.h>
  13. #include <iostream>
  14. #include <sstream>
  15. #include <time.h>
  16. using namespace std;
  17. using namespace isc;
  18. using namespace isc::asiolink;
  19. using namespace isc::dhcp;
  20. using namespace isc::dhcp::test;
  21. // This is a concrete implementation of a Lease database. It does not do
  22. // anything useful and is used for abstract LeaseMgr class testing.
  23. class ConcreteLeaseMgr : public LeaseMgr {
  24. public:
  25. /// @brief The sole lease manager constructor
  26. ///
  27. /// dbconfig is a generic way of passing parameters. Parameters
  28. /// are passed in the "name=value" format, separated by spaces.
  29. /// Values may be enclosed in double quotes, if needed.
  30. ConcreteLeaseMgr(const DatabaseConnection::ParameterMap&)
  31. : LeaseMgr()
  32. {}
  33. /// @brief Destructor
  34. virtual ~ConcreteLeaseMgr()
  35. {}
  36. /// @brief Adds an IPv4 lease.
  37. ///
  38. /// @param lease lease to be added
  39. virtual bool addLease(const Lease4Ptr&) {
  40. return (false);
  41. }
  42. /// @brief Adds an IPv6 lease.
  43. ///
  44. /// @param lease lease to be added
  45. virtual bool addLease(const Lease6Ptr&) {
  46. return (false);
  47. }
  48. /// @brief Returns existing IPv4 lease for specified IPv4 address.
  49. ///
  50. /// @param addr address of the searched lease
  51. ///
  52. /// @return smart pointer to the lease (or NULL if a lease is not found)
  53. virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress&) const {
  54. return (Lease4Ptr());
  55. }
  56. /// @brief Returns existing IPv4 leases for specified hardware address.
  57. ///
  58. /// Although in the usual case there will be only one lease, for mobile
  59. /// clients or clients with multiple static/fixed/reserved leases there
  60. /// can be more than one. Thus return type is a container, not a single
  61. /// pointer.
  62. ///
  63. /// @param hwaddr hardware address of the client
  64. ///
  65. /// @return lease collection
  66. virtual Lease4Collection getLease4(const HWAddr&) const {
  67. return (Lease4Collection());
  68. }
  69. /// @brief Returns existing IPv4 leases for specified hardware address
  70. /// and a subnet
  71. ///
  72. /// There can be at most one lease for a given HW address in a single
  73. /// pool, so this method with either return a single lease or NULL.
  74. ///
  75. /// @param hwaddr hardware address of the client
  76. /// @param subnet_id identifier of the subnet that lease must belong to
  77. ///
  78. /// @return a pointer to the lease (or NULL if a lease is not found)
  79. virtual Lease4Ptr getLease4(const HWAddr&, SubnetID) const {
  80. return (Lease4Ptr());
  81. }
  82. /// @brief Returns existing IPv4 lease for specified client-id
  83. ///
  84. /// @param clientid client identifier
  85. ///
  86. /// @return lease collection
  87. virtual Lease4Collection getLease4(const ClientId&) const {
  88. return (Lease4Collection());
  89. }
  90. /// @brief Returns existing IPv4 lease for specified client identifier,
  91. /// HW address and subnet identifier.
  92. ///
  93. /// @param client_id Aclient identifier
  94. /// @param hwaddr A HW address.
  95. /// @param subnet_id A subnet identifier.
  96. ///
  97. /// @return A pointer to an existing lease or NULL if lease not found.
  98. virtual Lease4Ptr
  99. getLease4(const ClientId&, const HWAddr&, SubnetID) const {
  100. return (Lease4Ptr());
  101. }
  102. /// @brief Returns existing IPv4 lease for specified client-id
  103. ///
  104. /// There can be at most one lease for a given HW address in a single
  105. /// pool, so this method with either return a single lease or NULL.
  106. ///
  107. /// @param clientid client identifier
  108. /// @param subnet_id identifier of the subnet that lease must belong to
  109. ///
  110. /// @return a pointer to the lease (or NULL if a lease is not found)
  111. virtual Lease4Ptr getLease4(const ClientId&, SubnetID) const {
  112. return (Lease4Ptr());
  113. }
  114. /// @brief Returns existing IPv6 lease for a given IPv6 address.
  115. ///
  116. /// @param addr address of the searched lease
  117. ///
  118. /// @return smart pointer to the lease (or NULL if a lease is not found)
  119. virtual Lease6Ptr getLease6(Lease::Type /* not used yet */,
  120. const isc::asiolink::IOAddress&) const {
  121. return (Lease6Ptr());
  122. }
  123. /// @brief Returns existing IPv6 lease for a given DUID+IA combination
  124. ///
  125. /// @param duid ignored
  126. /// @param iaid ignored
  127. ///
  128. /// @return whatever is set in leases6_ field
  129. virtual Lease6Collection getLeases6(Lease::Type /* not used yet */,
  130. const DUID&, uint32_t) const {
  131. return (leases6_);
  132. }
  133. /// @brief Returns existing IPv6 lease for a given DUID+IA+subnet-id combination
  134. ///
  135. /// @param duid ignored
  136. /// @param iaid ignored
  137. /// @param subnet_id ignored
  138. ///
  139. /// @return whatever is set in leases6_ field
  140. virtual Lease6Collection getLeases6(Lease::Type /* not used yet */,
  141. const DUID&, uint32_t, SubnetID) const {
  142. return (leases6_);
  143. }
  144. /// @brief Returns expired DHCPv6 leases.
  145. ///
  146. /// This method is not implemented.
  147. virtual void getExpiredLeases6(Lease6Collection&, const size_t) const {
  148. isc_throw(NotImplemented, "ConcreteLeaseMgr::getExpiredLeases6 is not"
  149. " implemented");
  150. }
  151. /// @brief Returns expired DHCPv4 leases.
  152. ///
  153. /// This method is not implemented.
  154. virtual void getExpiredLeases4(Lease4Collection&, const size_t) const {
  155. isc_throw(NotImplemented, "ConcreteLeaseMgr::getExpiredLeases4 is not"
  156. " implemented");
  157. }
  158. /// @brief Updates IPv4 lease.
  159. ///
  160. /// @param lease4 The lease to be updated.
  161. ///
  162. /// If no such lease is present, an exception will be thrown.
  163. virtual void updateLease4(const Lease4Ptr&) {}
  164. /// @brief Updates IPv4 lease.
  165. ///
  166. /// @param lease4 The lease to be updated.
  167. ///
  168. /// If no such lease is present, an exception will be thrown.
  169. virtual void updateLease6(const Lease6Ptr&) {}
  170. /// @brief Deletes a lease.
  171. ///
  172. /// @param addr Address of the lease to be deleted. (This can be either
  173. /// a V4 address or a V6 address.)
  174. ///
  175. /// @return true if deletion was successful, false if no such lease exists
  176. virtual bool deleteLease(const isc::asiolink::IOAddress&) {
  177. return (false);
  178. }
  179. /// @brief Deletes all expired and reclaimed DHCPv4 leases.
  180. ///
  181. /// @param secs Number of seconds since expiration of leases before
  182. /// they can be removed. Leases which have expired later than this
  183. /// time will not be deleted.
  184. virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t) {
  185. isc_throw(NotImplemented, "ConcreteLeaseMgr::deleteExpiredReclaimedLeases4"
  186. " is not implemented");
  187. }
  188. /// @brief Deletes all expired and reclaimed DHCPv6 leases.
  189. ///
  190. /// @param secs Number of seconds since expiration of leases before
  191. /// they can be removed. Leases which have expired later than this
  192. /// time will not be deleted.
  193. virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t) {
  194. isc_throw(NotImplemented, "ConcreteLeaseMgr::deleteExpiredReclaimedLeases6"
  195. " is not implemented");
  196. }
  197. /// @brief Pretends to wipe all IPv4 leases from a subnet
  198. /// @param subnet_id (ignored, but one day may specify the subnet)
  199. virtual size_t wipeLeases4(const SubnetID&) {
  200. isc_throw(NotImplemented, "ConreteLeaseMgr::wipeLeases4 not implemented");
  201. }
  202. /// @brief Pretends to wipe all IPv4 leases from a subnet
  203. /// @param subnet_id (ignored, but one day may specify the subnet)
  204. virtual size_t wipeLeases6(const SubnetID&) {
  205. isc_throw(NotImplemented, "ConreteLeaseMgr::wipeLeases4 not implemented");
  206. }
  207. /// @brief Returns backend type.
  208. ///
  209. /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
  210. ///
  211. /// @return Type of the backend.
  212. virtual std::string getType() const {
  213. return (std::string("concrete"));
  214. }
  215. /// @brief Returns backend name.
  216. ///
  217. /// If the backend is a database, this is the name of the database or the
  218. /// file. Otherwise it is just the same as the type.
  219. ///
  220. /// @return Name of the backend.
  221. virtual std::string getName() const {
  222. return (std::string("concrete"));
  223. }
  224. /// @brief Returns description of the backend.
  225. ///
  226. /// This description may be multiline text that describes the backend.
  227. ///
  228. /// @return Description of the backend.
  229. virtual std::string getDescription() const {
  230. return (std::string("This is a dummy concrete backend implementation."));
  231. }
  232. /// @brief Returns backend version.
  233. virtual std::pair<uint32_t, uint32_t> getVersion() const {
  234. return (make_pair(uint32_t(0), uint32_t(0)));
  235. }
  236. /// @brief Commit transactions
  237. virtual void commit() {
  238. }
  239. /// @brief Rollback transactions
  240. virtual void rollback() {
  241. }
  242. // We need to use it in ConcreteLeaseMgr
  243. using LeaseMgr::getLease6;
  244. Lease6Collection leases6_; ///< getLease6 methods return this as is
  245. };
  246. class LeaseMgrTest : public GenericLeaseMgrTest {
  247. public:
  248. LeaseMgrTest() {
  249. }
  250. /// @brief Reopen the database
  251. ///
  252. /// No-op implementation. We need to provide concrete implementation,
  253. /// as this is a pure virtual method in GenericLeaseMgrTest.
  254. virtual void reopen(Universe) {
  255. }
  256. };
  257. namespace {
  258. // This test checks if getLease6() method is working properly for 0 (NULL),
  259. // 1 (return the lease) and more than 1 leases (throw).
  260. TEST_F(LeaseMgrTest, getLease6) {
  261. DatabaseConnection::ParameterMap pmap;
  262. boost::scoped_ptr<ConcreteLeaseMgr> mgr(new ConcreteLeaseMgr(pmap));
  263. vector<Lease6Ptr> leases = createLeases6();
  264. mgr->leases6_.clear();
  265. // For no leases, the function should return NULL pointer
  266. Lease6Ptr lease;
  267. // the getLease6() is calling getLeases6(), which is a dummy. It returns
  268. // whatever is there in leases6_ field.
  269. EXPECT_NO_THROW(lease = mgr->getLease6(leasetype6_[1], *leases[1]->duid_,
  270. leases[1]->iaid_,
  271. leases[1]->subnet_id_));
  272. EXPECT_TRUE(Lease6Ptr() == lease);
  273. // For a single lease, the function should return that lease
  274. mgr->leases6_.push_back(leases[1]);
  275. EXPECT_NO_THROW(lease = mgr->getLease6(leasetype6_[1], *leases[1]->duid_,
  276. leases[1]->iaid_,
  277. leases[1]->subnet_id_));
  278. EXPECT_TRUE(lease);
  279. EXPECT_NO_THROW(detailCompareLease(lease, leases[1]));
  280. // Add one more lease. There are 2 now. It should throw
  281. mgr->leases6_.push_back(leases[2]);
  282. EXPECT_THROW(lease = mgr->getLease6(leasetype6_[1], *leases[1]->duid_,
  283. leases[1]->iaid_,
  284. leases[1]->subnet_id_),
  285. MultipleRecords);
  286. }
  287. // There's no point in calling any other methods in LeaseMgr, as they
  288. // are purely virtual, so we would only call ConcreteLeaseMgr methods.
  289. // Those methods are just stubs that do not return anything.
  290. }; // end of anonymous namespace