lease_unittest.cc 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. // Copyright (C) 2013-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 <config.h>
  7. #include <asiolink/io_address.h>
  8. #include <dhcp/duid.h>
  9. #include <dhcpsrv/lease.h>
  10. #include <util/pointer_util.h>
  11. #include <gtest/gtest.h>
  12. #include <vector>
  13. #include <sstream>
  14. using namespace isc;
  15. using namespace isc::asiolink;
  16. using namespace isc::dhcp;
  17. namespace {
  18. /// Hardware address used by different tests.
  19. const uint8_t HWADDR[] = {0x08, 0x00, 0x2b, 0x02, 0x3f, 0x4e};
  20. /// Client id used by different tests.
  21. const uint8_t CLIENTID[] = {0x17, 0x34, 0xe2, 0xff, 0x09, 0x92, 0x54};
  22. /// Valid lifetime value used by different tests.
  23. const uint32_t VALID_LIFETIME = 500;
  24. /// Subnet ID used by different tests.
  25. const uint32_t SUBNET_ID = 42;
  26. /// IAID value used by different tests.
  27. const uint32_t IAID = 7;
  28. /// @brief Creates an instance of the lease with certain FQDN data.
  29. ///
  30. /// @param hostname Hostname.
  31. /// @param fqdn_fwd Forward FQDN update setting for a created lease.
  32. /// @param fqdn_rev Reverse FQDN update setting for a created lease.
  33. ///
  34. /// @return Instance of the created lease.
  35. Lease4 createLease4(const std::string& hostname, const bool fqdn_fwd,
  36. const bool fqdn_rev) {
  37. Lease4 lease;
  38. lease.hostname_ = hostname;
  39. lease.fqdn_fwd_ = fqdn_fwd;
  40. lease.fqdn_rev_ = fqdn_rev;
  41. return (lease);
  42. }
  43. /// @brief Fixture class used in Lease4 testing.
  44. class Lease4Test : public ::testing::Test {
  45. public:
  46. /// @brief Default constructor
  47. ///
  48. /// Currently it only initializes hardware address.
  49. Lease4Test() {
  50. hwaddr_.reset(new HWAddr(HWADDR, sizeof(HWADDR), HTYPE_ETHER));
  51. clientid_.reset(new ClientId(CLIENTID, sizeof(CLIENTID)));
  52. }
  53. /// Hardware address, used by tests.
  54. HWAddrPtr hwaddr_;
  55. /// Pointer to the client identifier used by tests.
  56. ClientIdPtr clientid_;
  57. };
  58. // This test checks if the Lease4 structure can be instantiated correctly.
  59. TEST_F(Lease4Test, constructor) {
  60. // Get current time for the use in Lease.
  61. const time_t current_time = time(NULL);
  62. // We want to check that various addresses work, so let's iterate over
  63. // these.
  64. const uint32_t ADDRESS[] = {
  65. 0x00000000, 0x01020304, 0x7fffffff, 0x80000000, 0x80000001, 0xffffffff
  66. };
  67. for (int i = 0; i < sizeof(ADDRESS) / sizeof(ADDRESS[0]); ++i) {
  68. // Create the lease
  69. Lease4 lease(ADDRESS[i], hwaddr_, clientid_, VALID_LIFETIME, 0, 0,
  70. current_time, SUBNET_ID, true, true,
  71. "hostname.example.com.");
  72. EXPECT_EQ(ADDRESS[i], lease.addr_.toUint32());
  73. EXPECT_TRUE(util::equalValues(hwaddr_, lease.hwaddr_));
  74. EXPECT_TRUE(util::equalValues(clientid_, lease.client_id_));
  75. EXPECT_EQ(0, lease.t1_);
  76. EXPECT_EQ(0, lease.t2_);
  77. EXPECT_EQ(VALID_LIFETIME, lease.valid_lft_);
  78. EXPECT_EQ(current_time, lease.cltt_);
  79. EXPECT_EQ(SUBNET_ID, lease.subnet_id_);
  80. EXPECT_EQ("hostname.example.com.", lease.hostname_);
  81. EXPECT_TRUE(lease.fqdn_fwd_);
  82. EXPECT_TRUE(lease.fqdn_rev_);
  83. EXPECT_EQ(Lease::STATE_DEFAULT, lease.state_);
  84. }
  85. }
  86. // This test verfies that copy constructor copies Lease4 fields correctly.
  87. TEST_F(Lease4Test, copyConstructor) {
  88. // Get current time for the use in Lease4.
  89. const time_t current_time = time(NULL);
  90. // Create the lease
  91. Lease4 lease(0xffffffff, hwaddr_, clientid_, VALID_LIFETIME, 0, 0, current_time,
  92. SUBNET_ID);
  93. // Declined is a non-default state. We'll see if the state will be copied
  94. // or the default state will be set for the copied lease.
  95. lease.state_ = Lease::STATE_DECLINED;
  96. // Use copy constructor to copy the lease.
  97. Lease4 copied_lease(lease);
  98. // Both leases should be now equal. When doing this check we assume that
  99. // the equality operator works correctly.
  100. EXPECT_TRUE(lease == copied_lease);
  101. // Client IDs are equal, but they should be in two distinct pointers.
  102. EXPECT_FALSE(lease.client_id_ == copied_lease.client_id_);
  103. // Hardware addresses are equal, but they should point to two objects,
  104. // each holding the same data. The content should be equal...
  105. EXPECT_TRUE(*lease.hwaddr_ == *copied_lease.hwaddr_);
  106. // ... but it should point to different objects.
  107. EXPECT_FALSE(lease.hwaddr_ == copied_lease.hwaddr_);
  108. // Now let's check that the hwaddr pointer is copied even if it's NULL:
  109. lease.hwaddr_.reset();
  110. Lease4 copied_lease2(lease);
  111. EXPECT_TRUE(lease == copied_lease2);
  112. }
  113. // This test verfies that the assignment operator copies all Lease4 fields
  114. // correctly.
  115. TEST_F(Lease4Test, operatorAssign) {
  116. // Get the current time for the use in Lease4.
  117. const time_t current_time = time(NULL);
  118. // Create the lease
  119. Lease4 lease(0xffffffff, hwaddr_, clientid_, VALID_LIFETIME, 0, 0, current_time,
  120. SUBNET_ID);
  121. // Declined is a non-default state. We'll see if the state will be copied
  122. // or the default state will be set for the copied lease.
  123. lease.state_ = Lease::STATE_DECLINED;
  124. // Create a default lease.
  125. Lease4 copied_lease;
  126. // Use assignment operator to assign new lease.
  127. copied_lease = lease;
  128. // Both leases should be now equal. When doing this check we assume that
  129. // the equality operator works correctly.
  130. EXPECT_TRUE(lease == copied_lease);
  131. // Client IDs are equal, but they should be in two distinct pointers.
  132. EXPECT_FALSE(lease.client_id_ == copied_lease.client_id_);
  133. // Hardware addresses are equal, but they should point to two objects,
  134. // each holding the same data. The content should be equal...
  135. EXPECT_TRUE(*lease.hwaddr_ == *copied_lease.hwaddr_);
  136. // ... but it should point to different objects.
  137. EXPECT_FALSE(lease.hwaddr_ == copied_lease.hwaddr_);
  138. // Now let's check that the hwaddr pointer is copied even if it's NULL:
  139. lease.hwaddr_.reset();
  140. copied_lease = lease;
  141. EXPECT_TRUE(lease == copied_lease);
  142. }
  143. // This test verifies that it is correctly determined when the lease
  144. // belongs to the particular client identified by the client identifier
  145. // and hw address.
  146. TEST_F(Lease4Test, leaseBelongsToClient) {
  147. // Client identifier that matches the one in the lease.
  148. ClientIdPtr matching_client_id = ClientId::fromText("01:02:03:04");
  149. // Client identifier that doesn't match the one in the lease.
  150. ClientIdPtr diff_client_id = ClientId::fromText("01:02:03:05");
  151. // Null (no) client identifier.
  152. ClientIdPtr null_client_id;
  153. // HW Address that matches the one in the lease.
  154. HWAddrPtr matching_hw(new HWAddr(HWAddr::fromText("00:01:02:03:04:05",
  155. HTYPE_ETHER)));
  156. // HW Address that doesn't match the one in the lease.
  157. HWAddrPtr diff_hw(new HWAddr(HWAddr::fromText("00:01:02:03:04:06",
  158. HTYPE_ETHER)));
  159. // Null HW Address.
  160. HWAddrPtr null_hw;
  161. // Create the lease with MAC address and Client Identifier.
  162. Lease4 lease(IOAddress("192.0.2.1"), matching_hw, matching_client_id,
  163. 60, time(NULL), 0, 0, 1);
  164. // Verify cases for lease that has both hw address and client identifier.
  165. EXPECT_TRUE(lease.belongsToClient(matching_hw, matching_client_id));
  166. EXPECT_FALSE(lease.belongsToClient(matching_hw, diff_client_id));
  167. EXPECT_TRUE(lease.belongsToClient(matching_hw, null_client_id));
  168. EXPECT_TRUE(lease.belongsToClient(diff_hw, matching_client_id));
  169. EXPECT_FALSE(lease.belongsToClient(diff_hw, diff_client_id));
  170. EXPECT_FALSE(lease.belongsToClient(diff_hw, null_client_id));
  171. EXPECT_TRUE(lease.belongsToClient(null_hw, matching_client_id));
  172. EXPECT_FALSE(lease.belongsToClient(null_hw, diff_client_id));
  173. EXPECT_FALSE(lease.belongsToClient(null_hw, null_client_id));
  174. // Verify cases for lease that has only HW address.
  175. lease.client_id_ = null_client_id;
  176. EXPECT_TRUE(lease.belongsToClient(matching_hw, matching_client_id));
  177. EXPECT_TRUE(lease.belongsToClient(matching_hw, diff_client_id));
  178. EXPECT_TRUE(lease.belongsToClient(matching_hw, null_client_id));
  179. EXPECT_FALSE(lease.belongsToClient(diff_hw, matching_client_id));
  180. EXPECT_FALSE(lease.belongsToClient(diff_hw, diff_client_id));
  181. EXPECT_FALSE(lease.belongsToClient(diff_hw, null_client_id));
  182. EXPECT_FALSE(lease.belongsToClient(null_hw, matching_client_id));
  183. EXPECT_FALSE(lease.belongsToClient(null_hw, diff_client_id));
  184. EXPECT_FALSE(lease.belongsToClient(null_hw, null_client_id));
  185. // Verify cases for lease that has only client identifier.
  186. lease.client_id_ = matching_client_id;
  187. lease.hwaddr_ = null_hw;
  188. EXPECT_TRUE(lease.belongsToClient(matching_hw, matching_client_id));
  189. EXPECT_FALSE(lease.belongsToClient(matching_hw, diff_client_id));
  190. EXPECT_FALSE(lease.belongsToClient(matching_hw, null_client_id));
  191. EXPECT_TRUE(lease.belongsToClient(diff_hw, matching_client_id));
  192. EXPECT_FALSE(lease.belongsToClient(diff_hw, diff_client_id));
  193. EXPECT_FALSE(lease.belongsToClient(diff_hw, null_client_id));
  194. EXPECT_TRUE(lease.belongsToClient(null_hw, matching_client_id));
  195. EXPECT_FALSE(lease.belongsToClient(null_hw, diff_client_id));
  196. EXPECT_FALSE(lease.belongsToClient(null_hw, null_client_id));
  197. }
  198. /// @brief Lease4 Equality Test
  199. ///
  200. /// Checks that the operator==() correctly compares two leases for equality.
  201. /// As operator!=() is also defined for this class, every check on operator==()
  202. /// is followed by the reverse check on operator!=().
  203. TEST_F(Lease4Test, operatorEquals) {
  204. // Random values for the tests
  205. const uint32_t ADDRESS = 0x01020304;
  206. const time_t current_time = time(NULL);
  207. // Check when the leases are equal.
  208. Lease4 lease1(ADDRESS, hwaddr_, clientid_, VALID_LIFETIME, current_time, 0,
  209. 0, SUBNET_ID);
  210. // We need to make an explicit copy. Otherwise the second lease will just
  211. // store a pointer and we'll have two leases pointing to a single HWAddr
  212. // or client. That would make modifications to only one impossible.
  213. HWAddrPtr hwcopy(new HWAddr(*hwaddr_));
  214. ClientIdPtr clientid_copy(new ClientId(*clientid_));
  215. Lease4 lease2(ADDRESS, hwcopy, clientid_copy, VALID_LIFETIME, current_time,
  216. 0, 0, SUBNET_ID);
  217. EXPECT_TRUE(lease1 == lease2);
  218. EXPECT_FALSE(lease1 != lease2);
  219. // Now vary individual fields in a lease and check that the leases compare
  220. // not equal in every case.
  221. lease1.addr_ = IOAddress(ADDRESS + 1);
  222. EXPECT_FALSE(lease1 == lease2);
  223. EXPECT_TRUE(lease1 != lease2);
  224. lease1.addr_ = lease2.addr_;
  225. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  226. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  227. ++lease1.hwaddr_->hwaddr_[0];
  228. EXPECT_FALSE(lease1 == lease2);
  229. EXPECT_TRUE(lease1 != lease2);
  230. lease1.hwaddr_ = lease2.hwaddr_;
  231. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  232. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  233. std::vector<uint8_t> clientid_vec = clientid_->getClientId();
  234. ++clientid_vec[0];
  235. lease1.client_id_.reset(new ClientId(clientid_vec));
  236. EXPECT_FALSE(lease1 == lease2);
  237. EXPECT_TRUE(lease1 != lease2);
  238. --clientid_vec[0];
  239. lease1.client_id_.reset(new ClientId(clientid_vec));
  240. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  241. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  242. ++lease1.t1_;
  243. EXPECT_FALSE(lease1 == lease2);
  244. EXPECT_TRUE(lease1 != lease2);
  245. lease1.t1_ = lease2.t1_;
  246. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  247. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  248. ++lease1.t2_;
  249. EXPECT_FALSE(lease1 == lease2);
  250. EXPECT_TRUE(lease1 != lease2);
  251. lease1.t2_ = lease2.t2_;
  252. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  253. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  254. ++lease1.valid_lft_;
  255. EXPECT_FALSE(lease1 == lease2);
  256. EXPECT_TRUE(lease1 != lease2);
  257. lease1.valid_lft_ = lease2.valid_lft_;
  258. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  259. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  260. ++lease1.cltt_;
  261. EXPECT_FALSE(lease1 == lease2);
  262. EXPECT_TRUE(lease1 != lease2);
  263. lease1.cltt_ = lease2.cltt_;
  264. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  265. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  266. ++lease1.subnet_id_;
  267. EXPECT_FALSE(lease1 == lease2);
  268. EXPECT_TRUE(lease1 != lease2);
  269. lease1.subnet_id_ = lease2.subnet_id_;
  270. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  271. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  272. lease1.hostname_ += std::string("Something random");
  273. EXPECT_FALSE(lease1 == lease2);
  274. EXPECT_TRUE(lease1 != lease2);
  275. lease1.hostname_ = lease2.hostname_;
  276. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  277. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  278. lease1.fqdn_fwd_ = !lease1.fqdn_fwd_;
  279. EXPECT_FALSE(lease1 == lease2);
  280. EXPECT_TRUE(lease1 != lease2);
  281. lease1.fqdn_fwd_ = lease2.fqdn_fwd_;
  282. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  283. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  284. lease1.fqdn_rev_ = !lease1.fqdn_rev_;
  285. EXPECT_FALSE(lease1 == lease2);
  286. EXPECT_TRUE(lease1 != lease2);
  287. lease1.fqdn_rev_ = lease2.fqdn_rev_;
  288. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  289. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  290. lease1.state_ += 1;
  291. EXPECT_FALSE(lease1 == lease2);
  292. EXPECT_TRUE(lease1 != lease2);
  293. lease2.state_ += 1;
  294. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  295. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  296. }
  297. // Verify that the client id can be returned as a vector object and if client
  298. // id is NULL the empty vector is returned.
  299. TEST_F(Lease4Test, getClientIdVector) {
  300. // Create a lease.
  301. Lease4 lease;
  302. // By default, the lease should have client id set to NULL. If it doesn't,
  303. // continuing the test makes no sense.
  304. ASSERT_FALSE(lease.client_id_);
  305. // When client id is NULL the vector returned should be empty.
  306. EXPECT_TRUE(lease.getClientIdVector().empty());
  307. // Initialize client identifier to non-null value.
  308. lease.client_id_ = clientid_;
  309. // Check that the returned vector, encapsulating client id is equal to
  310. // the one that has been used to set the client id for the lease.
  311. std::vector<uint8_t> returned_vec = lease.getClientIdVector();
  312. EXPECT_TRUE(returned_vec == clientid_->getClientId());
  313. }
  314. // Verify the behavior of the function which checks FQDN data for equality.
  315. TEST_F(Lease4Test, hasIdenticalFqdn) {
  316. Lease4 lease = createLease4("myhost.example.com.", true, true);
  317. EXPECT_TRUE(lease.hasIdenticalFqdn(createLease4("myhost.example.com.",
  318. true, true)));
  319. EXPECT_FALSE(lease.hasIdenticalFqdn(createLease4("other.example.com.",
  320. true, true)));
  321. EXPECT_FALSE(lease.hasIdenticalFqdn(createLease4("myhost.example.com.",
  322. false, true)));
  323. EXPECT_FALSE(lease.hasIdenticalFqdn(createLease4("myhost.example.com.",
  324. true, false)));
  325. EXPECT_FALSE(lease.hasIdenticalFqdn(createLease4("myhost.example.com.",
  326. false, false)));
  327. EXPECT_FALSE(lease.hasIdenticalFqdn(createLease4("other.example.com.",
  328. false, false)));
  329. }
  330. // Verify that toText() method reports Lease4 structure properly.
  331. TEST_F(Lease4Test, toText) {
  332. const time_t current_time = 12345678;
  333. Lease4 lease(IOAddress("192.0.2.3"), hwaddr_, clientid_, 3600, 123,
  334. 456, current_time, 789);
  335. std::stringstream expected;
  336. expected << "Address: 192.0.2.3\n"
  337. << "Valid life: 3600\n"
  338. << "T1: 123\n"
  339. << "T2: 456\n"
  340. << "Cltt: 12345678\n"
  341. << "Hardware addr: " << hwaddr_->toText(false) << "\n"
  342. << "Client id: " << clientid_->toText() << "\n"
  343. << "Subnet ID: 789\n"
  344. << "State: default\n";
  345. EXPECT_EQ(expected.str(), lease.toText());
  346. // Now let's try with a lease without hardware address and client identifier.
  347. lease.hwaddr_.reset();
  348. lease.client_id_.reset();
  349. expected.str("");
  350. expected << "Address: 192.0.2.3\n"
  351. << "Valid life: 3600\n"
  352. << "T1: 123\n"
  353. << "T2: 456\n"
  354. << "Cltt: 12345678\n"
  355. << "Hardware addr: (none)\n"
  356. << "Client id: (none)\n"
  357. << "Subnet ID: 789\n"
  358. << "State: default\n";
  359. EXPECT_EQ(expected.str(), lease.toText());
  360. }
  361. // Verify that decline() method properly clears up specific fields.
  362. TEST_F(Lease4Test, decline) {
  363. const time_t current_time = 12345678;
  364. Lease4 lease(IOAddress("192.0.2.3"), hwaddr_, clientid_, 3600, 123,
  365. 456, current_time, 789);
  366. lease.hostname_="foo.example.org";
  367. lease.fqdn_fwd_ = true;
  368. lease.fqdn_rev_ = true;
  369. time_t now = time(NULL);
  370. // Move lease to declined state and set its valid-lifetime to 123 seconds
  371. lease.decline(123);
  372. ASSERT_TRUE(lease.hwaddr_);
  373. EXPECT_EQ("", lease.hwaddr_->toText(false));
  374. EXPECT_FALSE(lease.client_id_);
  375. EXPECT_EQ(0, lease.t1_);
  376. EXPECT_EQ(0, lease.t2_);
  377. EXPECT_TRUE(now <= lease.cltt_);
  378. EXPECT_TRUE(lease.cltt_ <= now + 1);
  379. EXPECT_EQ("", lease.hostname_);
  380. EXPECT_FALSE(lease.fqdn_fwd_);
  381. EXPECT_FALSE(lease.fqdn_rev_);
  382. EXPECT_EQ(Lease::STATE_DECLINED, lease.state_);
  383. EXPECT_EQ(123, lease.valid_lft_);
  384. }
  385. // Verify that the lease states are correctly returned in the textual format.
  386. TEST_F(Lease4Test, stateToText) {
  387. EXPECT_EQ("default", Lease4::statesToText(Lease::STATE_DEFAULT));
  388. EXPECT_EQ("declined", Lease4::statesToText(Lease::STATE_DECLINED));
  389. EXPECT_EQ("expired-reclaimed", Lease4::statesToText(Lease::STATE_EXPIRED_RECLAIMED));
  390. }
  391. /// @brief Creates an instance of the lease with certain FQDN data.
  392. ///
  393. /// @param hostname Hostname.
  394. /// @param fqdn_fwd Forward FQDN update setting for a created lease.
  395. /// @param fqdn_rev Reverse FQDN update setting for a created lease.
  396. ///
  397. /// @return Instance of the created lease.
  398. Lease6 createLease6(const std::string& hostname, const bool fqdn_fwd,
  399. const bool fqdn_rev) {
  400. Lease6 lease;
  401. lease.hostname_ = hostname;
  402. lease.fqdn_fwd_ = fqdn_fwd;
  403. lease.fqdn_rev_ = fqdn_rev;
  404. return (lease);
  405. }
  406. // Lease6 is also defined in lease_mgr.h, so is tested in this file as well.
  407. // This test checks if the Lease6 structure can be instantiated correctly
  408. TEST(Lease6Test, Lease6ConstructorDefault) {
  409. // check a variety of addresses with different bits set.
  410. const char* ADDRESS[] = {
  411. "::", "::1", "2001:db8:1::456",
  412. "7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
  413. "8000::", "8000::1",
  414. "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
  415. };
  416. // Other values
  417. uint8_t llt[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
  418. DuidPtr duid(new DUID(llt, sizeof(llt)));
  419. uint32_t iaid = IAID; // Just a number
  420. SubnetID subnet_id = 8; // Just another number
  421. for (int i = 0; i < sizeof(ADDRESS) / sizeof(ADDRESS[0]); ++i) {
  422. IOAddress addr(ADDRESS[i]);
  423. Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr,
  424. duid, iaid, 100, 200, 50, 80,
  425. subnet_id));
  426. EXPECT_TRUE(lease->addr_ == addr);
  427. EXPECT_TRUE(*lease->duid_ == *duid);
  428. EXPECT_TRUE(lease->iaid_ == iaid);
  429. EXPECT_TRUE(lease->subnet_id_ == subnet_id);
  430. EXPECT_TRUE(lease->type_ == Lease::TYPE_NA);
  431. EXPECT_TRUE(lease->preferred_lft_ == 100);
  432. EXPECT_TRUE(lease->valid_lft_ == 200);
  433. EXPECT_TRUE(lease->t1_ == 50);
  434. EXPECT_TRUE(lease->t2_ == 80);
  435. EXPECT_FALSE(lease->fqdn_fwd_);
  436. EXPECT_FALSE(lease->fqdn_rev_);
  437. EXPECT_TRUE(lease->hostname_.empty());
  438. }
  439. // Lease6 must be instantiated with a DUID, not with NULL pointer
  440. IOAddress addr(ADDRESS[0]);
  441. Lease6Ptr lease2;
  442. EXPECT_THROW(lease2.reset(new Lease6(Lease::TYPE_NA, addr,
  443. DuidPtr(), iaid, 100, 200, 50, 80,
  444. subnet_id)), InvalidOperation);
  445. }
  446. // This test verifies that the Lease6 constructor which accepts FQDN data,
  447. // sets the data correctly for the lease.
  448. TEST(Lease6Test, Lease6ConstructorWithFQDN) {
  449. // check a variety of addresses with different bits set.
  450. const char* ADDRESS[] = {
  451. "::", "::1", "2001:db8:1::456",
  452. "7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
  453. "8000::", "8000::1",
  454. "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
  455. };
  456. // Other values
  457. uint8_t llt[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
  458. DuidPtr duid(new DUID(llt, sizeof(llt)));
  459. uint32_t iaid = IAID; // Just a number
  460. SubnetID subnet_id = 8; // Just another number
  461. for (int i = 0; i < sizeof(ADDRESS) / sizeof(ADDRESS[0]); ++i) {
  462. IOAddress addr(ADDRESS[i]);
  463. Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr,
  464. duid, iaid, 100, 200, 50, 80, subnet_id,
  465. true, true, "host.example.com."));
  466. EXPECT_TRUE(lease->addr_ == addr);
  467. EXPECT_TRUE(*lease->duid_ == *duid);
  468. EXPECT_TRUE(lease->iaid_ == iaid);
  469. EXPECT_TRUE(lease->subnet_id_ == subnet_id);
  470. EXPECT_TRUE(lease->type_ == Lease::TYPE_NA);
  471. EXPECT_TRUE(lease->preferred_lft_ == 100);
  472. EXPECT_TRUE(lease->valid_lft_ == 200);
  473. EXPECT_TRUE(lease->t1_ == 50);
  474. EXPECT_TRUE(lease->t2_ == 80);
  475. EXPECT_TRUE(lease->fqdn_fwd_);
  476. EXPECT_TRUE(lease->fqdn_rev_);
  477. EXPECT_EQ("host.example.com.", lease->hostname_);
  478. }
  479. // Lease6 must be instantiated with a DUID, not with NULL pointer
  480. IOAddress addr(ADDRESS[0]);
  481. Lease6Ptr lease2;
  482. EXPECT_THROW(lease2.reset(new Lease6(Lease::TYPE_NA, addr,
  483. DuidPtr(), iaid, 100, 200, 50, 80,
  484. subnet_id)), InvalidOperation);
  485. }
  486. /// @brief Lease6 Equality Test
  487. ///
  488. /// Checks that the operator==() correctly compares two leases for equality.
  489. /// As operator!=() is also defined for this class, every check on operator==()
  490. /// is followed by the reverse check on operator!=().
  491. TEST(Lease6Test, operatorEquals) {
  492. // check a variety of addresses with different bits set.
  493. const IOAddress addr("2001:db8:1::456");
  494. uint8_t duid_array[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
  495. DuidPtr duid(new DUID(duid_array, sizeof(duid_array)));
  496. uint32_t iaid = IAID; // just a number
  497. SubnetID subnet_id = 8; // just another number
  498. // Check for equality.
  499. Lease6 lease1(Lease::TYPE_NA, addr, duid, iaid, 100, 200, 50, 80,
  500. subnet_id);
  501. Lease6 lease2(Lease::TYPE_NA, addr, duid, iaid, 100, 200, 50, 80,
  502. subnet_id);
  503. // cltt_ constructs with time(NULL), make sure they are always equal
  504. lease1.cltt_ = lease2.cltt_;
  505. EXPECT_TRUE(lease1 == lease2);
  506. EXPECT_FALSE(lease1 != lease2);
  507. // Go through and alter all the fields one by one
  508. lease1.addr_ = IOAddress("::1");
  509. EXPECT_FALSE(lease1 == lease2);
  510. EXPECT_TRUE(lease1 != lease2);
  511. lease1.addr_ = lease2.addr_;
  512. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  513. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  514. lease1.type_ = Lease::TYPE_PD;
  515. EXPECT_FALSE(lease1 == lease2);
  516. EXPECT_TRUE(lease1 != lease2);
  517. lease1.type_ = lease2.type_;
  518. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  519. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  520. ++lease1.prefixlen_;
  521. EXPECT_FALSE(lease1 == lease2);
  522. EXPECT_TRUE(lease1 != lease2);
  523. lease1.prefixlen_ = lease2.prefixlen_;
  524. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  525. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  526. ++lease1.iaid_;
  527. EXPECT_FALSE(lease1 == lease2);
  528. EXPECT_TRUE(lease1 != lease2);
  529. lease1.iaid_ = lease2.iaid_;
  530. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  531. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  532. ++duid_array[0];
  533. lease1.duid_.reset(new DUID(duid_array, sizeof(duid_array)));
  534. EXPECT_FALSE(lease1 == lease2);
  535. EXPECT_TRUE(lease1 != lease2);
  536. --duid_array[0];
  537. lease1.duid_.reset(new DUID(duid_array, sizeof(duid_array)));
  538. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  539. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  540. ++lease1.preferred_lft_;
  541. EXPECT_FALSE(lease1 == lease2);
  542. EXPECT_TRUE(lease1 != lease2);
  543. lease1.preferred_lft_ = lease2.preferred_lft_;
  544. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  545. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  546. ++lease1.valid_lft_;
  547. EXPECT_FALSE(lease1 == lease2);
  548. EXPECT_TRUE(lease1 != lease2);
  549. lease1.valid_lft_ = lease2.valid_lft_;
  550. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  551. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  552. ++lease1.t1_;
  553. EXPECT_FALSE(lease1 == lease2);
  554. EXPECT_TRUE(lease1 != lease2);
  555. lease1.t1_ = lease2.t1_;
  556. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  557. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  558. ++lease1.t2_;
  559. EXPECT_FALSE(lease1 == lease2);
  560. EXPECT_TRUE(lease1 != lease2);
  561. lease1.t2_ = lease2.t2_;
  562. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  563. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  564. ++lease1.cltt_;
  565. EXPECT_FALSE(lease1 == lease2);
  566. EXPECT_TRUE(lease1 != lease2);
  567. lease1.cltt_ = lease2.cltt_;
  568. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  569. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  570. ++lease1.subnet_id_;
  571. EXPECT_FALSE(lease1 == lease2);
  572. EXPECT_TRUE(lease1 != lease2);
  573. lease1.subnet_id_ = lease2.subnet_id_;
  574. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  575. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  576. lease1.hostname_ += std::string("Something random");
  577. EXPECT_FALSE(lease1 == lease2);
  578. EXPECT_TRUE(lease1 != lease2);
  579. lease1.hostname_ = lease2.hostname_;
  580. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  581. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  582. lease1.fqdn_fwd_ = !lease1.fqdn_fwd_;
  583. EXPECT_FALSE(lease1 == lease2);
  584. EXPECT_TRUE(lease1 != lease2);
  585. lease1.fqdn_fwd_ = lease2.fqdn_fwd_;
  586. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  587. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  588. lease1.fqdn_rev_ = !lease1.fqdn_rev_;
  589. EXPECT_FALSE(lease1 == lease2);
  590. EXPECT_TRUE(lease1 != lease2);
  591. lease1.fqdn_rev_ = lease2.fqdn_rev_;
  592. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  593. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  594. lease1.state_ += 1;
  595. EXPECT_FALSE(lease1 == lease2);
  596. EXPECT_TRUE(lease1 != lease2);
  597. lease2.state_ += 1;
  598. EXPECT_TRUE(lease1 == lease2); // Check that the reversion has made the
  599. EXPECT_FALSE(lease1 != lease2); // ... leases equal
  600. }
  601. // Checks if lease expiration is calculated properly
  602. TEST(Lease6Test, Lease6Expired) {
  603. const IOAddress addr("2001:db8:1::456");
  604. const uint8_t duid_array[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
  605. const DuidPtr duid(new DUID(duid_array, sizeof(duid_array)));
  606. const uint32_t iaid = IAID; // Just a number
  607. const SubnetID subnet_id = 8; // Just another number
  608. Lease6 lease(Lease::TYPE_NA, addr, duid, iaid, 100, 200, 50, 80,
  609. subnet_id);
  610. // Case 1: a second before expiration
  611. lease.cltt_ = time(NULL) - 100;
  612. lease.valid_lft_ = 101;
  613. EXPECT_FALSE(lease.expired());
  614. // Case 2: the lease will expire after this second is concluded
  615. lease.cltt_ = time(NULL) - 101;
  616. EXPECT_FALSE(lease.expired());
  617. // Case 3: the lease is expired
  618. lease.cltt_ = time(NULL) - 102;
  619. EXPECT_TRUE(lease.expired());
  620. }
  621. // Verify that the DUID can be returned as a vector object and if DUID is NULL
  622. // the empty vector is returned.
  623. TEST(Lease6Test, getDuidVector) {
  624. // Create a lease.
  625. Lease6 lease;
  626. // By default, the lease should have client id set to NULL. If it doesn't,
  627. // continuing the test makes no sense.
  628. ASSERT_FALSE(lease.duid_);
  629. // When client id is NULL the vector returned should be empty.
  630. EXPECT_TRUE(lease.getDuidVector().empty());
  631. // Now, let's set the non NULL DUID. Fill it with the 8 bytes, each
  632. // holding a value of 0x42.
  633. std::vector<uint8_t> duid_vec(8, 0x42);
  634. lease.duid_ = DuidPtr(new DUID(duid_vec));
  635. // Check that the returned vector, encapsulating DUID is equal to
  636. // the one that has been used to set the DUID for the lease.
  637. std::vector<uint8_t> returned_vec = lease.getDuidVector();
  638. EXPECT_TRUE(returned_vec == duid_vec);
  639. }
  640. // Verify that decline() method properly clears up specific fields.
  641. TEST(Lease6Test, decline) {
  642. uint8_t llt[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
  643. DuidPtr duid(new DUID(llt, sizeof(llt)));
  644. HWAddrPtr hwaddr(new HWAddr(HWADDR, sizeof(HWADDR), HTYPE_ETHER));
  645. // Let's create a lease for 2001:db8::1, DUID, iaid=1234,
  646. // t1=1000, t2=2000, pref=3000, valid=4000, subnet-id = 1
  647. Lease6 lease(Lease::TYPE_NA, IOAddress("2001:db8::1"), duid,
  648. 1234, 3000, 4000, 1000, 2000, 1, hwaddr);
  649. lease.cltt_ = 12345678;
  650. lease.hostname_ = "foo.example.org";
  651. lease.fqdn_fwd_ = true;
  652. lease.fqdn_rev_ = true;
  653. time_t now = time(NULL);
  654. // Move the lease to declined state and set probation-period to 123 seconds
  655. lease.decline(123);
  656. ASSERT_TRUE(lease.duid_);
  657. ASSERT_EQ("00", lease.duid_->toText());
  658. ASSERT_FALSE(lease.hwaddr_);
  659. EXPECT_EQ(0, lease.t1_);
  660. EXPECT_EQ(0, lease.t2_);
  661. EXPECT_EQ(0, lease.preferred_lft_);
  662. EXPECT_TRUE(now <= lease.cltt_);
  663. EXPECT_TRUE(lease.cltt_ <= now + 1);
  664. EXPECT_EQ("", lease.hostname_);
  665. EXPECT_FALSE(lease.fqdn_fwd_);
  666. EXPECT_FALSE(lease.fqdn_rev_);
  667. EXPECT_EQ(Lease::STATE_DECLINED, lease.state_);
  668. EXPECT_EQ(123, lease.valid_lft_);
  669. }
  670. // Verify the behavior of the function which checks FQDN data for equality.
  671. TEST(Lease6Test, hasIdenticalFqdn) {
  672. Lease6 lease = createLease6("myhost.example.com.", true, true);
  673. EXPECT_TRUE(lease.hasIdenticalFqdn(createLease6("myhost.example.com.",
  674. true, true)));
  675. EXPECT_FALSE(lease.hasIdenticalFqdn(createLease6("other.example.com.",
  676. true, true)));
  677. EXPECT_FALSE(lease.hasIdenticalFqdn(createLease6("myhost.example.com.",
  678. false, true)));
  679. EXPECT_FALSE(lease.hasIdenticalFqdn(createLease6("myhost.example.com.",
  680. true, false)));
  681. EXPECT_FALSE(lease.hasIdenticalFqdn(createLease6("myhost.example.com.",
  682. false, false)));
  683. EXPECT_FALSE(lease.hasIdenticalFqdn(createLease6("other.example.com.",
  684. false, false)));
  685. }
  686. // Verify that toText() method reports Lease4 structure properly.
  687. TEST(Lease6Test, toText) {
  688. HWAddrPtr hwaddr(new HWAddr(HWADDR, sizeof(HWADDR), HTYPE_ETHER));
  689. uint8_t llt[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
  690. DuidPtr duid(new DUID(llt, sizeof(llt)));
  691. Lease6 lease(Lease::TYPE_NA, IOAddress("2001:db8::1"), duid, 123456,
  692. 400, 800, 100, 200, 5678, hwaddr, 128);
  693. lease.cltt_ = 12345678;
  694. lease.state_ = Lease::STATE_DECLINED;
  695. std::stringstream expected;
  696. expected << "Type: IA_NA(" << static_cast<int>(Lease::TYPE_NA) << ")\n"
  697. << "Address: 2001:db8::1\n"
  698. << "Prefix length: 128\n"
  699. << "IAID: 123456\n"
  700. << "Pref life: 400\n"
  701. << "Valid life: 800\n"
  702. << "Cltt: 12345678\n"
  703. << "DUID: 00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f\n"
  704. << "Hardware addr: " << hwaddr->toText(false) << "\n"
  705. << "Subnet ID: 5678\n"
  706. << "State: declined\n";
  707. EXPECT_EQ(expected.str(), lease.toText());
  708. // Now let's try with a lease without hardware address.
  709. lease.hwaddr_.reset();
  710. expected.str("");
  711. expected << "Type: IA_NA(" << static_cast<int>(Lease::TYPE_NA) << ")\n"
  712. << "Address: 2001:db8::1\n"
  713. << "Prefix length: 128\n"
  714. << "IAID: 123456\n"
  715. << "Pref life: 400\n"
  716. << "Valid life: 800\n"
  717. << "Cltt: 12345678\n"
  718. << "DUID: 00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f\n"
  719. << "Hardware addr: (none)\n"
  720. << "Subnet ID: 5678\n"
  721. << "State: declined\n";
  722. EXPECT_EQ(expected.str(), lease.toText());
  723. }
  724. // Verify that the lease states are correctly returned in the textual format.
  725. TEST(Lease6Test, stateToText) {
  726. EXPECT_EQ("default", Lease6::statesToText(Lease::STATE_DEFAULT));
  727. EXPECT_EQ("declined", Lease6::statesToText(Lease::STATE_DECLINED));
  728. EXPECT_EQ("expired-reclaimed", Lease6::statesToText(Lease::STATE_EXPIRED_RECLAIMED));
  729. }
  730. }; // end of anonymous namespace