alloc_engine4_unittest.cc 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428
  1. // Copyright (C) 2015 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 <dhcpsrv/tests/alloc_engine_utils.h>
  16. #include <dhcpsrv/tests/test_utils.h>
  17. using namespace std;
  18. using namespace isc::hooks;
  19. using namespace isc::asiolink;
  20. namespace isc {
  21. namespace dhcp {
  22. namespace test {
  23. // This test checks if the v4 Allocation Engine can be instantiated, parses
  24. // parameters string and allocators are created.
  25. TEST_F(AllocEngine4Test, constructor) {
  26. boost::scoped_ptr<AllocEngine> x;
  27. // Hashed and random allocators are not supported yet
  28. ASSERT_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_HASHED, 5, false)),
  29. NotImplemented);
  30. ASSERT_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_RANDOM, 5, false)),
  31. NotImplemented);
  32. // Create V4 (ipv6=false) Allocation Engine that will try at most
  33. // 100 attempts to pick up a lease
  34. ASSERT_NO_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100,
  35. false)));
  36. // There should be V4 allocator
  37. ASSERT_TRUE(x->getAllocator(Lease::TYPE_V4));
  38. // Check that allocators for V6 stuff are not created
  39. EXPECT_THROW(x->getAllocator(Lease::TYPE_NA), BadValue);
  40. EXPECT_THROW(x->getAllocator(Lease::TYPE_TA), BadValue);
  41. EXPECT_THROW(x->getAllocator(Lease::TYPE_PD), BadValue);
  42. }
  43. // This test checks if the simple IPv4 allocation can succeed
  44. TEST_F(AllocEngine4Test, simpleAlloc4) {
  45. boost::scoped_ptr<AllocEngine> engine;
  46. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  47. 100, false)));
  48. ASSERT_TRUE(engine);
  49. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
  50. false, true, "somehost.example.com.", false);
  51. Lease4Ptr lease = engine->allocateLease4(ctx);
  52. // The new lease has been allocated, so the old lease should not exist.
  53. EXPECT_FALSE(ctx.old_lease_);
  54. // Check that we got a lease
  55. ASSERT_TRUE(lease);
  56. // Do all checks on the lease
  57. checkLease4(lease);
  58. // Check that the lease is indeed in LeaseMgr
  59. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  60. ASSERT_TRUE(from_mgr);
  61. // Now check that the lease in LeaseMgr has the same parameters
  62. detailCompareLease(lease, from_mgr);
  63. }
  64. // This test checks if the fake allocation (for DISCOVER) can succeed
  65. TEST_F(AllocEngine4Test, fakeAlloc4) {
  66. boost::scoped_ptr<AllocEngine> engine;
  67. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  68. 100, false)));
  69. ASSERT_TRUE(engine);
  70. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  71. IOAddress("0.0.0.0"), false, true,
  72. "host.example.com.", true);
  73. Lease4Ptr lease = engine->allocateLease4(ctx);
  74. // The new lease has been allocated, so the old lease should not exist.
  75. EXPECT_FALSE(ctx.old_lease_);
  76. // Check that we got a lease
  77. ASSERT_TRUE(lease);
  78. // Do all checks on the lease
  79. checkLease4(lease);
  80. // Check that the lease is NOT in LeaseMgr
  81. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  82. ASSERT_FALSE(from_mgr);
  83. }
  84. // This test checks if the allocation with a hint that is valid (in range,
  85. // in pool and free) can succeed
  86. TEST_F(AllocEngine4Test, allocWithValidHint4) {
  87. boost::scoped_ptr<AllocEngine> engine;
  88. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  89. 100, false)));
  90. ASSERT_TRUE(engine);
  91. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  92. IOAddress("192.0.2.105"), true, true,
  93. "host.example.com.", false);
  94. Lease4Ptr lease = engine->allocateLease4(ctx);
  95. // Check that we got a lease
  96. ASSERT_TRUE(lease);
  97. // We have allocated the new lease, so the old lease should not exist.
  98. EXPECT_FALSE(ctx.old_lease_);
  99. // We should get what we asked for
  100. EXPECT_EQ(lease->addr_.toText(), "192.0.2.105");
  101. // Do all checks on the lease
  102. checkLease4(lease);
  103. // Check that the lease is indeed in LeaseMgr
  104. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  105. ASSERT_TRUE(from_mgr);
  106. // Now check that the lease in LeaseMgr has the same parameters
  107. detailCompareLease(lease, from_mgr);
  108. }
  109. // This test checks if the allocation with a hint that is in range,
  110. // in pool, but is currently used can succeed
  111. TEST_F(AllocEngine4Test, allocWithUsedHint4) {
  112. boost::scoped_ptr<AllocEngine> engine;
  113. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  114. 100, false)));
  115. ASSERT_TRUE(engine);
  116. // Let's create a lease and put it in the LeaseMgr
  117. uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
  118. HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER));
  119. uint8_t clientid2[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
  120. time_t now = time(NULL);
  121. Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2,
  122. clientid2, sizeof(clientid2), 1, 2, 3, now, subnet_->getID()));
  123. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(used));
  124. // Another client comes in and request an address that is in pool, but
  125. // unfortunately it is used already. The same address must not be allocated
  126. // twice.
  127. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  128. IOAddress("192.0.2.106"), false, false,
  129. "", true);
  130. Lease4Ptr lease = engine->allocateLease4(ctx);
  131. // New lease has been allocated, so the old lease should not exist.
  132. EXPECT_FALSE(ctx.old_lease_);
  133. // Check that we got a lease
  134. ASSERT_TRUE(lease);
  135. // Allocated address must be different
  136. EXPECT_NE(used->addr_, lease->addr_);
  137. // We should NOT get what we asked for, because it is used already
  138. EXPECT_NE("192.0.2.106", lease->addr_.toText());
  139. // Do all checks on the lease
  140. checkLease4(lease);
  141. // The lease should not be in the LeaseMgr because it was a failed allocation.
  142. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  143. ASSERT_FALSE(from_mgr);
  144. }
  145. // This test checks if an allocation with a hint that is out of the blue
  146. // can succeed. The invalid hint should be ignored completely.
  147. TEST_F(AllocEngine4Test, allocBogusHint4) {
  148. boost::scoped_ptr<AllocEngine> engine;
  149. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  150. 100, false)));
  151. ASSERT_TRUE(engine);
  152. // Client would like to get a 10.1.1.1 lease, which does not belong to any
  153. // supported lease. Allocation engine should ignore it and carry on
  154. // with the normal allocation
  155. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  156. IOAddress("10.1.1.1"), false, false,
  157. "", true);
  158. Lease4Ptr lease = engine->allocateLease4(ctx);
  159. // Check that we got a lease
  160. ASSERT_TRUE(lease);
  161. // We have allocated a new lease, so the old lease should not exist.
  162. EXPECT_FALSE(ctx.old_lease_);
  163. // We should NOT get what we asked for, because it is used already
  164. EXPECT_NE("10.1.1.1", lease->addr_.toText());
  165. // Do all checks on the lease
  166. checkLease4(lease);
  167. // Check that the lease is not in the LeaseMgr as it is a fake allocation.
  168. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  169. EXPECT_FALSE(from_mgr);
  170. }
  171. // This test checks that NULL values are handled properly
  172. TEST_F(AllocEngine4Test, allocateLease4Nulls) {
  173. boost::scoped_ptr<AllocEngine> engine;
  174. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  175. 100, false)));
  176. ASSERT_TRUE(engine);
  177. // Allocations without subnet are not allowed
  178. AllocEngine::ClientContext4 ctx1(Subnet4Ptr(), clientid_, hwaddr_,
  179. IOAddress("0.0.0.0"), false, false,
  180. "", false);
  181. Lease4Ptr lease = engine->allocateLease4(ctx1);
  182. EXPECT_FALSE(lease);
  183. // Allocations without HW address are not allowed
  184. AllocEngine::ClientContext4 ctx2(subnet_, clientid_, HWAddrPtr(),
  185. IOAddress("0.0.0.0"), false, false,
  186. "", false);
  187. lease = engine->allocateLease4(ctx2);
  188. EXPECT_FALSE(lease);
  189. EXPECT_FALSE(ctx2.old_lease_);
  190. // Allocations without client-id are allowed
  191. clientid_.reset();
  192. AllocEngine::ClientContext4 ctx3(subnet_, ClientIdPtr(), hwaddr_,
  193. IOAddress("0.0.0.0"), false, false,
  194. "", false);
  195. lease = engine->allocateLease4(ctx3);
  196. // Check that we got a lease
  197. ASSERT_TRUE(lease);
  198. // New lease has been allocated, so the old lease should not exist.
  199. EXPECT_FALSE(ctx3.old_lease_);
  200. // Do all checks on the lease
  201. checkLease4(lease);
  202. // Check that the lease is indeed in LeaseMgr
  203. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  204. ASSERT_TRUE(from_mgr);
  205. // Now check that the lease in LeaseMgr has the same parameters
  206. detailCompareLease(lease, from_mgr);
  207. }
  208. // This test verifies that the allocator picks addresses that belong to the
  209. // pool
  210. TEST_F(AllocEngine4Test, IterativeAllocator) {
  211. boost::scoped_ptr<NakedAllocEngine::Allocator>
  212. alloc(new NakedAllocEngine::IterativeAllocator(Lease::TYPE_V4));
  213. for (int i = 0; i < 1000; ++i) {
  214. IOAddress candidate = alloc->pickAddress(subnet_, clientid_,
  215. IOAddress("0.0.0.0"));
  216. EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate));
  217. }
  218. }
  219. // This test verifies that the iterative allocator really walks over all addresses
  220. // in all pools in specified subnet. It also must not pick the same address twice
  221. // unless it runs out of pool space and must start over.
  222. TEST_F(AllocEngine4Test, IterativeAllocator_manyPools4) {
  223. NakedAllocEngine::IterativeAllocator alloc(Lease::TYPE_V4);
  224. // Let's start from 2, as there is 2001:db8:1::10 - 2001:db8:1::20 pool already.
  225. for (int i = 2; i < 10; ++i) {
  226. stringstream min, max;
  227. min << "192.0.2." << i * 10 + 1;
  228. max << "192.0.2." << i * 10 + 9;
  229. Pool4Ptr pool(new Pool4(IOAddress(min.str()),
  230. IOAddress(max.str())));
  231. // cout << "Adding pool: " << min.str() << "-" << max.str() << endl;
  232. subnet_->addPool(pool);
  233. }
  234. int total = 10 + 8 * 9; // first pool (.100 - .109) has 10 addresses in it,
  235. // there are 8 extra pools with 9 addresses in each.
  236. // Let's keep picked addresses here and check their uniqueness.
  237. std::set<IOAddress> generated_addrs;
  238. int cnt = 0;
  239. while (++cnt) {
  240. IOAddress candidate = alloc.pickAddress(subnet_, clientid_, IOAddress("0.0.0.0"));
  241. EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate));
  242. // One way to easily verify that the iterative allocator really works is
  243. // to uncomment the following line and observe its output that it
  244. // covers all defined subnets.
  245. // cout << candidate.toText() << endl;
  246. if (generated_addrs.find(candidate) == generated_addrs.end()) {
  247. // We haven't had this
  248. generated_addrs.insert(candidate);
  249. } else {
  250. // We have seen this address before. That should mean that we
  251. // iterated over all addresses.
  252. if (generated_addrs.size() == total) {
  253. // We have exactly the number of address in all pools
  254. break;
  255. }
  256. ADD_FAILURE() << "Too many or not enough unique addresses generated.";
  257. break;
  258. }
  259. if ( cnt>total ) {
  260. ADD_FAILURE() << "Too many unique addresses generated.";
  261. break;
  262. }
  263. }
  264. }
  265. // This test checks if really small pools are working
  266. TEST_F(AllocEngine4Test, smallPool4) {
  267. boost::scoped_ptr<AllocEngine> engine;
  268. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  269. 100, false)));
  270. ASSERT_TRUE(engine);
  271. IOAddress addr("192.0.2.17");
  272. CfgMgr& cfg_mgr = CfgMgr::instance();
  273. // Get rid of the default subnet configuration.
  274. cfg_mgr.clear();
  275. // Create configuration similar to other tests, but with a single address pool
  276. subnet_ = Subnet4Ptr(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3));
  277. pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address
  278. subnet_->addPool(pool_);
  279. cfg_mgr.getStagingCfg()->getCfgSubnets4()->add(subnet_);
  280. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  281. IOAddress("0.0.0.0"), false, false,
  282. "host.example.com.", false);
  283. Lease4Ptr lease = engine->allocateLease4(ctx);
  284. // Check that we got that single lease
  285. ASSERT_TRUE(lease);
  286. // We have allocated new lease, so the old lease should not exist.
  287. EXPECT_FALSE(ctx.old_lease_);
  288. EXPECT_EQ("192.0.2.17", lease->addr_.toText());
  289. // Do all checks on the lease
  290. checkLease4(lease);
  291. // Check that the lease is indeed in LeaseMgr
  292. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  293. ASSERT_TRUE(from_mgr);
  294. // Now check that the lease in LeaseMgr has the same parameters
  295. detailCompareLease(lease, from_mgr);
  296. }
  297. // This test checks if all addresses in a pool are currently used, the attempt
  298. // to find out a new lease fails.
  299. TEST_F(AllocEngine4Test, outOfAddresses4) {
  300. boost::scoped_ptr<AllocEngine> engine;
  301. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  302. 100, false)));
  303. ASSERT_TRUE(engine);
  304. IOAddress addr("192.0.2.17");
  305. CfgMgr& cfg_mgr = CfgMgr::instance();
  306. // Get rid of the default test configuration.
  307. cfg_mgr.clear();
  308. // Create configuration similar to other tests, but with a single address pool
  309. subnet_ = Subnet4Ptr(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3));
  310. pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address
  311. subnet_->addPool(pool_);
  312. cfg_mgr.getStagingCfg()->getCfgSubnets4()->add(subnet_);
  313. // Just a different hw/client-id for the second client
  314. uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
  315. HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER));
  316. uint8_t clientid2[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
  317. time_t now = time(NULL);
  318. Lease4Ptr lease(new Lease4(addr, hwaddr2, clientid2,
  319. sizeof(clientid2), 501, 502, 503, now,
  320. subnet_->getID()));
  321. lease->cltt_ = time(NULL) - 10; // Allocated 10 seconds ago
  322. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
  323. // There is just a single address in the pool and allocated it to someone
  324. // else, so the allocation should fail
  325. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  326. IOAddress("0.0.0.0"), false, false,
  327. "host.example.com.", false);
  328. Lease4Ptr lease2 = engine->allocateLease4(ctx);
  329. EXPECT_FALSE(lease2);
  330. EXPECT_FALSE(ctx.old_lease_);
  331. }
  332. // This test checks if an expired lease can be reused in DISCOVER (fake allocation)
  333. TEST_F(AllocEngine4Test, discoverReuseExpiredLease4) {
  334. boost::scoped_ptr<AllocEngine> engine;
  335. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  336. 100, false)));
  337. ASSERT_TRUE(engine);
  338. IOAddress addr("192.0.2.15");
  339. CfgMgr& cfg_mgr = CfgMgr::instance();
  340. // Get rid of the default test configuration.
  341. cfg_mgr.clear();
  342. // Create configuration similar to other tests, but with a single address pool
  343. subnet_ = Subnet4Ptr(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3));
  344. pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address
  345. subnet_->addPool(pool_);
  346. cfg_mgr.getStagingCfg()->getCfgSubnets4()->add(subnet_);
  347. // Just a different hw/client-id for the second client
  348. uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
  349. HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER));
  350. uint8_t clientid2[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
  351. time_t now = time(NULL) - 500; // Allocated 500 seconds ago
  352. Lease4Ptr lease(new Lease4(addr, hwaddr2, clientid2, sizeof(clientid2),
  353. 495, 100, 200, now, subnet_->getID()));
  354. // Copy the lease, so as it can be compared with the old lease returned
  355. // by the allocation engine.
  356. Lease4 original_lease(*lease);
  357. // Lease was assigned 500 seconds ago, but its valid lifetime is 495, so it
  358. // is expired already
  359. ASSERT_TRUE(lease->expired());
  360. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
  361. // CASE 1: Asking for any address
  362. AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
  363. IOAddress("0.0.0.0"), false, false,
  364. "", true);
  365. lease = engine->allocateLease4(ctx1);
  366. // Check that we got that single lease
  367. ASSERT_TRUE(lease);
  368. EXPECT_EQ(addr, lease->addr_);
  369. // We are reusing expired lease, the old (expired) instance should be
  370. // returned. The returned instance should be the same as the original
  371. // lease.
  372. ASSERT_TRUE(ctx1.old_lease_);
  373. EXPECT_TRUE(original_lease == *ctx1.old_lease_);
  374. // Do all checks on the lease (if subnet-id, preferred/valid times are ok etc.)
  375. checkLease4(lease);
  376. // CASE 2: Asking specifically for this address
  377. AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
  378. IOAddress(addr), false, false,
  379. "", true);
  380. lease = engine->allocateLease4(ctx2);
  381. // Check that we got that single lease
  382. ASSERT_TRUE(lease);
  383. EXPECT_EQ(addr, lease->addr_);
  384. // We are updating expired lease. The copy of the old lease should be
  385. // returned and it should be equal to the original lease.
  386. ASSERT_TRUE(ctx2.old_lease_);
  387. EXPECT_TRUE(*ctx2.old_lease_ == original_lease);
  388. }
  389. // This test checks if an expired lease can be reused in REQUEST (actual allocation)
  390. TEST_F(AllocEngine4Test, requestReuseExpiredLease4) {
  391. boost::scoped_ptr<AllocEngine> engine;
  392. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  393. 100, false)));
  394. ASSERT_TRUE(engine);
  395. IOAddress addr("192.0.2.105");
  396. // Just a different hw/client-id for the second client
  397. uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
  398. HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER));
  399. uint8_t clientid2[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
  400. time_t now = time(NULL) - 500; // Allocated 500 seconds ago
  401. Lease4Ptr lease(new Lease4(addr, hwaddr2, clientid2, sizeof(clientid2),
  402. sizeof(hwaddr2), 495, 100, 200, now,
  403. subnet_->getID()));
  404. // Make a copy of the lease, so as we can comapre that with the old lease
  405. // instance returned by the allocation engine.
  406. Lease4 original_lease(*lease);
  407. // Lease was assigned 500 seconds ago, but its valid lifetime is 495, so it
  408. // is expired already
  409. ASSERT_TRUE(lease->expired());
  410. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
  411. // A client comes along, asking specifically for this address
  412. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  413. IOAddress(addr), false, false,
  414. "host.example.com.", false);
  415. lease = engine->allocateLease4(ctx);
  416. // Check that he got that single lease
  417. ASSERT_TRUE(lease);
  418. EXPECT_EQ(addr, lease->addr_);
  419. // Check that the lease is indeed updated in LeaseMgr
  420. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(addr);
  421. ASSERT_TRUE(from_mgr);
  422. // Now check that the lease in LeaseMgr has the same parameters
  423. detailCompareLease(lease, from_mgr);
  424. // The allocation engine should return a copy of the old lease. This
  425. // lease should be equal to the original lease.
  426. ASSERT_TRUE(ctx.old_lease_);
  427. EXPECT_TRUE(*ctx.old_lease_ == original_lease);
  428. }
  429. // This test checks that when the client requests the address which belongs
  430. // to another client, the allocation engine returns NULL (for the
  431. // DHCPREQUEST case) or a lease for the address which belongs to this
  432. // client (DHCPDISCOVER case).
  433. TEST_F(AllocEngine4Test, requestOtherClientLease) {
  434. // Create the first lease.
  435. Lease4Ptr lease(new Lease4(IOAddress("192.0.2.101"), hwaddr_, 0, 0,
  436. 100, 30, 60, time(NULL), subnet_->getID(),
  437. false, false, ""));
  438. // Create the second lease.
  439. Lease4Ptr lease2(new Lease4(IOAddress("192.0.2.102"), hwaddr2_, 0, 0,
  440. 100, 30, 60, time(NULL), subnet_->getID(),
  441. false, false, ""));
  442. // Add leases for both clients to the Lease Manager.
  443. LeaseMgrFactory::instance().addLease(lease);
  444. LeaseMgrFactory::instance().addLease(lease2);
  445. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  446. // First client requests the lease which belongs to the second client.
  447. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("192.0.2.102"),
  448. false, false, "", false);
  449. Lease4Ptr new_lease = engine.allocateLease4(ctx);
  450. // Allocation engine should return NULL.
  451. ASSERT_FALSE(new_lease);
  452. // Now simulate the DHCPDISCOVER case when the provided address is
  453. // treated as a hint. The engine should return a lease for a
  454. // different address than requested.
  455. ctx.fake_allocation_ = true;
  456. new_lease = engine.allocateLease4(ctx);
  457. ASSERT_TRUE(new_lease);
  458. EXPECT_EQ("192.0.2.101", new_lease->addr_.toText());
  459. }
  460. // This test checks the behavior of the allocation engine in the following
  461. // scenario:
  462. // - Client has no lease in the database.
  463. // - Client has a reservation.
  464. // - Client sends DHCPREQUEST without requested IP Address, nor ciaddr.
  465. // - Client is allocated a reserved address.
  466. //
  467. // Note that client must normally include a requested IP address or ciaddr
  468. // in its message. But, we still want to provision clients that don't do that.
  469. // The server simply picks reserved address or any other available one if there
  470. // is no reservation.
  471. TEST_F(AllocEngine4Test, reservedAddressNoHint) {
  472. // Create reservation for the client.
  473. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  474. Host::IDENT_HWADDR, subnet_->getID(),
  475. SubnetID(0), IOAddress("192.0.2.123")));
  476. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  477. CfgMgr::instance().commit();
  478. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  479. // Try to allocate a lease without specifying a hint. This is actually
  480. // incorrect behavior of the client to not send an address it wants to
  481. // obtain but the server should handle this gracefully.
  482. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  483. IOAddress("0.0.0.0"), false, false,
  484. "", false);
  485. AllocEngine::findReservation(ctx);
  486. Lease4Ptr lease = engine.allocateLease4(ctx);
  487. ASSERT_TRUE(lease);
  488. EXPECT_EQ("192.0.2.123", lease->addr_.toText());
  489. // Make sure that the lease has been committed to the lease database.
  490. // And that the committed lease is equal to the one returned.
  491. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  492. ASSERT_TRUE(from_mgr);
  493. detailCompareLease(lease, from_mgr);
  494. // Initially, there was no lease for this client, so the returned old
  495. // lease should be NULL.
  496. EXPECT_FALSE(ctx.old_lease_);
  497. }
  498. // This test checks behavior of the allocation engine in the following scenario:
  499. // - Client has no lease in the database.
  500. // - Client has a reservation.
  501. // - Client sends DHCPDISCOVER without requested IP Address.
  502. // - Server returns DHCPOFFER with the reserved address.
  503. TEST_F(AllocEngine4Test,reservedAddressNoHintFakeAllocation) {
  504. // Create reservation for the client.
  505. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  506. Host::IDENT_HWADDR, subnet_->getID(),
  507. SubnetID(0), IOAddress("192.0.2.123")));
  508. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  509. CfgMgr::instance().commit();
  510. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  511. // Query allocation engine for the lease to be assigned to this
  512. // client without specifying the address to be assigned.
  513. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  514. IOAddress("0.0.0.0"), false, false,
  515. "", true);
  516. AllocEngine::findReservation(ctx);
  517. Lease4Ptr lease = engine.allocateLease4(ctx);
  518. ASSERT_TRUE(lease);
  519. // The allocation engine should return a reserved address.
  520. EXPECT_EQ("192.0.2.123", lease->addr_.toText());
  521. // This is a "fake" allocation so the returned lease should not be committed
  522. // to the lease database.
  523. EXPECT_FALSE(LeaseMgrFactory::instance().getLease4(lease->addr_));
  524. // Client had no lease in the database, so the old lease returned should
  525. // be NULL.
  526. EXPECT_FALSE(ctx.old_lease_);
  527. }
  528. // This test checks the behavior of the allocation engine in the following
  529. // scenario:
  530. // - Client has no lease in the database.
  531. // - Client has a reservation.
  532. // - Client sends DHCPREQUEST with a requested IP address
  533. // - Server returns DHCPNAK when requested IP address is different than
  534. // the reserved address. Note that the allocation engine returns NULL
  535. // to indicate to the server that it should send DHCPNAK.
  536. // - Server allocates a reserved address to the client when the client requests
  537. // this address using requested IP address option.
  538. TEST_F(AllocEngine4Test, reservedAddressHint) {
  539. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  540. Host::IDENT_HWADDR, subnet_->getID(),
  541. SubnetID(0), IOAddress("192.0.2.123")));
  542. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  543. CfgMgr::instance().commit();
  544. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  545. AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
  546. IOAddress("192.0.2.234"), false, false,
  547. "", false);
  548. AllocEngine::findReservation(ctx1);
  549. Lease4Ptr lease = engine.allocateLease4(ctx1);
  550. // The client requested a different address than reserved, so
  551. // the allocation engine should return NULL lease. When the server
  552. // receives a NULL lease for the client, it will send a DHCPNAK.
  553. ASSERT_FALSE(lease);
  554. ASSERT_FALSE(ctx1.old_lease_);
  555. // Now, request a correct address. The client should obtain it.
  556. AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
  557. IOAddress("192.0.2.123"), false, false,
  558. "", false);
  559. AllocEngine::findReservation(ctx2);
  560. lease = engine.allocateLease4(ctx2);
  561. ASSERT_TRUE(lease);
  562. EXPECT_EQ("192.0.2.123", lease->addr_.toText());
  563. // Make sure that the lease has been committed to the lease database.
  564. // And that the committed lease is equal to the one returned.
  565. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  566. ASSERT_TRUE(from_mgr);
  567. detailCompareLease(lease, from_mgr);
  568. EXPECT_FALSE(ctx2.old_lease_);
  569. }
  570. // This test checks the behavior of the allocation engine in the following
  571. // scenario:
  572. // - Client has no lease in the database.
  573. // - Client has a reservation.
  574. // - Client sends DHCPDISCOVER with a requested IP address as a hint.
  575. // - Server offers a reserved address, even though it is different than the
  576. // requested address.
  577. TEST_F(AllocEngine4Test, reservedAddressHintFakeAllocation) {
  578. // Create a reservation for the client.
  579. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  580. Host::IDENT_HWADDR, subnet_->getID(),
  581. SubnetID(0), IOAddress("192.0.2.123")));
  582. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  583. CfgMgr::instance().commit();
  584. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  585. // Query the allocation engine for the lease to be assigned to the client
  586. // and specify a hint being a different address than the reserved one.
  587. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  588. IOAddress("192.0.2.234"), false, false,
  589. "", true);
  590. AllocEngine::findReservation(ctx);
  591. Lease4Ptr lease = engine.allocateLease4(ctx);
  592. ASSERT_TRUE(lease);
  593. // Allocation engine should return reserved address.
  594. EXPECT_EQ("192.0.2.123", lease->addr_.toText());
  595. // This is a "fake" allocation so the returned lease should not be committed
  596. // to the lease database.
  597. EXPECT_FALSE(LeaseMgrFactory::instance().getLease4(lease->addr_));
  598. EXPECT_FALSE(ctx.old_lease_);
  599. }
  600. // This test checks that the behavior of the allocation engine in the following
  601. // scenario:
  602. // - Client has a lease for the address from the dynamic pool in the database.
  603. // - Client has a reservation for a different address than the one for which
  604. // the client has a lease.
  605. // - Client sends DHCPREQUEST, asking for the reserved address (as it has been
  606. // offered to it when it sent DHCPDISCOVER).
  607. // - Server allocates a reserved address and removes the lease for the address
  608. // previously allocated to the client.
  609. TEST_F(AllocEngine4Test, reservedAddressExistingLease) {
  610. // Create the reservation for the client.
  611. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  612. Host::IDENT_HWADDR, subnet_->getID(),
  613. SubnetID(0), IOAddress("192.0.2.123")));
  614. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  615. CfgMgr::instance().commit();
  616. // Create a lease for the client with a different address than the reserved
  617. // one.
  618. Lease4Ptr lease(new Lease4(IOAddress("192.0.2.101"), hwaddr_, 0, 0,
  619. 100, 30, 60, time(NULL), subnet_->getID(),
  620. false, false, ""));
  621. LeaseMgrFactory::instance().addLease(lease);
  622. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  623. // Request allocation of the reserved address.
  624. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  625. IOAddress("192.0.2.123"), false, false,
  626. "", false);
  627. AllocEngine::findReservation(ctx);
  628. Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
  629. ASSERT_TRUE(allocated_lease);
  630. // The engine should have allocated the reserved address.
  631. EXPECT_EQ("192.0.2.123", allocated_lease->addr_.toText());
  632. // Make sure that the lease has been committed to the lease database.
  633. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(allocated_lease->addr_);
  634. ASSERT_TRUE(from_mgr);
  635. detailCompareLease(allocated_lease, from_mgr);
  636. // The previous lease should have been replaced by a new one. The previous
  637. // lease should be returned by the allocation engine to the caller.
  638. ASSERT_TRUE(ctx.old_lease_);
  639. EXPECT_EQ("192.0.2.101", ctx.old_lease_->addr_.toText());
  640. detailCompareLease(ctx.old_lease_, lease);
  641. }
  642. // This test checks that the behavior of the allocation engine in the following
  643. // scenario:
  644. // - Client A has a lease in the database.
  645. // - Client B has a reservation for the address in use by client A.
  646. // - Client B sends a DHCPREQUEST requesting the allocation of the reserved
  647. // lease (in use by client A).
  648. // - Server determines that the reserved address is in use by a different client
  649. // and returns DHCPNAK to client B.
  650. TEST_F(AllocEngine4Test, reservedAddressHijacked) {
  651. // Create host reservation for the client B.
  652. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  653. Host::IDENT_HWADDR, subnet_->getID(),
  654. SubnetID(0), IOAddress("192.0.2.123")));
  655. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  656. CfgMgr::instance().commit();
  657. // Allocate a lease for the client A for the same address as reserved
  658. // for the client B.
  659. Lease4Ptr lease(new Lease4(IOAddress("192.0.2.123"), hwaddr2_, 0, 0,
  660. 100, 30, 60, time(NULL), subnet_->getID(),
  661. false, false, ""));
  662. LeaseMgrFactory::instance().addLease(lease);
  663. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  664. // Try to allocate the reserved lease to client B.
  665. AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
  666. IOAddress("192.0.2.123"), false, false,
  667. "", false);
  668. AllocEngine::findReservation(ctx1);
  669. Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
  670. // The lease is allocated to someone else, so the allocation should not
  671. // succeed.
  672. ASSERT_FALSE(allocated_lease);
  673. EXPECT_FALSE(ctx1.old_lease_);
  674. // Make sure that the allocation engine didn't modify the lease of the
  675. // client A.
  676. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  677. ASSERT_TRUE(from_mgr);
  678. detailCompareLease(lease, from_mgr);
  679. // Try doing the same thing, but this time do not request any specific
  680. // address. It should have the same effect.
  681. AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
  682. IOAddress("0.0.0.0"), false, false,
  683. "", false);
  684. AllocEngine::findReservation(ctx2);
  685. allocated_lease = engine.allocateLease4(ctx2);
  686. ASSERT_FALSE(allocated_lease);
  687. EXPECT_FALSE(ctx2.old_lease_);
  688. from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  689. ASSERT_TRUE(from_mgr);
  690. detailCompareLease(lease, from_mgr);
  691. }
  692. // This test checks that the behavior of the allocation engine in the following
  693. // scenario:
  694. // - Client A has a lease in the database.
  695. // - Client B has a reservation for the address in use by client A.
  696. // - Client B sends a DHCPDISCOVER.
  697. // - Server determines that the reserved address is in use by a different client
  698. // so it offers an address from the dynamic pool.
  699. TEST_F(AllocEngine4Test, reservedAddressHijackedFakeAllocation) {
  700. // Create a reservation for the client B.
  701. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  702. Host::IDENT_HWADDR, subnet_->getID(),
  703. SubnetID(0), IOAddress("192.0.2.123")));
  704. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  705. CfgMgr::instance().commit();
  706. // Create a lease for the client A.
  707. Lease4Ptr lease(new Lease4(IOAddress("192.0.2.123"), hwaddr2_, 0, 0,
  708. 100, 30, 60, time(NULL), subnet_->getID(),
  709. false, false, ""));
  710. LeaseMgrFactory::instance().addLease(lease);
  711. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  712. // Query allocation engine for the lease to be allocated to the client B.
  713. // The allocation engine is not able to allocate the lease to the client
  714. // B, because the address is in use by client A.
  715. AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
  716. IOAddress("192.0.2.123"), false, false,
  717. "", true);
  718. AllocEngine::findReservation(ctx1);
  719. Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
  720. // The allocation engine should return a lease but for a different address
  721. // than requested because this address is in use.
  722. ASSERT_TRUE(allocated_lease);
  723. EXPECT_FALSE(ctx1.old_lease_);
  724. EXPECT_NE(allocated_lease->addr_.toText(), "192.0.2.123");
  725. EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, allocated_lease->addr_));
  726. // Do the same test. But, this time do not specify any address to be
  727. // allocated.
  728. AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
  729. IOAddress("0.0.0.0"), false, false,
  730. "", true);
  731. AllocEngine::findReservation(ctx2);
  732. allocated_lease = engine.allocateLease4(ctx2);
  733. ASSERT_TRUE(allocated_lease);
  734. EXPECT_NE(allocated_lease->addr_.toText(), "192.0.2.123");
  735. EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, allocated_lease->addr_));
  736. EXPECT_FALSE(ctx2.old_lease_);
  737. }
  738. // This test checks that the behavior of the allocation engine in the following
  739. // scenario:
  740. // - Client has a reservation.
  741. // - Client has a lease in the database for a different address than reserved.
  742. // - Client sends a DHCPREQUEST and asks for a different address than reserved,
  743. // and different than it has in a database.
  744. // - Server doesn't allocate the reserved address to the client because the
  745. // client asked for the different address.
  746. //
  747. // Note that in this case the client should get the DHCPNAK and should fall back
  748. // to the DHCPDISCOVER.
  749. TEST_F(AllocEngine4Test, reservedAddressExistingLeaseInvalidHint) {
  750. // Create a reservation for the client.
  751. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  752. Host::IDENT_HWADDR, subnet_->getID(),
  753. SubnetID(0), IOAddress("192.0.2.123")));
  754. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  755. CfgMgr::instance().commit();
  756. // Create a lease for the client for a different address than reserved.
  757. Lease4Ptr lease(new Lease4(IOAddress("192.0.2.101"), hwaddr_, 0, 0,
  758. 100, 30, 60, time(NULL), subnet_->getID(),
  759. false, false, ""));
  760. LeaseMgrFactory::instance().addLease(lease);
  761. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  762. // Try to allocate a lease and specify a different address than reserved
  763. // and different from the one that client is currently using.
  764. AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
  765. IOAddress("192.0.2.102"), false, false,
  766. "", false);
  767. AllocEngine::findReservation(ctx1);
  768. Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
  769. ASSERT_FALSE(allocated_lease);
  770. ASSERT_FALSE(ctx1.old_lease_);
  771. // Repeat the test, but this time ask for the address that the client
  772. // has allocated.
  773. AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
  774. IOAddress("192.0.2.101"), false, false,
  775. "", false);
  776. allocated_lease = engine.allocateLease4(ctx2);
  777. // The client has reservation so the server wants to allocate a
  778. // reserved address and doesn't want to renew the address that the
  779. // client is currently using. This is equivalent of the case when
  780. // the client tries to renew the lease but there is a new reservation
  781. // for this client. The server doesn't allow for the renewal and
  782. // responds with DHCPNAK to force the client to return to the
  783. // DHCP server discovery.
  784. EXPECT_FALSE(allocated_lease);
  785. EXPECT_FALSE(ctx2.old_lease_);
  786. }
  787. // This test checks that the behavior of the allocation engine in the following
  788. // scenario:
  789. // - Client has a lease in the database.
  790. // - Client has a reservation for a different address than the one for which it
  791. // has a lease.
  792. // - Client sends a DHCPDISCOVER and asks for a different address than reserved
  793. // and different from which it has a lease for.
  794. // - Server ignores the client's hint and offers a reserved address.
  795. TEST_F(AllocEngine4Test, reservedAddressExistingLeaseFakeAllocation) {
  796. // Create a reservation for the client.
  797. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  798. Host::IDENT_HWADDR, subnet_->getID(),
  799. SubnetID(0), IOAddress("192.0.2.123")));
  800. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  801. CfgMgr::instance().commit();
  802. // Create a lease for a different address than reserved.
  803. Lease4Ptr lease(new Lease4(IOAddress("192.0.2.101"), hwaddr_, 0, 0,
  804. 100, 30, 60, time(NULL), subnet_->getID(),
  805. false, false, ""));
  806. LeaseMgrFactory::instance().addLease(lease);
  807. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  808. // Try to allocate a lease and use a completely different address
  809. // as a hint.
  810. AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
  811. IOAddress("192.0.2.102"), false, false,
  812. "", true);
  813. AllocEngine::findReservation(ctx1);
  814. Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
  815. // Server should offer a lease for a reserved address.
  816. ASSERT_TRUE(allocated_lease);
  817. EXPECT_EQ("192.0.2.123", allocated_lease->addr_.toText());
  818. // The lease should not be allocated until the client sends a DHCPREQUEST.
  819. EXPECT_FALSE(LeaseMgrFactory::instance().getLease4(allocated_lease->addr_));
  820. // Old lease should contain the currently used lease.
  821. ASSERT_TRUE(ctx1.old_lease_);
  822. EXPECT_EQ("192.0.2.101", ctx1.old_lease_->addr_.toText());
  823. // Repeat the test but this time ask for the address for which the
  824. // client has a lease.
  825. AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
  826. IOAddress("192.0.2.101"), false, false,
  827. "", true);
  828. AllocEngine::findReservation(ctx2);
  829. allocated_lease = engine.allocateLease4(ctx2);
  830. // The server should offer the lease, but not for the address that
  831. // the client requested. The server should offer a reserved address.
  832. ASSERT_TRUE(allocated_lease);
  833. EXPECT_EQ("192.0.2.123", allocated_lease->addr_.toText());
  834. // Old lease should contain the currently used lease.
  835. ASSERT_TRUE(ctx2.old_lease_);
  836. EXPECT_EQ("192.0.2.101", ctx2.old_lease_->addr_.toText());
  837. }
  838. // This test checks that the behavior of the allocation engine in the following
  839. // scenario:
  840. // - Client has a reservation.
  841. // - Client has a lease for a different address than reserved.
  842. // - Client sends a DHCPREQUEST to allocate a lease.
  843. // - The server determines that the client has a reservation for the
  844. // different address than it is currently using and should assign
  845. // a reserved address and remove the previous lease.
  846. TEST_F(AllocEngine4Test, reservedAddressExistingLeaseNoHint) {
  847. // Create a reservation.
  848. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  849. Host::IDENT_HWADDR, subnet_->getID(),
  850. SubnetID(0), IOAddress("192.0.2.123")));
  851. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  852. CfgMgr::instance().commit();
  853. // Create a lease for a different address than reserved.
  854. Lease4Ptr lease(new Lease4(IOAddress("192.0.2.101"), hwaddr_, 0, 0,
  855. 100, 30, 60, time(NULL), subnet_->getID(),
  856. false, false, ""));
  857. LeaseMgrFactory::instance().addLease(lease);
  858. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  859. // Try to allocate a lease with providing no hint.
  860. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  861. IOAddress("0.0.0.0"), false, false,
  862. "", false);
  863. AllocEngine::findReservation(ctx);
  864. Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
  865. // The reserved address should be allocated.
  866. ASSERT_TRUE(allocated_lease);
  867. EXPECT_EQ("192.0.2.123", allocated_lease->addr_.toText());
  868. // The previous lease should be removed.
  869. EXPECT_FALSE(LeaseMgrFactory::instance().getLease4(lease->addr_));
  870. // Make sure that the allocated lease is committed in the lease database.
  871. Lease4Ptr from_mgr =
  872. LeaseMgrFactory::instance().getLease4(allocated_lease->addr_);
  873. ASSERT_TRUE(from_mgr);
  874. detailCompareLease(allocated_lease, from_mgr);
  875. // Old lease should be returned.
  876. ASSERT_TRUE(ctx.old_lease_);
  877. detailCompareLease(lease, ctx.old_lease_);
  878. }
  879. // This test checks that the behavior of the allocation engine in the following
  880. // scenario:
  881. // - Client has a reservation.
  882. // - Client has a lease for a different address than reserved.
  883. // - Client sends a DHCPDISCOVER with no hint.
  884. // - Server determines that there is a reservation for the client and that
  885. // the reserved address should be offered when the client sends a
  886. // DHCPDISCOVER.
  887. TEST_F(AllocEngine4Test, reservedAddressExistingLeaseNoHintFakeAllocation) {
  888. // Create a reservation.
  889. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  890. Host::IDENT_HWADDR, subnet_->getID(),
  891. SubnetID(0), IOAddress("192.0.2.123")));
  892. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  893. CfgMgr::instance().commit();
  894. // Create a lease for a different address than reserved.
  895. Lease4Ptr lease(new Lease4(IOAddress("192.0.2.101"), hwaddr_, 0, 0,
  896. 100, 30, 60, time(NULL), subnet_->getID(),
  897. false, false, ""));
  898. LeaseMgrFactory::instance().addLease(lease);
  899. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  900. // Query the allocation engine for the lease to be allocated for the
  901. // client.
  902. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  903. IOAddress("0.0.0.0"), false, false,
  904. "", true);
  905. AllocEngine::findReservation(ctx);
  906. Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
  907. // The server should offer the reserved address.
  908. ASSERT_TRUE(allocated_lease);
  909. EXPECT_EQ("192.0.2.123", allocated_lease->addr_.toText());
  910. // The lease should not be committed to the lease database until the
  911. // client sends a DHCPREQUEST.
  912. EXPECT_FALSE(LeaseMgrFactory::instance().getLease4(allocated_lease->addr_));
  913. // The old lease should reflect what is in the database.
  914. ASSERT_TRUE(ctx.old_lease_);
  915. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  916. ASSERT_TRUE(from_mgr);
  917. detailCompareLease(lease, from_mgr);
  918. }
  919. // This test checks that the behavior of the allocation engine in the following
  920. // scenario:
  921. // - Client A has a lease for the address.
  922. // - Client B has a reservation for the same address that the Client A is using.
  923. // - Client B requests allocation of the reserved address.
  924. // - Server returns DHCPNAK to the client to indicate that the requested address
  925. // can't be allocated.
  926. // - Client A renews the lease.
  927. // - Server determines that the lease that the Client A is trying to renew
  928. // is for the address reserved for Client B. Therefore, the server returns
  929. // DHCPNAK to force the client to return to the server discovery.
  930. // - The Client A sends DHCPDISCOVER.
  931. // - The server offers an address to the Client A, which is different than
  932. // the address reserved for Client B.
  933. // - The Client A requests allocation of the offered address.
  934. // - The server allocates the new address to Client A.
  935. // - The Client B sends DHCPDISCOVER to the server.
  936. // - The server offers a reserved address to the Client B.
  937. // - The Client B requests the offered address.
  938. // - The server allocates the reserved address to the Client B.
  939. TEST_F(AllocEngine4Test, reservedAddressConflictResolution) {
  940. // Create a reservation for client B.
  941. HostPtr host(new Host(&hwaddr2_->hwaddr_[0], hwaddr2_->hwaddr_.size(),
  942. Host::IDENT_HWADDR, subnet_->getID(),
  943. SubnetID(0), IOAddress("192.0.2.101")));
  944. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  945. CfgMgr::instance().commit();
  946. // Create a lease for Client A.
  947. Lease4Ptr lease(new Lease4(IOAddress("192.0.2.101"), hwaddr_, 0, 0,
  948. 100, 30, 60, time(NULL), subnet_->getID(),
  949. false, false, ""));
  950. LeaseMgrFactory::instance().addLease(lease);
  951. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  952. // Client B sends a DHCPREQUEST to allocate a reserved lease. The
  953. // allocation engine can't allocate a reserved lease for this client
  954. // because this specific address is in use by the Client A.
  955. AllocEngine::ClientContext4 ctx1(subnet_, ClientIdPtr(), hwaddr2_,
  956. IOAddress("192.0.2.101"), false, false,
  957. "", false);
  958. AllocEngine::findReservation(ctx1);
  959. Lease4Ptr offered_lease = engine.allocateLease4(ctx1);
  960. ASSERT_FALSE(offered_lease);
  961. // Client A tries to renew the lease. The renewal should fail because
  962. // server detects that Client A doesn't have reservation for this
  963. // address.
  964. AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
  965. IOAddress("192.0.2.101"), false, false,
  966. "", false);
  967. AllocEngine::findReservation(ctx2);
  968. ASSERT_FALSE(engine.allocateLease4(ctx2));
  969. ASSERT_FALSE(ctx2.old_lease_);
  970. // Client A returns to DHCPDISCOVER and should be offered a lease.
  971. // The offered lease address must be different than the one the
  972. // Client B has reservation for.
  973. AllocEngine::ClientContext4 ctx3(subnet_, clientid_, hwaddr_,
  974. IOAddress("192.0.2.101"), false, false,
  975. "", true);
  976. AllocEngine::findReservation(ctx3);
  977. offered_lease = engine.allocateLease4(ctx3);
  978. ASSERT_TRUE(offered_lease);
  979. EXPECT_NE(offered_lease->addr_.toText(), "192.0.2.101");
  980. // Client A tries to acquire the lease. It should succeed. At this point
  981. // the previous lease should be released and become available for the
  982. // Client B.
  983. AllocEngine::ClientContext4 ctx4(subnet_, clientid_, hwaddr_,
  984. offered_lease->addr_, false, false,
  985. "", false);
  986. AllocEngine::findReservation(ctx4);
  987. Lease4Ptr allocated_lease = engine.allocateLease4(ctx4);
  988. ASSERT_TRUE(allocated_lease);
  989. EXPECT_NE(allocated_lease->addr_.toText(), "192.0.2.101");
  990. // Client B tries to get the lease again. It should be offered
  991. // a reserved lease.
  992. AllocEngine::ClientContext4 ctx5(subnet_, ClientIdPtr(), hwaddr2_,
  993. IOAddress("0.0.0.0"), false, false,
  994. "", true);
  995. AllocEngine::findReservation(ctx5);
  996. offered_lease = engine.allocateLease4(ctx5);
  997. ASSERT_TRUE(offered_lease);
  998. EXPECT_EQ("192.0.2.101", offered_lease->addr_.toText());
  999. // Client B requests allocation of the lease and it should succeed.
  1000. AllocEngine::ClientContext4 ctx6(subnet_, ClientIdPtr(), hwaddr2_,
  1001. offered_lease->addr_, false, false,
  1002. "", false);
  1003. allocated_lease = engine.allocateLease4(ctx6);
  1004. ASSERT_TRUE(allocated_lease);
  1005. EXPECT_EQ("192.0.2.101", allocated_lease->addr_.toText());
  1006. }
  1007. // This test checks that the address is not assigned from the dynamic
  1008. // pool if it has been reserved for another client.
  1009. TEST_F(AllocEngine4Test, reservedAddressVsDynamicPool) {
  1010. // Create a reservation for the client.
  1011. HostPtr host(new Host(&hwaddr2_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  1012. Host::IDENT_HWADDR, subnet_->getID(),
  1013. SubnetID(0), IOAddress("192.0.2.100")));
  1014. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  1015. CfgMgr::instance().commit();
  1016. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  1017. // Different client tries to allocate a lease. Note, that we're using
  1018. // an iterative allocator which would pick the first address from the
  1019. // dynamic pool, i.e. 192.0.2.100. This address is reserved so we expect
  1020. // that a different address will be allocated.
  1021. AllocEngine::ClientContext4 ctx(subnet_, ClientIdPtr(), hwaddr_,
  1022. IOAddress("0.0.0.0"), false, false,
  1023. "", false);
  1024. AllocEngine::findReservation(ctx);
  1025. Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
  1026. ASSERT_TRUE(allocated_lease);
  1027. EXPECT_NE(allocated_lease->addr_.toText(), "192.0.2.100");
  1028. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(allocated_lease->addr_);
  1029. ASSERT_TRUE(from_mgr);
  1030. detailCompareLease(allocated_lease, from_mgr);
  1031. }
  1032. // This test checks that the client requesting an address which is
  1033. // reserved for another client will get no lease or a different
  1034. // address will be assigned if the client is sending a DHCPDISCOVER.
  1035. TEST_F(AllocEngine4Test, reservedAddressHintUsedByOtherClient) {
  1036. // Create a reservation for the client.
  1037. HostPtr host(new Host(&hwaddr2_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  1038. Host::IDENT_HWADDR, subnet_->getID(),
  1039. SubnetID(0), IOAddress("192.0.2.100")));
  1040. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  1041. CfgMgr::instance().commit();
  1042. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  1043. // Different client is requesting this address.
  1044. AllocEngine::ClientContext4 ctx1(subnet_, ClientIdPtr(), hwaddr_,
  1045. IOAddress("192.0.2.100"), false, false,
  1046. "", false);
  1047. AllocEngine::findReservation(ctx1);
  1048. Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
  1049. // The client should get no lease (DHCPNAK).
  1050. ASSERT_FALSE(allocated_lease);
  1051. // The same client should get a different lease than requested if
  1052. // if is sending a DHCPDISCOVER (fake allocation is true).
  1053. AllocEngine::ClientContext4 ctx2(subnet_, ClientIdPtr(), hwaddr_,
  1054. IOAddress("192.0.2.100"), false, false,
  1055. "", true);
  1056. AllocEngine::findReservation(ctx2);
  1057. allocated_lease = engine.allocateLease4(ctx2);
  1058. ASSERT_TRUE(allocated_lease);
  1059. // Make sure the lease obtained is for a different address.
  1060. EXPECT_NE(allocated_lease->addr_.toText(), "192.0.2.100");
  1061. }
  1062. // This test checks that the allocation engine refuses to allocate an
  1063. // address when the pool is exhausted, and the only available
  1064. // address is reserved for a different client.
  1065. TEST_F(AllocEngine4Test, reservedAddressShortPool) {
  1066. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  1067. // Create short pool with only one address.
  1068. initSubnet(IOAddress("192.0.2.100"), IOAddress("192.0.2.100"));
  1069. // Reserve the address for a different client.
  1070. HostPtr host(new Host(&hwaddr2_->hwaddr_[0], hwaddr2_->hwaddr_.size(),
  1071. Host::IDENT_HWADDR, subnet_->getID(),
  1072. SubnetID(0), IOAddress("192.0.2.100")));
  1073. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  1074. CfgMgr::instance().commit();
  1075. // Allocation engine should determine that the available address is
  1076. // reserved for someone else and not allocate it.
  1077. AllocEngine::ClientContext4 ctx1(subnet_, ClientIdPtr(), hwaddr_,
  1078. IOAddress("0.0.0.0"), false, false,
  1079. "", false);
  1080. AllocEngine::findReservation(ctx1);
  1081. Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
  1082. EXPECT_FALSE(allocated_lease);
  1083. // Now, let's remove the reservation.
  1084. initSubnet(IOAddress("192.0.2.100"), IOAddress("192.0.2.100"));
  1085. CfgMgr::instance().commit();
  1086. // Address should be successfully allocated.
  1087. AllocEngine::ClientContext4 ctx2(subnet_, ClientIdPtr(), hwaddr_,
  1088. IOAddress("0.0.0.0"), false, false,
  1089. "", false);
  1090. AllocEngine::findReservation(ctx2);
  1091. allocated_lease = engine.allocateLease4(ctx2);
  1092. ASSERT_TRUE(allocated_lease);
  1093. EXPECT_EQ("192.0.2.100", allocated_lease->addr_.toText());
  1094. }
  1095. // This test checks that the AllocEngine allocates an address from the
  1096. // dynamic pool if the client's reservation is made for a hostname but
  1097. // not for an address.
  1098. TEST_F(AllocEngine4Test, reservedHostname) {
  1099. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  1100. // Create a reservation for a hostname. Address is set to 0 which
  1101. // indicates that there is no reservation.
  1102. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  1103. Host::IDENT_HWADDR, subnet_->getID(),
  1104. SubnetID(0), IOAddress::IPV4_ZERO_ADDRESS(),
  1105. "foo.example.org"));
  1106. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  1107. CfgMgr::instance().commit();
  1108. // Try to allocate a lease.
  1109. AllocEngine::ClientContext4 ctx(subnet_, ClientIdPtr(), hwaddr_,
  1110. IOAddress::IOAddress("192.0.2.109"), false, false,
  1111. "foo.example.org", true);
  1112. AllocEngine::findReservation(ctx);
  1113. Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
  1114. ASSERT_TRUE(allocated_lease);
  1115. ASSERT_FALSE(allocated_lease->addr_.isV4Zero());
  1116. ASSERT_EQ("192.0.2.109", allocated_lease->addr_.toText());
  1117. ctx.requested_address_ = allocated_lease->addr_;
  1118. ctx.fake_allocation_ = false;
  1119. allocated_lease = engine.allocateLease4(ctx);
  1120. ASSERT_TRUE(allocated_lease);
  1121. EXPECT_EQ("192.0.2.109", allocated_lease->addr_.toText());
  1122. }
  1123. // This test checks that the AllocEngine::findReservation method finds
  1124. // and returns host reservation for the DHCPv4 client using the data from
  1125. // the client context. If the host reservation can't be found, it sets
  1126. // the value of NULL in the host_ field of the client context.
  1127. TEST_F(AllocEngine4Test, findReservation) {
  1128. // Create the instance of the allocation engine.
  1129. AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
  1130. // Context is required to call the AllocEngine::findReservation.
  1131. AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
  1132. IOAddress("0.0.0.0"), false, false,
  1133. "", false);
  1134. // There is no reservation in the database so no host should be
  1135. // retruned.
  1136. ASSERT_NO_THROW(engine.findReservation(ctx));
  1137. EXPECT_FALSE(ctx.host_);
  1138. // Create a reservation for the client.
  1139. HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  1140. Host::IDENT_HWADDR, subnet_->getID(),
  1141. SubnetID(0), IOAddress("192.0.2.100")));
  1142. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  1143. CfgMgr::instance().commit();
  1144. // This time the reservation should be returned.
  1145. ASSERT_NO_THROW(engine.findReservation(ctx));
  1146. EXPECT_TRUE(ctx.host_);
  1147. EXPECT_EQ(ctx.host_->getIPv4Reservation(), host->getIPv4Reservation());
  1148. // If the host reservation mode for the subnet is disabled, the
  1149. // host should not be returned, even though it exists in the
  1150. // host database.
  1151. subnet_->setHostReservationMode(Subnet::HR_DISABLED);
  1152. ASSERT_NO_THROW(engine.findReservation(ctx));
  1153. EXPECT_FALSE(ctx.host_);
  1154. // Check the third possible reservation mode.
  1155. subnet_->setHostReservationMode(Subnet::HR_OUT_OF_POOL);
  1156. ASSERT_NO_THROW(engine.findReservation(ctx));
  1157. EXPECT_TRUE(ctx.host_);
  1158. EXPECT_EQ(ctx.host_->getIPv4Reservation(), host->getIPv4Reservation());
  1159. // This time use the client identifier to search for the host.
  1160. host.reset(new Host(&clientid_->getClientId()[0],
  1161. clientid_->getClientId().size(),
  1162. Host::IDENT_DUID, subnet_->getID(),
  1163. SubnetID(0), IOAddress("192.0.2.101")));
  1164. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  1165. CfgMgr::instance().commit();
  1166. ASSERT_NO_THROW(engine.findReservation(ctx));
  1167. EXPECT_TRUE(ctx.host_);
  1168. EXPECT_EQ(ctx.host_->getIPv4Reservation(), host->getIPv4Reservation());
  1169. // Remove the subnet. Subnet id is required to find host reservations, so
  1170. // if it is set to NULL, no reservation should be returned
  1171. ctx.subnet_.reset();
  1172. ASSERT_NO_THROW(engine.findReservation(ctx));
  1173. EXPECT_FALSE(ctx.host_);
  1174. // The same if there is a mismatch of the subnet id between the reservation
  1175. // and the context.
  1176. ctx.subnet_ = subnet_;
  1177. host.reset(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
  1178. Host::IDENT_HWADDR, subnet_->getID() + 1,
  1179. SubnetID(0), IOAddress("192.0.2.100")));
  1180. CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
  1181. CfgMgr::instance().commit();
  1182. ASSERT_NO_THROW(engine.findReservation(ctx));
  1183. EXPECT_FALSE(ctx.host_);
  1184. }
  1185. }; // namespace test
  1186. }; // namespace dhcp
  1187. }; // namespace isc