mysql_lease_mgr_unittest.cc 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275
  1. // Copyright (C) 2012 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 <asiolink/io_address.h>
  16. #include <dhcpsrv/lease_mgr_factory.h>
  17. #include <dhcpsrv/mysql_lease_mgr.h>
  18. #include <dhcpsrv/tests/test_utils.h>
  19. #include <gtest/gtest.h>
  20. #include <algorithm>
  21. #include <iostream>
  22. #include <sstream>
  23. #include <string>
  24. #include <utility>
  25. using namespace isc;
  26. using namespace isc::asiolink;
  27. using namespace isc::dhcp;
  28. using namespace isc::dhcp::test;
  29. using namespace std;
  30. namespace {
  31. // This holds statements to create and destroy the schema.
  32. #include "schema_copy.h"
  33. // IPv4 and IPv6 addresses used in the tests
  34. const char* ADDRESS4[] = {
  35. "192.0.2.0", "192.0.2.1", "192.0.2.2", "192.0.2.3",
  36. "192.0.2.4", "192.0.2.5", "192.0.2.6", "192.0.2.7",
  37. NULL
  38. };
  39. const char* ADDRESS6[] = {
  40. "2001:db8::0", "2001:db8::1", "2001:db8::2", "2001:db8::3",
  41. "2001:db8::4", "2001:db8::5", "2001:db8::6", "2001:db8::7",
  42. NULL
  43. };
  44. // Connection strings.
  45. // Database: keatest
  46. // Host: localhost
  47. // Username: keatest
  48. // Password: keatest
  49. const char* VALID_TYPE = "type=mysql";
  50. const char* INVALID_TYPE = "type=unknown";
  51. const char* VALID_NAME = "name=keatest";
  52. const char* INVALID_NAME = "name=invalidname";
  53. const char* VALID_HOST = "host=localhost";
  54. const char* INVALID_HOST = "host=invalidhost";
  55. const char* VALID_USER = "user=keatest";
  56. const char* INVALID_USER = "user=invaliduser";
  57. const char* VALID_PASSWORD = "password=keatest";
  58. const char* INVALID_PASSWORD = "password=invalid";
  59. // Given a combination of strings above, produce a connection string.
  60. string connectionString(const char* type, const char* name, const char* host,
  61. const char* user, const char* password) {
  62. const string space = " ";
  63. string result = "";
  64. if (type != NULL) {
  65. result += string(type);
  66. }
  67. if (name != NULL) {
  68. if (! result.empty()) {
  69. result += space;
  70. }
  71. result += string(name);
  72. }
  73. if (host != NULL) {
  74. if (! result.empty()) {
  75. result += space;
  76. }
  77. result += string(host);
  78. }
  79. if (user != NULL) {
  80. if (! result.empty()) {
  81. result += space;
  82. }
  83. result += string(user);
  84. }
  85. if (password != NULL) {
  86. if (! result.empty()) {
  87. result += space;
  88. }
  89. result += string(password);
  90. }
  91. return (result);
  92. }
  93. // Return valid connection string
  94. string
  95. validConnectionString() {
  96. return (connectionString(VALID_TYPE, VALID_NAME, VALID_HOST,
  97. VALID_USER, VALID_PASSWORD));
  98. }
  99. // @brief Clear everything from the database
  100. //
  101. // There is no error checking in this code: if something fails, one of the
  102. // tests will (should) fall over.
  103. void destroySchema() {
  104. // Initialise
  105. MYSQL handle;
  106. (void) mysql_init(&handle);
  107. // Open database
  108. (void) mysql_real_connect(&handle, "localhost", "keatest",
  109. "keatest", "keatest", 0, NULL, 0);
  110. // Get rid of everything in it.
  111. for (int i = 0; destroy_statement[i] != NULL; ++i) {
  112. (void) mysql_query(&handle, destroy_statement[i]);
  113. }
  114. // ... and close
  115. (void) mysql_close(&handle);
  116. }
  117. // @brief Create the Schema
  118. //
  119. // Creates all the tables in what is assumed to be an empty database.
  120. //
  121. // There is no error checking in this code: if it fails, one of the tests
  122. // will fall over.
  123. void createSchema() {
  124. // Initialise
  125. MYSQL handle;
  126. (void) mysql_init(&handle);
  127. // Open database
  128. (void) mysql_real_connect(&handle, "localhost", "keatest",
  129. "keatest", "keatest", 0, NULL, 0);
  130. // Execute creation statements.
  131. for (int i = 0; create_statement[i] != NULL; ++i) {
  132. (void) mysql_query(&handle, create_statement[i]);
  133. }
  134. // ... and close
  135. (void) mysql_close(&handle);
  136. }
  137. /// @brief Test fixture class for testing MySQL Lease Manager
  138. ///
  139. /// Opens the database prior to each test and closes it afterwards.
  140. /// All pending transactions are deleted prior to closure.
  141. class MySqlLeaseMgrTest : public ::testing::Test {
  142. public:
  143. /// @brief Constructor
  144. ///
  145. /// Deletes everything from the database and opens it.
  146. MySqlLeaseMgrTest() {
  147. // Initialize address strings and IOAddresses
  148. for (int i = 0; ADDRESS4[i] != NULL; ++i) {
  149. string addr(ADDRESS4[i]);
  150. straddress4_.push_back(addr);
  151. IOAddress ioaddr(addr);
  152. ioaddress4_.push_back(ioaddr);
  153. }
  154. for (int i = 0; ADDRESS6[i] != NULL; ++i) {
  155. string addr(ADDRESS6[i]);
  156. straddress6_.push_back(addr);
  157. IOAddress ioaddr(addr);
  158. ioaddress6_.push_back(ioaddr);
  159. }
  160. // Ensure schema is the correct one.
  161. destroySchema();
  162. createSchema();
  163. // Connect to the database
  164. try {
  165. LeaseMgrFactory::create(validConnectionString());
  166. } catch (...) {
  167. std::cerr << "*** ERROR: unable to open database. The test\n"
  168. "*** environment is broken and must be fixed before\n"
  169. "*** the MySQL tests will run correctly.\n"
  170. "*** The reason for the problem is described in the\n"
  171. "*** accompanying exception output.\n";
  172. throw;
  173. }
  174. lmptr_ = &(LeaseMgrFactory::instance());
  175. }
  176. /// @brief Destructor
  177. ///
  178. /// Rolls back all pending transactions. The deletion of lmptr_ will close
  179. /// the database. Then reopen it and delete everything created by the test.
  180. virtual ~MySqlLeaseMgrTest() {
  181. lmptr_->rollback();
  182. LeaseMgrFactory::destroy();
  183. destroySchema();
  184. }
  185. /// @brief Reopen the database
  186. ///
  187. /// Closes the database and re-open it. Anything committed should be
  188. /// visible.
  189. void reopen() {
  190. LeaseMgrFactory::destroy();
  191. LeaseMgrFactory::create(validConnectionString());
  192. lmptr_ = &(LeaseMgrFactory::instance());
  193. }
  194. /// @brief Initialize Lease4 Fields
  195. ///
  196. /// Returns a pointer to a Lease4 structure. Different values are put into
  197. /// the lease according to the address passed.
  198. ///
  199. /// This is just a convenience function for the test methods.
  200. ///
  201. /// @param address Address to use for the initialization
  202. ///
  203. /// @return Lease4Ptr. This will not point to anything if the
  204. /// initialization failed (e.g. unknown address).
  205. Lease4Ptr initializeLease4(std::string address) {
  206. Lease4Ptr lease(new Lease4());
  207. // Set the address of the lease
  208. lease->addr_ = IOAddress(address);
  209. // Initialize unused fields.
  210. lease->ext_ = 0; // Not saved
  211. lease->t1_ = 0; // Not saved
  212. lease->t2_ = 0; // Not saved
  213. lease->fixed_ = false; // Unused
  214. lease->hostname_ = std::string(""); // Unused
  215. lease->fqdn_fwd_ = false; // Unused
  216. lease->fqdn_rev_ = false; // Unused
  217. lease->comments_ = std::string(""); // Unused
  218. // Set other parameters. For historical reasons, address 0 is not used.
  219. if (address == straddress4_[0]) {
  220. lease->hwaddr_ = vector<uint8_t>(6, 0x08);
  221. lease->client_id_ = ClientIdPtr(
  222. new ClientId(vector<uint8_t>(8, 0x42)));
  223. lease->valid_lft_ = 8677;
  224. lease->cltt_ = 168256;
  225. lease->subnet_id_ = 23;
  226. } else if (address == straddress4_[1]) {
  227. lease->hwaddr_ = vector<uint8_t>(6, 0x19);
  228. lease->client_id_ = ClientIdPtr(
  229. new ClientId(vector<uint8_t>(8, 0x53)));
  230. lease->valid_lft_ = 3677;
  231. lease->cltt_ = 123456;
  232. lease->subnet_id_ = 73;
  233. } else if (address == straddress4_[2]) {
  234. lease->hwaddr_ = vector<uint8_t>(6, 0x2a);
  235. lease->client_id_ = ClientIdPtr(
  236. new ClientId(vector<uint8_t>(8, 0x64)));
  237. lease->valid_lft_ = 5412;
  238. lease->cltt_ = 234567;
  239. lease->subnet_id_ = 73; // Same as lease 1
  240. } else if (address == straddress4_[3]) {
  241. lease->hwaddr_ = vector<uint8_t>(6, 0x19); // Same as lease 1
  242. lease->client_id_ = ClientIdPtr(
  243. new ClientId(vector<uint8_t>(8, 0x75)));
  244. // The times used in the next tests are deliberately restricted - we
  245. // should be able to cope with valid lifetimes up to 0xffffffff.
  246. // However, this will lead to overflows.
  247. // @TODO: test overflow conditions when code has been fixed
  248. lease->valid_lft_ = 7000;
  249. lease->cltt_ = 234567;
  250. lease->subnet_id_ = 37;
  251. } else if (address == straddress4_[4]) {
  252. lease->hwaddr_ = vector<uint8_t>(6, 0x4c);
  253. // Same ClientId as straddr4_[1]
  254. lease->client_id_ = ClientIdPtr(
  255. new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
  256. lease->valid_lft_ = 7736;
  257. lease->cltt_ = 222456;
  258. lease->subnet_id_ = 85;
  259. } else if (address == straddress4_[5]) {
  260. lease->hwaddr_ = vector<uint8_t>(6, 0x19); // Same as lease 1
  261. // Same ClientId and IAID as straddress4_1
  262. lease->client_id_ = ClientIdPtr(
  263. new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
  264. lease->valid_lft_ = 7832;
  265. lease->cltt_ = 227476;
  266. lease->subnet_id_ = 175;
  267. } else if (address == straddress4_[6]) {
  268. lease->hwaddr_ = vector<uint8_t>(6, 0x6e);
  269. // Same ClientId as straddress4_1
  270. lease->client_id_ = ClientIdPtr(
  271. new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
  272. lease->valid_lft_ = 1832;
  273. lease->cltt_ = 627476;
  274. lease->subnet_id_ = 112;
  275. } else if (address == straddress4_[7]) {
  276. lease->hwaddr_ = vector<uint8_t>(); // Empty
  277. lease->client_id_ = ClientIdPtr(
  278. new ClientId(vector<uint8_t>())); // Empty
  279. lease->valid_lft_ = 7975;
  280. lease->cltt_ = 213876;
  281. lease->subnet_id_ = 19;
  282. } else {
  283. // Unknown address, return an empty pointer.
  284. lease.reset();
  285. }
  286. return (lease);
  287. }
  288. /// @brief Initialize Lease6 Fields
  289. ///
  290. /// Returns a pointer to a Lease6 structure. Different values are put into
  291. /// the lease according to the address passed.
  292. ///
  293. /// This is just a convenience function for the test methods.
  294. ///
  295. /// @param address Address to use for the initialization
  296. ///
  297. /// @return Lease6Ptr. This will not point to anything if the initialization
  298. /// failed (e.g. unknown address).
  299. Lease6Ptr initializeLease6(std::string address) {
  300. Lease6Ptr lease(new Lease6());
  301. // Set the address of the lease
  302. lease->addr_ = IOAddress(address);
  303. // Initialize unused fields.
  304. lease->t1_ = 0; // Not saved
  305. lease->t2_ = 0; // Not saved
  306. lease->fixed_ = false; // Unused
  307. lease->hostname_ = std::string(""); // Unused
  308. lease->fqdn_fwd_ = false; // Unused
  309. lease->fqdn_rev_ = false; // Unused
  310. lease->comments_ = std::string(""); // Unused
  311. // Set other parameters. For historical reasons, address 0 is not used.
  312. if (address == straddress6_[0]) {
  313. lease->type_ = Lease6::LEASE_IA_TA;
  314. lease->prefixlen_ = 4;
  315. lease->iaid_ = 142;
  316. lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x77)));
  317. lease->preferred_lft_ = 900;
  318. lease->valid_lft_ = 8677;
  319. lease->cltt_ = 168256;
  320. lease->subnet_id_ = 23;
  321. } else if (address == straddress6_[1]) {
  322. lease->type_ = Lease6::LEASE_IA_TA;
  323. lease->prefixlen_ = 0;
  324. lease->iaid_ = 42;
  325. lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
  326. lease->preferred_lft_ = 3600;
  327. lease->valid_lft_ = 3677;
  328. lease->cltt_ = 123456;
  329. lease->subnet_id_ = 73;
  330. } else if (address == straddress6_[2]) {
  331. lease->type_ = Lease6::LEASE_IA_PD;
  332. lease->prefixlen_ = 7;
  333. lease->iaid_ = 89;
  334. lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x3a)));
  335. lease->preferred_lft_ = 1800;
  336. lease->valid_lft_ = 5412;
  337. lease->cltt_ = 234567;
  338. lease->subnet_id_ = 73; // Same as lease 1
  339. } else if (address == straddress6_[3]) {
  340. lease->type_ = Lease6::LEASE_IA_NA;
  341. lease->prefixlen_ = 28;
  342. lease->iaid_ = 0xfffffffe;
  343. vector<uint8_t> duid;
  344. for (uint8_t i = 31; i < 126; ++i) {
  345. duid.push_back(i);
  346. }
  347. lease->duid_ = DuidPtr(new DUID(duid));
  348. // The times used in the next tests are deliberately restricted - we
  349. // should be able to cope with valid lifetimes up to 0xffffffff.
  350. // However, this will lead to overflows.
  351. // @TODO: test overflow conditions when code has been fixed
  352. lease->preferred_lft_ = 7200;
  353. lease->valid_lft_ = 7000;
  354. lease->cltt_ = 234567;
  355. lease->subnet_id_ = 37;
  356. } else if (address == straddress6_[4]) {
  357. // Same DUID and IAID as straddress6_1
  358. lease->type_ = Lease6::LEASE_IA_PD;
  359. lease->prefixlen_ = 15;
  360. lease->iaid_ = 42;
  361. lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
  362. lease->preferred_lft_ = 4800;
  363. lease->valid_lft_ = 7736;
  364. lease->cltt_ = 222456;
  365. lease->subnet_id_ = 671;
  366. } else if (address == straddress6_[5]) {
  367. // Same DUID and IAID as straddress6_1
  368. lease->type_ = Lease6::LEASE_IA_PD;
  369. lease->prefixlen_ = 24;
  370. lease->iaid_ = 42; // Same as lease 4
  371. lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
  372. // Same as lease 4
  373. lease->preferred_lft_ = 5400;
  374. lease->valid_lft_ = 7832;
  375. lease->cltt_ = 227476;
  376. lease->subnet_id_ = 175;
  377. } else if (address == straddress6_[6]) {
  378. // Same DUID as straddress6_1
  379. lease->type_ = Lease6::LEASE_IA_PD;
  380. lease->prefixlen_ = 24;
  381. lease->iaid_ = 93;
  382. lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
  383. // Same as lease 4
  384. lease->preferred_lft_ = 5400;
  385. lease->valid_lft_ = 1832;
  386. lease->cltt_ = 627476;
  387. lease->subnet_id_ = 112;
  388. } else if (address == straddress6_[7]) {
  389. // Same IAID as straddress6_1
  390. lease->type_ = Lease6::LEASE_IA_PD;
  391. lease->prefixlen_ = 24;
  392. lease->iaid_ = 42;
  393. lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0xe5)));
  394. lease->preferred_lft_ = 5600;
  395. lease->valid_lft_ = 7975;
  396. lease->cltt_ = 213876;
  397. lease->subnet_id_ = 19;
  398. } else {
  399. // Unknown address, return an empty pointer.
  400. lease.reset();
  401. }
  402. return (lease);
  403. }
  404. /// @brief Check Leases present and different
  405. ///
  406. /// Checks a vector of lease pointers and ensures that all the leases
  407. /// they point to are present and different. If not, a GTest assertion
  408. /// will fail.
  409. ///
  410. /// @param leases Vector of pointers to leases
  411. template <typename T>
  412. void checkLeasesDifferent(const std::vector<T>& leases) const {
  413. // Check they were created
  414. for (int i = 0; i < leases.size(); ++i) {
  415. ASSERT_TRUE(leases[i]);
  416. }
  417. // Check they are different
  418. for (int i = 0; i < (leases.size() - 1); ++i) {
  419. for (int j = (i + 1); j < leases.size(); ++j) {
  420. stringstream s;
  421. s << "Comparing leases " << i << " & " << j << " for equality";
  422. SCOPED_TRACE(s.str());
  423. EXPECT_TRUE(*leases[i] != *leases[j]);
  424. }
  425. }
  426. }
  427. /// @brief Creates leases for the test
  428. ///
  429. /// Creates all leases for the test and checks that they are different.
  430. ///
  431. /// @return vector<Lease4Ptr> Vector of pointers to leases
  432. vector<Lease4Ptr> createLeases4() {
  433. // Create leases for each address
  434. vector<Lease4Ptr> leases;
  435. for (int i = 0; i < straddress4_.size(); ++i) {
  436. leases.push_back(initializeLease4(straddress4_[i]));
  437. }
  438. EXPECT_EQ(8, leases.size());
  439. // Check all were created and that they are different.
  440. checkLeasesDifferent(leases);
  441. return (leases);
  442. }
  443. /// @brief Creates leases for the test
  444. ///
  445. /// Creates all leases for the test and checks that they are different.
  446. ///
  447. /// @return vector<Lease6Ptr> Vector of pointers to leases
  448. vector<Lease6Ptr> createLeases6() {
  449. // Create leases for each address
  450. vector<Lease6Ptr> leases;
  451. for (int i = 0; i < straddress6_.size(); ++i) {
  452. leases.push_back(initializeLease6(straddress6_[i]));
  453. }
  454. EXPECT_EQ(8, leases.size());
  455. // Check all were created and that they are different.
  456. checkLeasesDifferent(leases);
  457. return (leases);
  458. }
  459. // Member variables
  460. LeaseMgr* lmptr_; ///< Pointer to the lease manager
  461. vector<string> straddress4_; ///< String forms of IPv4 addresses
  462. vector<IOAddress> ioaddress4_; ///< IOAddress forms of IPv4 addresses
  463. vector<string> straddress6_; ///< String forms of IPv6 addresses
  464. vector<IOAddress> ioaddress6_; ///< IOAddress forms of IPv6 addresses
  465. };
  466. /// @brief Check that database can be opened
  467. ///
  468. /// This test checks if the MySqlLeaseMgr can be instantiated. This happens
  469. /// only if the database can be opened. Note that this is not part of the
  470. /// MySqlLeaseMgr test fixure set. This test checks that the database can be
  471. /// opened: the fixtures assume that and check basic operations.
  472. TEST(MySqlOpenTest, OpenDatabase) {
  473. // Schema needs to be created for the test to work.
  474. destroySchema();
  475. createSchema();
  476. // Check that lease manager open the database opens correctly and tidy up.
  477. // If it fails, print the error message.
  478. try {
  479. LeaseMgrFactory::create(validConnectionString());
  480. EXPECT_NO_THROW((void) LeaseMgrFactory::instance());
  481. LeaseMgrFactory::destroy();
  482. } catch (const isc::Exception& ex) {
  483. FAIL() << "*** ERROR: unable to open database, reason:\n"
  484. << " " << ex.what() << "\n"
  485. << "*** The test environment is broken and must be fixed\n"
  486. << "*** before the MySQL tests will run correctly.\n";
  487. }
  488. // Check that attempting to get an instance of the lease manager when
  489. // none is set throws an exception.
  490. EXPECT_THROW(LeaseMgrFactory::instance(), NoLeaseManager);
  491. // Check that wrong specification of backend throws an exception.
  492. // (This is really a check on LeaseMgrFactory, but is convenient to
  493. // perform here.)
  494. EXPECT_THROW(LeaseMgrFactory::create(connectionString(
  495. NULL, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
  496. InvalidParameter);
  497. EXPECT_THROW(LeaseMgrFactory::create(connectionString(
  498. INVALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)),
  499. InvalidType);
  500. // Check that invalid login data causes an exception.
  501. EXPECT_THROW(LeaseMgrFactory::create(connectionString(
  502. VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)),
  503. DbOpenError);
  504. EXPECT_THROW(LeaseMgrFactory::create(connectionString(
  505. VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)),
  506. DbOpenError);
  507. EXPECT_THROW(LeaseMgrFactory::create(connectionString(
  508. VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
  509. DbOpenError);
  510. EXPECT_THROW(LeaseMgrFactory::create(connectionString(
  511. VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)),
  512. DbOpenError);
  513. // Check for missing parameters
  514. EXPECT_THROW(LeaseMgrFactory::create(connectionString(
  515. VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
  516. NoDatabaseName);
  517. // Tidy up after the test
  518. destroySchema();
  519. }
  520. /// @brief Check the getType() method
  521. ///
  522. /// getType() returns a string giving the type of the backend, which should
  523. /// always be "mysql".
  524. TEST_F(MySqlLeaseMgrTest, getType) {
  525. EXPECT_EQ(std::string("mysql"), lmptr_->getType());
  526. }
  527. /// @brief Check conversion functions
  528. ///
  529. /// The server works using cltt and valid_filetime. In the database, the
  530. /// information is stored as expire_time and valid-lifetime, which are
  531. /// related by
  532. ///
  533. /// expire_time = cltt + valid_lifetime
  534. ///
  535. /// This test checks that the conversion is correct. It does not check that the
  536. /// data is entered into the database correctly, only that the MYSQL_TIME
  537. /// structure used for the entry is correctly set up.
  538. TEST_F(MySqlLeaseMgrTest, checkTimeConversion) {
  539. const time_t cltt = time(NULL);
  540. const uint32_t valid_lft = 86400; // 1 day
  541. struct tm tm_expire;
  542. MYSQL_TIME mysql_expire;
  543. // Work out what the broken-down time will be for one day
  544. // after the current time.
  545. time_t expire_time = cltt + valid_lft;
  546. (void) localtime_r(&expire_time, &tm_expire);
  547. // Convert to the database time
  548. MySqlLeaseMgr::convertToDatabaseTime(cltt, valid_lft, mysql_expire);
  549. // Are the times the same?
  550. EXPECT_EQ(tm_expire.tm_year + 1900, mysql_expire.year);
  551. EXPECT_EQ(tm_expire.tm_mon + 1, mysql_expire.month);
  552. EXPECT_EQ(tm_expire.tm_mday, mysql_expire.day);
  553. EXPECT_EQ(tm_expire.tm_hour, mysql_expire.hour);
  554. EXPECT_EQ(tm_expire.tm_min, mysql_expire.minute);
  555. EXPECT_EQ(tm_expire.tm_sec, mysql_expire.second);
  556. EXPECT_EQ(0, mysql_expire.second_part);
  557. EXPECT_EQ(0, mysql_expire.neg);
  558. // Convert back
  559. time_t converted_cltt = 0;
  560. MySqlLeaseMgr::convertFromDatabaseTime(mysql_expire, valid_lft, converted_cltt);
  561. EXPECT_EQ(cltt, converted_cltt);
  562. }
  563. /// @brief Check getName() returns correct database name
  564. TEST_F(MySqlLeaseMgrTest, getName) {
  565. EXPECT_EQ(std::string("keatest"), lmptr_->getName());
  566. }
  567. /// @brief Check that getVersion() returns the expected version
  568. TEST_F(MySqlLeaseMgrTest, checkVersion) {
  569. // Check version
  570. pair<uint32_t, uint32_t> version;
  571. ASSERT_NO_THROW(version = lmptr_->getVersion());
  572. EXPECT_EQ(CURRENT_VERSION_VERSION, version.first);
  573. EXPECT_EQ(CURRENT_VERSION_MINOR, version.second);
  574. }
  575. /// @brief Basic Lease4 Checks
  576. ///
  577. /// Checks that the addLease, getLease4 (by address) and deleteLease (with an
  578. /// IPv4 address) works.
  579. TEST_F(MySqlLeaseMgrTest, basicLease4) {
  580. // Get the leases to be used for the test.
  581. vector<Lease4Ptr> leases = createLeases4();
  582. // Start the tests. Add three leases to the database, read them back and
  583. // check they are what we think they are.
  584. EXPECT_TRUE(lmptr_->addLease(leases[1]));
  585. EXPECT_TRUE(lmptr_->addLease(leases[2]));
  586. EXPECT_TRUE(lmptr_->addLease(leases[3]));
  587. lmptr_->commit();
  588. // Reopen the database to ensure that they actually got stored.
  589. reopen();
  590. Lease4Ptr l_returned = lmptr_->getLease4(ioaddress4_[1]);
  591. ASSERT_TRUE(l_returned);
  592. detailCompareLease(leases[1], l_returned);
  593. l_returned = lmptr_->getLease4(ioaddress4_[2]);
  594. ASSERT_TRUE(l_returned);
  595. detailCompareLease(leases[2], l_returned);
  596. l_returned = lmptr_->getLease4(ioaddress4_[3]);
  597. ASSERT_TRUE(l_returned);
  598. detailCompareLease(leases[3], l_returned);
  599. // Check that we can't add a second lease with the same address
  600. EXPECT_FALSE(lmptr_->addLease(leases[1]));
  601. // Delete a lease, check that it's gone, and that we can't delete it
  602. // a second time.
  603. EXPECT_TRUE(lmptr_->deleteLease(ioaddress4_[1]));
  604. l_returned = lmptr_->getLease4(ioaddress4_[1]);
  605. EXPECT_FALSE(l_returned);
  606. EXPECT_FALSE(lmptr_->deleteLease(ioaddress4_[1]));
  607. // Check that the second address is still there.
  608. l_returned = lmptr_->getLease4(ioaddress4_[2]);
  609. ASSERT_TRUE(l_returned);
  610. detailCompareLease(leases[2], l_returned);
  611. }
  612. /// @brief Basic Lease6 Checks
  613. ///
  614. /// Checks that the addLease, getLease6 (by address) and deleteLease (with an
  615. /// IPv6 address) works.
  616. TEST_F(MySqlLeaseMgrTest, basicLease6) {
  617. // Get the leases to be used for the test.
  618. vector<Lease6Ptr> leases = createLeases6();
  619. // Start the tests. Add three leases to the database, read them back and
  620. // check they are what we think they are.
  621. EXPECT_TRUE(lmptr_->addLease(leases[1]));
  622. EXPECT_TRUE(lmptr_->addLease(leases[2]));
  623. EXPECT_TRUE(lmptr_->addLease(leases[3]));
  624. lmptr_->commit();
  625. // Reopen the database to ensure that they actually got stored.
  626. reopen();
  627. Lease6Ptr l_returned = lmptr_->getLease6(ioaddress6_[1]);
  628. ASSERT_TRUE(l_returned);
  629. detailCompareLease(leases[1], l_returned);
  630. l_returned = lmptr_->getLease6(ioaddress6_[2]);
  631. ASSERT_TRUE(l_returned);
  632. detailCompareLease(leases[2], l_returned);
  633. l_returned = lmptr_->getLease6(ioaddress6_[3]);
  634. ASSERT_TRUE(l_returned);
  635. detailCompareLease(leases[3], l_returned);
  636. // Check that we can't add a second lease with the same address
  637. EXPECT_FALSE(lmptr_->addLease(leases[1]));
  638. // Delete a lease, check that it's gone, and that we can't delete it
  639. // a second time.
  640. EXPECT_TRUE(lmptr_->deleteLease(ioaddress6_[1]));
  641. l_returned = lmptr_->getLease6(ioaddress6_[1]);
  642. EXPECT_FALSE(l_returned);
  643. EXPECT_FALSE(lmptr_->deleteLease(ioaddress6_[1]));
  644. // Check that the second address is still there.
  645. l_returned = lmptr_->getLease6(ioaddress6_[2]);
  646. ASSERT_TRUE(l_returned);
  647. detailCompareLease(leases[2], l_returned);
  648. }
  649. /// @brief Check GetLease4 methods - access by Hardware Address
  650. ///
  651. /// Adds leases to the database and checks that they can be accessed via
  652. /// a combination of DIUID and IAID.
  653. TEST_F(MySqlLeaseMgrTest, getLease4Hwaddr) {
  654. // Get the leases to be used for the test and add to the database
  655. vector<Lease4Ptr> leases = createLeases4();
  656. for (int i = 0; i < leases.size(); ++i) {
  657. EXPECT_TRUE(lmptr_->addLease(leases[i]));
  658. }
  659. // Get the leases matching the hardware address of lease 1
  660. Lease4Collection returned = lmptr_->getLease4(leases[1]->hwaddr_);
  661. // Should be three leases, matching leases[1], [3] and [5].
  662. ASSERT_EQ(3, returned.size());
  663. // Easiest way to check is to look at the addresses.
  664. vector<string> addresses;
  665. for (Lease4Collection::const_iterator i = returned.begin();
  666. i != returned.end(); ++i) {
  667. addresses.push_back((*i)->addr_.toText());
  668. }
  669. sort(addresses.begin(), addresses.end());
  670. EXPECT_EQ(straddress4_[1], addresses[0]);
  671. EXPECT_EQ(straddress4_[3], addresses[1]);
  672. EXPECT_EQ(straddress4_[5], addresses[2]);
  673. // Repeat test with just one expected match
  674. returned = lmptr_->getLease4(leases[2]->hwaddr_);
  675. EXPECT_EQ(1, returned.size());
  676. detailCompareLease(leases[2], *returned.begin());
  677. // Check that an empty vector is valid
  678. EXPECT_TRUE(leases[7]->hwaddr_.empty());
  679. returned = lmptr_->getLease4(leases[7]->hwaddr_);
  680. EXPECT_EQ(1, returned.size());
  681. detailCompareLease(leases[7], *returned.begin());
  682. // Try to get something with invalid hardware address
  683. vector<uint8_t> invalid(6, 0);
  684. returned = lmptr_->getLease4(invalid);
  685. EXPECT_EQ(0, returned.size());
  686. }
  687. // @brief Get lease4 by hardware address (2)
  688. //
  689. // Check that the system can cope with getting a hardware address of
  690. // any size.
  691. TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSize) {
  692. // Create leases, although we need only one.
  693. vector<Lease4Ptr> leases = createLeases4();
  694. // Now add leases with increasing hardware address size.
  695. for (uint8_t i = 0; i <= Lease4::HWADDR_MAX; ++i) {
  696. leases[1]->hwaddr_.resize(i, i);
  697. EXPECT_TRUE(lmptr_->addLease(leases[1]));
  698. Lease4Collection returned = lmptr_->getLease4(leases[1]->hwaddr_);
  699. ASSERT_EQ(1, returned.size());
  700. detailCompareLease(leases[1], *returned.begin());
  701. (void) lmptr_->deleteLease(leases[1]->addr_);
  702. }
  703. // Expect some problem when accessing a lease that had too long a hardware
  704. // address. (The 42 is a random value put in each byte of the address.)
  705. // In fact the address is stored in a truncated form, so we won't find it
  706. // when we look.
  707. // @todo Check if there is some way of detecting that data added
  708. // to the database is truncated. There does not appear to
  709. // be any indication in the C API.
  710. leases[1]->hwaddr_.resize(Lease4::HWADDR_MAX + 100, 42);
  711. EXPECT_TRUE(lmptr_->addLease(leases[1]));
  712. Lease4Collection returned = lmptr_->getLease4(leases[1]->hwaddr_);
  713. EXPECT_EQ(0, returned.size());
  714. }
  715. /// @brief Check GetLease4 methods - access by Hardware Address & Subnet ID
  716. ///
  717. /// Adds leases to the database and checks that they can be accessed via
  718. /// a combination of hardware address and subnet ID
  719. TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetId) {
  720. // Get the leases to be used for the test and add to the database
  721. vector<Lease4Ptr> leases = createLeases4();
  722. for (int i = 0; i < leases.size(); ++i) {
  723. EXPECT_TRUE(lmptr_->addLease(leases[i]));
  724. }
  725. // Get the leases matching the hardware address of lease 1 and
  726. // subnet ID of lease 1. Result should be a single lease - lease 1.
  727. Lease4Ptr returned = lmptr_->getLease4(leases[1]->hwaddr_,
  728. leases[1]->subnet_id_);
  729. ASSERT_TRUE(returned);
  730. detailCompareLease(leases[1], returned);
  731. // Try for a match to the hardware address of lease 1 and the wrong
  732. // subnet ID.
  733. returned = lmptr_->getLease4(leases[1]->hwaddr_,
  734. leases[1]->subnet_id_ + 1);
  735. EXPECT_FALSE(returned);
  736. // Try for a match to the subnet ID of lease 1 (and lease 4) but
  737. // the wrong hardware address.
  738. vector<uint8_t> invalid_hwaddr(15, 0x77);
  739. returned = lmptr_->getLease4(invalid_hwaddr,
  740. leases[1]->subnet_id_);
  741. EXPECT_FALSE(returned);
  742. // Try for a match to an unknown hardware address and an unknown
  743. // subnet ID.
  744. returned = lmptr_->getLease4(invalid_hwaddr,
  745. leases[1]->subnet_id_ + 1);
  746. EXPECT_FALSE(returned);
  747. // Add a second lease with the same values as the first and check that
  748. // an attempt to access the database by these parameters throws a
  749. // "multiple records" exception. (We expect there to be only one record
  750. // with that combination, so getting them via getLeaseX() (as opposed
  751. // to getLeaseXCollection() should throw an exception.)
  752. EXPECT_TRUE(lmptr_->deleteLease(leases[2]->addr_));
  753. leases[1]->addr_ = leases[2]->addr_;
  754. EXPECT_TRUE(lmptr_->addLease(leases[1]));
  755. EXPECT_THROW(returned = lmptr_->getLease4(leases[1]->hwaddr_,
  756. leases[1]->subnet_id_),
  757. isc::dhcp::MultipleRecords);
  758. // Delete all leases in the database
  759. for (int i = 0; ADDRESS4[i] != NULL; ++i) {
  760. IOAddress addr(ADDRESS4[i]);
  761. (void) lmptr_->deleteLease(addr);
  762. }
  763. }
  764. // @brief Get lease4 by hardware address and subnet ID (2)
  765. //
  766. // Check that the system can cope with getting a hardware address of
  767. // any size.
  768. TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetIdSize) {
  769. // Create leases, although we need only one.
  770. vector<Lease4Ptr> leases = createLeases4();
  771. // Now add leases with increasing hardware address size and check
  772. // that they can be retrieved.
  773. for (uint8_t i = 0; i <= Lease4::HWADDR_MAX; ++i) {
  774. leases[1]->hwaddr_.resize(i, i);
  775. EXPECT_TRUE(lmptr_->addLease(leases[1]));
  776. Lease4Ptr returned = lmptr_->getLease4(leases[1]->hwaddr_,
  777. leases[1]->subnet_id_);
  778. ASSERT_TRUE(returned);
  779. detailCompareLease(leases[1], returned);
  780. (void) lmptr_->deleteLease(leases[1]->addr_);
  781. }
  782. // Expect some error when getting a lease with too long a hardware
  783. // address. Set the contents of each byte to 42, a random value.
  784. // @todo Check if there is some way of detecting that data added
  785. // to the database is truncated. There does not appear to
  786. // be any indication in the C API.
  787. leases[1]->hwaddr_.resize(Lease4::HWADDR_MAX + 100, 42);
  788. EXPECT_TRUE(lmptr_->addLease(leases[1]));
  789. Lease4Ptr returned = lmptr_->getLease4(leases[1]->hwaddr_,
  790. leases[1]->subnet_id_);
  791. EXPECT_FALSE(returned);
  792. }
  793. /// @brief Check GetLease4 methods - access by Client ID
  794. ///
  795. /// Adds leases to the database and checks that they can be accessed via
  796. /// the Client ID.
  797. TEST_F(MySqlLeaseMgrTest, getLease4ClientId) {
  798. // Get the leases to be used for the test and add to the database
  799. vector<Lease4Ptr> leases = createLeases4();
  800. for (int i = 0; i < leases.size(); ++i) {
  801. EXPECT_TRUE(lmptr_->addLease(leases[i]));
  802. }
  803. // Get the leases matching the Client ID address of lease 1
  804. Lease4Collection returned = lmptr_->getLease4(*leases[1]->client_id_);
  805. // Should be four leases, matching leases[1], [4], [5] and [6].
  806. ASSERT_EQ(4, returned.size());
  807. // Easiest way to check is to look at the addresses.
  808. vector<string> addresses;
  809. for (Lease4Collection::const_iterator i = returned.begin();
  810. i != returned.end(); ++i) {
  811. addresses.push_back((*i)->addr_.toText());
  812. }
  813. sort(addresses.begin(), addresses.end());
  814. EXPECT_EQ(straddress4_[1], addresses[0]);
  815. EXPECT_EQ(straddress4_[4], addresses[1]);
  816. EXPECT_EQ(straddress4_[5], addresses[2]);
  817. EXPECT_EQ(straddress4_[6], addresses[3]);
  818. // Repeat test with just one expected match
  819. returned = lmptr_->getLease4(*leases[3]->client_id_);
  820. EXPECT_EQ(1, returned.size());
  821. detailCompareLease(leases[3], *returned.begin());
  822. // Check that an empty vector is valid
  823. EXPECT_TRUE(leases[7]->client_id_->getClientId().empty());
  824. returned = lmptr_->getLease4(leases[7]->hwaddr_);
  825. EXPECT_EQ(1, returned.size());
  826. detailCompareLease(leases[7], *returned.begin());
  827. // Try to get something with invalid client ID
  828. const uint8_t invalid_data[] = {0, 0, 0};
  829. ClientId invalid(invalid_data, sizeof(invalid_data));
  830. returned = lmptr_->getLease4(invalid);
  831. EXPECT_EQ(0, returned.size());
  832. }
  833. // @brief Get Lease4 by client ID (2)
  834. //
  835. // Check that the system can cope with a client ID of any size.
  836. TEST_F(MySqlLeaseMgrTest, getLease4ClientIdSize) {
  837. // Create leases, although we need only one.
  838. vector<Lease4Ptr> leases = createLeases4();
  839. // Now add leases with increasing Client ID size can be retrieved.
  840. // For speed, go from 0 to 128 is steps of 16.
  841. // Intermediate client_id_max is to overcome problem if
  842. // ClientId::MAX_CLIENT_ID_LEN is used in an EXPECT_EQ.
  843. int client_id_max = ClientId::MAX_CLIENT_ID_LEN;
  844. EXPECT_EQ(128, client_id_max);
  845. for (uint8_t i = 0; i <= client_id_max; i += 16) {
  846. vector<uint8_t> clientid_vec(i, i);
  847. leases[1]->client_id_.reset(new ClientId(clientid_vec));
  848. EXPECT_TRUE(lmptr_->addLease(leases[1]));
  849. Lease4Collection returned = lmptr_->getLease4(*leases[1]->client_id_);
  850. ASSERT_TRUE(returned.size() == 1);
  851. detailCompareLease(leases[1], *returned.begin());
  852. (void) lmptr_->deleteLease(leases[1]->addr_);
  853. }
  854. // Don't bother to check client IDs longer than the maximum -
  855. // these cannot be constructed, and that limitation is tested
  856. // in the DUID/Client ID unit tests.
  857. }
  858. /// @brief Check GetLease4 methods - access by Client ID & Subnet ID
  859. ///
  860. /// Adds leases to the database and checks that they can be accessed via
  861. /// a combination of client and subnet IDs.
  862. TEST_F(MySqlLeaseMgrTest, getLease4ClientIdSubnetId) {
  863. // Get the leases to be used for the test and add to the database
  864. vector<Lease4Ptr> leases = createLeases4();
  865. for (int i = 0; i < leases.size(); ++i) {
  866. EXPECT_TRUE(lmptr_->addLease(leases[i]));
  867. }
  868. // Get the leases matching the client ID of lease 1 and
  869. // subnet ID of lease 1. Result should be a single lease - lease 1.
  870. Lease4Ptr returned = lmptr_->getLease4(*leases[1]->client_id_,
  871. leases[1]->subnet_id_);
  872. ASSERT_TRUE(returned);
  873. detailCompareLease(leases[1], returned);
  874. // Try for a match to the client ID of lease 1 and the wrong
  875. // subnet ID.
  876. returned = lmptr_->getLease4(*leases[1]->client_id_,
  877. leases[1]->subnet_id_ + 1);
  878. EXPECT_FALSE(returned);
  879. // Try for a match to the subnet ID of lease 1 (and lease 4) but
  880. // the wrong client ID
  881. const uint8_t invalid_data[] = {0, 0, 0};
  882. ClientId invalid(invalid_data, sizeof(invalid_data));
  883. returned = lmptr_->getLease4(invalid, leases[1]->subnet_id_);
  884. EXPECT_FALSE(returned);
  885. // Try for a match to an unknown hardware address and an unknown
  886. // subnet ID.
  887. returned = lmptr_->getLease4(invalid, leases[1]->subnet_id_ + 1);
  888. EXPECT_FALSE(returned);
  889. }
  890. /// @brief Check GetLease6 methods - access by DUID/IAID
  891. ///
  892. /// Adds leases to the database and checks that they can be accessed via
  893. /// a combination of DIUID and IAID.
  894. TEST_F(MySqlLeaseMgrTest, getLease6DuidIaid) {
  895. // Get the leases to be used for the test.
  896. vector<Lease6Ptr> leases = createLeases6();
  897. ASSERT_LE(6, leases.size()); // Expect to access leases 0 through 5
  898. // Add them to the database
  899. for (int i = 0; i < leases.size(); ++i) {
  900. EXPECT_TRUE(lmptr_->addLease(leases[i]));
  901. }
  902. // Get the leases matching the DUID and IAID of lease[1].
  903. Lease6Collection returned = lmptr_->getLease6(*leases[1]->duid_,
  904. leases[1]->iaid_);
  905. // Should be three leases, matching leases[1], [4] and [5].
  906. ASSERT_EQ(3, returned.size());
  907. // Easiest way to check is to look at the addresses.
  908. vector<string> addresses;
  909. for (Lease6Collection::const_iterator i = returned.begin();
  910. i != returned.end(); ++i) {
  911. addresses.push_back((*i)->addr_.toText());
  912. }
  913. sort(addresses.begin(), addresses.end());
  914. EXPECT_EQ(straddress6_[1], addresses[0]);
  915. EXPECT_EQ(straddress6_[4], addresses[1]);
  916. EXPECT_EQ(straddress6_[5], addresses[2]);
  917. // Check that nothing is returned when either the IAID or DUID match
  918. // nothing.
  919. returned = lmptr_->getLease6(*leases[1]->duid_, leases[1]->iaid_ + 1);
  920. EXPECT_EQ(0, returned.size());
  921. // Alter the leases[1] DUID to match nothing in the database.
  922. vector<uint8_t> duid_vector = leases[1]->duid_->getDuid();
  923. ++duid_vector[0];
  924. DUID new_duid(duid_vector);
  925. returned = lmptr_->getLease6(new_duid, leases[1]->iaid_);
  926. EXPECT_EQ(0, returned.size());
  927. }
  928. // @brief Get Lease4 by DUID and IAID (2)
  929. //
  930. // Check that the system can cope with a DUID of any size.
  931. TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSize) {
  932. // Create leases, although we need only one.
  933. vector<Lease6Ptr> leases = createLeases6();
  934. // Now add leases with increasing DUID size can be retrieved.
  935. // For speed, go from 0 to 128 is steps of 16.
  936. int duid_max = DUID::MAX_DUID_LEN;
  937. EXPECT_EQ(128, duid_max);
  938. for (uint8_t i = 0; i <= duid_max; i += 16) {
  939. vector<uint8_t> duid_vec(i, i);
  940. leases[1]->duid_.reset(new DUID(duid_vec));
  941. EXPECT_TRUE(lmptr_->addLease(leases[1]));
  942. Lease6Collection returned = lmptr_->getLease6(*leases[1]->duid_,
  943. leases[1]->iaid_);
  944. EXPECT_EQ(1, returned.size());
  945. detailCompareLease(leases[1], *returned.begin());
  946. (void) lmptr_->deleteLease(leases[1]->addr_);
  947. }
  948. // Don't bother to check DUIDs longer than the maximum - these cannot be
  949. // constructed, and that limitation is tested in the DUID/Client ID unit
  950. // tests.
  951. }
  952. /// @brief Check GetLease6 methods - access by DUID/IAID/SubnetID
  953. ///
  954. /// Adds leases to the database and checks that they can be accessed via
  955. /// a combination of DIUID and IAID.
  956. TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSubnetId) {
  957. // Get the leases to be used for the test and add them to the database.
  958. vector<Lease6Ptr> leases = createLeases6();
  959. for (int i = 0; i < leases.size(); ++i) {
  960. EXPECT_TRUE(lmptr_->addLease(leases[i]));
  961. }
  962. // Get the leases matching the DUID and IAID of lease[1].
  963. Lease6Ptr returned = lmptr_->getLease6(*leases[1]->duid_,
  964. leases[1]->iaid_,
  965. leases[1]->subnet_id_);
  966. ASSERT_TRUE(returned);
  967. EXPECT_TRUE(*returned == *leases[1]);
  968. // Modify each of the three parameters (DUID, IAID, Subnet ID) and
  969. // check that nothing is returned.
  970. returned = lmptr_->getLease6(*leases[1]->duid_, leases[1]->iaid_ + 1,
  971. leases[1]->subnet_id_);
  972. EXPECT_FALSE(returned);
  973. returned = lmptr_->getLease6(*leases[1]->duid_, leases[1]->iaid_,
  974. leases[1]->subnet_id_ + 1);
  975. EXPECT_FALSE(returned);
  976. // Alter the leases[1] DUID to match nothing in the database.
  977. vector<uint8_t> duid_vector = leases[1]->duid_->getDuid();
  978. ++duid_vector[0];
  979. DUID new_duid(duid_vector);
  980. returned = lmptr_->getLease6(new_duid, leases[1]->iaid_,
  981. leases[1]->subnet_id_);
  982. EXPECT_FALSE(returned);
  983. }
  984. // @brief Get Lease4 by DUID, IAID & subnet ID (2)
  985. //
  986. // Check that the system can cope with a DUID of any size.
  987. TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSubnetIdSize) {
  988. // Create leases, although we need only one.
  989. vector<Lease6Ptr> leases = createLeases6();
  990. // Now add leases with increasing DUID size can be retrieved.
  991. // For speed, go from 0 to 128 is steps of 16.
  992. int duid_max = DUID::MAX_DUID_LEN;
  993. EXPECT_EQ(128, duid_max);
  994. for (uint8_t i = 0; i <= duid_max; i += 16) {
  995. vector<uint8_t> duid_vec(i, i);
  996. leases[1]->duid_.reset(new DUID(duid_vec));
  997. EXPECT_TRUE(lmptr_->addLease(leases[1]));
  998. Lease6Ptr returned = lmptr_->getLease6(*leases[1]->duid_,
  999. leases[1]->iaid_,
  1000. leases[1]->subnet_id_);
  1001. ASSERT_TRUE(returned);
  1002. detailCompareLease(leases[1], returned);
  1003. (void) lmptr_->deleteLease(leases[1]->addr_);
  1004. }
  1005. // Don't bother to check DUIDs longer than the maximum - these cannot be
  1006. // constructed, and that limitation is tested in the DUID/Client ID unit
  1007. // tests.
  1008. }
  1009. /// @brief Lease4 update tests
  1010. ///
  1011. /// Checks that we are able to update a lease in the database.
  1012. TEST_F(MySqlLeaseMgrTest, updateLease4) {
  1013. // Get the leases to be used for the test and add them to the database.
  1014. vector<Lease4Ptr> leases = createLeases4();
  1015. for (int i = 0; i < leases.size(); ++i) {
  1016. EXPECT_TRUE(lmptr_->addLease(leases[i]));
  1017. }
  1018. // Modify some fields in lease 1 (not the address) and update it.
  1019. ++leases[1]->subnet_id_;
  1020. leases[1]->valid_lft_ *= 2;
  1021. lmptr_->updateLease4(leases[1]);
  1022. // ... and check what is returned is what is expected.
  1023. Lease4Ptr l_returned = lmptr_->getLease4(ioaddress4_[1]);
  1024. ASSERT_TRUE(l_returned);
  1025. detailCompareLease(leases[1], l_returned);
  1026. // Alter the lease again and check.
  1027. ++leases[1]->subnet_id_;
  1028. leases[1]->cltt_ += 6;
  1029. lmptr_->updateLease4(leases[1]);
  1030. // Explicitly clear the returned pointer before getting new data to ensure
  1031. // that the new data is returned.
  1032. l_returned.reset();
  1033. l_returned = lmptr_->getLease4(ioaddress4_[1]);
  1034. ASSERT_TRUE(l_returned);
  1035. detailCompareLease(leases[1], l_returned);
  1036. // Check we can do an update without changing data.
  1037. lmptr_->updateLease4(leases[1]);
  1038. l_returned.reset();
  1039. l_returned = lmptr_->getLease4(ioaddress4_[1]);
  1040. ASSERT_TRUE(l_returned);
  1041. detailCompareLease(leases[1], l_returned);
  1042. // Try updating a lease not in the database.
  1043. lmptr_->deleteLease(ioaddress4_[2]);
  1044. EXPECT_THROW(lmptr_->updateLease4(leases[2]), isc::dhcp::NoSuchLease);
  1045. }
  1046. /// @brief Lease6 update tests
  1047. ///
  1048. /// Checks that we are able to update a lease in the database.
  1049. TEST_F(MySqlLeaseMgrTest, updateLease6) {
  1050. // Get the leases to be used for the test.
  1051. vector<Lease6Ptr> leases = createLeases6();
  1052. ASSERT_LE(3, leases.size()); // Expect to access leases 0 through 2
  1053. // Add a lease to the database and check that the lease is there.
  1054. EXPECT_TRUE(lmptr_->addLease(leases[1]));
  1055. lmptr_->commit();
  1056. Lease6Ptr l_returned = lmptr_->getLease6(ioaddress6_[1]);
  1057. ASSERT_TRUE(l_returned);
  1058. detailCompareLease(leases[1], l_returned);
  1059. // Modify some fields in lease 1 (not the address) and update it.
  1060. ++leases[1]->iaid_;
  1061. leases[1]->type_ = Lease6::LEASE_IA_PD;
  1062. leases[1]->valid_lft_ *= 2;
  1063. lmptr_->updateLease6(leases[1]);
  1064. lmptr_->commit();
  1065. // ... and check what is returned is what is expected.
  1066. l_returned.reset();
  1067. l_returned = lmptr_->getLease6(ioaddress6_[1]);
  1068. ASSERT_TRUE(l_returned);
  1069. detailCompareLease(leases[1], l_returned);
  1070. // Alter the lease again and check.
  1071. ++leases[1]->iaid_;
  1072. leases[1]->type_ = Lease6::LEASE_IA_TA;
  1073. leases[1]->cltt_ += 6;
  1074. leases[1]->prefixlen_ = 93;
  1075. lmptr_->updateLease6(leases[1]);
  1076. l_returned.reset();
  1077. l_returned = lmptr_->getLease6(ioaddress6_[1]);
  1078. ASSERT_TRUE(l_returned);
  1079. detailCompareLease(leases[1], l_returned);
  1080. // Check we can do an update without changing data.
  1081. lmptr_->updateLease6(leases[1]);
  1082. l_returned.reset();
  1083. l_returned = lmptr_->getLease6(ioaddress6_[1]);
  1084. ASSERT_TRUE(l_returned);
  1085. detailCompareLease(leases[1], l_returned);
  1086. // Try updating a lease not in the database.
  1087. EXPECT_THROW(lmptr_->updateLease6(leases[2]), isc::dhcp::NoSuchLease);
  1088. }
  1089. }; // Of anonymous namespace