mysql_lease_mgr_unittest.cc 50 KB

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