alloc_engine_unittest.cc 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004
  1. // Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <config.h>
  15. #include <asiolink/io_address.h>
  16. #include <dhcp/duid.h>
  17. #include <dhcp/dhcp4.h>
  18. #include <dhcpsrv/alloc_engine.h>
  19. #include <dhcpsrv/cfgmgr.h>
  20. #include <dhcpsrv/lease_mgr.h>
  21. #include <dhcpsrv/lease_mgr_factory.h>
  22. #include <dhcpsrv/memfile_lease_mgr.h>
  23. #include <dhcpsrv/tests/test_utils.h>
  24. #include <hooks/server_hooks.h>
  25. #include <hooks/callout_manager.h>
  26. #include <hooks/hooks_manager.h>
  27. #include <boost/shared_ptr.hpp>
  28. #include <boost/scoped_ptr.hpp>
  29. #include <gtest/gtest.h>
  30. #include <iostream>
  31. #include <sstream>
  32. #include <algorithm>
  33. #include <set>
  34. #include <time.h>
  35. using namespace std;
  36. using namespace isc;
  37. using namespace isc::asiolink;
  38. using namespace isc::hooks;
  39. using namespace isc::dhcp;
  40. using namespace isc::dhcp::test;
  41. namespace {
  42. /// @brief Allocation engine with some internal methods exposed
  43. class NakedAllocEngine : public AllocEngine {
  44. public:
  45. /// @brief the sole constructor
  46. /// @param engine_type specifies engine type (e.g. iterative)
  47. /// @param attempts number of lease selection attempts before giving up
  48. /// @param ipv6 specifies if the engine is IPv6 or IPv4
  49. NakedAllocEngine(AllocEngine::AllocType engine_type,
  50. unsigned int attempts, bool ipv6 = true)
  51. :AllocEngine(engine_type, attempts, ipv6) {
  52. }
  53. // Expose internal classes for testing purposes
  54. using AllocEngine::Allocator;
  55. using AllocEngine::IterativeAllocator;
  56. using AllocEngine::getAllocator;
  57. /// @brief IterativeAllocator with internal methods exposed
  58. class NakedIterativeAllocator: public AllocEngine::IterativeAllocator {
  59. public:
  60. /// @brief constructor
  61. /// @param type pool types that will be interated
  62. NakedIterativeAllocator(Lease::Type type)
  63. :IterativeAllocator(type) {
  64. }
  65. using AllocEngine::IterativeAllocator::increaseAddress;
  66. using AllocEngine::IterativeAllocator::increasePrefix;
  67. };
  68. };
  69. /// @brief Used in Allocation Engine tests for IPv6
  70. class AllocEngine6Test : public ::testing::Test {
  71. public:
  72. /// @brief Default constructor
  73. ///
  74. /// Sets duid_, iaid_, subnet_, pool_ fields to example values used
  75. /// in many tests, initializes cfg_mgr configuration and creates
  76. /// lease database.
  77. AllocEngine6Test() {
  78. duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
  79. iaid_ = 42;
  80. // Initialize a subnet and short address pool.
  81. initSubnet(IOAddress("2001:db8:1::"),
  82. IOAddress("2001:db8:1::10"),
  83. IOAddress("2001:db8:1::20"));
  84. initFqdn("", false, false);
  85. factory_.create("type=memfile leasefile4= leasefile6=");
  86. }
  87. /// @brief Configures a subnet and adds one pool to it.
  88. ///
  89. /// This function removes existing v6 subnets before configuring
  90. /// a new one.
  91. ///
  92. /// @param subnet Address of a subnet to be configured.
  93. /// @param pool_start First address in the address pool.
  94. /// @param pool_end Last address in the address pool.
  95. void initSubnet(const IOAddress& subnet, const IOAddress& pool_start,
  96. const IOAddress& pool_end) {
  97. CfgMgr& cfg_mgr = CfgMgr::instance();
  98. cfg_mgr.deleteSubnets6();
  99. subnet_ = Subnet6Ptr(new Subnet6(subnet, 56, 1, 2, 3, 4));
  100. pool_ = Pool6Ptr(new Pool6(Lease::TYPE_NA, pool_start, pool_end));
  101. subnet_->addPool(pool_);
  102. pd_pool_ = Pool6Ptr(new Pool6(Lease::TYPE_PD, subnet, 56, 64));
  103. subnet_->addPool(pd_pool_);
  104. cfg_mgr.addSubnet6(subnet_);
  105. }
  106. /// @brief Initializes FQDN data for a test.
  107. ///
  108. /// The initialized values are used by the test fixture class members to
  109. /// verify the correctness of a lease.
  110. ///
  111. /// @param hostname Hostname to be assigned to a lease.
  112. /// @param fqdn_fwd Indicates whether or not to perform forward DNS update
  113. /// for a lease.
  114. /// @param fqdn_fwd Indicates whether or not to perform reverse DNS update
  115. /// for a lease.
  116. void initFqdn(const std::string& hostname, const bool fqdn_fwd,
  117. const bool fqdn_rev) {
  118. hostname_ = hostname;
  119. fqdn_fwd_ = fqdn_fwd;
  120. fqdn_rev_ = fqdn_rev;
  121. }
  122. /// @brief attempts to convert leases collection to a single lease
  123. ///
  124. /// This operation makes sense if there is at most one lease in the
  125. /// collection. Otherwise it will throw.
  126. ///
  127. /// @param col collection of leases (zero or one leases allowed)
  128. /// @throw MultipleRecords if there is more than one lease
  129. /// @return Lease6 pointer (or NULL if collection was empty)
  130. Lease6Ptr expectOneLease(const Lease6Collection& col) {
  131. if (col.size() > 1) {
  132. isc_throw(MultipleRecords, "More than one lease found in collection");
  133. }
  134. if (col.empty()) {
  135. return (Lease6Ptr());
  136. }
  137. return (*col.begin());
  138. }
  139. /// @brief checks if Lease6 matches expected configuration
  140. ///
  141. /// @param lease lease to be checked
  142. /// @param exp_type expected lease type
  143. /// @param exp_pd_len expected prefix length
  144. void checkLease6(const Lease6Ptr& lease, Lease::Type exp_type,
  145. uint8_t exp_pd_len = 128) {
  146. // that is belongs to the right subnet
  147. EXPECT_EQ(lease->subnet_id_, subnet_->getID());
  148. EXPECT_TRUE(subnet_->inRange(lease->addr_));
  149. EXPECT_TRUE(subnet_->inPool(exp_type, lease->addr_));
  150. // that it have proper parameters
  151. EXPECT_EQ(exp_type, lease->type_);
  152. EXPECT_EQ(iaid_, lease->iaid_);
  153. EXPECT_EQ(subnet_->getValid(), lease->valid_lft_);
  154. EXPECT_EQ(subnet_->getPreferred(), lease->preferred_lft_);
  155. EXPECT_EQ(subnet_->getT1(), lease->t1_);
  156. EXPECT_EQ(subnet_->getT2(), lease->t2_);
  157. EXPECT_EQ(exp_pd_len, lease->prefixlen_);
  158. EXPECT_EQ(fqdn_fwd_, lease->fqdn_fwd_);
  159. EXPECT_EQ(fqdn_rev_, lease->fqdn_rev_);
  160. EXPECT_EQ(hostname_, lease->hostname_);
  161. EXPECT_TRUE(*lease->duid_ == *duid_);
  162. /// @todo: check cltt
  163. }
  164. /// @brief Checks if specified address is increased properly
  165. ///
  166. /// Method uses gtest macros to mark check failure.
  167. ///
  168. /// @param alloc IterativeAllocator that is tested
  169. /// @param input address to be increased
  170. /// @param exp_output expected address after increase
  171. void
  172. checkAddrIncrease(NakedAllocEngine::NakedIterativeAllocator& alloc,
  173. std::string input, std::string exp_output) {
  174. EXPECT_EQ(exp_output, alloc.increaseAddress(IOAddress(input)).toText());
  175. }
  176. /// @brief Checks if increasePrefix() works as expected
  177. ///
  178. /// Method uses gtest macros to mark check failure.
  179. ///
  180. /// @param alloc allocator to be tested
  181. /// @param input IPv6 prefix (as a string)
  182. /// @param prefix_len prefix len
  183. /// @param exp_output expected output (string)
  184. void
  185. checkPrefixIncrease(NakedAllocEngine::NakedIterativeAllocator& alloc,
  186. std::string input, uint8_t prefix_len,
  187. std::string exp_output) {
  188. EXPECT_EQ(exp_output, alloc.increasePrefix(IOAddress(input), prefix_len)
  189. .toText());
  190. }
  191. /// @brief Checks if the simple allocation can succeed
  192. ///
  193. /// The type of lease is determined by pool type (pool->getType()
  194. ///
  195. /// @param pool pool from which the lease will be allocated from
  196. /// @param hint address to be used as a hint
  197. /// @param fake true - this is fake allocation (SOLICIT)
  198. /// @return allocated lease (or NULL)
  199. Lease6Ptr simpleAlloc6Test(const Pool6Ptr& pool, const IOAddress& hint,
  200. bool fake) {
  201. Lease::Type type = pool->getType();
  202. uint8_t expected_len = pool->getLength();
  203. boost::scoped_ptr<AllocEngine> engine;
  204. EXPECT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  205. 100)));
  206. // We can't use ASSERT macros in non-void methods
  207. EXPECT_TRUE(engine);
  208. if (!engine) {
  209. return (Lease6Ptr());
  210. }
  211. Lease6Ptr lease;
  212. EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(subnet_,
  213. duid_, iaid_, hint, type, false, false,
  214. "", fake, CalloutHandlePtr(), old_leases_)));
  215. // Check that we got a lease
  216. EXPECT_TRUE(lease);
  217. if (!lease) {
  218. return (Lease6Ptr());
  219. }
  220. // Do all checks on the lease
  221. checkLease6(lease, type, expected_len);
  222. // Check that the lease is indeed in LeaseMgr
  223. Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(type,
  224. lease->addr_);
  225. if (!fake) {
  226. // This is a real (REQUEST) allocation, the lease must be in the DB
  227. EXPECT_TRUE(from_mgr);
  228. if (!from_mgr) {
  229. return (Lease6Ptr());
  230. }
  231. // Now check that the lease in LeaseMgr has the same parameters
  232. detailCompareLease(lease, from_mgr);
  233. } else {
  234. // This is a fake (SOLICIT) allocation, the lease must not be in DB
  235. EXPECT_FALSE(from_mgr);
  236. if (from_mgr) {
  237. return (Lease6Ptr());
  238. }
  239. }
  240. return (lease);
  241. }
  242. /// @brief Checks if the address allocation with a hint that is in range,
  243. /// in pool, but is currently used, can succeed
  244. ///
  245. /// Method uses gtest macros to mark check failure.
  246. ///
  247. /// @param type lease type
  248. /// @param used_addr address should be preallocated (simulates prior
  249. /// allocation by some other user)
  250. /// @param requested address requested by the client
  251. /// @param expected_pd_len expected PD len (128 for addresses)
  252. void allocWithUsedHintTest(Lease::Type type, IOAddress used_addr,
  253. IOAddress requested, uint8_t expected_pd_len) {
  254. boost::scoped_ptr<AllocEngine> engine;
  255. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  256. 100)));
  257. ASSERT_TRUE(engine);
  258. // Let's create a lease and put it in the LeaseMgr
  259. DuidPtr duid2 = boost::shared_ptr<DUID>(new DUID(vector<uint8_t>(8, 0xff)));
  260. time_t now = time(NULL);
  261. Lease6Ptr used(new Lease6(type, used_addr,
  262. duid2, 1, 2, 3, 4, now, subnet_->getID()));
  263. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(used));
  264. // Another client comes in and request an address that is in pool, but
  265. // unfortunately it is used already. The same address must not be allocated
  266. // twice.
  267. Lease6Ptr lease;
  268. EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(subnet_,
  269. duid_, iaid_, requested, type, false, false, "", false,
  270. CalloutHandlePtr(), old_leases_)));
  271. // Check that we got a lease
  272. ASSERT_TRUE(lease);
  273. // Allocated address must be different
  274. EXPECT_NE(used_addr, lease->addr_);
  275. // We should NOT get what we asked for, because it is used already
  276. EXPECT_NE(requested, lease->addr_);
  277. // Do all checks on the lease
  278. checkLease6(lease, type, expected_pd_len);
  279. // Check that the lease is indeed in LeaseMgr
  280. Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
  281. lease->addr_);
  282. ASSERT_TRUE(from_mgr);
  283. // Now check that the lease in LeaseMgr has the same parameters
  284. detailCompareLease(lease, from_mgr);
  285. }
  286. /// @brief checks if bogus hint can be ignored and the allocation succeeds
  287. ///
  288. /// This test checks if the allocation with a hing that is out of the blue
  289. /// can succeed. The invalid hint should be ingored completely.
  290. ///
  291. /// @param type Lease type
  292. /// @param hint hint (as send by a client)
  293. /// @param expectd_pd_len (used in validation)
  294. void allocBogusHint6(Lease::Type type, IOAddress hint,
  295. uint8_t expected_pd_len) {
  296. boost::scoped_ptr<AllocEngine> engine;
  297. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  298. 100)));
  299. ASSERT_TRUE(engine);
  300. // Client would like to get a 3000::abc lease, which does not belong to any
  301. // supported lease. Allocation engine should ignore it and carry on
  302. // with the normal allocation
  303. Lease6Ptr lease;
  304. EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(subnet_,
  305. duid_, iaid_, hint, type, false,
  306. false, "", false, CalloutHandlePtr(), old_leases_)));
  307. // Check that we got a lease
  308. ASSERT_TRUE(lease);
  309. // We should NOT get what we asked for, because it is used already
  310. EXPECT_NE(hint, lease->addr_);
  311. // Do all checks on the lease
  312. checkLease6(lease, type, expected_pd_len);
  313. // Check that the lease is indeed in LeaseMgr
  314. Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
  315. lease->addr_);
  316. ASSERT_TRUE(from_mgr);
  317. // Now check that the lease in LeaseMgr has the same parameters
  318. detailCompareLease(lease, from_mgr);
  319. }
  320. virtual ~AllocEngine6Test() {
  321. factory_.destroy();
  322. }
  323. DuidPtr duid_; ///< client-identifier (value used in tests)
  324. uint32_t iaid_; ///< IA identifier (value used in tests)
  325. Subnet6Ptr subnet_; ///< subnet6 (used in tests)
  326. Pool6Ptr pool_; ///< NA pool belonging to subnet_
  327. Pool6Ptr pd_pool_; ///< PD pool belonging to subnet_
  328. std::string hostname_; ///< Hostname
  329. bool fqdn_fwd_; ///< Perform forward update for a lease.
  330. bool fqdn_rev_; ///< Perform reverse update for a lease.
  331. LeaseMgrFactory factory_; ///< pointer to LeaseMgr factory
  332. /// @brief Collection of leases being replaced by newly allocated or renewed
  333. /// leases.
  334. Lease6Collection old_leases_;
  335. };
  336. /// @brief Used in Allocation Engine tests for IPv4
  337. class AllocEngine4Test : public ::testing::Test {
  338. public:
  339. /// @brief Default constructor
  340. ///
  341. /// Sets clientid_, hwaddr_, subnet_, pool_ fields to example values
  342. /// used in many tests, initializes cfg_mgr configuration and creates
  343. /// lease database.
  344. AllocEngine4Test() {
  345. clientid_ = ClientIdPtr(new ClientId(vector<uint8_t>(8, 0x44)));
  346. static uint8_t mac[] = { 0, 1, 22, 33, 44, 55};
  347. // Let's use odd hardware type to check if there is no Ethernet
  348. // hardcoded anywhere.
  349. hwaddr_ = HWAddrPtr(new HWAddr(mac, sizeof(mac), HTYPE_FDDI));
  350. // instantiate cfg_mgr
  351. CfgMgr& cfg_mgr = CfgMgr::instance();
  352. subnet_ = Subnet4Ptr(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3));
  353. pool_ = Pool4Ptr(new Pool4(IOAddress("192.0.2.100"),
  354. IOAddress("192.0.2.109")));
  355. subnet_->addPool(pool_);
  356. cfg_mgr.addSubnet4(subnet_);
  357. factory_.create("type=memfile leasefile4= leasefile6=");
  358. }
  359. /// @brief checks if Lease4 matches expected configuration
  360. ///
  361. /// @param lease lease to be checked
  362. void checkLease4(const Lease4Ptr& lease) {
  363. // Check that is belongs to the right subnet
  364. EXPECT_EQ(lease->subnet_id_, subnet_->getID());
  365. EXPECT_TRUE(subnet_->inRange(lease->addr_));
  366. EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
  367. // Check that it has proper parameters
  368. EXPECT_EQ(subnet_->getValid(), lease->valid_lft_);
  369. EXPECT_EQ(subnet_->getT1(), lease->t1_);
  370. EXPECT_EQ(subnet_->getT2(), lease->t2_);
  371. if (lease->client_id_ && !clientid_) {
  372. ADD_FAILURE() << "Lease4 has a client-id, while it should have none.";
  373. } else
  374. if (!lease->client_id_ && clientid_) {
  375. ADD_FAILURE() << "Lease4 has no client-id, but it was expected to have one.";
  376. } else
  377. if (lease->client_id_ && clientid_) {
  378. EXPECT_TRUE(*lease->client_id_ == *clientid_);
  379. }
  380. EXPECT_TRUE(lease->hwaddr_ == hwaddr_->hwaddr_);
  381. /// @todo: check cltt
  382. }
  383. virtual ~AllocEngine4Test() {
  384. factory_.destroy();
  385. }
  386. ClientIdPtr clientid_; ///< Client-identifier (value used in tests)
  387. HWAddrPtr hwaddr_; ///< Hardware address (value used in tests)
  388. Subnet4Ptr subnet_; ///< Subnet4 (used in tests)
  389. Pool4Ptr pool_; ///< Pool belonging to subnet_
  390. LeaseMgrFactory factory_; ///< Pointer to LeaseMgr factory
  391. Lease4Ptr old_lease_; ///< Holds previous instance of the lease.
  392. };
  393. // This test checks if the v6 Allocation Engine can be instantiated, parses
  394. // parameters string and allocators are created.
  395. TEST_F(AllocEngine6Test, constructor) {
  396. boost::scoped_ptr<AllocEngine> x;
  397. // Hashed and random allocators are not supported yet
  398. ASSERT_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_HASHED, 5)), NotImplemented);
  399. ASSERT_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_RANDOM, 5)), NotImplemented);
  400. ASSERT_NO_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100, true)));
  401. // Check that allocator for normal addresses is created
  402. ASSERT_TRUE(x->getAllocator(Lease::TYPE_NA));
  403. // Check that allocator for temporary address is created
  404. ASSERT_TRUE(x->getAllocator(Lease::TYPE_TA));
  405. // Check that allocator for prefixes is created
  406. ASSERT_TRUE(x->getAllocator(Lease::TYPE_PD));
  407. // There should be no V4 allocator
  408. EXPECT_THROW(x->getAllocator(Lease::TYPE_V4), BadValue);
  409. }
  410. // This test checks if the simple allocation (REQUEST) can succeed
  411. TEST_F(AllocEngine6Test, simpleAlloc6) {
  412. simpleAlloc6Test(pool_, IOAddress("::"), false);
  413. }
  414. // This test checks if the simple PD allocation (REQUEST) can succeed
  415. TEST_F(AllocEngine6Test, pdSimpleAlloc6) {
  416. simpleAlloc6Test(pd_pool_, IOAddress("::"), false);
  417. }
  418. // This test checks if the fake allocation (for SOLICIT) can succeed
  419. TEST_F(AllocEngine6Test, fakeAlloc6) {
  420. simpleAlloc6Test(pool_, IOAddress("::"), true);
  421. }
  422. // This test checks if the fake PD allocation (for SOLICIT) can succeed
  423. TEST_F(AllocEngine6Test, pdFakeAlloc6) {
  424. simpleAlloc6Test(pd_pool_, IOAddress("::"), true);
  425. };
  426. // This test checks if the allocation with a hint that is valid (in range,
  427. // in pool and free) can succeed
  428. TEST_F(AllocEngine6Test, allocWithValidHint6) {
  429. Lease6Ptr lease = simpleAlloc6Test(pool_, IOAddress("2001:db8:1::15"),
  430. false);
  431. // We should get what we asked for
  432. EXPECT_EQ("2001:db8:1::15", lease->addr_.toText());
  433. }
  434. // This test checks if the address allocation with a hint that is in range,
  435. // in pool, but is currently used, can succeed
  436. TEST_F(AllocEngine6Test, allocWithUsedHint6) {
  437. allocWithUsedHintTest(Lease::TYPE_NA,
  438. IOAddress("2001:db8:1::1f"), // allocate this as used
  439. IOAddress("2001:db8:1::1f"), // request this addr
  440. 128);
  441. }
  442. // This test checks if the PD allocation with a hint that is in range,
  443. // in pool, but is currently used, can succeed
  444. TEST_F(AllocEngine6Test, pdAllocWithUsedHint6) {
  445. allocWithUsedHintTest(Lease::TYPE_PD,
  446. IOAddress("2001:db8:1::"), // allocate this prefix as used
  447. IOAddress("2001:db8:1::"), // request this prefix
  448. 64);
  449. }
  450. // This test checks if the allocation with a hint that is out the blue
  451. // can succeed. The invalid hint should be ignored completely.
  452. TEST_F(AllocEngine6Test, allocBogusHint6) {
  453. allocBogusHint6(Lease::TYPE_NA, IOAddress("3000::abc"), 128);
  454. }
  455. // This test checks if the allocation with a hint that is out the blue
  456. // can succeed. The invalid hint should be ignored completely.
  457. TEST_F(AllocEngine6Test, pdAllocBogusHint6) {
  458. allocBogusHint6(Lease::TYPE_PD, IOAddress("3000::abc"), 64);
  459. }
  460. // This test checks that NULL values are handled properly
  461. TEST_F(AllocEngine6Test, allocateAddress6Nulls) {
  462. boost::scoped_ptr<AllocEngine> engine;
  463. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
  464. ASSERT_TRUE(engine);
  465. // Allocations without subnet are not allowed
  466. Lease6Ptr lease;
  467. EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(
  468. Subnet6Ptr(), duid_, iaid_, IOAddress("::"), Lease::TYPE_NA,
  469. false, false, "", false, CalloutHandlePtr(), old_leases_)));
  470. ASSERT_FALSE(lease);
  471. // Allocations without DUID are not allowed either
  472. EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(subnet_,
  473. DuidPtr(), iaid_, IOAddress("::"), Lease::TYPE_NA, false,
  474. false, "", false, CalloutHandlePtr(), old_leases_)));
  475. ASSERT_FALSE(lease);
  476. }
  477. // This test verifies that the allocator picks addresses that belong to the
  478. // pool
  479. TEST_F(AllocEngine6Test, IterativeAllocator) {
  480. boost::scoped_ptr<NakedAllocEngine::Allocator>
  481. alloc(new NakedAllocEngine::IterativeAllocator(Lease::TYPE_NA));
  482. for (int i = 0; i < 1000; ++i) {
  483. IOAddress candidate = alloc->pickAddress(subnet_, duid_, IOAddress("::"));
  484. EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate));
  485. }
  486. }
  487. TEST_F(AllocEngine6Test, IterativeAllocatorAddrStep) {
  488. NakedAllocEngine::NakedIterativeAllocator alloc(Lease::TYPE_NA);
  489. subnet_->delPools(Lease::TYPE_NA); // Get rid of default pool
  490. Pool6Ptr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1::1"),
  491. IOAddress("2001:db8:1::5")));
  492. Pool6Ptr pool2(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1::100"),
  493. IOAddress("2001:db8:1::100")));
  494. Pool6Ptr pool3(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1::105"),
  495. IOAddress("2001:db8:1::106")));
  496. subnet_->addPool(pool1);
  497. subnet_->addPool(pool2);
  498. subnet_->addPool(pool3);
  499. // Let's check the first pool (5 addresses here)
  500. EXPECT_EQ("2001:db8:1::1", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  501. EXPECT_EQ("2001:db8:1::2", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  502. EXPECT_EQ("2001:db8:1::3", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  503. EXPECT_EQ("2001:db8:1::4", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  504. EXPECT_EQ("2001:db8:1::5", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  505. // The second pool is easy - only one address here
  506. EXPECT_EQ("2001:db8:1::100", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  507. // This is the third and last pool, with 2 addresses in it
  508. EXPECT_EQ("2001:db8:1::105", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  509. EXPECT_EQ("2001:db8:1::106", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  510. // We iterated over all addresses and reached to the end of the last pool.
  511. // Let's wrap around and start from the beginning
  512. EXPECT_EQ("2001:db8:1::1", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  513. EXPECT_EQ("2001:db8:1::2", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  514. }
  515. TEST_F(AllocEngine6Test, IterativeAllocatorPrefixStep) {
  516. NakedAllocEngine::NakedIterativeAllocator alloc(Lease::TYPE_PD);
  517. subnet_.reset(new Subnet6(IOAddress("2001:db8::"), 32, 1, 2, 3, 4));
  518. Pool6Ptr pool1(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8::"), 56, 60));
  519. Pool6Ptr pool2(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1::"), 48, 48));
  520. Pool6Ptr pool3(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:2::"), 56, 64));
  521. subnet_->addPool(pool1);
  522. subnet_->addPool(pool2);
  523. subnet_->addPool(pool3);
  524. // We have a 2001:db8::/48 subnet that has 3 pools defined in it:
  525. // 2001:db8::/56 split into /60 prefixes (16 leases) (or 2001:db8:0:X0::)
  526. // 2001:db8:1::/48 split into a single /48 prefix (just 1 lease)
  527. // 2001:db8:2::/56 split into /64 prefixes (256 leases) (or 2001:db8:2:XX::)
  528. // First pool check (Let's check over all 16 leases)
  529. EXPECT_EQ("2001:db8::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  530. EXPECT_EQ("2001:db8:0:10::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  531. EXPECT_EQ("2001:db8:0:20::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  532. EXPECT_EQ("2001:db8:0:30::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  533. EXPECT_EQ("2001:db8:0:40::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  534. EXPECT_EQ("2001:db8:0:50::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  535. EXPECT_EQ("2001:db8:0:60::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  536. EXPECT_EQ("2001:db8:0:70::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  537. EXPECT_EQ("2001:db8:0:80::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  538. EXPECT_EQ("2001:db8:0:90::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  539. EXPECT_EQ("2001:db8:0:a0::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  540. EXPECT_EQ("2001:db8:0:b0::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  541. EXPECT_EQ("2001:db8:0:c0::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  542. EXPECT_EQ("2001:db8:0:d0::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  543. EXPECT_EQ("2001:db8:0:e0::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  544. EXPECT_EQ("2001:db8:0:f0::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  545. // Second pool (just one lease here)
  546. EXPECT_EQ("2001:db8:1::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  547. // Third pool (256 leases, let's check first and last explictly and the
  548. // rest over in a pool
  549. EXPECT_EQ("2001:db8:2::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  550. for (int i = 1; i < 255; i++) {
  551. stringstream exp;
  552. exp << "2001:db8:2:" << hex << i << dec << "::";
  553. EXPECT_EQ(exp.str(), alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  554. }
  555. EXPECT_EQ("2001:db8:2:ff::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  556. // Ok, we've iterated over all prefixes in all pools. We now wrap around.
  557. // We're looping over now (iterating over first pool again)
  558. EXPECT_EQ("2001:db8::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  559. EXPECT_EQ("2001:db8:0:10::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
  560. }
  561. // This test verifies that the iterative allocator can step over addresses
  562. TEST_F(AllocEngine6Test, IterativeAllocatorAddressIncrease) {
  563. NakedAllocEngine::NakedIterativeAllocator alloc(Lease::TYPE_NA);
  564. // Let's pick the first address
  565. IOAddress addr1 = alloc.pickAddress(subnet_, duid_, IOAddress("2001:db8:1::10"));
  566. // Check that we can indeed pick the first address from the pool
  567. EXPECT_EQ("2001:db8:1::10", addr1.toText());
  568. // Check that addresses can be increased properly
  569. checkAddrIncrease(alloc, "2001:db8::9", "2001:db8::a");
  570. checkAddrIncrease(alloc, "2001:db8::f", "2001:db8::10");
  571. checkAddrIncrease(alloc, "2001:db8::10", "2001:db8::11");
  572. checkAddrIncrease(alloc, "2001:db8::ff", "2001:db8::100");
  573. checkAddrIncrease(alloc, "2001:db8::ffff", "2001:db8::1:0");
  574. checkAddrIncrease(alloc, "::", "::1");
  575. checkAddrIncrease(alloc, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "::");
  576. }
  577. // This test verifies that the allocator can step over prefixes
  578. TEST_F(AllocEngine6Test, IterativeAllocatorPrefixIncrease) {
  579. NakedAllocEngine::NakedIterativeAllocator alloc(Lease::TYPE_PD);
  580. // For /128 prefix, increasePrefix should work the same as addressIncrease
  581. checkPrefixIncrease(alloc, "2001:db8::9", 128, "2001:db8::a");
  582. checkPrefixIncrease(alloc, "2001:db8::f", 128, "2001:db8::10");
  583. checkPrefixIncrease(alloc, "2001:db8::10", 128, "2001:db8::11");
  584. checkPrefixIncrease(alloc, "2001:db8::ff", 128, "2001:db8::100");
  585. checkPrefixIncrease(alloc, "2001:db8::ffff", 128, "2001:db8::1:0");
  586. checkPrefixIncrease(alloc, "::", 128, "::1");
  587. checkPrefixIncrease(alloc, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, "::");
  588. // Check that /64 prefixes can be generated
  589. checkPrefixIncrease(alloc, "2001:db8::", 64, "2001:db8:0:1::");
  590. // Check that prefix length not divisible by 8 are working
  591. checkPrefixIncrease(alloc, "2001:db8::", 128, "2001:db8::1");
  592. checkPrefixIncrease(alloc, "2001:db8::", 127, "2001:db8::2");
  593. checkPrefixIncrease(alloc, "2001:db8::", 126, "2001:db8::4");
  594. checkPrefixIncrease(alloc, "2001:db8::", 125, "2001:db8::8");
  595. checkPrefixIncrease(alloc, "2001:db8::", 124, "2001:db8::10");
  596. checkPrefixIncrease(alloc, "2001:db8::", 123, "2001:db8::20");
  597. checkPrefixIncrease(alloc, "2001:db8::", 122, "2001:db8::40");
  598. checkPrefixIncrease(alloc, "2001:db8::", 121, "2001:db8::80");
  599. checkPrefixIncrease(alloc, "2001:db8::", 120, "2001:db8::100");
  600. // These are not really useful cases, because there are bits set
  601. // int the last (128 - prefix_len) bits. Nevertheless, it shows
  602. // that the algorithm is working even in such cases
  603. checkPrefixIncrease(alloc, "2001:db8::1", 128, "2001:db8::2");
  604. checkPrefixIncrease(alloc, "2001:db8::1", 127, "2001:db8::3");
  605. checkPrefixIncrease(alloc, "2001:db8::1", 126, "2001:db8::5");
  606. checkPrefixIncrease(alloc, "2001:db8::1", 125, "2001:db8::9");
  607. checkPrefixIncrease(alloc, "2001:db8::1", 124, "2001:db8::11");
  608. checkPrefixIncrease(alloc, "2001:db8::1", 123, "2001:db8::21");
  609. checkPrefixIncrease(alloc, "2001:db8::1", 122, "2001:db8::41");
  610. checkPrefixIncrease(alloc, "2001:db8::1", 121, "2001:db8::81");
  611. checkPrefixIncrease(alloc, "2001:db8::1", 120, "2001:db8::101");
  612. // Let's try out couple real life scenarios
  613. checkPrefixIncrease(alloc, "2001:db8:1:abcd::", 64, "2001:db8:1:abce::");
  614. checkPrefixIncrease(alloc, "2001:db8:1:abcd::", 60, "2001:db8:1:abdd::");
  615. checkPrefixIncrease(alloc, "2001:db8:1:abcd::", 56, "2001:db8:1:accd::");
  616. checkPrefixIncrease(alloc, "2001:db8:1:abcd::", 52, "2001:db8:1:bbcd::");
  617. // And now let's try something over the top
  618. checkPrefixIncrease(alloc, "::", 1, "8000::");
  619. }
  620. // This test verifies that the iterative allocator really walks over all addresses
  621. // in all pools in specified subnet. It also must not pick the same address twice
  622. // unless it runs out of pool space and must start over.
  623. TEST_F(AllocEngine6Test, IterativeAllocator_manyPools6) {
  624. NakedAllocEngine::IterativeAllocator alloc(Lease::TYPE_NA);
  625. // let's start from 2, as there is 2001:db8:1::10 - 2001:db8:1::20 pool already.
  626. for (int i = 2; i < 10; ++i) {
  627. stringstream min, max;
  628. min << "2001:db8:1::" << hex << i*16 + 1;
  629. max << "2001:db8:1::" << hex << i*16 + 9;
  630. Pool6Ptr pool(new Pool6(Lease::TYPE_NA, IOAddress(min.str()),
  631. IOAddress(max.str())));
  632. subnet_->addPool(pool);
  633. }
  634. int total = 17 + 8 * 9; // First pool (::10 - ::20) has 17 addresses in it,
  635. // there are 8 extra pools with 9 addresses in each.
  636. // Let's keep picked addresses here and check their uniqueness.
  637. std::set<IOAddress> generated_addrs;
  638. int cnt = 0;
  639. while (++cnt) {
  640. IOAddress candidate = alloc.pickAddress(subnet_, duid_, IOAddress("::"));
  641. EXPECT_TRUE(subnet_->inPool(Lease::TYPE_NA, candidate));
  642. // One way to easily verify that the iterative allocator really works is
  643. // to uncomment the following line and observe its output that it
  644. // covers all defined pools.
  645. // cout << candidate.toText() << endl;
  646. if (generated_addrs.find(candidate) == generated_addrs.end()) {
  647. // We haven't had this.
  648. generated_addrs.insert(candidate);
  649. } else {
  650. // We have seen this address before. That should mean that we
  651. // iterated over all addresses.
  652. if (generated_addrs.size() == total) {
  653. // We have exactly the number of address in all pools.
  654. break;
  655. }
  656. ADD_FAILURE() << "Too many or not enough unique addresses generated.";
  657. break;
  658. }
  659. if ( cnt>total ) {
  660. ADD_FAILURE() << "Too many unique addresses generated.";
  661. break;
  662. }
  663. }
  664. }
  665. // This test checks if really small pools are working
  666. TEST_F(AllocEngine6Test, smallPool6) {
  667. boost::scoped_ptr<AllocEngine> engine;
  668. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
  669. ASSERT_TRUE(engine);
  670. IOAddress addr("2001:db8:1::ad");
  671. // Create a subnet with a pool that has one address.
  672. initSubnet(IOAddress("2001:db8:1::"), addr, addr);
  673. // Initialize FQDN for a lease.
  674. initFqdn("myhost.example.com", true, true);
  675. Lease6Ptr lease;
  676. EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(subnet_,
  677. duid_, iaid_, IOAddress("::"), Lease::TYPE_NA, fqdn_fwd_,
  678. fqdn_rev_, hostname_, false, CalloutHandlePtr(),
  679. old_leases_)));
  680. // Check that we got that single lease
  681. ASSERT_TRUE(lease);
  682. EXPECT_EQ("2001:db8:1::ad", lease->addr_.toText());
  683. // Do all checks on the lease
  684. checkLease6(lease, Lease::TYPE_NA, 128);
  685. // Check that the lease is indeed in LeaseMgr
  686. Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
  687. lease->addr_);
  688. ASSERT_TRUE(from_mgr);
  689. // Now check that the lease in LeaseMgr has the same parameters
  690. detailCompareLease(lease, from_mgr);
  691. // This is a new lease allocation. The old lease corresponding to a newly
  692. // allocated lease should be NULL.
  693. ASSERT_EQ(1, old_leases_.size());
  694. EXPECT_FALSE(old_leases_[0]);
  695. }
  696. // This test checks if all addresses in a pool are currently used, the attempt
  697. // to find out a new lease fails.
  698. TEST_F(AllocEngine6Test, outOfAddresses6) {
  699. boost::scoped_ptr<AllocEngine> engine;
  700. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
  701. ASSERT_TRUE(engine);
  702. IOAddress addr("2001:db8:1::ad");
  703. CfgMgr& cfg_mgr = CfgMgr::instance();
  704. cfg_mgr.deleteSubnets6(); // Get rid of the default test configuration
  705. // Create configuration similar to other tests, but with a single address pool
  706. subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
  707. pool_ = Pool6Ptr(new Pool6(Lease::TYPE_NA, addr, addr)); // just a single address
  708. subnet_->addPool(pool_);
  709. cfg_mgr.addSubnet6(subnet_);
  710. // Just a different duid
  711. DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff)));
  712. const uint32_t other_iaid = 3568;
  713. Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr, other_duid, other_iaid,
  714. 501, 502, 503, 504, subnet_->getID(), 0));
  715. lease->cltt_ = time(NULL) - 10; // Allocated 10 seconds ago
  716. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
  717. // There is just a single address in the pool and allocated it to someone
  718. // else, so the allocation should fail
  719. Lease6Ptr lease2;
  720. EXPECT_NO_THROW(lease2 = expectOneLease(engine->allocateLeases6(subnet_,
  721. duid_, iaid_, IOAddress("::"), Lease::TYPE_NA, false, false,
  722. "", false, CalloutHandlePtr(), old_leases_)));
  723. EXPECT_FALSE(lease2);
  724. }
  725. // This test checks if an expired lease can be reused in SOLICIT (fake allocation)
  726. TEST_F(AllocEngine6Test, solicitReuseExpiredLease6) {
  727. boost::scoped_ptr<AllocEngine> engine;
  728. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
  729. ASSERT_TRUE(engine);
  730. IOAddress addr("2001:db8:1::ad");
  731. // Create one subnet with a pool holding one address.
  732. initSubnet(IOAddress("2001:db8:1::"), addr, addr);
  733. // Initialize FQDN data for the lease.
  734. initFqdn("myhost.example.com", true, true);
  735. // Just a different duid
  736. DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff)));
  737. const uint32_t other_iaid = 3568;
  738. Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr, other_duid, other_iaid,
  739. 501, 502, 503, 504, subnet_->getID(), 0));
  740. lease->cltt_ = time(NULL) - 500; // Allocated 500 seconds ago
  741. lease->valid_lft_ = 495; // Lease was valid for 495 seconds
  742. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
  743. // Make sure that we really created expired lease
  744. ASSERT_TRUE(lease->expired());
  745. // CASE 1: Asking for any address
  746. EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(subnet_,
  747. duid_, iaid_, IOAddress("::"), Lease::TYPE_NA, fqdn_fwd_,
  748. fqdn_rev_, hostname_, true, CalloutHandlePtr(),
  749. old_leases_)));
  750. // Check that we got that single lease
  751. ASSERT_TRUE(lease);
  752. EXPECT_EQ(addr, lease->addr_);
  753. // Do all checks on the lease (if subnet-id, preferred/valid times are ok etc.)
  754. checkLease6(lease, Lease::TYPE_NA, 128);
  755. // CASE 2: Asking specifically for this address
  756. EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(subnet_,
  757. duid_, iaid_, addr, Lease::TYPE_NA, false, false, "",
  758. true, CalloutHandlePtr(), old_leases_)));
  759. // Check that we got that single lease
  760. ASSERT_TRUE(lease);
  761. EXPECT_EQ(addr, lease->addr_);
  762. }
  763. // This test checks if an expired lease can be reused in REQUEST (actual allocation)
  764. TEST_F(AllocEngine6Test, requestReuseExpiredLease6) {
  765. boost::scoped_ptr<AllocEngine> engine;
  766. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
  767. ASSERT_TRUE(engine);
  768. IOAddress addr("2001:db8:1::ad");
  769. CfgMgr& cfg_mgr = CfgMgr::instance();
  770. cfg_mgr.deleteSubnets6(); // Get rid of the default test configuration
  771. // Create configuration similar to other tests, but with a single address pool
  772. subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
  773. pool_ = Pool6Ptr(new Pool6(Lease::TYPE_NA, addr, addr)); // just a single address
  774. subnet_->addPool(pool_);
  775. cfg_mgr.addSubnet6(subnet_);
  776. // Let's create an expired lease
  777. DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff)));
  778. const uint32_t other_iaid = 3568;
  779. const SubnetID other_subnetid = 999;
  780. Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr, other_duid, other_iaid,
  781. 501, 502, 503, 504, other_subnetid, 0));
  782. lease->cltt_ = time(NULL) - 500; // Allocated 500 seconds ago
  783. lease->valid_lft_ = 495; // Lease was valid for 495 seconds
  784. lease->fqdn_fwd_ = true;
  785. lease->fqdn_rev_ = true;
  786. lease->hostname_ = "myhost.example.com.";
  787. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
  788. // A client comes along, asking specifically for this address
  789. EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(subnet_,
  790. duid_, iaid_, addr, Lease::TYPE_NA, false, false, "",
  791. false, CalloutHandlePtr(), old_leases_)));
  792. // Check that he got that single lease
  793. ASSERT_TRUE(lease);
  794. EXPECT_EQ(addr, lease->addr_);
  795. // This reactivated lease should have updated FQDN data.
  796. EXPECT_TRUE(lease->hostname_.empty());
  797. EXPECT_FALSE(lease->fqdn_fwd_);
  798. EXPECT_FALSE(lease->fqdn_rev_);
  799. // Check that the old lease has been returned.
  800. Lease6Ptr old_lease = expectOneLease(old_leases_);
  801. // It should at least have the same IPv6 address.
  802. EXPECT_EQ(lease->addr_, old_lease->addr_);
  803. // Check that it carries not updated FQDN data.
  804. EXPECT_EQ("myhost.example.com.", old_lease->hostname_);
  805. EXPECT_TRUE(old_lease->fqdn_fwd_);
  806. EXPECT_TRUE(old_lease->fqdn_rev_);
  807. // Check that the lease is indeed updated in LeaseMgr
  808. Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
  809. addr);
  810. ASSERT_TRUE(from_mgr);
  811. // Now check that the lease in LeaseMgr has the same parameters
  812. detailCompareLease(lease, from_mgr);
  813. }
  814. // --- IPv4 ---
  815. // This test checks if the v4 Allocation Engine can be instantiated, parses
  816. // parameters string and allocators are created.
  817. TEST_F(AllocEngine4Test, constructor) {
  818. boost::scoped_ptr<AllocEngine> x;
  819. // Hashed and random allocators are not supported yet
  820. ASSERT_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_HASHED, 5, false)),
  821. NotImplemented);
  822. ASSERT_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_RANDOM, 5, false)),
  823. NotImplemented);
  824. // Create V4 (ipv6=false) Allocation Engine that will try at most
  825. // 100 attempts to pick up a lease
  826. ASSERT_NO_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100,
  827. false)));
  828. // There should be V4 allocator
  829. ASSERT_TRUE(x->getAllocator(Lease::TYPE_V4));
  830. // Check that allocators for V6 stuff are not created
  831. EXPECT_THROW(x->getAllocator(Lease::TYPE_NA), BadValue);
  832. EXPECT_THROW(x->getAllocator(Lease::TYPE_TA), BadValue);
  833. EXPECT_THROW(x->getAllocator(Lease::TYPE_PD), BadValue);
  834. }
  835. // This test checks if the simple IPv4 allocation can succeed
  836. TEST_F(AllocEngine4Test, simpleAlloc4) {
  837. boost::scoped_ptr<AllocEngine> engine;
  838. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  839. 100, false)));
  840. ASSERT_TRUE(engine);
  841. Lease4Ptr lease = engine->allocateLease4(subnet_, clientid_, hwaddr_,
  842. IOAddress("0.0.0.0"),
  843. false, true,
  844. "somehost.example.com.",
  845. false, CalloutHandlePtr(),
  846. old_lease_);
  847. // The new lease has been allocated, so the old lease should not exist.
  848. EXPECT_FALSE(old_lease_);
  849. // Check that we got a lease
  850. ASSERT_TRUE(lease);
  851. // Do all checks on the lease
  852. checkLease4(lease);
  853. // Check that the lease is indeed in LeaseMgr
  854. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  855. ASSERT_TRUE(from_mgr);
  856. // Now check that the lease in LeaseMgr has the same parameters
  857. detailCompareLease(lease, from_mgr);
  858. }
  859. // This test checks if the fake allocation (for DISCOVER) can succeed
  860. TEST_F(AllocEngine4Test, fakeAlloc4) {
  861. boost::scoped_ptr<AllocEngine> engine;
  862. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  863. 100, false)));
  864. ASSERT_TRUE(engine);
  865. Lease4Ptr lease = engine->allocateLease4(subnet_, clientid_, hwaddr_,
  866. IOAddress("0.0.0.0"),
  867. false, true, "host.example.com.",
  868. true, CalloutHandlePtr(),
  869. old_lease_);
  870. // The new lease has been allocated, so the old lease should not exist.
  871. EXPECT_FALSE(old_lease_);
  872. // Check that we got a lease
  873. ASSERT_TRUE(lease);
  874. // Do all checks on the lease
  875. checkLease4(lease);
  876. // Check that the lease is NOT in LeaseMgr
  877. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  878. ASSERT_FALSE(from_mgr);
  879. }
  880. // This test checks if the allocation with a hint that is valid (in range,
  881. // in pool and free) can succeed
  882. TEST_F(AllocEngine4Test, allocWithValidHint4) {
  883. boost::scoped_ptr<AllocEngine> engine;
  884. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  885. 100, false)));
  886. ASSERT_TRUE(engine);
  887. Lease4Ptr lease = engine->allocateLease4(subnet_, clientid_, hwaddr_,
  888. IOAddress("192.0.2.105"),
  889. true, true, "host.example.com.",
  890. false, CalloutHandlePtr(),
  891. old_lease_);
  892. // Check that we got a lease
  893. ASSERT_TRUE(lease);
  894. // We have allocated the new lease, so the old lease should not exist.
  895. EXPECT_FALSE(old_lease_);
  896. // We should get what we asked for
  897. EXPECT_EQ(lease->addr_.toText(), "192.0.2.105");
  898. // Do all checks on the lease
  899. checkLease4(lease);
  900. // Check that the lease is indeed in LeaseMgr
  901. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  902. ASSERT_TRUE(from_mgr);
  903. // Now check that the lease in LeaseMgr has the same parameters
  904. detailCompareLease(lease, from_mgr);
  905. }
  906. // This test checks if the allocation with a hint that is in range,
  907. // in pool, but is currently used) can succeed
  908. TEST_F(AllocEngine4Test, allocWithUsedHint4) {
  909. boost::scoped_ptr<AllocEngine> engine;
  910. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  911. 100, false)));
  912. ASSERT_TRUE(engine);
  913. // Let's create a lease and put it in the LeaseMgr
  914. uint8_t hwaddr2[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
  915. uint8_t clientid2[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
  916. time_t now = time(NULL);
  917. Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2, sizeof(hwaddr2),
  918. clientid2, sizeof(clientid2), 1, 2, 3, now, subnet_->getID()));
  919. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(used));
  920. // Another client comes in and request an address that is in pool, but
  921. // unfortunately it is used already. The same address must not be allocated
  922. // twice.
  923. Lease4Ptr lease = engine->allocateLease4(subnet_, clientid_, hwaddr_,
  924. IOAddress("192.0.2.106"),
  925. false, false, "",
  926. false, CalloutHandlePtr(),
  927. old_lease_);
  928. // New lease has been allocated, so the old lease should not exist.
  929. EXPECT_FALSE(old_lease_);
  930. // Check that we got a lease
  931. ASSERT_TRUE(lease);
  932. // Allocated address must be different
  933. EXPECT_NE(used->addr_, lease->addr_);
  934. // We should NOT get what we asked for, because it is used already
  935. EXPECT_NE("192.0.2.106", lease->addr_.toText());
  936. // Do all checks on the lease
  937. checkLease4(lease);
  938. // Check that the lease is indeed in LeaseMgr
  939. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  940. ASSERT_TRUE(from_mgr);
  941. // Now check that the lease in LeaseMgr has the same parameters
  942. detailCompareLease(lease, from_mgr);
  943. }
  944. // This test checks if the allocation with a hint that is out the blue
  945. // can succeed. The invalid hint should be ignored completely.
  946. TEST_F(AllocEngine4Test, allocBogusHint4) {
  947. boost::scoped_ptr<AllocEngine> engine;
  948. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  949. 100, false)));
  950. ASSERT_TRUE(engine);
  951. // Client would like to get a 3000::abc lease, which does not belong to any
  952. // supported lease. Allocation engine should ignore it and carry on
  953. // with the normal allocation
  954. Lease4Ptr lease = engine->allocateLease4(subnet_, clientid_, hwaddr_,
  955. IOAddress("10.1.1.1"),
  956. false, false, "",
  957. false, CalloutHandlePtr(),
  958. old_lease_);
  959. // Check that we got a lease
  960. ASSERT_TRUE(lease);
  961. // We have allocated a new lease, so the old lease should not exist.
  962. EXPECT_FALSE(old_lease_);
  963. // We should NOT get what we asked for, because it is used already
  964. EXPECT_NE("10.1.1.1", lease->addr_.toText());
  965. // Do all checks on the lease
  966. checkLease4(lease);
  967. // Check that the lease is indeed in LeaseMgr
  968. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  969. ASSERT_TRUE(from_mgr);
  970. // Now check that the lease in LeaseMgr has the same parameters
  971. detailCompareLease(lease, from_mgr);
  972. }
  973. // This test checks that NULL values are handled properly
  974. TEST_F(AllocEngine4Test, allocateLease4Nulls) {
  975. boost::scoped_ptr<AllocEngine> engine;
  976. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  977. 100, false)));
  978. ASSERT_TRUE(engine);
  979. // Allocations without subnet are not allowed
  980. Lease4Ptr lease = engine->allocateLease4(SubnetPtr(), clientid_, hwaddr_,
  981. IOAddress("0.0.0.0"),
  982. false, false, "",
  983. false, CalloutHandlePtr(),
  984. old_lease_);
  985. EXPECT_FALSE(lease);
  986. // Allocations without HW address are not allowed
  987. lease = engine->allocateLease4(subnet_, clientid_, HWAddrPtr(),
  988. IOAddress("0.0.0.0"),
  989. false, false, "",
  990. false, CalloutHandlePtr(),
  991. old_lease_);
  992. EXPECT_FALSE(lease);
  993. EXPECT_FALSE(old_lease_);
  994. // Allocations without client-id are allowed
  995. clientid_ = ClientIdPtr();
  996. lease = engine->allocateLease4(subnet_, ClientIdPtr(), hwaddr_,
  997. IOAddress("0.0.0.0"),
  998. true, true, "myhost.example.com.",
  999. false, CalloutHandlePtr(),
  1000. old_lease_);
  1001. // Check that we got a lease
  1002. ASSERT_TRUE(lease);
  1003. // New lease has been allocated, so the old lease should not exist.
  1004. EXPECT_FALSE(old_lease_);
  1005. // Do all checks on the lease
  1006. checkLease4(lease);
  1007. // Check that the lease is indeed in LeaseMgr
  1008. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  1009. ASSERT_TRUE(from_mgr);
  1010. // Now check that the lease in LeaseMgr has the same parameters
  1011. detailCompareLease(lease, from_mgr);
  1012. }
  1013. // This test verifies that the allocator picks addresses that belong to the
  1014. // pool
  1015. TEST_F(AllocEngine4Test, IterativeAllocator) {
  1016. boost::scoped_ptr<NakedAllocEngine::Allocator>
  1017. alloc(new NakedAllocEngine::IterativeAllocator(Lease::TYPE_V4));
  1018. for (int i = 0; i < 1000; ++i) {
  1019. IOAddress candidate = alloc->pickAddress(subnet_, clientid_,
  1020. IOAddress("0.0.0.0"));
  1021. EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate));
  1022. }
  1023. }
  1024. // This test verifies that the iterative allocator really walks over all addresses
  1025. // in all pools in specified subnet. It also must not pick the same address twice
  1026. // unless it runs out of pool space and must start over.
  1027. TEST_F(AllocEngine4Test, IterativeAllocator_manyPools4) {
  1028. NakedAllocEngine::IterativeAllocator alloc(Lease::TYPE_V4);
  1029. // Let's start from 2, as there is 2001:db8:1::10 - 2001:db8:1::20 pool already.
  1030. for (int i = 2; i < 10; ++i) {
  1031. stringstream min, max;
  1032. min << "192.0.2." << i * 10 + 1;
  1033. max << "192.0.2." << i * 10 + 9;
  1034. Pool4Ptr pool(new Pool4(IOAddress(min.str()),
  1035. IOAddress(max.str())));
  1036. // cout << "Adding pool: " << min.str() << "-" << max.str() << endl;
  1037. subnet_->addPool(pool);
  1038. }
  1039. int total = 10 + 8 * 9; // first pool (.100 - .109) has 10 addresses in it,
  1040. // there are 8 extra pools with 9 addresses in each.
  1041. // Let's keep picked addresses here and check their uniqueness.
  1042. std::set<IOAddress> generated_addrs;
  1043. int cnt = 0;
  1044. while (++cnt) {
  1045. IOAddress candidate = alloc.pickAddress(subnet_, clientid_, IOAddress("0.0.0.0"));
  1046. EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, candidate));
  1047. // One way to easily verify that the iterative allocator really works is
  1048. // to uncomment the following line and observe its output that it
  1049. // covers all defined subnets.
  1050. // cout << candidate.toText() << endl;
  1051. if (generated_addrs.find(candidate) == generated_addrs.end()) {
  1052. // We haven't had this
  1053. generated_addrs.insert(candidate);
  1054. } else {
  1055. // We have seen this address before. That should mean that we
  1056. // iterated over all addresses.
  1057. if (generated_addrs.size() == total) {
  1058. // We have exactly the number of address in all pools
  1059. break;
  1060. }
  1061. ADD_FAILURE() << "Too many or not enough unique addresses generated.";
  1062. break;
  1063. }
  1064. if ( cnt>total ) {
  1065. ADD_FAILURE() << "Too many unique addresses generated.";
  1066. break;
  1067. }
  1068. }
  1069. }
  1070. // This test checks if really small pools are working
  1071. TEST_F(AllocEngine4Test, smallPool4) {
  1072. boost::scoped_ptr<AllocEngine> engine;
  1073. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  1074. 100, false)));
  1075. ASSERT_TRUE(engine);
  1076. IOAddress addr("192.0.2.17");
  1077. CfgMgr& cfg_mgr = CfgMgr::instance();
  1078. cfg_mgr.deleteSubnets4(); // Get rid of the default test configuration
  1079. // Create configuration similar to other tests, but with a single address pool
  1080. subnet_ = Subnet4Ptr(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3));
  1081. pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address
  1082. subnet_->addPool(pool_);
  1083. cfg_mgr.addSubnet4(subnet_);
  1084. Lease4Ptr lease = engine->allocateLease4(subnet_, clientid_, hwaddr_,
  1085. IOAddress("0.0.0.0"),
  1086. true, true, "host.example.com.",
  1087. false, CalloutHandlePtr(),
  1088. old_lease_);
  1089. // Check that we got that single lease
  1090. ASSERT_TRUE(lease);
  1091. // We have allocated new lease, so the old lease should not exist.
  1092. EXPECT_FALSE(old_lease_);
  1093. EXPECT_EQ("192.0.2.17", lease->addr_.toText());
  1094. // Do all checks on the lease
  1095. checkLease4(lease);
  1096. // Check that the lease is indeed in LeaseMgr
  1097. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  1098. ASSERT_TRUE(from_mgr);
  1099. // Now check that the lease in LeaseMgr has the same parameters
  1100. detailCompareLease(lease, from_mgr);
  1101. }
  1102. // This test checks if all addresses in a pool are currently used, the attempt
  1103. // to find out a new lease fails.
  1104. TEST_F(AllocEngine4Test, outOfAddresses4) {
  1105. boost::scoped_ptr<AllocEngine> engine;
  1106. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  1107. 100, false)));
  1108. ASSERT_TRUE(engine);
  1109. IOAddress addr("192.0.2.17");
  1110. CfgMgr& cfg_mgr = CfgMgr::instance();
  1111. cfg_mgr.deleteSubnets4(); // Get rid of the default test configuration
  1112. // Create configuration similar to other tests, but with a single address pool
  1113. subnet_ = Subnet4Ptr(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3));
  1114. pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address
  1115. subnet_->addPool(pool_);
  1116. cfg_mgr.addSubnet4(subnet_);
  1117. // Just a different hw/client-id for the second client
  1118. uint8_t hwaddr2[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
  1119. uint8_t clientid2[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
  1120. time_t now = time(NULL);
  1121. Lease4Ptr lease(new Lease4(addr, hwaddr2, sizeof(hwaddr2), clientid2,
  1122. sizeof(clientid2), 501, 502, 503, now,
  1123. subnet_->getID()));
  1124. lease->cltt_ = time(NULL) - 10; // Allocated 10 seconds ago
  1125. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
  1126. // There is just a single address in the pool and allocated it to someone
  1127. // else, so the allocation should fail
  1128. Lease4Ptr lease2 = engine->allocateLease4(subnet_, clientid_, hwaddr_,
  1129. IOAddress("0.0.0.0"),
  1130. false, false, "",
  1131. false, CalloutHandlePtr(),
  1132. old_lease_);
  1133. EXPECT_FALSE(lease2);
  1134. EXPECT_FALSE(old_lease_);
  1135. }
  1136. // This test checks if an expired lease can be reused in DISCOVER (fake allocation)
  1137. TEST_F(AllocEngine4Test, discoverReuseExpiredLease4) {
  1138. boost::scoped_ptr<AllocEngine> engine;
  1139. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  1140. 100, false)));
  1141. ASSERT_TRUE(engine);
  1142. IOAddress addr("192.0.2.15");
  1143. CfgMgr& cfg_mgr = CfgMgr::instance();
  1144. cfg_mgr.deleteSubnets4(); // Get rid of the default test configuration
  1145. // Create configuration similar to other tests, but with a single address pool
  1146. subnet_ = Subnet4Ptr(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3));
  1147. pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address
  1148. subnet_->addPool(pool_);
  1149. cfg_mgr.addSubnet4(subnet_);
  1150. // Just a different hw/client-id for the second client
  1151. uint8_t hwaddr2[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
  1152. uint8_t clientid2[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
  1153. time_t now = time(NULL) - 500; // Allocated 500 seconds ago
  1154. Lease4Ptr lease(new Lease4(addr, clientid2, sizeof(clientid2),
  1155. hwaddr2, sizeof(hwaddr2),
  1156. 495, 100, 200, now, subnet_->getID()));
  1157. // Copy the lease, so as it can be compared with the old lease returned
  1158. // by the allocation engine.
  1159. Lease4 original_lease(*lease);
  1160. // Lease was assigned 500 seconds ago, but its valid lifetime is 495, so it
  1161. // is expired already
  1162. ASSERT_TRUE(lease->expired());
  1163. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
  1164. // CASE 1: Asking for any address
  1165. lease = engine->allocateLease4(subnet_, clientid_, hwaddr_,
  1166. IOAddress("0.0.0.0"),
  1167. false, false, "",
  1168. true, CalloutHandlePtr(),
  1169. old_lease_);
  1170. // Check that we got that single lease
  1171. ASSERT_TRUE(lease);
  1172. EXPECT_EQ(addr, lease->addr_);
  1173. // We are reusing expired lease, the old (expired) instance should be
  1174. // returned. The returned instance should be the same as the original
  1175. // lease.
  1176. ASSERT_TRUE(old_lease_);
  1177. EXPECT_TRUE(original_lease == *old_lease_);
  1178. // Do all checks on the lease (if subnet-id, preferred/valid times are ok etc.)
  1179. checkLease4(lease);
  1180. // CASE 2: Asking specifically for this address
  1181. lease = engine->allocateLease4(subnet_, clientid_, hwaddr_,
  1182. IOAddress(addr),
  1183. false, false, "",
  1184. true, CalloutHandlePtr(),
  1185. old_lease_);
  1186. // Check that we got that single lease
  1187. ASSERT_TRUE(lease);
  1188. EXPECT_EQ(addr, lease->addr_);
  1189. // We are updating expired lease. The copy of the old lease should be
  1190. // returned and it should be equal to the original lease.
  1191. ASSERT_TRUE(old_lease_);
  1192. EXPECT_TRUE(*old_lease_ == original_lease);
  1193. }
  1194. // This test checks if an expired lease can be reused in REQUEST (actual allocation)
  1195. TEST_F(AllocEngine4Test, requestReuseExpiredLease4) {
  1196. boost::scoped_ptr<AllocEngine> engine;
  1197. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  1198. 100, false)));
  1199. ASSERT_TRUE(engine);
  1200. IOAddress addr("192.0.2.105");
  1201. // Just a different hw/client-id for the second client
  1202. uint8_t hwaddr2[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
  1203. uint8_t clientid2[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
  1204. time_t now = time(NULL) - 500; // Allocated 500 seconds ago
  1205. Lease4Ptr lease(new Lease4(addr, clientid2, sizeof(clientid2), hwaddr2,
  1206. sizeof(hwaddr2), 495, 100, 200, now,
  1207. subnet_->getID()));
  1208. // Make a copy of the lease, so as we can comapre that with the old lease
  1209. // instance returned by the allocation engine.
  1210. Lease4 original_lease(*lease);
  1211. // Lease was assigned 500 seconds ago, but its valid lifetime is 495, so it
  1212. // is expired already
  1213. ASSERT_TRUE(lease->expired());
  1214. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
  1215. // A client comes along, asking specifically for this address
  1216. lease = engine->allocateLease4(subnet_, clientid_, hwaddr_,
  1217. IOAddress(addr),
  1218. false, true, "host.example.com.",
  1219. false, CalloutHandlePtr(),
  1220. old_lease_);
  1221. // Check that he got that single lease
  1222. ASSERT_TRUE(lease);
  1223. EXPECT_EQ(addr, lease->addr_);
  1224. // Check that the lease is indeed updated in LeaseMgr
  1225. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(addr);
  1226. ASSERT_TRUE(from_mgr);
  1227. // Now check that the lease in LeaseMgr has the same parameters
  1228. detailCompareLease(lease, from_mgr);
  1229. // The allocation engine should return a copy of the old lease. This
  1230. // lease should be equal to the original lease.
  1231. ASSERT_TRUE(old_lease_);
  1232. EXPECT_TRUE(*old_lease_ == original_lease);
  1233. }
  1234. /// @todo write renewLease6
  1235. // This test checks if a lease is really renewed when renewLease4 method is
  1236. // called
  1237. TEST_F(AllocEngine4Test, renewLease4) {
  1238. boost::scoped_ptr<AllocEngine> engine;
  1239. CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
  1240. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  1241. 100, false)));
  1242. ASSERT_TRUE(engine);
  1243. IOAddress addr("192.0.2.102");
  1244. const uint32_t old_lifetime = 100;
  1245. const uint32_t old_t1 = 50;
  1246. const uint32_t old_t2 = 75;
  1247. const time_t old_timestamp = time(NULL) - 45; // Allocated 45 seconds ago
  1248. // Just a different hw/client-id for the second client
  1249. const uint8_t hwaddr2[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
  1250. const uint8_t clientid2[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
  1251. Lease4Ptr lease(new Lease4(addr, clientid2, sizeof(clientid2), hwaddr2,
  1252. sizeof(hwaddr2), old_lifetime, old_t1, old_t2,
  1253. old_timestamp, subnet_->getID()));
  1254. ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
  1255. // Lease was assigned 45 seconds ago and is valid for 100 seconds. Let's
  1256. // renew it.
  1257. ASSERT_FALSE(lease->expired());
  1258. lease = engine->renewLease4(subnet_, clientid_, hwaddr_, true,
  1259. true, "host.example.com.", lease,
  1260. callout_handle, false);
  1261. // Check that he got that single lease
  1262. ASSERT_TRUE(lease);
  1263. EXPECT_EQ(addr, lease->addr_);
  1264. // Check that the lease matches subnet_, hwaddr_,clientid_ parameters
  1265. checkLease4(lease);
  1266. // Check that the lease is indeed updated in LeaseMgr
  1267. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(addr);
  1268. ASSERT_TRUE(from_mgr);
  1269. // Now check that the lease in LeaseMgr has the same parameters
  1270. detailCompareLease(lease, from_mgr);
  1271. }
  1272. /// @brief helper class used in Hooks testing in AllocEngine6
  1273. ///
  1274. /// It features a couple of callout functions and buffers to store
  1275. /// the data that is accessible via callouts.
  1276. class HookAllocEngine6Test : public AllocEngine6Test {
  1277. public:
  1278. HookAllocEngine6Test() {
  1279. resetCalloutBuffers();
  1280. }
  1281. virtual ~HookAllocEngine6Test() {
  1282. HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts(
  1283. "lease6_select");
  1284. }
  1285. /// @brief clears out buffers, so callouts can store received arguments
  1286. void resetCalloutBuffers() {
  1287. callback_name_ = string("");
  1288. callback_subnet6_.reset();
  1289. callback_fake_allocation_ = false;
  1290. callback_lease6_.reset();
  1291. callback_argument_names_.clear();
  1292. callback_addr_original_ = IOAddress("::");
  1293. callback_addr_updated_ = IOAddress("::");
  1294. }
  1295. /// callback that stores received callout name and received values
  1296. static int
  1297. lease6_select_callout(CalloutHandle& callout_handle) {
  1298. callback_name_ = string("lease6_select");
  1299. callout_handle.getArgument("subnet6", callback_subnet6_);
  1300. callout_handle.getArgument("fake_allocation", callback_fake_allocation_);
  1301. callout_handle.getArgument("lease6", callback_lease6_);
  1302. callback_addr_original_ = callback_lease6_->addr_;
  1303. callback_argument_names_ = callout_handle.getArgumentNames();
  1304. return (0);
  1305. }
  1306. /// callback that overrides the lease with different values
  1307. static int
  1308. lease6_select_different_callout(CalloutHandle& callout_handle) {
  1309. // Let's call the basic callout, so it can record all parameters
  1310. lease6_select_callout(callout_handle);
  1311. // Now we need to tweak the least a bit
  1312. Lease6Ptr lease;
  1313. callout_handle.getArgument("lease6", lease);
  1314. callback_addr_updated_ = addr_override_;
  1315. lease->addr_ = callback_addr_updated_;
  1316. lease->t1_ = t1_override_;
  1317. lease->t2_ = t2_override_;
  1318. lease->preferred_lft_ = pref_override_;
  1319. lease->valid_lft_ = valid_override_;
  1320. return (0);
  1321. }
  1322. // Values to be used in callout to override lease6 content
  1323. static const IOAddress addr_override_;
  1324. static const uint32_t t1_override_;
  1325. static const uint32_t t2_override_;
  1326. static const uint32_t pref_override_;
  1327. static const uint32_t valid_override_;
  1328. // Callback will store original and overridden values here
  1329. static IOAddress callback_addr_original_;
  1330. static IOAddress callback_addr_updated_;
  1331. // Buffers (callback will store received values here)
  1332. static string callback_name_;
  1333. static Subnet6Ptr callback_subnet6_;
  1334. static Lease6Ptr callback_lease6_;
  1335. static bool callback_fake_allocation_;
  1336. static vector<string> callback_argument_names_;
  1337. };
  1338. // For some reason intialization within a class makes the linker confused.
  1339. // linker complains about undefined references if they are defined within
  1340. // the class declaration.
  1341. const IOAddress HookAllocEngine6Test::addr_override_("2001:db8::abcd");
  1342. const uint32_t HookAllocEngine6Test::t1_override_ = 6000;
  1343. const uint32_t HookAllocEngine6Test::t2_override_ = 7000;
  1344. const uint32_t HookAllocEngine6Test::pref_override_ = 8000;
  1345. const uint32_t HookAllocEngine6Test::valid_override_ = 9000;
  1346. IOAddress HookAllocEngine6Test::callback_addr_original_("::");
  1347. IOAddress HookAllocEngine6Test::callback_addr_updated_("::");
  1348. string HookAllocEngine6Test::callback_name_;
  1349. Subnet6Ptr HookAllocEngine6Test::callback_subnet6_;
  1350. Lease6Ptr HookAllocEngine6Test::callback_lease6_;
  1351. bool HookAllocEngine6Test::callback_fake_allocation_;
  1352. vector<string> HookAllocEngine6Test::callback_argument_names_;
  1353. // This test checks if the lease6_select callout is executed and expected
  1354. // parameters as passed.
  1355. TEST_F(HookAllocEngine6Test, lease6_select) {
  1356. // Note: The following order is working as expected:
  1357. // 1. create AllocEngine (that register hook points)
  1358. // 2. call loadLibraries()
  1359. //
  1360. // This order, however, causes segfault in HooksManager
  1361. // 1. call loadLibraries()
  1362. // 2. create AllocEngine (that register hook points)
  1363. // Create allocation engine (hook names are registered in its ctor)
  1364. boost::scoped_ptr<AllocEngine> engine;
  1365. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
  1366. ASSERT_TRUE(engine);
  1367. // Initialize Hooks Manager
  1368. vector<string> libraries; // no libraries at this time
  1369. HooksManager::loadLibraries(libraries);
  1370. // Install pkt6_receive_callout
  1371. EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
  1372. "lease6_select", lease6_select_callout));
  1373. CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
  1374. Lease6Ptr lease;
  1375. EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(subnet_,
  1376. duid_, iaid_, IOAddress("::"), Lease::TYPE_NA, false, false,
  1377. "", false, callout_handle, old_leases_)));
  1378. // Check that we got a lease
  1379. ASSERT_TRUE(lease);
  1380. // Do all checks on the lease
  1381. checkLease6(lease, Lease::TYPE_NA, 128);
  1382. // Check that the lease is indeed in LeaseMgr
  1383. Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
  1384. lease->addr_);
  1385. ASSERT_TRUE(from_mgr);
  1386. // Check that callouts were indeed called
  1387. EXPECT_EQ("lease6_select", callback_name_);
  1388. // Now check that the lease in LeaseMgr has the same parameters
  1389. ASSERT_TRUE(callback_lease6_);
  1390. detailCompareLease(callback_lease6_, from_mgr);
  1391. ASSERT_TRUE(callback_subnet6_);
  1392. EXPECT_EQ(subnet_->toText(), callback_subnet6_->toText());
  1393. EXPECT_FALSE(callback_fake_allocation_);
  1394. // Check if all expected parameters are reported. It's a bit tricky, because
  1395. // order may be different. If the test starts failing, because someone tweaked
  1396. // hooks engine, we'll have to implement proper vector matching (ignoring order)
  1397. vector<string> expected_argument_names;
  1398. expected_argument_names.push_back("fake_allocation");
  1399. expected_argument_names.push_back("lease6");
  1400. expected_argument_names.push_back("subnet6");
  1401. sort(callback_argument_names_.begin(), callback_argument_names_.end());
  1402. sort(expected_argument_names.begin(), expected_argument_names.end());
  1403. EXPECT_TRUE(callback_argument_names_ == expected_argument_names);
  1404. }
  1405. // This test checks if lease6_select callout is able to override the values
  1406. // in a lease6.
  1407. TEST_F(HookAllocEngine6Test, change_lease6_select) {
  1408. // Make sure that the overridden values are different than the ones from
  1409. // subnet originally used to create the lease
  1410. ASSERT_NE(t1_override_, subnet_->getT1());
  1411. ASSERT_NE(t2_override_, subnet_->getT2());
  1412. ASSERT_NE(pref_override_, subnet_->getPreferred());
  1413. ASSERT_NE(valid_override_, subnet_->getValid());
  1414. ASSERT_FALSE(subnet_->inRange(addr_override_));
  1415. // Create allocation engine (hook names are registered in its ctor)
  1416. boost::scoped_ptr<AllocEngine> engine;
  1417. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
  1418. ASSERT_TRUE(engine);
  1419. // Initialize Hooks Manager
  1420. vector<string> libraries; // no libraries at this time
  1421. HooksManager::loadLibraries(libraries);
  1422. // Install a callout
  1423. EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
  1424. "lease6_select", lease6_select_different_callout));
  1425. // Normally, dhcpv6_srv would passed the handle when calling allocateLeases6,
  1426. // but in tests we need to create it on our own.
  1427. CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
  1428. // Call allocateLeases6. Callouts should be triggered here.
  1429. Lease6Ptr lease;
  1430. EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(subnet_,
  1431. duid_, iaid_, IOAddress("::"), Lease::TYPE_NA, false, false,
  1432. "", false, callout_handle, old_leases_)));
  1433. // Check that we got a lease
  1434. ASSERT_TRUE(lease);
  1435. // See if the values overridden by callout are there
  1436. EXPECT_TRUE(lease->addr_.equals(addr_override_));
  1437. EXPECT_EQ(t1_override_, lease->t1_);
  1438. EXPECT_EQ(t2_override_, lease->t2_);
  1439. EXPECT_EQ(pref_override_, lease->preferred_lft_);
  1440. EXPECT_EQ(valid_override_, lease->valid_lft_);
  1441. // Now check if the lease is in the database
  1442. Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease->type_,
  1443. lease->addr_);
  1444. ASSERT_TRUE(from_mgr);
  1445. // Check if values in the database are overridden
  1446. EXPECT_TRUE(from_mgr->addr_.equals(addr_override_));
  1447. EXPECT_EQ(t1_override_, from_mgr->t1_);
  1448. EXPECT_EQ(t2_override_, from_mgr->t2_);
  1449. EXPECT_EQ(pref_override_, from_mgr->preferred_lft_);
  1450. EXPECT_EQ(valid_override_, from_mgr->valid_lft_);
  1451. }
  1452. /// @brief helper class used in Hooks testing in AllocEngine4
  1453. ///
  1454. /// It features a couple of callout functions and buffers to store
  1455. /// the data that is accessible via callouts.
  1456. ///
  1457. /// Note: lease4_renew callout is tested from DHCPv4 server.
  1458. /// See HooksDhcpv4SrvTest.basic_lease4_renew in
  1459. /// src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
  1460. class HookAllocEngine4Test : public AllocEngine4Test {
  1461. public:
  1462. HookAllocEngine4Test() {
  1463. resetCalloutBuffers();
  1464. }
  1465. virtual ~HookAllocEngine4Test() {
  1466. HooksManager::preCalloutsLibraryHandle().deregisterAllCallouts(
  1467. "lease4_select");
  1468. }
  1469. /// @brief clears out buffers, so callouts can store received arguments
  1470. void resetCalloutBuffers() {
  1471. callback_name_ = string("");
  1472. callback_subnet4_.reset();
  1473. callback_fake_allocation_ = false;
  1474. callback_lease4_.reset();
  1475. callback_argument_names_.clear();
  1476. callback_addr_original_ = IOAddress("::");
  1477. callback_addr_updated_ = IOAddress("::");
  1478. }
  1479. /// callback that stores received callout name and received values
  1480. static int
  1481. lease4_select_callout(CalloutHandle& callout_handle) {
  1482. callback_name_ = string("lease4_select");
  1483. callout_handle.getArgument("subnet4", callback_subnet4_);
  1484. callout_handle.getArgument("fake_allocation", callback_fake_allocation_);
  1485. callout_handle.getArgument("lease4", callback_lease4_);
  1486. callback_addr_original_ = callback_lease4_->addr_;
  1487. callback_argument_names_ = callout_handle.getArgumentNames();
  1488. return (0);
  1489. }
  1490. /// callback that overrides the lease with different values
  1491. static int
  1492. lease4_select_different_callout(CalloutHandle& callout_handle) {
  1493. // Let's call the basic callout, so it can record all parameters
  1494. lease4_select_callout(callout_handle);
  1495. // Now we need to tweak the least a bit
  1496. Lease4Ptr lease;
  1497. callout_handle.getArgument("lease4", lease);
  1498. callback_addr_updated_ = addr_override_;
  1499. lease->addr_ = callback_addr_updated_;
  1500. lease->t1_ = t1_override_;
  1501. lease->t2_ = t2_override_;
  1502. lease->valid_lft_ = valid_override_;
  1503. return (0);
  1504. }
  1505. // Values to be used in callout to override lease4 content
  1506. static const IOAddress addr_override_;
  1507. static const uint32_t t1_override_;
  1508. static const uint32_t t2_override_;
  1509. static const uint32_t valid_override_;
  1510. // Callback will store original and overridden values here
  1511. static IOAddress callback_addr_original_;
  1512. static IOAddress callback_addr_updated_;
  1513. // Buffers (callback will store received values here)
  1514. static string callback_name_;
  1515. static Subnet4Ptr callback_subnet4_;
  1516. static Lease4Ptr callback_lease4_;
  1517. static bool callback_fake_allocation_;
  1518. static vector<string> callback_argument_names_;
  1519. };
  1520. // For some reason intialization within a class makes the linker confused.
  1521. // linker complains about undefined references if they are defined within
  1522. // the class declaration.
  1523. const IOAddress HookAllocEngine4Test::addr_override_("192.0.3.1");
  1524. const uint32_t HookAllocEngine4Test::t1_override_ = 4000;
  1525. const uint32_t HookAllocEngine4Test::t2_override_ = 7000;
  1526. const uint32_t HookAllocEngine4Test::valid_override_ = 9000;
  1527. IOAddress HookAllocEngine4Test::callback_addr_original_("::");
  1528. IOAddress HookAllocEngine4Test::callback_addr_updated_("::");
  1529. string HookAllocEngine4Test::callback_name_;
  1530. Subnet4Ptr HookAllocEngine4Test::callback_subnet4_;
  1531. Lease4Ptr HookAllocEngine4Test::callback_lease4_;
  1532. bool HookAllocEngine4Test::callback_fake_allocation_;
  1533. vector<string> HookAllocEngine4Test::callback_argument_names_;
  1534. // This test checks if the lease4_select callout is executed and expected
  1535. // parameters as passed.
  1536. TEST_F(HookAllocEngine4Test, lease4_select) {
  1537. // Note: The following order is working as expected:
  1538. // 1. create AllocEngine (that register hook points)
  1539. // 2. call loadLibraries()
  1540. //
  1541. // This order, however, causes segfault in HooksManager
  1542. // 1. call loadLibraries()
  1543. // 2. create AllocEngine (that register hook points)
  1544. // Create allocation engine (hook names are registered in its ctor)
  1545. boost::scoped_ptr<AllocEngine> engine;
  1546. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  1547. 100, false)));
  1548. ASSERT_TRUE(engine);
  1549. // Initialize Hooks Manager
  1550. vector<string> libraries; // no libraries at this time
  1551. HooksManager::loadLibraries(libraries);
  1552. // Install pkt4_receive_callout
  1553. EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
  1554. "lease4_select", lease4_select_callout));
  1555. CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
  1556. Lease4Ptr lease = engine->allocateLease4(subnet_, clientid_, hwaddr_,
  1557. IOAddress("0.0.0.0"),
  1558. false, false, "",
  1559. false, callout_handle,
  1560. old_lease_);
  1561. // Check that we got a lease
  1562. ASSERT_TRUE(lease);
  1563. // Do all checks on the lease
  1564. checkLease4(lease);
  1565. // Check that the lease is indeed in LeaseMgr
  1566. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  1567. ASSERT_TRUE(from_mgr);
  1568. // Check that callouts were indeed called
  1569. EXPECT_EQ("lease4_select", callback_name_);
  1570. // Now check that the lease in LeaseMgr has the same parameters
  1571. ASSERT_TRUE(callback_lease4_);
  1572. detailCompareLease(callback_lease4_, from_mgr);
  1573. ASSERT_TRUE(callback_subnet4_);
  1574. EXPECT_EQ(subnet_->toText(), callback_subnet4_->toText());
  1575. EXPECT_EQ(callback_fake_allocation_, false);
  1576. // Check if all expected parameters are reported. It's a bit tricky, because
  1577. // order may be different. If the test starts failing, because someone tweaked
  1578. // hooks engine, we'll have to implement proper vector matching (ignoring order)
  1579. vector<string> expected_argument_names;
  1580. expected_argument_names.push_back("fake_allocation");
  1581. expected_argument_names.push_back("lease4");
  1582. expected_argument_names.push_back("subnet4");
  1583. EXPECT_TRUE(callback_argument_names_ == expected_argument_names);
  1584. }
  1585. // This test checks if lease4_select callout is able to override the values
  1586. // in a lease4.
  1587. TEST_F(HookAllocEngine4Test, change_lease4_select) {
  1588. // Make sure that the overridden values are different than the ones from
  1589. // subnet originally used to create the lease
  1590. ASSERT_NE(t1_override_, subnet_->getT1());
  1591. ASSERT_NE(t2_override_, subnet_->getT2());
  1592. ASSERT_NE(valid_override_, subnet_->getValid());
  1593. ASSERT_FALSE(subnet_->inRange(addr_override_));
  1594. // Create allocation engine (hook names are registered in its ctor)
  1595. boost::scoped_ptr<AllocEngine> engine;
  1596. ASSERT_NO_THROW(engine.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE,
  1597. 100, false)));
  1598. ASSERT_TRUE(engine);
  1599. // Initialize Hooks Manager
  1600. vector<string> libraries; // no libraries at this time
  1601. HooksManager::loadLibraries(libraries);
  1602. // Install a callout
  1603. EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
  1604. "lease4_select", lease4_select_different_callout));
  1605. // Normally, dhcpv4_srv would passed the handle when calling allocateLease4,
  1606. // but in tests we need to create it on our own.
  1607. CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
  1608. // Call allocateLease4. Callouts should be triggered here.
  1609. Lease4Ptr lease = engine->allocateLease4(subnet_, clientid_, hwaddr_,
  1610. IOAddress("0.0.0.0"),
  1611. false, false, "",
  1612. false, callout_handle,
  1613. old_lease_);
  1614. // Check that we got a lease
  1615. ASSERT_TRUE(lease);
  1616. // See if the values overridden by callout are there
  1617. EXPECT_TRUE(lease->addr_.equals(addr_override_));
  1618. EXPECT_EQ(t1_override_, lease->t1_);
  1619. EXPECT_EQ(t2_override_, lease->t2_);
  1620. EXPECT_EQ(valid_override_, lease->valid_lft_);
  1621. // Now check if the lease is in the database
  1622. Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
  1623. ASSERT_TRUE(from_mgr);
  1624. // Check if values in the database are overridden
  1625. EXPECT_TRUE(from_mgr->addr_.equals(addr_override_));
  1626. EXPECT_EQ(t1_override_, from_mgr->t1_);
  1627. EXPECT_EQ(t2_override_, from_mgr->t2_);
  1628. EXPECT_EQ(valid_override_, from_mgr->valid_lft_);
  1629. }
  1630. }; // End of anonymous namespace