mysql_lease_mgr_unittest.cc 50 KB

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