memfile_lease_mgr_unittest.cc 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515
  1. // Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <config.h>
  7. #include <asiolink/asio_wrapper.h>
  8. #include <asiolink/io_address.h>
  9. #include <dhcp/duid.h>
  10. #include <dhcp/iface_mgr.h>
  11. #include <dhcpsrv/cfgmgr.h>
  12. #include <dhcpsrv/lease_mgr.h>
  13. #include <dhcpsrv/lease_mgr_factory.h>
  14. #include <dhcpsrv/memfile_lease_mgr.h>
  15. #include <dhcpsrv/timer_mgr.h>
  16. #include <dhcpsrv/tests/lease_file_io.h>
  17. #include <dhcpsrv/tests/test_utils.h>
  18. #include <dhcpsrv/tests/generic_lease_mgr_unittest.h>
  19. #include <util/pid_file.h>
  20. #include <util/stopwatch.h>
  21. #include <boost/bind.hpp>
  22. #include <gtest/gtest.h>
  23. #include <cstdlib>
  24. #include <iostream>
  25. #include <fstream>
  26. #include <queue>
  27. #include <sstream>
  28. #include <unistd.h>
  29. using namespace std;
  30. using namespace isc;
  31. using namespace isc::asiolink;
  32. using namespace isc::dhcp;
  33. using namespace isc::dhcp::test;
  34. using namespace isc::util;
  35. namespace {
  36. /// @brief Class derived from @c Memfile_LeaseMgr to test LFC timer.
  37. ///
  38. /// This class provides a custom callback function which is invoked
  39. /// when the timer for Lease File Cleanup goes off. It is used to
  40. /// test that the timer is correctly installed.
  41. class LFCMemfileLeaseMgr : public Memfile_LeaseMgr {
  42. public:
  43. /// @brief Constructor.
  44. ///
  45. /// Sets the counter for callbacks to 0.
  46. LFCMemfileLeaseMgr(const DatabaseConnection::ParameterMap& parameters)
  47. : Memfile_LeaseMgr(parameters), lfc_cnt_(0) {
  48. }
  49. /// @brief Returns the number of callback executions.
  50. int getLFCCount() {
  51. return (lfc_cnt_);
  52. }
  53. protected:
  54. /// @brief Custom callback.
  55. ///
  56. /// This callback function increases the counter of callback executions.
  57. /// By examining the counter value a test may verify that the callback
  58. /// was triggered an expected number of times.
  59. virtual void lfcCallback() {
  60. ++lfc_cnt_;
  61. }
  62. private:
  63. /// @brief Counter of callback function executions.
  64. int lfc_cnt_;
  65. };
  66. /// @brief A derivation of the lease manager exposing protected methods.
  67. class NakedMemfileLeaseMgr : public Memfile_LeaseMgr {
  68. public:
  69. /// @brief Constructor.
  70. ///
  71. /// Creates instance of the lease manager.
  72. NakedMemfileLeaseMgr(const DatabaseConnection::ParameterMap& parameters)
  73. : Memfile_LeaseMgr(parameters) {
  74. }
  75. using Memfile_LeaseMgr::lfcCallback;
  76. };
  77. /// @brief Test fixture class for @c Memfile_LeaseMgr
  78. class MemfileLeaseMgrTest : public GenericLeaseMgrTest {
  79. public:
  80. /// @brief memfile lease mgr test constructor
  81. ///
  82. /// Creates memfile and stores it in lmptr_ pointer
  83. MemfileLeaseMgrTest() :
  84. io4_(getLeaseFilePath("leasefile4_0.csv")),
  85. io6_(getLeaseFilePath("leasefile6_0.csv")),
  86. timer_mgr_(TimerMgr::instance()) {
  87. std::ostringstream s;
  88. s << KEA_LFC_BUILD_DIR << "/kea-lfc";
  89. setenv("KEA_LFC_EXECUTABLE", s.str().c_str(), 1);
  90. // Remove lease files and products of Lease File Cleanup.
  91. removeFiles(getLeaseFilePath("leasefile4_0.csv"));
  92. removeFiles(getLeaseFilePath("leasefile6_0.csv"));
  93. }
  94. /// @brief Reopens the connection to the backend.
  95. ///
  96. /// This function is called by unit tests to force reconnection of the
  97. /// backend to check that the leases are stored and can be retrieved
  98. /// from the storage.
  99. ///
  100. /// @param u Universe (V4 or V6)
  101. virtual void reopen(Universe u) {
  102. LeaseMgrFactory::destroy();
  103. startBackend(u);
  104. }
  105. /// @brief destructor
  106. ///
  107. /// destroys lease manager backend.
  108. virtual ~MemfileLeaseMgrTest() {
  109. // Stop TimerMgr worker thread if it is running.
  110. timer_mgr_->stopThread();
  111. // Make sure there are no timers registered.
  112. timer_mgr_->unregisterTimers();
  113. LeaseMgrFactory::destroy();
  114. // Remove lease files and products of Lease File Cleanup.
  115. removeFiles(getLeaseFilePath("leasefile4_0.csv"));
  116. removeFiles(getLeaseFilePath("leasefile6_0.csv"));
  117. }
  118. /// @brief Remove files being products of Lease File Cleanup.
  119. ///
  120. /// @param base_name Path to the lease file name. This file is removed
  121. /// and all files which names are crated from this name (having specific
  122. /// suffixes used by Lease File Cleanup mechanism).
  123. void removeFiles(const std::string& base_name) const {
  124. // Generate suffixes and append them to the base name. The
  125. // resulting file names are the ones that may exist as a
  126. // result of LFC.
  127. for (int i = static_cast<int>(Memfile_LeaseMgr::FILE_CURRENT);
  128. i <= static_cast<int>(Memfile_LeaseMgr::FILE_FINISH);
  129. ++i) {
  130. Memfile_LeaseMgr::LFCFileType type = static_cast<
  131. Memfile_LeaseMgr::LFCFileType>(i);
  132. LeaseFileIO io(Memfile_LeaseMgr::appendSuffix(base_name, type));
  133. io.removeFile();
  134. }
  135. }
  136. /// @brief Return path to the lease file used by unit tests.
  137. ///
  138. /// @param filename Name of the lease file appended to the path to the
  139. /// directory where test data is held.
  140. ///
  141. /// @return Full path to the lease file.
  142. static std::string getLeaseFilePath(const std::string& filename) {
  143. std::ostringstream s;
  144. s << TEST_DATA_BUILDDIR << "/" << filename;
  145. return (s.str());
  146. }
  147. /// @brief Returns the configuration string for the backend.
  148. ///
  149. /// This string configures the @c LeaseMgrFactory to create the memfile
  150. /// backend and use leasefile4_0.csv and leasefile6_0.csv files as
  151. /// storage for leases.
  152. ///
  153. /// @param no_universe Indicates whether universe parameter should be
  154. /// included (false), or not (true).
  155. ///
  156. /// @return Configuration string for @c LeaseMgrFactory.
  157. static std::string getConfigString(Universe u) {
  158. std::ostringstream s;
  159. s << "type=memfile " << (u == V4 ? "universe=4 " : "universe=6 ")
  160. << "name="
  161. << getLeaseFilePath(u == V4 ? "leasefile4_0.csv" : "leasefile6_0.csv");
  162. return (s.str());
  163. }
  164. /// @brief Creates instance of the backend.
  165. ///
  166. /// @param u Universe (v4 or V6).
  167. void startBackend(Universe u) {
  168. try {
  169. LeaseMgrFactory::create(getConfigString(u));
  170. } catch (...) {
  171. std::cerr << "*** ERROR: unable to create instance of the Memfile\n"
  172. " lease database backend.\n";
  173. throw;
  174. }
  175. lmptr_ = &(LeaseMgrFactory::instance());
  176. }
  177. /// @brief Runs @c IfaceMgr::receive6 in a look for a specified time.
  178. ///
  179. /// @param ms Duration in milliseconds.
  180. void setTestTime(const uint32_t ms) {
  181. // Measure test time and exit if timeout hit.
  182. Stopwatch stopwatch;
  183. while (stopwatch.getTotalMilliseconds() < ms) {
  184. // Block for one 1 millisecond.
  185. IfaceMgr::instance().receive6(0, 1000);
  186. }
  187. }
  188. /// @brief Waits for the specified process to finish.
  189. ///
  190. /// @param process An object which started the process.
  191. /// @param timeout Timeout in seconds.
  192. ///
  193. /// @return true if the process ended, false otherwise
  194. bool waitForProcess(const Memfile_LeaseMgr& lease_mgr,
  195. const uint8_t timeout) {
  196. uint32_t iterations = 0;
  197. const uint32_t iterations_max = timeout * 1000;
  198. while (lease_mgr.isLFCRunning() && (iterations < iterations_max)) {
  199. usleep(1000);
  200. ++iterations;
  201. }
  202. return (iterations < iterations_max);
  203. }
  204. /// @brief Object providing access to v4 lease IO.
  205. LeaseFileIO io4_;
  206. /// @brief Object providing access to v6 lease IO.
  207. LeaseFileIO io6_;
  208. /// @brief Pointer to the instance of the @c TimerMgr.
  209. TimerMgrPtr timer_mgr_;
  210. };
  211. // This test checks if the LeaseMgr can be instantiated and that it
  212. // parses parameters string properly.
  213. TEST_F(MemfileLeaseMgrTest, constructor) {
  214. DatabaseConnection::ParameterMap pmap;
  215. pmap["universe"] = "4";
  216. pmap["persist"] = "false";
  217. boost::scoped_ptr<Memfile_LeaseMgr> lease_mgr;
  218. EXPECT_NO_THROW(lease_mgr.reset(new Memfile_LeaseMgr(pmap)));
  219. pmap["lfc-interval"] = "10";
  220. pmap["persist"] = "true";
  221. pmap["name"] = getLeaseFilePath("leasefile4_1.csv");
  222. EXPECT_NO_THROW(lease_mgr.reset(new Memfile_LeaseMgr(pmap)));
  223. // Expecting that persist parameter is yes or no. Everything other than
  224. // that is wrong.
  225. pmap["persist"] = "bogus";
  226. pmap["name"] = getLeaseFilePath("leasefile4_1.csv");
  227. EXPECT_THROW(lease_mgr.reset(new Memfile_LeaseMgr(pmap)), isc::BadValue);
  228. // The lfc-interval must be an integer.
  229. pmap["persist"] = "true";
  230. pmap["lfc-interval"] = "bogus";
  231. EXPECT_THROW(lease_mgr.reset(new Memfile_LeaseMgr(pmap)), isc::BadValue);
  232. }
  233. // Checks if the getType() and getName() methods both return "memfile".
  234. TEST_F(MemfileLeaseMgrTest, getTypeAndName) {
  235. startBackend(V4);
  236. EXPECT_EQ(std::string("memfile"), lmptr_->getType());
  237. EXPECT_EQ(std::string("memory"), lmptr_->getName());
  238. }
  239. // Checks if the path to the lease files is initialized correctly.
  240. TEST_F(MemfileLeaseMgrTest, getLeaseFilePath) {
  241. // Initialize IO objects, so as the test csv files get removed after the
  242. // test (when destructors are called).
  243. LeaseFileIO io4(getLeaseFilePath("leasefile4_1.csv"));
  244. LeaseFileIO io6(getLeaseFilePath("leasefile6_1.csv"));
  245. DatabaseConnection::ParameterMap pmap;
  246. pmap["universe"] = "4";
  247. pmap["name"] = getLeaseFilePath("leasefile4_1.csv");
  248. boost::scoped_ptr<Memfile_LeaseMgr> lease_mgr(new Memfile_LeaseMgr(pmap));
  249. EXPECT_EQ(pmap["name"],
  250. lease_mgr->getLeaseFilePath(Memfile_LeaseMgr::V4));
  251. pmap["persist"] = "false";
  252. lease_mgr.reset(new Memfile_LeaseMgr(pmap));
  253. EXPECT_TRUE(lease_mgr->getLeaseFilePath(Memfile_LeaseMgr::V4).empty());
  254. EXPECT_TRUE(lease_mgr->getLeaseFilePath(Memfile_LeaseMgr::V6).empty());
  255. }
  256. // Check if the persitLeases correctly checks that leases should not be written
  257. // to disk when disabled through configuration.
  258. TEST_F(MemfileLeaseMgrTest, persistLeases) {
  259. // Initialize IO objects, so as the test csv files get removed after the
  260. // test (when destructors are called).
  261. LeaseFileIO io4(getLeaseFilePath("leasefile4_1.csv"));
  262. LeaseFileIO io6(getLeaseFilePath("leasefile6_1.csv"));
  263. DatabaseConnection::ParameterMap pmap;
  264. pmap["universe"] = "4";
  265. // Specify the names of the lease files. Leases will be written.
  266. pmap["name"] = getLeaseFilePath("leasefile4_1.csv");
  267. boost::scoped_ptr<Memfile_LeaseMgr> lease_mgr(new Memfile_LeaseMgr(pmap));
  268. lease_mgr.reset(new Memfile_LeaseMgr(pmap));
  269. EXPECT_TRUE(lease_mgr->persistLeases(Memfile_LeaseMgr::V4));
  270. EXPECT_FALSE(lease_mgr->persistLeases(Memfile_LeaseMgr::V6));
  271. pmap["universe"] = "6";
  272. pmap["name"] = getLeaseFilePath("leasefile6_1.csv");
  273. lease_mgr.reset(new Memfile_LeaseMgr(pmap));
  274. EXPECT_FALSE(lease_mgr->persistLeases(Memfile_LeaseMgr::V4));
  275. EXPECT_TRUE(lease_mgr->persistLeases(Memfile_LeaseMgr::V6));
  276. // This should disable writes of leases to disk.
  277. pmap["persist"] = "false";
  278. lease_mgr.reset(new Memfile_LeaseMgr(pmap));
  279. EXPECT_FALSE(lease_mgr->persistLeases(Memfile_LeaseMgr::V4));
  280. EXPECT_FALSE(lease_mgr->persistLeases(Memfile_LeaseMgr::V6));
  281. }
  282. // Check if it is possible to schedule the timer to perform the Lease
  283. // File Cleanup periodically.
  284. TEST_F(MemfileLeaseMgrTest, lfcTimer) {
  285. DatabaseConnection::ParameterMap pmap;
  286. pmap["type"] = "memfile";
  287. pmap["universe"] = "4";
  288. // Specify the names of the lease files. Leases will be written.
  289. pmap["name"] = getLeaseFilePath("leasefile4_0.csv");
  290. pmap["lfc-interval"] = "1";
  291. boost::scoped_ptr<LFCMemfileLeaseMgr>
  292. lease_mgr(new LFCMemfileLeaseMgr(pmap));
  293. // Start worker thread to execute LFC periodically.
  294. ASSERT_NO_THROW(timer_mgr_->startThread());
  295. // Run the test for at most 2.9 seconds.
  296. setTestTime(2900);
  297. // Stop worker thread.
  298. ASSERT_NO_THROW(timer_mgr_->stopThread());
  299. // Within 2.9 we should record two LFC executions.
  300. EXPECT_EQ(2, lease_mgr->getLFCCount());
  301. }
  302. // This test checks if the LFC timer is disabled (doesn't trigger)
  303. // cleanups when the lfc-interval is set to 0.
  304. TEST_F(MemfileLeaseMgrTest, lfcTimerDisabled) {
  305. DatabaseConnection::ParameterMap pmap;
  306. pmap["type"] = "memfile";
  307. pmap["universe"] = "4";
  308. pmap["name"] = getLeaseFilePath("leasefile4_0.csv");
  309. // Set the LFC interval to 0, which should effectively disable it.
  310. pmap["lfc-interval"] = "0";
  311. boost::scoped_ptr<LFCMemfileLeaseMgr>
  312. lease_mgr(new LFCMemfileLeaseMgr(pmap));
  313. // Start worker thread to execute LFC periodically.
  314. ASSERT_NO_THROW(timer_mgr_->startThread());
  315. // Run the test for at most 1.9 seconds.
  316. setTestTime(1900);
  317. // Stop worker thread to make sure it is not running when lease
  318. // manager is destroyed. The lease manager will be unable to
  319. // unregster timer when the thread is active.
  320. ASSERT_NO_THROW(timer_mgr_->stopThread());
  321. // There should be no LFC execution recorded.
  322. EXPECT_EQ(0, lease_mgr->getLFCCount());
  323. }
  324. // This test checks that the callback function executing the cleanup of the
  325. // DHCPv4 lease file works as expected.
  326. TEST_F(MemfileLeaseMgrTest, leaseFileCleanup4) {
  327. // This string contains the lease file header, which matches
  328. // the contents of the new file in which no leases have been
  329. // stored.
  330. std::string new_file_contents =
  331. "address,hwaddr,client_id,valid_lifetime,expire,"
  332. "subnet_id,fqdn_fwd,fqdn_rev,hostname,state\n";
  333. // This string contains the contents of the lease file with exactly
  334. // one lease, but two entries. One of the entries should be removed
  335. // as a result of lease file cleanup.
  336. std::string current_file_contents = new_file_contents +
  337. "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1\n"
  338. "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,,1\n";
  339. LeaseFileIO current_file(getLeaseFilePath("leasefile4_0.csv"));
  340. current_file.writeFile(current_file_contents);
  341. std::string previous_file_contents = new_file_contents +
  342. "192.0.2.3,03:03:03:03:03:03,,200,200,8,1,1,,1\n"
  343. "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,1\n";
  344. LeaseFileIO previous_file(getLeaseFilePath("leasefile4_0.csv.2"));
  345. previous_file.writeFile(previous_file_contents);
  346. // Create the backend.
  347. DatabaseConnection::ParameterMap pmap;
  348. pmap["type"] = "memfile";
  349. pmap["universe"] = "4";
  350. pmap["name"] = getLeaseFilePath("leasefile4_0.csv");
  351. pmap["lfc-interval"] = "1";
  352. boost::scoped_ptr<NakedMemfileLeaseMgr> lease_mgr(new NakedMemfileLeaseMgr(pmap));
  353. // Try to run the lease file cleanup.
  354. ASSERT_NO_THROW(lease_mgr->lfcCallback());
  355. // The new lease file should have been created and it should contain
  356. // no leases.
  357. ASSERT_TRUE(current_file.exists());
  358. EXPECT_EQ(new_file_contents, current_file.readFile());
  359. // Wait for the LFC process to complete.
  360. ASSERT_TRUE(waitForProcess(*lease_mgr, 2));
  361. // And make sure it has returned an exit status of 0.
  362. EXPECT_EQ(0, lease_mgr->getLFCExitStatus())
  363. << "Executing the LFC process failed: make sure that"
  364. " the kea-lfc program has been compiled.";
  365. // Check if we can still write to the lease file.
  366. std::vector<uint8_t> hwaddr_vec(6);
  367. HWAddrPtr hwaddr(new HWAddr(hwaddr_vec, HTYPE_ETHER));
  368. Lease4Ptr new_lease(new Lease4(IOAddress("192.0.2.45"), hwaddr, 0, 0,
  369. 100, 50, 60, 0, 1));
  370. ASSERT_NO_THROW(lease_mgr->addLease(new_lease));
  371. std::string updated_file_contents = new_file_contents +
  372. "192.0.2.45,00:00:00:00:00:00,,100,100,1,0,0,,0\n";
  373. EXPECT_EQ(updated_file_contents, current_file.readFile());
  374. // This string contains the contents of the lease file we
  375. // expect after the LFC run. It has two leases with one
  376. // entry each.
  377. std::string result_file_contents = new_file_contents +
  378. "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,,1\n"
  379. "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,1\n";
  380. // The LFC should have created a file with the two leases and moved it
  381. // to leasefile4_0.csv.2
  382. LeaseFileIO input_file(getLeaseFilePath("leasefile4_0.csv.2"), false);
  383. ASSERT_TRUE(input_file.exists());
  384. // And this file should contain the contents of the result file.
  385. EXPECT_EQ(result_file_contents, input_file.readFile());
  386. }
  387. // This test checks that the callback function executing the cleanup of the
  388. // DHCPv6 lease file works as expected.
  389. TEST_F(MemfileLeaseMgrTest, leaseFileCleanup6) {
  390. // This string contains the lease file header, which matches
  391. // the contents of the new file in which no leases have been
  392. // stored.
  393. std::string new_file_contents =
  394. "address,duid,valid_lifetime,expire,subnet_id,"
  395. "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
  396. "fqdn_rev,hostname,hwaddr,state\n";
  397. // This string contains the contents of the lease file with exactly
  398. // one lease, but two entries. One of the entries should be removed
  399. // as a result of lease file cleanup.
  400. std::string current_file_contents = new_file_contents +
  401. "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,200,"
  402. "8,100,0,7,0,1,1,,,1\n"
  403. "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
  404. "8,100,0,7,0,1,1,,,1\n";
  405. LeaseFileIO current_file(getLeaseFilePath("leasefile6_0.csv"));
  406. current_file.writeFile(current_file_contents);
  407. std::string previous_file_contents = new_file_contents +
  408. "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,200,"
  409. "8,100,0,7,0,1,1,,,1\n"
  410. "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
  411. "8,100,0,7,0,1,1,,,1\n";
  412. LeaseFileIO previous_file(getLeaseFilePath("leasefile6_0.csv.2"));
  413. previous_file.writeFile(previous_file_contents);
  414. // Create the backend.
  415. DatabaseConnection::ParameterMap pmap;
  416. pmap["type"] = "memfile";
  417. pmap["universe"] = "6";
  418. pmap["name"] = getLeaseFilePath("leasefile6_0.csv");
  419. pmap["lfc-interval"] = "1";
  420. boost::scoped_ptr<NakedMemfileLeaseMgr> lease_mgr(new NakedMemfileLeaseMgr(pmap));
  421. // Try to run the lease file cleanup.
  422. ASSERT_NO_THROW(lease_mgr->lfcCallback());
  423. // The new lease file should have been created and it should contain
  424. // no leases.
  425. ASSERT_TRUE(current_file.exists());
  426. EXPECT_EQ(new_file_contents, current_file.readFile());
  427. // Wait for the LFC process to complete.
  428. ASSERT_TRUE(waitForProcess(*lease_mgr, 2));
  429. // And make sure it has returned an exit status of 0.
  430. EXPECT_EQ(0, lease_mgr->getLFCExitStatus())
  431. << "Executing the LFC process failed: make sure that"
  432. " the kea-lfc program has been compiled.";
  433. // Check if we can still write to the lease file.
  434. std::vector<uint8_t> duid_vec(13);
  435. DuidPtr duid(new DUID(duid_vec));
  436. Lease6Ptr new_lease(new Lease6(Lease::TYPE_NA, IOAddress("3000::1"),duid,
  437. 123, 300, 400, 100, 300, 2));
  438. new_lease->cltt_ = 0;
  439. ASSERT_NO_THROW(lease_mgr->addLease(new_lease));
  440. std::string update_file_contents = new_file_contents +
  441. "3000::1,00:00:00:00:00:00:00:00:00:00:00:00:00,400,"
  442. "400,2,300,0,123,128,0,0,,,0\n";
  443. EXPECT_EQ(update_file_contents, current_file.readFile());
  444. // This string contains the contents of the lease file we
  445. // expect after the LFC run. It has two leases with one
  446. // entry each.
  447. std::string result_file_contents = new_file_contents +
  448. "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
  449. "8,100,0,7,0,1,1,,,1\n"
  450. "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
  451. "8,100,0,7,0,1,1,,,1\n";
  452. // The LFC should have created a file with the two leases and moved it
  453. // to leasefile6_0.csv.2
  454. LeaseFileIO input_file(getLeaseFilePath("leasefile6_0.csv.2"), false);
  455. ASSERT_TRUE(input_file.exists());
  456. // And this file should contain the contents of the result file.
  457. EXPECT_EQ(result_file_contents, input_file.readFile());
  458. }
  459. // This test verifies that EXIT_FAILURE status code is returned when
  460. // the LFC process fails to start.
  461. TEST_F(MemfileLeaseMgrTest, leaseFileCleanupStartFail) {
  462. // This string contains the lease file header, which matches
  463. // the contents of the new file in which no leases have been
  464. // stored.
  465. std::string new_file_contents =
  466. "address,hwaddr,client_id,valid_lifetime,expire,"
  467. "subnet_id,fqdn_fwd,fqdn_rev,hostname,state\n";
  468. // Create the lease file to be used by the backend.
  469. std::string current_file_contents = new_file_contents +
  470. "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1\n";
  471. LeaseFileIO current_file(getLeaseFilePath("leasefile4_0.csv"));
  472. current_file.writeFile(current_file_contents);
  473. // Specify invalid path to the kea-lfc executable. This should result
  474. // in failure status code returned by the child process.
  475. setenv("KEA_LFC_EXECUTABLE", "foobar", 1);
  476. // Create the backend.
  477. DatabaseConnection::ParameterMap pmap;
  478. pmap["type"] = "memfile";
  479. pmap["universe"] = "4";
  480. pmap["name"] = getLeaseFilePath("leasefile4_0.csv");
  481. pmap["lfc-interval"] = "1";
  482. boost::scoped_ptr<NakedMemfileLeaseMgr> lease_mgr(new NakedMemfileLeaseMgr(pmap));
  483. // Try to run the lease file cleanup.
  484. ASSERT_NO_THROW(lease_mgr->lfcCallback());
  485. // Wait for the LFC process to complete.
  486. ASSERT_TRUE(waitForProcess(*lease_mgr, 2));
  487. // And make sure it has returned an error.
  488. EXPECT_EQ(EXIT_FAILURE, lease_mgr->getLFCExitStatus())
  489. << "Executing the LFC process failed: make sure that"
  490. " the kea-lfc program has been compiled.";
  491. }
  492. // This test checks that the callback function executing the cleanup of the
  493. // files doesn't move the current file if the finish file exists
  494. TEST_F(MemfileLeaseMgrTest, leaseFileFinish) {
  495. // This string contains the lease file header, which matches
  496. // the contents of the new file in which no leases have been
  497. // stored.
  498. std::string new_file_contents =
  499. "address,duid,valid_lifetime,expire,subnet_id,"
  500. "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
  501. "fqdn_rev,hostname,hwaddr,state\n";
  502. // This string contains the contents of the current lease file.
  503. // It should not be moved.
  504. std::string current_file_contents = new_file_contents +
  505. "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,200,"
  506. "8,100,0,7,0,1,1,,,1\n"
  507. "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
  508. "8,100,0,7,0,1,1,,,1\n";
  509. LeaseFileIO current_file(getLeaseFilePath("leasefile6_0.csv"));
  510. current_file.writeFile(current_file_contents);
  511. // This string contains the contents of the finish file. It should
  512. // be moved to the previous file.
  513. std::string finish_file_contents = new_file_contents +
  514. "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
  515. "8,100,0,7,0,1,1,,,1\n";
  516. LeaseFileIO finish_file(getLeaseFilePath("leasefile6_0.csv.completed"));
  517. finish_file.writeFile(finish_file_contents);
  518. // Create the backend.
  519. DatabaseConnection::ParameterMap pmap;
  520. pmap["type"] = "memfile";
  521. pmap["universe"] = "6";
  522. pmap["name"] = getLeaseFilePath("leasefile6_0.csv");
  523. pmap["lfc-interval"] = "1";
  524. boost::scoped_ptr<NakedMemfileLeaseMgr> lease_mgr(new NakedMemfileLeaseMgr(pmap));
  525. // Try to run the lease file cleanup.
  526. ASSERT_NO_THROW(lease_mgr->lfcCallback());
  527. // The current lease file should not have been touched.
  528. ASSERT_TRUE(current_file.exists());
  529. EXPECT_EQ(current_file_contents, current_file.readFile());
  530. // Wait for the LFC process to complete.
  531. ASSERT_TRUE(waitForProcess(*lease_mgr, 5));
  532. // And make sure it has returned an exit status of 0.
  533. EXPECT_EQ(0, lease_mgr->getLFCExitStatus())
  534. << "Executing the LFC process failed: make sure that"
  535. " the kea-lfc program has been compiled.";
  536. // The LFC should have moved the finish file to the previous file -
  537. // leasefile6_0.csv.2
  538. LeaseFileIO previous_file(getLeaseFilePath("leasefile6_0.csv.2"), false);
  539. ASSERT_TRUE(previous_file.exists());
  540. // And this file should contain the contents of the finish file.
  541. EXPECT_EQ(finish_file_contents, previous_file.readFile());
  542. // The finish file should have been removed
  543. ASSERT_FALSE(finish_file.exists());
  544. }
  545. // This test checks that the callback function executing the cleanup of the
  546. // files doesn't move the current file if the copy file exists
  547. TEST_F(MemfileLeaseMgrTest, leaseFileCopy) {
  548. // This string contains the lease file header, which matches
  549. // the contents of the new file in which no leases have been
  550. // stored.
  551. std::string new_file_contents =
  552. "address,duid,valid_lifetime,expire,subnet_id,"
  553. "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
  554. "fqdn_rev,hostname,hwaddr,state\n";
  555. // This string contains the contents of the current lease file.
  556. // It should not be moved.
  557. std::string current_file_contents = new_file_contents +
  558. "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,200,"
  559. "8,100,0,7,0,1,1,,,1\n"
  560. "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
  561. "8,100,0,7,0,1,1,,,1\n";
  562. LeaseFileIO current_file(getLeaseFilePath("leasefile6_0.csv"));
  563. current_file.writeFile(current_file_contents);
  564. // This string contains the contents of the copy file. It should
  565. // be processed and moved to the previous file. As there is only
  566. // one lease the processing should result in the previous file being
  567. // the same.
  568. std::string input_file_contents = new_file_contents +
  569. "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
  570. "8,100,0,7,0,1,1,,,1\n";
  571. LeaseFileIO input_file(getLeaseFilePath("leasefile6_0.csv.1"));
  572. input_file.writeFile(input_file_contents);
  573. // Create the backend.
  574. DatabaseConnection::ParameterMap pmap;
  575. pmap["type"] = "memfile";
  576. pmap["universe"] = "6";
  577. pmap["name"] = getLeaseFilePath("leasefile6_0.csv");
  578. pmap["lfc-interval"] = "1";
  579. boost::scoped_ptr<NakedMemfileLeaseMgr> lease_mgr(new NakedMemfileLeaseMgr(pmap));
  580. // Try to run the lease file cleanup.
  581. ASSERT_NO_THROW(lease_mgr->lfcCallback());
  582. // The current lease file should not have been touched.
  583. ASSERT_TRUE(current_file.exists());
  584. EXPECT_EQ(current_file_contents, current_file.readFile());
  585. // Wait for the LFC process to complete.
  586. ASSERT_TRUE(waitForProcess(*lease_mgr, 5));
  587. // And make sure it has returned an exit status of 0.
  588. EXPECT_EQ(0, lease_mgr->getLFCExitStatus())
  589. << "Executing the LFC process failed: make sure that"
  590. " the kea-lfc program has been compiled.";
  591. // The LFC should have processed the lease and moved it to the previous
  592. // file - leasefile6_0.csv.2
  593. LeaseFileIO previous_file(getLeaseFilePath("leasefile6_0.csv.2"), false);
  594. ASSERT_TRUE(previous_file.exists());
  595. // And this file should contain the contents of the copy file.
  596. EXPECT_EQ(input_file_contents, previous_file.readFile());
  597. // The input file should have been removed
  598. ASSERT_FALSE(input_file.exists());
  599. }
  600. // Checks that adding/getting/deleting a Lease6 object works.
  601. TEST_F(MemfileLeaseMgrTest, addGetDelete6) {
  602. startBackend(V6);
  603. testAddGetDelete6(true); // true - check T1,T2 values
  604. // memfile is able to preserve those values, but some other
  605. // backends can't do that.
  606. }
  607. /// @brief Basic Lease4 Checks
  608. ///
  609. /// Checks that the addLease, getLease4 (by address) and deleteLease (with an
  610. /// IPv4 address) works.
  611. TEST_F(MemfileLeaseMgrTest, basicLease4) {
  612. startBackend(V4);
  613. testBasicLease4();
  614. }
  615. /// @todo Write more memfile tests
  616. // Simple test about lease4 retrieval through client id method
  617. TEST_F(MemfileLeaseMgrTest, getLease4ClientId) {
  618. startBackend(V4);
  619. testGetLease4ClientId();
  620. }
  621. // Checks that lease4 retrieval client id is null is working
  622. TEST_F(MemfileLeaseMgrTest, getLease4NullClientId) {
  623. startBackend(V4);
  624. testGetLease4NullClientId();
  625. }
  626. // Checks lease4 retrieval through HWAddr
  627. TEST_F(MemfileLeaseMgrTest, getLease4HWAddr1) {
  628. startBackend(V4);
  629. testGetLease4HWAddr1();
  630. }
  631. /// @brief Check GetLease4 methods - access by Hardware Address
  632. ///
  633. /// Adds leases to the database and checks that they can be accessed via
  634. /// a combination of DUID and IAID.
  635. TEST_F(MemfileLeaseMgrTest, getLease4HWAddr2) {
  636. startBackend(V4);
  637. testGetLease4HWAddr2();
  638. }
  639. // Checks lease4 retrieval with clientId, HWAddr and subnet_id
  640. TEST_F(MemfileLeaseMgrTest, getLease4ClientIdHWAddrSubnetId) {
  641. startBackend(V4);
  642. testGetLease4ClientIdHWAddrSubnetId();
  643. }
  644. /// @brief Basic Lease4 Checks
  645. ///
  646. /// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
  647. /// updateLease4() and deleteLease (IPv4 address) can handle NULL client-id.
  648. /// (client-id is optional and may not be present)
  649. TEST_F(MemfileLeaseMgrTest, lease4NullClientId) {
  650. startBackend(V4);
  651. testLease4NullClientId();
  652. }
  653. /// @brief Check GetLease4 methods - access by Hardware Address & Subnet ID
  654. ///
  655. /// Adds leases to the database and checks that they can be accessed via
  656. /// a combination of hardware address and subnet ID
  657. TEST_F(MemfileLeaseMgrTest, DISABLED_getLease4HwaddrSubnetId) {
  658. /// @todo: fails on memfile. It's probably a memfile bug.
  659. startBackend(V4);
  660. testGetLease4HWAddrSubnetId();
  661. }
  662. /// @brief Check GetLease4 methods - access by Client ID
  663. ///
  664. /// Adds leases to the database and checks that they can be accessed via
  665. /// the Client ID.
  666. TEST_F(MemfileLeaseMgrTest, getLease4ClientId2) {
  667. startBackend(V4);
  668. testGetLease4ClientId2();
  669. }
  670. // @brief Get Lease4 by client ID
  671. //
  672. // Check that the system can cope with a client ID of any size.
  673. TEST_F(MemfileLeaseMgrTest, getLease4ClientIdSize) {
  674. startBackend(V4);
  675. testGetLease4ClientIdSize();
  676. }
  677. /// @brief Check GetLease4 methods - access by Client ID & Subnet ID
  678. ///
  679. /// Adds leases to the database and checks that they can be accessed via
  680. /// a combination of client and subnet IDs.
  681. TEST_F(MemfileLeaseMgrTest, getLease4ClientIdSubnetId) {
  682. startBackend(V4);
  683. testGetLease4ClientIdSubnetId();
  684. }
  685. /// @brief Basic Lease6 Checks
  686. ///
  687. /// Checks that the addLease, getLease6 (by address) and deleteLease (with an
  688. /// IPv6 address) works.
  689. TEST_F(MemfileLeaseMgrTest, basicLease6) {
  690. startBackend(V6);
  691. testBasicLease6();
  692. }
  693. /// @brief Check GetLease6 methods - access by DUID/IAID
  694. ///
  695. /// Adds leases to the database and checks that they can be accessed via
  696. /// a combination of DUID and IAID.
  697. /// @todo: test disabled, because Memfile_LeaseMgr::getLeases6(Lease::Type,
  698. /// const DUID& duid, uint32_t iaid) const is not implemented yet.
  699. TEST_F(MemfileLeaseMgrTest, getLeases6DuidIaid) {
  700. startBackend(V6);
  701. testGetLeases6DuidIaid();
  702. }
  703. /// @brief Check that the system can cope with a DUID of allowed size.
  704. TEST_F(MemfileLeaseMgrTest, getLeases6DuidSize) {
  705. startBackend(V6);
  706. testGetLeases6DuidSize();
  707. }
  708. /// @brief Check that the expired DHCPv4 leases can be retrieved.
  709. ///
  710. /// This test adds a number of leases to the lease database and marks
  711. /// some of them as expired. Then it queries for expired leases and checks
  712. /// whether only expired leases are returned, and that they are returned in
  713. /// the order from most to least expired. It also checks that the lease
  714. /// which is marked as 'reclaimed' is not returned.
  715. TEST_F(MemfileLeaseMgrTest, getExpiredLeases4) {
  716. startBackend(V4);
  717. testGetExpiredLeases4();
  718. }
  719. /// @brief Check that the expired DHCPv6 leases can be retrieved.
  720. ///
  721. /// This test adds a number of leases to the lease database and marks
  722. /// some of them as expired. Then it queries for expired leases and checks
  723. /// whether only expired leases are returned, and that they are returned in
  724. /// the order from most to least expired. It also checks that the lease
  725. /// which is marked as 'reclaimed' is not returned.
  726. TEST_F(MemfileLeaseMgrTest, getExpiredLeases6) {
  727. startBackend(V6);
  728. testGetExpiredLeases6();
  729. }
  730. /// @brief Check that expired reclaimed DHCPv6 leases are removed.
  731. TEST_F(MemfileLeaseMgrTest, deleteExpiredReclaimedLeases6) {
  732. startBackend(V6);
  733. testDeleteExpiredReclaimedLeases6();
  734. }
  735. /// @brief Check that expired reclaimed DHCPv4 leases are removed.
  736. TEST_F(MemfileLeaseMgrTest, deleteExpiredReclaimedLeases4) {
  737. startBackend(V4);
  738. testDeleteExpiredReclaimedLeases4();
  739. }
  740. /// @brief Check that getLease6 methods discriminate by lease type.
  741. ///
  742. /// Adds six leases, two per lease type all with the same duid and iad but
  743. /// with alternating subnet_ids.
  744. /// It then verifies that all of getLeases6() method variants correctly
  745. /// discriminate between the leases based on lease type alone.
  746. /// @todo: Disabled, because type parameter in Memfile_LeaseMgr::getLease6
  747. /// (Lease::Type, const isc::asiolink::IOAddress& addr) const is not used.
  748. TEST_F(MemfileLeaseMgrTest, lease6LeaseTypeCheck) {
  749. startBackend(V6);
  750. testLease6LeaseTypeCheck();
  751. }
  752. /// @brief Check GetLease6 methods - access by DUID/IAID/SubnetID
  753. ///
  754. /// Adds leases to the database and checks that they can be accessed via
  755. /// a combination of DIUID and IAID.
  756. TEST_F(MemfileLeaseMgrTest, getLease6DuidIaidSubnetId) {
  757. startBackend(V6);
  758. testGetLease6DuidIaidSubnetId();
  759. }
  760. /// Checks that getLease6(type, duid, iaid, subnet-id) works with different
  761. /// DUID sizes
  762. TEST_F(MemfileLeaseMgrTest, getLease6DuidIaidSubnetIdSize) {
  763. startBackend(V6);
  764. testGetLease6DuidIaidSubnetIdSize();
  765. }
  766. /// @brief Lease4 update tests
  767. ///
  768. /// Checks that we are able to update a lease in the database.
  769. /// @todo: Disabled, because memfile does not throw when lease is updated.
  770. /// We should reconsider if lease{4,6} structures should have a limit
  771. /// implemented in them.
  772. TEST_F(MemfileLeaseMgrTest, DISABLED_updateLease4) {
  773. startBackend(V4);
  774. testUpdateLease4();
  775. }
  776. /// @brief Lease6 update tests
  777. ///
  778. /// Checks that we are able to update a lease in the database.
  779. /// @todo: Disabled, because memfile does not throw when lease is updated.
  780. /// We should reconsider if lease{4,6} structures should have a limit
  781. /// implemented in them.
  782. TEST_F(MemfileLeaseMgrTest, DISABLED_updateLease6) {
  783. startBackend(V6);
  784. testUpdateLease6();
  785. }
  786. /// @brief DHCPv4 Lease recreation tests
  787. ///
  788. /// Checks that the lease can be created, deleted and recreated with
  789. /// different parameters. It also checks that the re-created lease is
  790. /// correctly stored in the lease database.
  791. TEST_F(MemfileLeaseMgrTest, testRecreateLease4) {
  792. startBackend(V4);
  793. testRecreateLease4();
  794. }
  795. /// @brief DHCPv6 Lease recreation tests
  796. ///
  797. /// Checks that the lease can be created, deleted and recreated with
  798. /// different parameters. It also checks that the re-created lease is
  799. /// correctly stored in the lease database.
  800. TEST_F(MemfileLeaseMgrTest, testRecreateLease6) {
  801. startBackend(V6);
  802. testRecreateLease6();
  803. }
  804. // The following tests are not applicable for memfile. When adding
  805. // new tests to the list here, make sure to provide brief explanation
  806. // why they are not applicable:
  807. //
  808. // testGetLease4HWAddrSubnetIdSize() - memfile just keeps Lease structure
  809. // and does not do any checks of HWAddr content
  810. /// @brief Checks that null DUID is not allowed.
  811. /// Test is disabled as Memfile does not currently defend against a null DUID.
  812. TEST_F(MemfileLeaseMgrTest, DISABLED_nullDuid) {
  813. // Create leases, although we need only one.
  814. vector<Lease6Ptr> leases = createLeases6();
  815. leases[1]->duid_.reset();
  816. ASSERT_THROW(lmptr_->addLease(leases[1]), DbOperationError);
  817. }
  818. /// @brief Tests whether memfile can store and retrieve hardware addresses
  819. TEST_F(MemfileLeaseMgrTest, testLease6Mac) {
  820. startBackend(V6);
  821. testLease6MAC();
  822. }
  823. // Check that memfile reports version correctly.
  824. TEST_F(MemfileLeaseMgrTest, versionCheck) {
  825. // Check that V4 backend reports versions correctly.
  826. startBackend(V4);
  827. testVersion(Memfile_LeaseMgr::MAJOR_VERSION,
  828. Memfile_LeaseMgr::MINOR_VERSION);
  829. LeaseMgrFactory::destroy();
  830. // Check that V6 backends reports them ok, too.
  831. startBackend(V6);
  832. testVersion(Memfile_LeaseMgr::MAJOR_VERSION,
  833. Memfile_LeaseMgr::MINOR_VERSION);
  834. LeaseMgrFactory::destroy();
  835. }
  836. // Checks that declined IPv4 leases can be returned correctly.
  837. TEST_F(MemfileLeaseMgrTest, getDeclined4) {
  838. startBackend(V4);
  839. testGetDeclinedLeases4();
  840. }
  841. // Checks that declined IPv6 leases can be returned correctly.
  842. TEST_F(MemfileLeaseMgrTest, getDeclined6) {
  843. startBackend(V6);
  844. testGetDeclinedLeases6();
  845. }
  846. // This test checks that the backend reads DHCPv4 lease data from multiple
  847. // files.
  848. TEST_F(MemfileLeaseMgrTest, load4MultipleLeaseFiles) {
  849. LeaseFileIO io2(getLeaseFilePath("leasefile4_0.csv.2"));
  850. io2.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
  851. "fqdn_fwd,fqdn_rev,hostname,state\n"
  852. "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1\n"
  853. "192.0.2.11,bb:bb:bb:bb:bb:bb,,200,200,8,1,1,,1\n");
  854. LeaseFileIO io1(getLeaseFilePath("leasefile4_0.csv.1"));
  855. io1.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
  856. "fqdn_fwd,fqdn_rev,hostname,state\n"
  857. "192.0.2.1,01:01:01:01:01:01,,200,200,8,1,1,,1\n"
  858. "192.0.2.11,bb:bb:bb:bb:bb:bb,,200,400,8,1,1,,1\n"
  859. "192.0.2.12,cc:cc:cc:cc:cc:cc,,200,200,8,1,1,,1\n");
  860. LeaseFileIO io(getLeaseFilePath("leasefile4_0.csv"));
  861. io.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
  862. "fqdn_fwd,fqdn_rev,hostname,state\n"
  863. "192.0.2.10,0a:0a:0a:0a:0a:0a,,200,200,8,1,1,,1\n"
  864. "192.0.2.12,cc:cc:cc:cc:cc:cc,,200,400,8,1,1,,1\n");
  865. startBackend(V4);
  866. // This lease only exists in the second file and the cltt should
  867. // be 0.
  868. Lease4Ptr lease = lmptr_->getLease4(IOAddress("192.0.2.1"));
  869. ASSERT_TRUE(lease);
  870. EXPECT_EQ(0, lease->cltt_);
  871. // This lease only exists in the first file and the cltt should
  872. // be 0.
  873. lease = lmptr_->getLease4(IOAddress("192.0.2.2"));
  874. ASSERT_TRUE(lease);
  875. EXPECT_EQ(0, lease->cltt_);
  876. // This lease only exists in the third file and the cltt should
  877. // be 0.
  878. lease = lmptr_->getLease4(IOAddress("192.0.2.10"));
  879. ASSERT_TRUE(lease);
  880. EXPECT_EQ(0, lease->cltt_);
  881. // This lease exists in the first and second file and the cltt
  882. // should be calculated using the expiration time and the
  883. // valid lifetime from the second file.
  884. lease = lmptr_->getLease4(IOAddress("192.0.2.11"));
  885. ASSERT_TRUE(lease);
  886. EXPECT_EQ(200, lease->cltt_);
  887. // This lease exists in the second and third file and the cltt
  888. // should be calculated using the expiration time and the
  889. // valid lifetime from the third file.
  890. lease = lmptr_->getLease4(IOAddress("192.0.2.12"));
  891. ASSERT_TRUE(lease);
  892. EXPECT_EQ(200, lease->cltt_);
  893. }
  894. // This test checks that the lease database backend loads the file with
  895. // the .completed postfix instead of files with postfixes .1 and .2 if
  896. // the file with .completed postfix exists.
  897. TEST_F(MemfileLeaseMgrTest, load4CompletedFile) {
  898. LeaseFileIO io2(getLeaseFilePath("leasefile4_0.csv.2"));
  899. io2.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
  900. "fqdn_fwd,fqdn_rev,hostname,state\n"
  901. "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1\n"
  902. "192.0.2.11,bb:bb:bb:bb:bb:bb,,200,200,8,1,1,,1\n");
  903. LeaseFileIO io1(getLeaseFilePath("leasefile4_0.csv.1"));
  904. io1.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
  905. "fqdn_fwd,fqdn_rev,hostname,state\n"
  906. "192.0.2.1,01:01:01:01:01:01,,200,200,8,1,1,,1\n"
  907. "192.0.2.11,bb:bb:bb:bb:bb:bb,,200,400,8,1,1,,1\n"
  908. "192.0.2.12,cc:cc:cc:cc:cc:cc,,200,200,8,1,1,,1\n");
  909. LeaseFileIO io(getLeaseFilePath("leasefile4_0.csv"));
  910. io.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
  911. "fqdn_fwd,fqdn_rev,hostname,state\n"
  912. "192.0.2.10,0a:0a:0a:0a:0a:0a,,200,200,8,1,1,,1\n"
  913. "192.0.2.12,cc:cc:cc:cc:cc:cc,,200,400,8,1,1,,1\n");
  914. LeaseFileIO ioc(getLeaseFilePath("leasefile4_0.csv.completed"));
  915. ioc.writeFile("address,hwaddr,client_id,valid_lifetime,expire,subnet_id,"
  916. "fqdn_fwd,fqdn_rev,hostname,state\n"
  917. "192.0.2.13,ff:ff:ff:ff:ff:ff,,200,200,8,1,1,,1\n");
  918. startBackend(V4);
  919. // We expect that this file only holds leases that belong to the
  920. // lease file or to the file with .completed postfix.
  921. Lease4Ptr lease = lmptr_->getLease4(IOAddress("192.0.2.10"));
  922. ASSERT_TRUE(lease);
  923. EXPECT_EQ(0, lease->cltt_);
  924. lease = lmptr_->getLease4(IOAddress("192.0.2.12"));
  925. ASSERT_TRUE(lease);
  926. EXPECT_EQ(200, lease->cltt_);
  927. // This lease is in the .completed file.
  928. lease = lmptr_->getLease4(IOAddress("192.0.2.13"));
  929. ASSERT_TRUE(lease);
  930. EXPECT_EQ(0, lease->cltt_);
  931. // Leases from the .1 and .2 files should not be loaded.
  932. EXPECT_FALSE(lmptr_->getLease4(IOAddress("192.0.2.11")));
  933. EXPECT_FALSE(lmptr_->getLease4(IOAddress("192.0.2.1")));
  934. }
  935. // This test checks that backend constructor refuses to load leases from the
  936. // lease files if the LFC is in progress.
  937. TEST_F(MemfileLeaseMgrTest, load4LFCInProgress) {
  938. // Create the backend configuration.
  939. DatabaseConnection::ParameterMap pmap;
  940. pmap["type"] = "memfile";
  941. pmap["universe"] = "4";
  942. pmap["name"] = getLeaseFilePath("leasefile4_0.csv");
  943. pmap["lfc-interval"] = "1";
  944. // Create a pid file holding the PID of the current process. Choosing the
  945. // pid of the current process guarantees that when the backend starts up
  946. // the process is alive.
  947. PIDFile pid_file(Memfile_LeaseMgr::appendSuffix(pmap["name"], Memfile_LeaseMgr::FILE_PID));
  948. pid_file.write();
  949. // There is a pid file and the process which pid is in the file is
  950. // running, so the backend should refuse to start.
  951. boost::scoped_ptr<NakedMemfileLeaseMgr> lease_mgr;
  952. ASSERT_THROW(lease_mgr.reset(new NakedMemfileLeaseMgr(pmap)),
  953. DbOpenError);
  954. // Remove the pid file, and retry. The bakckend should be created.
  955. pid_file.deleteFile();
  956. ASSERT_NO_THROW(lease_mgr.reset(new NakedMemfileLeaseMgr(pmap)));
  957. }
  958. // This test checks that the backend reads DHCPv6 lease data from multiple
  959. // files.
  960. TEST_F(MemfileLeaseMgrTest, load6MultipleLeaseFiles) {
  961. LeaseFileIO io2(getLeaseFilePath("leasefile6_0.csv.2"));
  962. io2.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
  963. "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
  964. "state\n"
  965. "2001:db8:1::1,01:01:01:01:01:01:01:01:01:01:01:01:01,"
  966. "200,200,8,100,0,7,0,1,1,,,1\n"
  967. "2001:db8:1::2,02:02:02:02:02:02:02:02:02:02:02:02:02,"
  968. "200,200,8,100,0,7,0,1,1,,,1\n");
  969. LeaseFileIO io1(getLeaseFilePath("leasefile6_0.csv.1"));
  970. io1.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
  971. "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
  972. "state\n"
  973. "2001:db8:1::3,03:03:03:03:03:03:03:03:03:03:03:03:03,"
  974. "200,200,8,100,0,7,0,1,1,,,1\n"
  975. "2001:db8:1::2,02:02:02:02:02:02:02:02:02:02:02:02:02,"
  976. "300,800,8,100,0,7,0,1,1,,,1\n"
  977. "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
  978. "200,200,8,100,0,7,0,1,1,,,1\n");
  979. LeaseFileIO io(getLeaseFilePath("leasefile6_0.csv"));
  980. io.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
  981. "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
  982. "state\n"
  983. "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
  984. "400,1000,8,100,0,7,0,1,1,,,1\n"
  985. "2001:db8:1::5,05:05:05:05:05:05:05:05:05:05:05:05:05,"
  986. "200,200,8,100,0,7,0,1,1,,,1\n");
  987. startBackend(V6);
  988. // This lease only exists in the first file and the cltt should be 0.
  989. Lease6Ptr lease = lmptr_->getLease6(Lease::TYPE_NA,
  990. IOAddress("2001:db8:1::1"));
  991. ASSERT_TRUE(lease);
  992. EXPECT_EQ(0, lease->cltt_);
  993. // This lease exists in the first and second file and the cltt should
  994. // be calculated using the expiration time and the valid lifetime
  995. // from the second file.
  996. lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::2"));
  997. ASSERT_TRUE(lease);
  998. EXPECT_EQ(500, lease->cltt_);
  999. // This lease only exists in the second file and the cltt should be 0.
  1000. lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::3"));
  1001. ASSERT_TRUE(lease);
  1002. EXPECT_EQ(0, lease->cltt_);
  1003. // This lease exists in the second and third file and the cltt should
  1004. // be calculated using the expiration time and the valid lifetime
  1005. // from the third file.
  1006. lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::4"));
  1007. ASSERT_TRUE(lease);
  1008. EXPECT_EQ(600, lease->cltt_);
  1009. // This lease only exists in the third file and the cltt should be 0.
  1010. lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::5"));
  1011. ASSERT_TRUE(lease);
  1012. EXPECT_EQ(0, lease->cltt_);
  1013. }
  1014. // This test checks that the backend reads DHCPv6 lease data from the
  1015. // leasefile without the postfix and the file with a .1 postfix when
  1016. // the file with the .2 postfix is missing.
  1017. TEST_F(MemfileLeaseMgrTest, load6MultipleNoSecondFile) {
  1018. LeaseFileIO io1(getLeaseFilePath("leasefile6_0.csv.1"));
  1019. io1.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
  1020. "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
  1021. "state\n"
  1022. "2001:db8:1::3,03:03:03:03:03:03:03:03:03:03:03:03:03,"
  1023. "200,200,8,100,0,7,0,1,1,,,1\n"
  1024. "2001:db8:1::2,02:02:02:02:02:02:02:02:02:02:02:02:02,"
  1025. "300,800,8,100,0,7,0,1,1,,,1\n"
  1026. "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
  1027. "200,200,8,100,0,7,0,1,1,,,1\n");
  1028. LeaseFileIO io(getLeaseFilePath("leasefile6_0.csv"));
  1029. io.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
  1030. "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
  1031. "state\n"
  1032. "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
  1033. "400,1000,8,100,0,7,0,1,1,,,1\n"
  1034. "2001:db8:1::5,05:05:05:05:05:05:05:05:05:05:05:05:05,"
  1035. "200,200,8,100,0,7,0,1,1,,,1\n");
  1036. startBackend(V6);
  1037. // Check that leases from the leasefile6_0 and leasefile6_0.1 have
  1038. // been loaded.
  1039. Lease6Ptr lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::2"));
  1040. ASSERT_TRUE(lease);
  1041. EXPECT_EQ(500, lease->cltt_);
  1042. lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::3"));
  1043. ASSERT_TRUE(lease);
  1044. EXPECT_EQ(0, lease->cltt_);
  1045. lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::4"));
  1046. ASSERT_TRUE(lease);
  1047. EXPECT_EQ(600, lease->cltt_);
  1048. lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::5"));
  1049. ASSERT_TRUE(lease);
  1050. EXPECT_EQ(0, lease->cltt_);
  1051. // Make sure that a lease which is not in those files is not loaded.
  1052. EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1")));
  1053. }
  1054. // This test checks that the backend reads DHCPv6 lease data from the
  1055. // leasefile without the postfix and the file with a .2 postfix when
  1056. // the file with the .1 postfix is missing.
  1057. TEST_F(MemfileLeaseMgrTest, load6MultipleNoFirstFile) {
  1058. LeaseFileIO io2(getLeaseFilePath("leasefile6_0.csv.2"));
  1059. io2.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
  1060. "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
  1061. "state\n"
  1062. "2001:db8:1::1,01:01:01:01:01:01:01:01:01:01:01:01:01,"
  1063. "200,200,8,100,0,7,0,1,1,,,1\n"
  1064. "2001:db8:1::2,02:02:02:02:02:02:02:02:02:02:02:02:02,"
  1065. "200,200,8,100,0,7,0,1,1,,,1\n");
  1066. LeaseFileIO io(getLeaseFilePath("leasefile6_0.csv"));
  1067. io.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
  1068. "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
  1069. "state\n"
  1070. "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
  1071. "400,1000,8,100,0,7,0,1,1,,,1\n"
  1072. "2001:db8:1::5,05:05:05:05:05:05:05:05:05:05:05:05:05,"
  1073. "200,200,8,100,0,7,0,1,1,,,1\n");
  1074. startBackend(V6);
  1075. // Verify that leases which belong to the leasefile6_0.csv and
  1076. // leasefile6_0.2 are loaded.
  1077. Lease6Ptr lease = lmptr_->getLease6(Lease::TYPE_NA,
  1078. IOAddress("2001:db8:1::1"));
  1079. ASSERT_TRUE(lease);
  1080. EXPECT_EQ(0, lease->cltt_);
  1081. lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::2"));
  1082. ASSERT_TRUE(lease);
  1083. EXPECT_EQ(0, lease->cltt_);
  1084. lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::4"));
  1085. ASSERT_TRUE(lease);
  1086. EXPECT_EQ(600, lease->cltt_);
  1087. lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::5"));
  1088. ASSERT_TRUE(lease);
  1089. EXPECT_EQ(0, lease->cltt_);
  1090. // A lease which doesn't belong to these files should not be loaded.
  1091. EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::3")));
  1092. }
  1093. // This test checks that the lease database backend loads the file with
  1094. // the .completed postfix instead of files with postfixes .1 and .2 if
  1095. // the file with .completed postfix exists.
  1096. TEST_F(MemfileLeaseMgrTest, load6CompletedFile) {
  1097. LeaseFileIO io2(getLeaseFilePath("leasefile6_0.csv.2"));
  1098. io2.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
  1099. "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
  1100. "state\n"
  1101. "2001:db8:1::1,01:01:01:01:01:01:01:01:01:01:01:01:01,"
  1102. "200,200,8,100,0,7,0,1,1,,,1\n"
  1103. "2001:db8:1::2,02:02:02:02:02:02:02:02:02:02:02:02:02,"
  1104. "200,200,8,100,0,7,0,1,1,,,1\n");
  1105. LeaseFileIO io1(getLeaseFilePath("leasefile6_0.csv.1"));
  1106. io1.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
  1107. "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
  1108. "state\n"
  1109. "2001:db8:1::3,03:03:03:03:03:03:03:03:03:03:03:03:03,"
  1110. "200,200,8,100,0,7,0,1,1,,,1\n"
  1111. "2001:db8:1::2,02:02:02:02:02:02:02:02:02:02:02:02:02,"
  1112. "300,800,8,100,0,7,0,1,1,,,1\n"
  1113. "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
  1114. "200,200,8,100,0,7,0,1,1,,,1\n");
  1115. LeaseFileIO io(getLeaseFilePath("leasefile6_0.csv"));
  1116. io.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
  1117. "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
  1118. "state\n"
  1119. "2001:db8:1::4,04:04:04:04:04:04:04:04:04:04:04:04:04,"
  1120. "400,1000,8,100,0,7,0,1,1,,,1\n"
  1121. "2001:db8:1::5,05:05:05:05:05:05:05:05:05:05:05:05:05,"
  1122. "200,200,8,100,0,7,0,1,1,,,1\n");
  1123. LeaseFileIO ioc(getLeaseFilePath("leasefile6_0.csv.completed"));
  1124. ioc.writeFile("address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,"
  1125. "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,"
  1126. "state\n"
  1127. "2001:db8:1::125,ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff,"
  1128. "400,1000,8,100,0,7,0,1,1,,,1\n");
  1129. startBackend(V6);
  1130. // We expect that this file only holds leases that belong to the
  1131. // lease file or to the file with .completed postfix.
  1132. Lease6Ptr lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::4"));
  1133. ASSERT_TRUE(lease);
  1134. EXPECT_EQ(600, lease->cltt_);
  1135. lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::5"));
  1136. ASSERT_TRUE(lease);
  1137. EXPECT_EQ(0, lease->cltt_);
  1138. lease = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::125"));
  1139. ASSERT_TRUE(lease);
  1140. EXPECT_EQ(600, lease->cltt_);
  1141. // Leases from the .1 and .2 files should not be loaded.
  1142. EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1")));
  1143. EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::2")));
  1144. EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::3")));
  1145. }
  1146. // This test checks that backend constructor refuses to load leases from the
  1147. // lease files if the LFC is in progress.
  1148. TEST_F(MemfileLeaseMgrTest, load6LFCInProgress) {
  1149. // Create the backend configuration.
  1150. DatabaseConnection::ParameterMap pmap;
  1151. pmap["type"] = "memfile";
  1152. pmap["universe"] = "6";
  1153. pmap["name"] = getLeaseFilePath("leasefile6_0.csv");
  1154. pmap["lfc-interval"] = "1";
  1155. // Create a pid file holding the PID of the current process. Choosing the
  1156. // pid of the current process guarantees that when the backend starts up
  1157. // the process is alive.
  1158. PIDFile pid_file(Memfile_LeaseMgr::appendSuffix(pmap["name"], Memfile_LeaseMgr::FILE_PID));
  1159. pid_file.write();
  1160. // There is a pid file and the process which pid is in the file is
  1161. // running, so the backend should refuse to start.
  1162. boost::scoped_ptr<NakedMemfileLeaseMgr> lease_mgr;
  1163. ASSERT_THROW(lease_mgr.reset(new NakedMemfileLeaseMgr(pmap)),
  1164. DbOpenError);
  1165. // Remove the pid file, and retry. The bakckend should be created.
  1166. pid_file.deleteFile();
  1167. ASSERT_NO_THROW(lease_mgr.reset(new NakedMemfileLeaseMgr(pmap)));
  1168. }
  1169. // Verifies that LFC is automatically run during MemfileLeasemMgr construction
  1170. // when the lease file(s) being loaded need to be upgraded.
  1171. TEST_F(MemfileLeaseMgrTest, leaseUpgrade4) {
  1172. // Create header strings for each schema
  1173. std::string header_1_0 =
  1174. "address,hwaddr,client_id,valid_lifetime,expire,"
  1175. "subnet_id,fqdn_fwd,fqdn_rev,hostname\n";
  1176. std::string header_2_0 =
  1177. "address,hwaddr,client_id,valid_lifetime,expire,"
  1178. "subnet_id,fqdn_fwd,fqdn_rev,hostname,state\n";
  1179. // Create 1.0 Schema current lease file with two entries for
  1180. // the same lease
  1181. std::string current_file_contents = header_1_0 +
  1182. "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,\n"
  1183. "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,\n";
  1184. LeaseFileIO current_file(getLeaseFilePath("leasefile4_0.csv"));
  1185. current_file.writeFile(current_file_contents);
  1186. // Create 1.0 Schema previous lease file, with two entries for
  1187. // a another lease
  1188. std::string previous_file_contents = header_1_0 +
  1189. "192.0.2.3,03:03:03:03:03:03,,200,200,8,1,1,\n"
  1190. "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,\n";
  1191. LeaseFileIO previous_file(getLeaseFilePath("leasefile4_0.csv.2"));
  1192. previous_file.writeFile(previous_file_contents);
  1193. // Create the backend.
  1194. DatabaseConnection::ParameterMap pmap;
  1195. pmap["type"] = "memfile";
  1196. pmap["universe"] = "4";
  1197. pmap["name"] = getLeaseFilePath("leasefile4_0.csv");
  1198. pmap["lfc-interval"] = "0";
  1199. boost::scoped_ptr<NakedMemfileLeaseMgr> lease_mgr(new NakedMemfileLeaseMgr(pmap));
  1200. // Since lease files are loaded during lease manager
  1201. // constructor, LFC should get launched automatically.
  1202. // The new lease file should be 2.0 schema and have no entries
  1203. ASSERT_TRUE(current_file.exists());
  1204. EXPECT_EQ(header_2_0, current_file.readFile());
  1205. // Wait for the LFC process to complete and
  1206. // make sure it has returned an exit status of 0.
  1207. ASSERT_TRUE(waitForProcess(*lease_mgr, 2));
  1208. ASSERT_EQ(0, lease_mgr->getLFCExitStatus())
  1209. << "Executing the LFC process failed: make sure that"
  1210. " the kea-lfc program has been compiled.";
  1211. // The LFC should have created a 2.0 schema completion file with the
  1212. // one entry for each lease and moved it to leasefile4_0.csv.2
  1213. LeaseFileIO input_file(getLeaseFilePath("leasefile4_0.csv.2"), false);
  1214. ASSERT_TRUE(input_file.exists());
  1215. // Verify cleaned, converted contents
  1216. std::string result_file_contents = header_2_0 +
  1217. "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,,0\n"
  1218. "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,0\n";
  1219. EXPECT_EQ(result_file_contents, input_file.readFile());
  1220. }
  1221. TEST_F(MemfileLeaseMgrTest, leaseUpgrade6) {
  1222. // Create header strings for all three schemas
  1223. std::string header_1_0 =
  1224. "address,duid,valid_lifetime,expire,subnet_id,"
  1225. "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
  1226. "fqdn_rev,hostname\n";
  1227. std::string header_2_0 =
  1228. "address,duid,valid_lifetime,expire,subnet_id,"
  1229. "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
  1230. "fqdn_rev,hostname,hwaddr\n";
  1231. std::string header_3_0 =
  1232. "address,duid,valid_lifetime,expire,subnet_id,"
  1233. "pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,"
  1234. "fqdn_rev,hostname,hwaddr,state\n";
  1235. // The current lease file is schema 1.0 and has two entries for
  1236. // the same lease
  1237. std::string current_file_contents = header_1_0 +
  1238. "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,200,"
  1239. "8,100,0,7,0,1,1,,\n"
  1240. "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
  1241. "8,100,0,7,0,1,1,,\n";
  1242. LeaseFileIO current_file(getLeaseFilePath("leasefile6_0.csv"));
  1243. current_file.writeFile(current_file_contents);
  1244. // The previous lease file is schema 2.0 and has two entries for
  1245. // a different lease
  1246. std::string previous_file_contents = header_2_0 +
  1247. "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,200,"
  1248. "8,100,0,7,0,1,1,,11:22:33:44:55\n"
  1249. "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
  1250. "8,100,0,7,0,1,1,,11:22:33:44:55\n";
  1251. LeaseFileIO previous_file(getLeaseFilePath("leasefile6_0.csv.2"));
  1252. previous_file.writeFile(previous_file_contents);
  1253. // Create the backend.
  1254. DatabaseConnection::ParameterMap pmap;
  1255. pmap["type"] = "memfile";
  1256. pmap["universe"] = "6";
  1257. pmap["name"] = getLeaseFilePath("leasefile6_0.csv");
  1258. pmap["lfc-interval"] = "0";
  1259. boost::scoped_ptr<NakedMemfileLeaseMgr> lease_mgr(new NakedMemfileLeaseMgr(pmap));
  1260. // Since lease files are loaded during lease manager
  1261. // constructor, LFC should get launched automatically.
  1262. // The new lease file should been 3.0 and contain no leases.
  1263. ASSERT_TRUE(current_file.exists());
  1264. EXPECT_EQ(header_3_0, current_file.readFile());
  1265. // Wait for the LFC process to complete and
  1266. // make sure it has returned an exit status of 0.
  1267. ASSERT_TRUE(waitForProcess(*lease_mgr, 2));
  1268. ASSERT_EQ(0, lease_mgr->getLFCExitStatus())
  1269. << "Executing the LFC process failed: make sure that"
  1270. " the kea-lfc program has been compiled.";
  1271. // The LFC should have created a 3.0 schema cleaned file with one entry
  1272. // for each lease as leasefile6_0.csv.2
  1273. LeaseFileIO input_file(getLeaseFilePath("leasefile6_0.csv.2"), false);
  1274. ASSERT_TRUE(input_file.exists());
  1275. // Verify cleaned, converted contents
  1276. std::string result_file_contents = header_3_0 +
  1277. "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
  1278. "8,100,0,7,0,1,1,,,0\n"
  1279. "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
  1280. "8,100,0,7,0,1,1,,11:22:33:44:55,0\n";
  1281. EXPECT_EQ(result_file_contents, input_file.readFile());
  1282. }
  1283. }; // end of anonymous namespace