dhcp6_test_utils.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. // Copyright (C) 2013-2016 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. /// @file dhcp6_test_utils.h
  7. ///
  8. /// @brief This file contains utility classes used for DHCPv6 server testing
  9. #ifndef DHCP6_TEST_UTILS_H
  10. #define DHCP6_TEST_UTILS_H
  11. #include <gtest/gtest.h>
  12. #include <dhcp/pkt6.h>
  13. #include <dhcp/option6_ia.h>
  14. #include <dhcp/option6_iaaddr.h>
  15. #include <dhcp/option6_iaprefix.h>
  16. #include <dhcp/option6_status_code.h>
  17. #include <dhcp/option_int_array.h>
  18. #include <dhcp/option_custom.h>
  19. #include <dhcp/option.h>
  20. #include <dhcp/iface_mgr.h>
  21. #include <dhcpsrv/cfgmgr.h>
  22. #include <dhcpsrv/lease_mgr.h>
  23. #include <dhcpsrv/lease_mgr_factory.h>
  24. #include <dhcp6/dhcp6_srv.h>
  25. #include <dhcp6/parser_context.h>
  26. #include <hooks/hooks_manager.h>
  27. #include <list>
  28. namespace isc {
  29. namespace dhcp {
  30. namespace test {
  31. /// @brief Generic wrapper to provide strongly typed values.
  32. ///
  33. /// In many cases, the test fixture class methods require providing many
  34. /// parameters, of which some are optional. Some of the parameters may also
  35. /// be implicitly converted to other types. Non-careful test implementer
  36. /// may often "shift by one" or swap two values on the arguments list, which
  37. /// will be accepted by the compiler but will result in troubles running the
  38. /// function. Sometimes it takes non trivial amount of debugging to find out
  39. /// why the particular function fails until we find that the arguments were
  40. /// swapped or shifted. In addition, the use of classes wrapping simple types
  41. /// results in better readability of the test code.
  42. ///
  43. /// @tparam ValueType Type of the wrapped value.
  44. template<typename ValueType>
  45. struct SpecializedTypeWrapper {
  46. /// @brief Constructor
  47. ///
  48. /// @param value Wrapped value
  49. explicit SpecializedTypeWrapper(const ValueType& value)
  50. : value_(value) { }
  51. /// @brief Operator returning a wrapped value.
  52. operator ValueType () const {
  53. return (value_);
  54. }
  55. /// @brief Wrapped value.
  56. ValueType value_;
  57. };
  58. /// @brief Class representing strongly typed IAID.
  59. struct IAID : public SpecializedTypeWrapper<uint32_t> {
  60. /// @brief Constructor
  61. ///
  62. /// @param iaid IAID.
  63. explicit IAID(const uint32_t iaid)
  64. : SpecializedTypeWrapper<uint32_t>(iaid) { }
  65. };
  66. /// @brief Class representing strongly typed value for strict IAID checks.
  67. ///
  68. /// Strict IAID checks are used to verify that the particular address has been
  69. /// assign to a specific IA. In many cases we don't check that because it may
  70. /// not be possible to predict to which IA the specific lease will be assigned.
  71. struct StrictIAIDChecking : public SpecializedTypeWrapper<bool> {
  72. /// @brief Constructor.
  73. ///
  74. /// @param strict_check Boolean value indicating if strict checking should
  75. /// be performed.
  76. explicit StrictIAIDChecking(const bool strict_check)
  77. : SpecializedTypeWrapper<bool>(strict_check) { }
  78. /// @brief Convenience function returning an object indicating that strict
  79. /// checks should be performed.
  80. static const StrictIAIDChecking YES() {
  81. static StrictIAIDChecking strict_check(true);
  82. return (strict_check);
  83. }
  84. /// @brief Convenience function returning an object indicating that strict
  85. /// checks should not be performed.
  86. static StrictIAIDChecking NO() {
  87. static StrictIAIDChecking strict_check(false);
  88. return (strict_check);
  89. }
  90. };
  91. /// @brief Base class for DHCPv6 server testing.
  92. ///
  93. /// Currently it configures the test data path directory in
  94. /// the @c CfgMgr. When the object is destroyed, the original
  95. /// path is reverted.
  96. class BaseServerTest : public ::testing::Test {
  97. public:
  98. /// @brief Location of a test DUID file
  99. static const char* DUID_FILE;
  100. /// @brief Constructor.
  101. BaseServerTest();
  102. /// @brief Destructor.
  103. virtual ~BaseServerTest();
  104. private:
  105. /// @brief Holds the original data directory.
  106. std::string original_datadir_;
  107. };
  108. /// @brief "naked" Dhcpv6Srv class that exposes internal members
  109. class NakedDhcpv6Srv: public isc::dhcp::Dhcpv6Srv {
  110. public:
  111. NakedDhcpv6Srv(uint16_t port) : isc::dhcp::Dhcpv6Srv(port) {
  112. // Open the "memfile" database for leases
  113. std::string memfile = "type=memfile universe=6 persist=false";
  114. isc::dhcp::LeaseMgrFactory::create(memfile);
  115. }
  116. /// @brief fakes packet reception
  117. /// @param timeout ignored
  118. ///
  119. /// The method receives all packets queued in receive
  120. /// queue, one after another. Once the queue is empty,
  121. /// it initiates the shutdown procedure.
  122. ///
  123. /// See fake_received_ field for description
  124. virtual isc::dhcp::Pkt6Ptr receivePacket(int /*timeout*/) {
  125. // If there is anything prepared as fake incoming
  126. // traffic, use it
  127. if (!fake_received_.empty()) {
  128. isc::dhcp::Pkt6Ptr pkt = fake_received_.front();
  129. fake_received_.pop_front();
  130. return (pkt);
  131. }
  132. // If not, just trigger shutdown and
  133. // return immediately
  134. shutdown();
  135. return (isc::dhcp::Pkt6Ptr());
  136. }
  137. /// @brief fake packet sending
  138. ///
  139. /// Pretend to send a packet, but instead just store
  140. /// it in fake_send_ list where test can later inspect
  141. /// server's response.
  142. virtual void sendPacket(const isc::dhcp::Pkt6Ptr& pkt) {
  143. fake_sent_.push_back(pkt);
  144. }
  145. /// @brief adds a packet to fake receive queue
  146. ///
  147. /// See fake_received_ field for description
  148. void fakeReceive(const isc::dhcp::Pkt6Ptr& pkt) {
  149. fake_received_.push_back(pkt);
  150. }
  151. virtual ~NakedDhcpv6Srv() {
  152. // Close the lease database
  153. isc::dhcp::LeaseMgrFactory::destroy();
  154. }
  155. using Dhcpv6Srv::processSolicit;
  156. using Dhcpv6Srv::processRequest;
  157. using Dhcpv6Srv::processRenew;
  158. using Dhcpv6Srv::processRebind;
  159. using Dhcpv6Srv::processConfirm;
  160. using Dhcpv6Srv::processRelease;
  161. using Dhcpv6Srv::processDecline;
  162. using Dhcpv6Srv::processInfRequest;
  163. using Dhcpv6Srv::processClientFqdn;
  164. using Dhcpv6Srv::createNameChangeRequests;
  165. using Dhcpv6Srv::selectSubnet;
  166. using Dhcpv6Srv::testServerID;
  167. using Dhcpv6Srv::testUnicast;
  168. using Dhcpv6Srv::sanityCheck;
  169. using Dhcpv6Srv::classifyPacket;
  170. using Dhcpv6Srv::shutdown_;
  171. using Dhcpv6Srv::name_change_reqs_;
  172. using Dhcpv6Srv::VENDOR_CLASS_PREFIX;
  173. using Dhcpv6Srv::initContext;
  174. /// @brief packets we pretend to receive
  175. ///
  176. /// Instead of setting up sockets on interfaces that change between
  177. /// OSes, it is much easier to fake packet reception. This is a list
  178. /// of packets that we pretend to have received. You can schedule
  179. /// new packets to be received using fakeReceive() and
  180. /// NakedDhcpv6Srv::receivePacket() methods.
  181. std::list<isc::dhcp::Pkt6Ptr> fake_received_;
  182. std::list<isc::dhcp::Pkt6Ptr> fake_sent_;
  183. };
  184. /// @brief Test fixture for any tests requiring blank/empty configuration
  185. /// serves as base class for additional tests
  186. class NakedDhcpv6SrvTest : public BaseServerTest {
  187. public:
  188. /// @brief Constructor
  189. NakedDhcpv6SrvTest();
  190. // Generate IA_NA or IA_PD option with specified parameters
  191. boost::shared_ptr<isc::dhcp::Option6IA> generateIA
  192. (uint16_t type, uint32_t iaid, uint32_t t1, uint32_t t2);
  193. /// @brief generates interface-id option, based on text
  194. ///
  195. /// @param iface_id textual representation of the interface-id content
  196. ///
  197. /// @return pointer to the option object
  198. isc::dhcp::OptionPtr generateInterfaceId(const std::string& iface_id) {
  199. isc::dhcp::OptionBuffer tmp(iface_id.begin(), iface_id.end());
  200. return (isc::dhcp::OptionPtr
  201. (new isc::dhcp::Option(isc::dhcp::Option::V6,
  202. D6O_INTERFACE_ID, tmp)));
  203. }
  204. // Generate client-id option
  205. isc::dhcp::OptionPtr generateClientId(size_t duid_size = 32) {
  206. isc::dhcp::OptionBuffer clnt_duid(duid_size);
  207. for (size_t i = 0; i < duid_size; i++) {
  208. clnt_duid[i] = 100 + i;
  209. }
  210. duid_ = isc::dhcp::DuidPtr(new isc::dhcp::DUID(clnt_duid));
  211. return (isc::dhcp::OptionPtr
  212. (new isc::dhcp::Option(isc::dhcp::Option::V6, D6O_CLIENTID,
  213. clnt_duid.begin(),
  214. clnt_duid.begin() + duid_size)));
  215. }
  216. // Checks if server response (ADVERTISE or REPLY) includes proper
  217. // server-id.
  218. void checkServerId(const isc::dhcp::Pkt6Ptr& rsp,
  219. const isc::dhcp::OptionPtr& expected_srvid)
  220. {
  221. // check that server included its server-id
  222. isc::dhcp::OptionPtr tmp = rsp->getOption(D6O_SERVERID);
  223. EXPECT_EQ(tmp->getType(), expected_srvid->getType() );
  224. ASSERT_EQ(tmp->len(), expected_srvid->len() );
  225. EXPECT_TRUE(tmp->getData() == expected_srvid->getData());
  226. }
  227. // Checks if server response (ADVERTISE or REPLY) includes proper
  228. // client-id.
  229. void checkClientId(const isc::dhcp::Pkt6Ptr& rsp,
  230. const isc::dhcp::OptionPtr& expected_clientid)
  231. {
  232. // check that server included our own client-id
  233. isc::dhcp::OptionPtr tmp = rsp->getOption(D6O_CLIENTID);
  234. ASSERT_TRUE(tmp);
  235. EXPECT_EQ(expected_clientid->getType(), tmp->getType());
  236. ASSERT_EQ(expected_clientid->len(), tmp->len());
  237. // check that returned client-id is valid
  238. EXPECT_TRUE(expected_clientid->getData() == tmp->getData());
  239. }
  240. // Checks if server response is a NAK
  241. void checkNakResponse(const isc::dhcp::Pkt6Ptr& rsp,
  242. uint8_t expected_message_type,
  243. uint32_t expected_transid,
  244. uint16_t expected_status_code,
  245. uint32_t expected_t1, uint32_t expected_t2)
  246. {
  247. // Check if we get response at all
  248. checkResponse(rsp, expected_message_type, expected_transid);
  249. // Check that IA_NA was returned
  250. isc::dhcp::OptionPtr option_ia_na = rsp->getOption(D6O_IA_NA);
  251. ASSERT_TRUE(option_ia_na);
  252. // check that the status is no address available
  253. boost::shared_ptr<isc::dhcp::Option6IA> ia =
  254. boost::dynamic_pointer_cast<isc::dhcp::Option6IA>(option_ia_na);
  255. ASSERT_TRUE(ia);
  256. checkIA_NAStatusCode(ia, expected_status_code, expected_t1,
  257. expected_t2);
  258. }
  259. /// @brief Checks that the server inserted expected status code in IA_NA
  260. ///
  261. /// Check that the server used status code as expected, i.e. that it has
  262. /// no addresses (if status code is non-zero) and that expected status
  263. /// code really appears there. In some limited cases (reply to RELEASE)
  264. /// it may be used to verify positive case, where IA_NA response is
  265. /// expected to not include address.
  266. ///
  267. /// Status code indicates type of error encountered (in theory it can also
  268. /// indicate success, but servers typically don't send success status
  269. /// as this is the default result and it saves bandwidth)
  270. /// @param ia IA_NA container to be checked
  271. /// @param expected_status_code expected value in status-code option
  272. /// @param expected_t1 expected T1 in IA_NA option
  273. /// @param expected_t2 expected T2 in IA_NA option
  274. /// @param check_addr whether to check for address with 0 lifetimes
  275. void checkIA_NAStatusCode
  276. (const boost::shared_ptr<isc::dhcp::Option6IA>& ia,
  277. uint16_t expected_status_code, uint32_t expected_t1,
  278. uint32_t expected_t2, bool check_addr = true);
  279. void checkMsgStatusCode(const isc::dhcp::Pkt6Ptr& msg,
  280. uint16_t expected_status)
  281. {
  282. isc::dhcp::Option6StatusCodePtr status =
  283. boost::dynamic_pointer_cast<isc::dhcp::Option6StatusCode>
  284. (msg->getOption(D6O_STATUS_CODE));
  285. // It is ok to not include status success as this is the default
  286. // behavior
  287. if (expected_status == STATUS_Success && !status) {
  288. return;
  289. }
  290. EXPECT_TRUE(status);
  291. if (status) {
  292. // We don't have dedicated class for status code, so let's
  293. // just interpret first 2 bytes as status. Remainder of the
  294. // status code option content is just a text explanation
  295. // what went wrong.
  296. EXPECT_EQ(static_cast<uint16_t>(expected_status),
  297. status->getStatusCode());
  298. }
  299. }
  300. // Basic checks for generated response (message type and transaction-id).
  301. void checkResponse(const isc::dhcp::Pkt6Ptr& rsp,
  302. uint8_t expected_message_type,
  303. uint32_t expected_transid) {
  304. ASSERT_TRUE(rsp);
  305. EXPECT_EQ(expected_message_type, rsp->getType());
  306. EXPECT_EQ(expected_transid, rsp->getTransid());
  307. }
  308. virtual ~NakedDhcpv6SrvTest();
  309. // A DUID used in most tests (typically as client-id)
  310. isc::dhcp::DuidPtr duid_;
  311. int rcode_;
  312. isc::data::ConstElementPtr comment_;
  313. // Name of a valid network interface
  314. std::string valid_iface_;
  315. };
  316. // We need to pass one reference to the Dhcp6Client, which is defined in
  317. // dhcp6_client.h. That header includes this file. To avoid circular
  318. // dependencies, we use forward declaration here.
  319. class Dhcp6Client;
  320. // Provides suport for tests against a preconfigured subnet6
  321. // extends upon NakedDhcp6SrvTest
  322. class Dhcpv6SrvTest : public NakedDhcpv6SrvTest {
  323. public:
  324. /// @brief Specifies expected outcome
  325. enum ExpectedResult {
  326. SHOULD_PASS, // pass = accept decline, move lease to declined state.
  327. SHOULD_FAIL // fail = reject the decline
  328. };
  329. /// @brief Specifies what address should the client include in its Decline
  330. enum AddressInclusion {
  331. VALID_ADDR, // Client will include its own, valid address
  332. BOGUS_ADDR, // Client will include an address it doesn't own
  333. NO_ADDR, // Client will send empty IA_NA (without address)
  334. NO_IA // Client will not send IA_NA at all
  335. };
  336. /// @brief Constructor that initializes a simple default configuration
  337. ///
  338. /// Sets up a single subnet6 with one pool for addresses and second
  339. /// pool for prefixes.
  340. Dhcpv6SrvTest();
  341. /// @brief destructor
  342. ///
  343. /// Removes existing configuration.
  344. ~Dhcpv6SrvTest() {
  345. isc::dhcp::CfgMgr::instance().clear();
  346. };
  347. /// @brief Runs DHCPv6 configuration from the JSON string.
  348. ///
  349. /// @param config String holding server configuration in JSON format.
  350. void configure(const std::string& config);
  351. /// @brief Configure the DHCPv6 server using the JSON string.
  352. ///
  353. /// @param config String holding server configuration in JSON format.
  354. /// @param srv Server to be configured.
  355. void configure(const std::string& config, NakedDhcpv6Srv& srv);
  356. /// @brief Checks that server response (ADVERTISE or REPLY) contains proper
  357. /// IA_NA option
  358. ///
  359. /// @param rsp server's response
  360. /// @param expected_iaid expected IAID value
  361. /// @param expected_t1 expected T1 value
  362. /// @param expected_t2 expected T2 value
  363. /// @return IAADDR option for easy chaining with checkIAAddr method
  364. boost::shared_ptr<isc::dhcp::Option6IAAddr>
  365. checkIA_NA(const isc::dhcp::Pkt6Ptr& rsp, uint32_t expected_iaid,
  366. uint32_t expected_t1, uint32_t expected_t2);
  367. /// @brief Checks that server response (ADVERTISE or REPLY) contains proper
  368. /// IA_PD option
  369. ///
  370. /// @param rsp server's response
  371. /// @param expected_iaid expected IAID value
  372. /// @param expected_t1 expected T1 value
  373. /// @param expected_t2 expected T2 value
  374. /// @return IAPREFIX option for easy chaining with checkIAAddr method
  375. boost::shared_ptr<isc::dhcp::Option6IAPrefix>
  376. checkIA_PD(const isc::dhcp::Pkt6Ptr& rsp, uint32_t expected_iaid,
  377. uint32_t expected_t1, uint32_t expected_t2);
  378. // Check that generated IAADDR option contains expected address
  379. // and lifetime values match the configured subnet
  380. void checkIAAddr(const boost::shared_ptr<isc::dhcp::Option6IAAddr>& addr,
  381. const isc::asiolink::IOAddress& expected_addr,
  382. isc::dhcp::Lease::Type type) {
  383. // Check that the assigned address is indeed from the configured pool.
  384. // Note that when comparing addresses, we compare the textual
  385. // representation. IOAddress does not support being streamed to
  386. // an ostream, which means it can't be used in EXPECT_EQ.
  387. EXPECT_TRUE(subnet_->inPool(type, addr->getAddress()));
  388. EXPECT_EQ(expected_addr.toText(), addr->getAddress().toText());
  389. EXPECT_EQ(subnet_->getPreferred(), addr->getPreferred());
  390. EXPECT_EQ(subnet_->getValid(), addr->getValid());
  391. }
  392. // Checks if the lease sent to client is present in the database
  393. // and is valid when checked against the configured subnet
  394. isc::dhcp::Lease6Ptr checkLease
  395. (const isc::dhcp::DuidPtr& duid, const isc::dhcp::OptionPtr& ia_na,
  396. boost::shared_ptr<isc::dhcp::Option6IAAddr> addr);
  397. /// @brief Check if the specified lease is present in the data base.
  398. ///
  399. /// @param lease Lease to be searched in the database.
  400. /// @return Pointer to the lease in the database.
  401. isc::dhcp::Lease6Ptr checkLease(const isc::dhcp::Lease6& lease);
  402. /// @brief Verifies received IAPrefix option
  403. ///
  404. /// Verifies if the received IAPrefix option matches the lease in the
  405. /// database.
  406. ///
  407. /// @param duid client's DUID
  408. /// @param ia_pd IA_PD option that contains the IAPRefix option
  409. /// @param prefix pointer to the IAPREFIX option
  410. /// @return corresponding IPv6 lease (if found)
  411. isc::dhcp::Lease6Ptr checkPdLease
  412. (const isc::dhcp::DuidPtr& duid, const isc::dhcp::OptionPtr& ia_pd,
  413. boost::shared_ptr<isc::dhcp::Option6IAPrefix> prefix);
  414. /// @brief Creates a message with specified IA
  415. ///
  416. /// A utility function that creates a message of the specified type with
  417. /// a specified container (IA_NA or IA_PD) and an address or prefix
  418. /// inside it.
  419. ///
  420. /// @param message_type type of the message (e.g. DHCPV6_SOLICIT)
  421. /// @param lease_type type of a lease (TYPE_NA or TYPE_PD)
  422. /// @param addr address or prefix to use in IADDRESS or IAPREFIX options
  423. /// @param prefix_len length of the prefix (used for prefixes only)
  424. /// @param iaid IA identifier (used in IA_XX option)
  425. /// @return created message
  426. isc::dhcp::Pkt6Ptr
  427. createMessage(uint8_t message_type, isc::dhcp::Lease::Type lease_type,
  428. const isc::asiolink::IOAddress& addr,
  429. const uint8_t prefix_len, const uint32_t iaid);
  430. /// @brief Creates instance of IA option holding single address or prefix.
  431. ///
  432. /// Utility function that creates an IA option instance with a single
  433. /// IPv6 address or prefix. This function is internally called by the
  434. /// @c createMessage function. It may be also used to add additional
  435. /// IA options to the message generated by @c createMessage (which adds
  436. /// a single IA option by itself.).
  437. ///
  438. /// @param lease_type type of the lease (TYPE_NA or TYPE_PD).
  439. /// @param addr address or prefix to use in IADDRESS or IAPREFIX options.
  440. /// @param prefix_len length of the prefix (used for PD, ignored for NA).
  441. /// @param iaid IA identifier.
  442. ///
  443. /// @return Created instance of the IA option.
  444. isc::dhcp::Option6IAPtr
  445. createIA(isc::dhcp::Lease::Type lease_type,
  446. const isc::asiolink::IOAddress& addr,
  447. const uint8_t prefix_len, const uint32_t iaid);
  448. /// @brief Compare options
  449. ///
  450. /// This method compares whether options content is identical. It writes
  451. /// both options to a buffer and then compares the buffers. Comparing
  452. /// two different instances of an option that has identical content
  453. /// will return true.
  454. ///
  455. /// It is safe to pass NULL pointers. Two NULL pointers are equal.
  456. /// NULL pointer and non-NULL pointers are obviously non-equal.
  457. ///
  458. /// @param option1 pointer to the first option
  459. /// @param option2
  460. /// @return true, if content is identical
  461. bool compareOptions(const isc::dhcp::OptionPtr& option1,
  462. const isc::dhcp::OptionPtr& option2);
  463. /// @brief Tests if the acquired lease is or is not declined.
  464. ///
  465. /// @param client Dhcp6Client instance
  466. /// @param duid1 DUID used during lease acquisition
  467. /// @param iaid1 IAID used during lease acquisition
  468. /// @param duid2 DUID used during Decline exchange
  469. /// @param iaid2 IAID used during Decline exchange
  470. /// @param addr_type specify what sort of address the client should
  471. /// include (its own, a bogus one or no address at all)
  472. /// @param expected_result SHOULD_PASS if the lease is expected to
  473. /// be successfully declined, or SHOULD_FAIL if the lease is expected
  474. /// to not be declined.
  475. void acquireAndDecline(Dhcp6Client& client,
  476. const std::string& duid1,
  477. const uint32_t iaid1,
  478. const std::string& duid2,
  479. const uint32_t iaid2,
  480. AddressInclusion addr_type,
  481. ExpectedResult expected_result);
  482. /// @brief Performs basic (positive) RENEW test
  483. ///
  484. /// See renewBasic and pdRenewBasic tests for detailed explanation.
  485. /// In essence the test attempts to perform a successful RENEW scenario.
  486. ///
  487. /// This method does not throw, but uses gtest macros to signify failures.
  488. ///
  489. /// @param type type (TYPE_NA or TYPE_PD)
  490. /// @param existing_addr address to be preinserted into the database
  491. /// @param renew_addr address being sent in RENEW
  492. /// @param prefix_len length of the prefix (128 for addresses)
  493. /// @param insert_before_renew should the lease be inserted into the database
  494. /// before we try renewal?
  495. void
  496. testRenewBasic(isc::dhcp::Lease::Type type,
  497. const std::string& existing_addr,
  498. const std::string& renew_addr, const uint8_t prefix_len,
  499. bool insert_before_renew = true);
  500. /// @brief Checks if RENEW with invalid IAID is processed correctly.
  501. ///
  502. /// @param type lease type (currently only IA_NA is supported)
  503. /// @param addr address to be renewed
  504. void
  505. testRenewWrongIAID(isc::dhcp::Lease::Type type,
  506. const asiolink::IOAddress& addr);
  507. /// @brief Checks if client A can renew address used by client B
  508. ///
  509. /// @param type lease type (currently only IA_NA is supported)
  510. /// @param addr address to be renewed
  511. void
  512. testRenewSomeoneElsesLease(isc::dhcp::Lease::Type type,
  513. const asiolink::IOAddress& addr);
  514. /// @brief Performs basic (positive) RELEASE test
  515. ///
  516. /// See releaseBasic and pdReleaseBasic tests for detailed explanation.
  517. /// In essence the test attempts to perform a successful RELEASE scenario.
  518. ///
  519. /// This method does not throw, but uses gtest macros to signify failures.
  520. ///
  521. /// @param type type (TYPE_NA or TYPE_PD)
  522. /// @param existing address to be preinserted into the database
  523. /// @param release_addr address being sent in RELEASE
  524. void
  525. testReleaseBasic(isc::dhcp::Lease::Type type,
  526. const isc::asiolink::IOAddress& existing,
  527. const isc::asiolink::IOAddress& release_addr);
  528. /// @brief Performs negative RELEASE test
  529. ///
  530. /// See releaseReject and pdReleaseReject tests for detailed
  531. /// explanation. In essence the test attempts to perform couple
  532. /// failed RELEASE scenarios.
  533. ///
  534. /// This method does not throw, but uses gtest macros to signify failures.
  535. ///
  536. /// @param type type (TYPE_NA or TYPE_PD)
  537. /// @param addr address being sent in RELEASE
  538. void
  539. testReleaseReject(isc::dhcp::Lease::Type type,
  540. const isc::asiolink::IOAddress& addr);
  541. /// @brief simulates reception of a packet of specified type and checks statistic
  542. ///
  543. /// @param pkt_type reception of a packet of this type will be simulated
  544. /// @param stat_name this statistic is expected to be set to 1
  545. void testReceiveStats(uint8_t pkt_type, const std::string& stat_name);
  546. /// A subnet used in most tests
  547. isc::dhcp::Subnet6Ptr subnet_;
  548. /// A normal, non-temporary pool used in most tests
  549. isc::dhcp::Pool6Ptr pool_;
  550. /// A prefix pool used in most tests
  551. isc::dhcp::Pool6Ptr pd_pool_;
  552. /// @brief Server object under test.
  553. NakedDhcpv6Srv srv_;
  554. };
  555. /// @brief Runs parser in JSON mode, useful for parser testing
  556. ///
  557. /// @param in string to be parsed
  558. /// @return ElementPtr structure representing parsed JSON
  559. inline isc::data::ConstElementPtr
  560. parseJSON(const std::string& in)
  561. {
  562. isc::dhcp::Parser6Context ctx;
  563. return (ctx.parseString(in, isc::dhcp::Parser6Context::PARSER_JSON));
  564. }
  565. /// @brief Runs parser in Dhcp6 mode
  566. ///
  567. /// This is a simplified Dhcp6 mode, so no outer { } and "Dhcp6" is
  568. /// needed. This format is used by most of the tests.
  569. ///
  570. /// @param in string to be parsed
  571. /// @return ElementPtr structure representing parsed JSON
  572. inline isc::data::ConstElementPtr
  573. parseDHCP6(const std::string& in)
  574. {
  575. try {
  576. isc::dhcp::Parser6Context ctx;
  577. return (ctx.parseString(in, isc::dhcp::Parser6Context::SUBPARSER_DHCP6));
  578. }
  579. catch (const std::exception& ex) {
  580. std::cout << "EXCEPTION: " << ex.what() << std::endl;
  581. throw;
  582. }
  583. }
  584. /// @brief Runs parser in option definition mode
  585. ///
  586. /// This function parses specified text as JSON that defines option definitions.
  587. ///
  588. /// @param in string to be parsed
  589. /// @return ElementPtr structure representing parsed JSON
  590. inline isc::data::ConstElementPtr
  591. parseOPTION_DEF(const std::string& in)
  592. {
  593. try {
  594. isc::dhcp::Parser6Context ctx;
  595. return (ctx.parseString(in, isc::dhcp::Parser6Context::PARSER_OPTION_DEF));
  596. }
  597. catch (const std::exception& ex) {
  598. std::cout << "EXCEPTION: " << ex.what() << std::endl;
  599. throw;
  600. }
  601. }
  602. }; // end of isc::dhcp::test namespace
  603. }; // end of isc::dhcp namespace
  604. }; // end of isc namespace
  605. #endif // DHCP6_TEST_UTILS_H