nc_remove_unittests.cc 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878
  1. // Copyright (C) 2013-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 <d2/d2_cfg_mgr.h>
  15. #include <d2/d2_cfg_mgr.h>
  16. #include <d2/nc_remove.h>
  17. #include <dns/messagerenderer.h>
  18. #include <nc_test_utils.h>
  19. #include <boost/function.hpp>
  20. #include <boost/bind.hpp>
  21. #include <gtest/gtest.h>
  22. using namespace std;
  23. using namespace isc;
  24. using namespace isc::d2;
  25. namespace {
  26. /// @brief Test class derived from NameRemoveTransaction to provide visiblity
  27. // to protected methods.
  28. class NameRemoveStub : public NameRemoveTransaction {
  29. public:
  30. NameRemoveStub(IOServicePtr& io_service,
  31. dhcp_ddns::NameChangeRequestPtr& ncr,
  32. DdnsDomainPtr& forward_domain,
  33. DdnsDomainPtr& reverse_domain,
  34. D2CfgMgrPtr& cfg_mgr)
  35. : NameRemoveTransaction(io_service, ncr, forward_domain,
  36. reverse_domain, cfg_mgr),
  37. simulate_send_exception_(false),
  38. simulate_build_request_exception_(false) {
  39. }
  40. virtual ~NameRemoveStub() {
  41. }
  42. /// @brief Simulates sending update requests to the DNS server
  43. ///
  44. /// This method simulates the initiation of an asynchronous send of
  45. /// a DNS update request. It overrides the actual sendUpdate method in
  46. /// the base class, thus avoiding an actual send, yet still increments
  47. /// the update attempt count and posts a next event of NOP_EVT.
  48. ///
  49. /// It will also simulate an exception-based failure of sendUpdate, if
  50. /// the simulate_send_exception_ flag is true.
  51. ///
  52. /// @param comment Parameter is unused, but present in base class method
  53. /// @param use_tsig Parameter is unused, but present in base class method.
  54. ///
  55. virtual void sendUpdate(const std::string& /* comment */,
  56. bool /* use_tsig = false */) {
  57. if (simulate_send_exception_) {
  58. // Make the flag a one-shot by resetting it.
  59. simulate_send_exception_ = false;
  60. // Transition to failed.
  61. transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
  62. return;
  63. }
  64. // Update send attempt count and post a NOP_EVT.
  65. setUpdateAttempts(getUpdateAttempts() + 1);
  66. postNextEvent(StateModel::NOP_EVT);
  67. }
  68. /// @brief Prepares the initial D2UpdateMessage
  69. ///
  70. /// This method overrides the NameChangeTransactio implementation to
  71. /// provide the ability to simulate an exception throw in the build
  72. /// request logic.
  73. /// If the one-shot flag, simulate_build_request_exception_ is true,
  74. /// this method will throw an exception, otherwise it will invoke the
  75. /// base class method, providing normal functionality.
  76. ///
  77. /// For parameter description see the NameChangeTransaction implementation.
  78. virtual D2UpdateMessagePtr prepNewRequest(DdnsDomainPtr domain) {
  79. if (simulate_build_request_exception_) {
  80. simulate_build_request_exception_ = false;
  81. isc_throw (NameRemoveTransactionError,
  82. "Simulated build requests exception");
  83. }
  84. return (NameChangeTransaction::prepNewRequest(domain));
  85. }
  86. /// @brief Simulates receiving a response
  87. ///
  88. /// This method simulates the completion of a DNSClient send. This allows
  89. /// the state handler logic devoted to dealing with IO completion to be
  90. /// fully exercised without requiring any actual IO. The two primary
  91. /// pieces of information gleaned from IO completion are the DNSClient
  92. /// status which indicates whether or not the IO exchange was successful
  93. /// and the rcode, which indicates the server's reaction to the request.
  94. ///
  95. /// This method updates the transaction's DNS status value to that of the
  96. /// given parameter, and then constructs and DNS update response message
  97. /// with the given rcode value. To complete the simulation it then posts
  98. /// a next event of IO_COMPLETED_EVT.
  99. ///
  100. /// @param status simulated DNSClient status
  101. /// @param rcode simulated server response code
  102. void fakeResponse(const DNSClient::Status& status,
  103. const dns::Rcode& rcode) {
  104. // Set the DNS update status. This is normally set in
  105. // DNSClient IO completion handler.
  106. setDnsUpdateStatus(status);
  107. // Construct an empty message with the given Rcode.
  108. D2UpdateMessagePtr msg(new D2UpdateMessage(D2UpdateMessage::OUTBOUND));
  109. msg->setRcode(rcode);
  110. // Set the update response to the message.
  111. setDnsUpdateResponse(msg);
  112. // Post the IO completion event.
  113. postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  114. }
  115. /// @brief Selects the first forward server.
  116. /// Some state handlers require a server to have been selected.
  117. /// This selects a server without going through the state
  118. /// transition(s) to do so.
  119. bool selectFwdServer() {
  120. if (getForwardDomain()) {
  121. initServerSelection(getForwardDomain());
  122. selectNextServer();
  123. return (getCurrentServer());
  124. }
  125. return (false);
  126. }
  127. /// @brief Selects the first reverse server.
  128. /// Some state handlers require a server to have been selected.
  129. /// This selects a server without going through the state
  130. /// transition(s) to do so.
  131. bool selectRevServer() {
  132. if (getReverseDomain()) {
  133. initServerSelection(getReverseDomain());
  134. selectNextServer();
  135. return (getCurrentServer());
  136. }
  137. return (false);
  138. }
  139. /// @brief One-shot flag which will simulate sendUpdate failure if true.
  140. bool simulate_send_exception_;
  141. /// @brief One-shot flag which will simulate an exception when sendUpdate
  142. /// failure if true.
  143. bool simulate_build_request_exception_;
  144. using StateModel::postNextEvent;
  145. using StateModel::setState;
  146. using StateModel::initDictionaries;
  147. using NameRemoveTransaction::defineEvents;
  148. using NameRemoveTransaction::verifyEvents;
  149. using NameRemoveTransaction::defineStates;
  150. using NameRemoveTransaction::verifyStates;
  151. using NameRemoveTransaction::readyHandler;
  152. using NameRemoveTransaction::selectingFwdServerHandler;
  153. using NameRemoveTransaction::getCurrentServer;
  154. using NameRemoveTransaction::removingFwdAddrsHandler;
  155. using NameRemoveTransaction::setDnsUpdateStatus;
  156. using NameRemoveTransaction::removingFwdRRsHandler;
  157. using NameRemoveTransaction::selectingRevServerHandler;
  158. using NameRemoveTransaction::removingRevPtrsHandler;
  159. using NameRemoveTransaction::processRemoveOkHandler;
  160. using NameRemoveTransaction::processRemoveFailedHandler;
  161. using NameRemoveTransaction::buildRemoveFwdAddressRequest;
  162. using NameRemoveTransaction::buildRemoveFwdRRsRequest;
  163. using NameRemoveTransaction::buildRemoveRevPtrsRequest;
  164. };
  165. typedef boost::shared_ptr<NameRemoveStub> NameRemoveStubPtr;
  166. /// @brief Test fixture for testing NameRemoveTransaction
  167. ///
  168. /// Note this class uses NameRemoveStub class to exercise non-public
  169. /// aspects of NameRemoveTransaction.
  170. class NameRemoveTransactionTest : public TransactionTest {
  171. public:
  172. NameRemoveTransactionTest() {
  173. }
  174. virtual ~NameRemoveTransactionTest() {
  175. }
  176. /// @brief Creates a transaction which requests an IPv4 DNS update.
  177. ///
  178. /// The transaction is constructed around a predefined (i.e. "canned")
  179. /// IPv4 NameChangeRequest. The request has both forward and reverse DNS
  180. /// changes requested. Based upon the change mask, the transaction
  181. /// will have either the forward, reverse, or both domains populated.
  182. ///
  183. /// @param change_mask determines which change directions are requested
  184. NameRemoveStubPtr makeTransaction4(int change_mask) {
  185. // Creates IPv4 remove request, forward, and reverse domains.
  186. setupForIPv4Transaction(dhcp_ddns::CHG_REMOVE, change_mask);
  187. // Now create the test transaction as would occur in update manager.
  188. return (NameRemoveStubPtr(new NameRemoveStub(io_service_, ncr_,
  189. forward_domain_,
  190. reverse_domain_,
  191. cfg_mgr_)));
  192. }
  193. /// @brief Creates a transaction which requests an IPv6 DNS update.
  194. ///
  195. /// The transaction is constructed around a predefined (i.e. "canned")
  196. /// IPv6 NameChangeRequest. The request has both forward and reverse DNS
  197. /// changes requested. Based upon the change mask, the transaction
  198. /// will have either the forward, reverse, or both domains populated.
  199. ///
  200. /// @param change_mask determines which change directions are requested
  201. NameRemoveStubPtr makeTransaction6(int change_mask) {
  202. // Creates IPv6 remove request, forward, and reverse domains.
  203. setupForIPv6Transaction(dhcp_ddns::CHG_REMOVE, change_mask);
  204. // Now create the test transaction as would occur in update manager.
  205. return (NameRemoveStubPtr(new NameRemoveStub(io_service_, ncr_,
  206. forward_domain_,
  207. reverse_domain_,
  208. cfg_mgr_)));
  209. }
  210. /// @brief Create a test transaction at a known point in the state model.
  211. ///
  212. /// Method prepares a new test transaction and sets its state and next
  213. /// event values to those given. This makes the transaction appear to
  214. /// be at that point in the state model without having to transition it
  215. /// through prerequisite states. It also provides the ability to set
  216. /// which change directions are requested: forward change only, reverse
  217. /// change only, or both.
  218. ///
  219. /// @param state value to set as the current state
  220. /// @param event value to post as the next event
  221. /// @param change_mask determines which change directions are requested
  222. /// @param family selects between an IPv4 (AF_INET) and IPv6 (AF_INET6)
  223. /// transaction.
  224. NameRemoveStubPtr prepHandlerTest(unsigned int state, unsigned int event,
  225. unsigned int change_mask
  226. = FWD_AND_REV_CHG,
  227. short family = AF_INET) {
  228. NameRemoveStubPtr name_remove = (family == AF_INET ?
  229. makeTransaction4(change_mask) :
  230. makeTransaction6(change_mask));
  231. name_remove->initDictionaries();
  232. name_remove->postNextEvent(event);
  233. name_remove->setState(state);
  234. return (name_remove);
  235. }
  236. };
  237. /// @brief Tests NameRemoveTransaction construction.
  238. /// This test verifies that:
  239. /// 1. Construction with invalid type of request
  240. /// 2. Valid construction functions properly
  241. TEST(NameRemoveTransaction, construction) {
  242. IOServicePtr io_service(new isc::asiolink::IOService());
  243. D2CfgMgrPtr cfg_mgr(new D2CfgMgr());
  244. const char* msg_str =
  245. "{"
  246. " \"change_type\" : 0 , "
  247. " \"forward_change\" : true , "
  248. " \"reverse_change\" : true , "
  249. " \"fqdn\" : \"example.com.\" , "
  250. " \"ip_address\" : \"192.168.2.1\" , "
  251. " \"dhcid\" : \"0102030405060708\" , "
  252. " \"lease_expires_on\" : \"20130121132405\" , "
  253. " \"lease_length\" : 1300 "
  254. "}";
  255. dhcp_ddns::NameChangeRequestPtr ncr;
  256. DnsServerInfoStoragePtr servers;
  257. DdnsDomainPtr forward_domain;
  258. DdnsDomainPtr reverse_domain;
  259. DdnsDomainPtr empty_domain;
  260. ASSERT_NO_THROW(ncr = dhcp_ddns::NameChangeRequest::fromJSON(msg_str));
  261. ASSERT_NO_THROW(forward_domain.reset(new DdnsDomain("*", "", servers)));
  262. ASSERT_NO_THROW(reverse_domain.reset(new DdnsDomain("*", "", servers)));
  263. // Verify that construction with wrong change type fails.
  264. EXPECT_THROW(NameRemoveTransaction(io_service, ncr,
  265. forward_domain, reverse_domain, cfg_mgr),
  266. NameRemoveTransactionError);
  267. // Verify that a valid construction attempt works.
  268. ncr->setChangeType(isc::dhcp_ddns::CHG_REMOVE);
  269. EXPECT_NO_THROW(NameRemoveTransaction(io_service, ncr,
  270. forward_domain, reverse_domain,
  271. cfg_mgr));
  272. }
  273. /// @brief Tests event and state dictionary construction and verification.
  274. TEST_F(NameRemoveTransactionTest, dictionaryCheck) {
  275. NameRemoveStubPtr name_remove;
  276. ASSERT_NO_THROW(name_remove = makeTransaction4(FWD_AND_REV_CHG));
  277. // Verify that the event and state dictionary validation fails prior
  278. // dictionary construction.
  279. ASSERT_THROW(name_remove->verifyEvents(), StateModelError);
  280. ASSERT_THROW(name_remove->verifyStates(), StateModelError);
  281. // Construct both dictionaries.
  282. ASSERT_NO_THROW(name_remove->defineEvents());
  283. ASSERT_NO_THROW(name_remove->defineStates());
  284. // Verify both event and state dictionaries now pass validation.
  285. ASSERT_NO_THROW(name_remove->verifyEvents());
  286. ASSERT_NO_THROW(name_remove->verifyStates());
  287. }
  288. /// @brief Tests construction of a DNS update request for removing forward
  289. /// DNS address RRs.
  290. TEST_F(NameRemoveTransactionTest, buildRemoveFwdAddressRequest) {
  291. // Create a IPv4 forward add transaction.
  292. // Verify the request builds without error.
  293. // and then verify the request contents.
  294. NameRemoveStubPtr name_remove;
  295. ASSERT_NO_THROW(name_remove = makeTransaction4(FORWARD_CHG));
  296. ASSERT_NO_THROW(name_remove->buildRemoveFwdAddressRequest());
  297. checkRemoveFwdAddressRequest(*name_remove);
  298. // Create a IPv6 forward add transaction.
  299. // Verify the request builds without error.
  300. // and then verify the request contents.
  301. ASSERT_NO_THROW(name_remove = makeTransaction6(FORWARD_CHG));
  302. ASSERT_NO_THROW(name_remove->buildRemoveFwdAddressRequest());
  303. checkRemoveFwdAddressRequest(*name_remove);
  304. }
  305. /// @brief Tests construction of a DNS update request for removing forward
  306. /// dns RR entries.
  307. TEST_F(NameRemoveTransactionTest, buildRemoveFwdRRsRequest) {
  308. // Create a IPv4 forward replace transaction.
  309. // Verify the request builds without error.
  310. // and then verify the request contents.
  311. NameRemoveStubPtr name_remove;
  312. ASSERT_NO_THROW(name_remove = makeTransaction4(FORWARD_CHG));
  313. ASSERT_NO_THROW(name_remove->buildRemoveFwdRRsRequest());
  314. checkRemoveFwdRRsRequest(*name_remove);
  315. // Create a IPv6 forward replace transaction.
  316. // Verify the request builds without error.
  317. // and then verify the request contents.
  318. ASSERT_NO_THROW(name_remove = makeTransaction6(FORWARD_CHG));
  319. ASSERT_NO_THROW(name_remove->buildRemoveFwdRRsRequest());
  320. checkRemoveFwdRRsRequest(*name_remove);
  321. }
  322. /// @brief Tests the construction of a DNS update request for removing a
  323. /// reverse dns entry.
  324. TEST_F(NameRemoveTransactionTest, buildRemoveRevPtrsRequest) {
  325. // Create a IPv4 reverse replace transaction.
  326. // Verify the request builds without error.
  327. // and then verify the request contents.
  328. NameRemoveStubPtr name_remove;
  329. ASSERT_NO_THROW(name_remove = makeTransaction4(REVERSE_CHG));
  330. ASSERT_NO_THROW(name_remove->buildRemoveRevPtrsRequest());
  331. checkRemoveRevPtrsRequest(*name_remove);
  332. // Create a IPv6 reverse replace transaction.
  333. // Verify the request builds without error.
  334. // and then verify the request contents.
  335. ASSERT_NO_THROW(name_remove = makeTransaction6(REVERSE_CHG));
  336. ASSERT_NO_THROW(name_remove->buildRemoveRevPtrsRequest());
  337. checkRemoveRevPtrsRequest(*name_remove);
  338. }
  339. // Tests the readyHandler functionality.
  340. // It verifies behavior for the following scenarios:
  341. //
  342. // 1. Posted event is START_EVT and request includes only a forward change
  343. // 2. Posted event is START_EVT and request includes both a forward and a
  344. // reverse change
  345. // 3. Posted event is START_EVT and request includes only a reverse change
  346. // 4. Posted event is invalid
  347. //
  348. TEST_F(NameRemoveTransactionTest, readyHandler) {
  349. NameRemoveStubPtr name_remove;
  350. // Create a transaction which includes only a forward change.
  351. ASSERT_NO_THROW(name_remove =
  352. prepHandlerTest(NameChangeTransaction::READY_ST,
  353. StateModel::START_EVT, FORWARD_CHG));
  354. // Run readyHandler.
  355. EXPECT_NO_THROW(name_remove->readyHandler());
  356. // Verify that a request requiring only a forward change, transitions to
  357. // selecting a forward server.
  358. EXPECT_EQ(NameChangeTransaction::SELECTING_FWD_SERVER_ST,
  359. name_remove->getCurrState());
  360. EXPECT_EQ(NameChangeTransaction::SELECT_SERVER_EVT,
  361. name_remove->getNextEvent());
  362. // Create a transaction which includes both a forward and a reverse change.
  363. ASSERT_NO_THROW(name_remove =
  364. prepHandlerTest(NameChangeTransaction::READY_ST,
  365. StateModel::START_EVT, FWD_AND_REV_CHG));
  366. // Run readyHandler.
  367. EXPECT_NO_THROW(name_remove->readyHandler());
  368. // Verify that a request requiring both forward and reverse, starts with
  369. // the forward change by transitioning to selecting a forward server.
  370. EXPECT_EQ(NameChangeTransaction::SELECTING_FWD_SERVER_ST,
  371. name_remove->getCurrState());
  372. EXPECT_EQ(NameChangeTransaction::SELECT_SERVER_EVT,
  373. name_remove->getNextEvent());
  374. // Create and prep a reverse only transaction.
  375. ASSERT_NO_THROW(name_remove =
  376. prepHandlerTest(NameChangeTransaction::READY_ST,
  377. StateModel::START_EVT, REVERSE_CHG));
  378. // Run readyHandler.
  379. EXPECT_NO_THROW(name_remove->readyHandler());
  380. // Verify that a request requiring only a reverse change, transitions to
  381. // selecting a reverse server.
  382. EXPECT_EQ(NameChangeTransaction::SELECTING_REV_SERVER_ST,
  383. name_remove->getCurrState());
  384. EXPECT_EQ(NameChangeTransaction::SELECT_SERVER_EVT,
  385. name_remove->getNextEvent());
  386. // Create and prep transaction, poised to run the handler but with an
  387. // invalid event.
  388. ASSERT_NO_THROW(name_remove =
  389. prepHandlerTest(NameChangeTransaction::READY_ST,
  390. StateModel::NOP_EVT));
  391. // Running the readyHandler should throw.
  392. EXPECT_THROW(name_remove->readyHandler(), NameRemoveTransactionError);
  393. }
  394. // Tests the selectingFwdServerHandler functionality.
  395. // It verifies behavior for the following scenarios:
  396. //
  397. // 1. Posted event is SELECT_SERVER_EVT
  398. // 2. Posted event is SERVER_IO_ERROR_EVT
  399. // 3. Posted event is invalid
  400. //
  401. TEST_F(NameRemoveTransactionTest, selectingFwdServerHandler) {
  402. NameRemoveStubPtr name_remove;
  403. // Create and prep a transaction, poised to run the handler.
  404. ASSERT_NO_THROW(name_remove =
  405. prepHandlerTest(NameChangeTransaction::
  406. SELECTING_FWD_SERVER_ST,
  407. NameChangeTransaction::SELECT_SERVER_EVT));
  408. // Call selectingFwdServerHandler enough times to select all of the
  409. // servers in it's current domain. The first time, it will be with
  410. // next event of SELECT_SERVER_EVT. Thereafter it will be with a next
  411. // event of SERVER_IO_ERROR_EVT.
  412. int num_servers = name_remove->getForwardDomain()->getServers()->size();
  413. for (int i = 0; i < num_servers; ++i) {
  414. // Run selectingFwdServerHandler.
  415. ASSERT_NO_THROW(name_remove->selectingFwdServerHandler())
  416. << " num_servers: " << num_servers
  417. << " selections: " << i;
  418. // Verify that a server was selected.
  419. ASSERT_TRUE(name_remove->getCurrentServer())
  420. << " num_servers: " << num_servers << " selections: " << i;
  421. // Verify that we transitioned correctly.
  422. ASSERT_EQ(NameRemoveTransaction::REMOVING_FWD_ADDRS_ST,
  423. name_remove->getCurrState())
  424. << " num_servers: " << num_servers << " selections: " << i;
  425. ASSERT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  426. name_remove->getNextEvent())
  427. << " num_servers: " << num_servers << " selections: " << i;
  428. // Post a server IO error event. This simulates an IO error occuring
  429. // and a need to select the new server.
  430. ASSERT_NO_THROW(name_remove->postNextEvent(NameChangeTransaction::
  431. SERVER_IO_ERROR_EVT))
  432. << " num_servers: " << num_servers
  433. << " selections: " << i;
  434. }
  435. // We should have exhausted the list of servers. Processing another
  436. // SERVER_IO_ERROR_EVT should transition us to failure.
  437. EXPECT_NO_THROW(name_remove->selectingFwdServerHandler());
  438. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  439. name_remove->getCurrState());
  440. EXPECT_EQ(NameChangeTransaction::NO_MORE_SERVERS_EVT,
  441. name_remove->getNextEvent());
  442. // Create and prep transaction, poised to run the handler but with an
  443. // invalid event.
  444. ASSERT_NO_THROW(name_remove =
  445. prepHandlerTest(NameChangeTransaction::
  446. SELECTING_FWD_SERVER_ST,
  447. StateModel::NOP_EVT));
  448. // Running the handler should throw.
  449. EXPECT_THROW(name_remove->selectingFwdServerHandler(),
  450. NameRemoveTransactionError);
  451. }
  452. // ************************ addingFwdAddrHandler Tests *****************
  453. // Tests that removingFwdAddrsHandler rejects invalid events.
  454. TEST_F(NameRemoveTransactionTest, removingFwdAddrsHandler_InvalidEvent) {
  455. NameRemoveStubPtr name_remove;
  456. // Create and prep a transaction, poised to run the handler but with
  457. // an invalid event.
  458. ASSERT_NO_THROW(name_remove =
  459. prepHandlerTest(NameRemoveTransaction::
  460. REMOVING_FWD_ADDRS_ST,
  461. StateModel::NOP_EVT));
  462. // Running the handler should throw.
  463. EXPECT_THROW(name_remove->removingFwdAddrsHandler(),
  464. NameRemoveTransactionError);
  465. }
  466. // Tests addingFwdAddrsHandler with the following scenario:
  467. //
  468. // The request includes only a forward change.
  469. // Initial posted event is SERVER_SELECTED_EVT.
  470. // The update request is sent without error.
  471. // A server response is received which indicates successful update
  472. //
  473. TEST_F(NameRemoveTransactionTest, removingFwdAddrsHandler_FwdOnlyOK) {
  474. NameRemoveStubPtr name_remove;
  475. // Create and prep a transaction, poised to run the handler.
  476. ASSERT_NO_THROW(name_remove =
  477. prepHandlerTest(NameRemoveTransaction::
  478. REMOVING_FWD_ADDRS_ST,
  479. NameChangeTransaction::
  480. SERVER_SELECTED_EVT, FORWARD_CHG));
  481. // Should not be an update message yet.
  482. D2UpdateMessagePtr update_msg = name_remove->getDnsUpdateRequest();
  483. ASSERT_FALSE(update_msg);
  484. // At this point completion flags should be false.
  485. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  486. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  487. // Run removingFwdAddrsHandler to construct and send the request.
  488. EXPECT_NO_THROW(name_remove->removingFwdAddrsHandler());
  489. // Verify that an update message was constructed properly.
  490. checkRemoveFwdAddressRequest(*name_remove);
  491. // Verify that we are still in this state and next event is NOP_EVT.
  492. // This indicates we "sent" the message and are waiting for IO completion.
  493. EXPECT_EQ(NameRemoveTransaction::REMOVING_FWD_ADDRS_ST,
  494. name_remove->getCurrState());
  495. EXPECT_EQ(NameChangeTransaction::NOP_EVT,
  496. name_remove->getNextEvent());
  497. // Simulate receiving a successful update response.
  498. name_remove->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NOERROR());
  499. // Run removingFwdAddrsHandler again to process the response.
  500. EXPECT_NO_THROW(name_remove->removingFwdAddrsHandler());
  501. // Completion flags should both still be false, as we are only partly
  502. // done with forward updates.
  503. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  504. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  505. // Since we succeeded, we should now attempt to remove any remaining
  506. // forward RRs.
  507. // Verify that we transitioned correctly.
  508. EXPECT_EQ(NameRemoveTransaction::REMOVING_FWD_RRS_ST,
  509. name_remove->getCurrState());
  510. EXPECT_EQ(NameRemoveTransaction::UPDATE_OK_EVT,
  511. name_remove->getNextEvent());
  512. }
  513. // Tests addingFwdAddrsHandler with the following scenario:
  514. //
  515. // The request includes only a forward change.
  516. // Initial posted event is SERVER_SELECTED_EVT.
  517. // The update request is sent without error.
  518. // A server response is received which indicates FQDN is not in use.
  519. //
  520. TEST_F(NameRemoveTransactionTest, removingFwdAddrsHandler_FqdnNotInUse) {
  521. NameRemoveStubPtr name_remove;
  522. // Create and prep a transaction, poised to run the handler.
  523. ASSERT_NO_THROW(name_remove =
  524. prepHandlerTest(NameRemoveTransaction::
  525. REMOVING_FWD_ADDRS_ST,
  526. NameChangeTransaction::
  527. SERVER_SELECTED_EVT, FORWARD_CHG));
  528. // Run removingFwdAddrsHandler to construct and send the request.
  529. EXPECT_NO_THROW(name_remove->removingFwdAddrsHandler());
  530. // Simulate receiving a RRSET does not exist.
  531. name_remove->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NXRRSET());
  532. // Run removingFwdAddrsHandler again to process the response.
  533. EXPECT_NO_THROW(name_remove->removingFwdAddrsHandler());
  534. // Completion flags should both still be false, as we are only partly
  535. // done with forward updates.
  536. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  537. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  538. // There was no address RR to remove, but we will still make sure there
  539. // are no other RRs for this FQDN.
  540. // Verify that we transitioned correctly.
  541. EXPECT_EQ(NameRemoveTransaction::REMOVING_FWD_RRS_ST,
  542. name_remove->getCurrState());
  543. EXPECT_EQ(NameRemoveTransaction::UPDATE_OK_EVT,
  544. name_remove->getNextEvent());
  545. }
  546. // Tests removingFwdAddrsHandler with the following scenario:
  547. //
  548. // The request includes a forward and reverse change.
  549. // Initial posted event is SERVER_SELECTED_EVT.
  550. // The update request is sent without error.
  551. // A server response is received which indicates the update was rejected.
  552. //
  553. TEST_F(NameRemoveTransactionTest, removingFwdAddrsHandler_OtherRcode) {
  554. NameRemoveStubPtr name_remove;
  555. // Create and prep a transaction, poised to run the handler.
  556. ASSERT_NO_THROW(name_remove =
  557. prepHandlerTest(NameRemoveTransaction::
  558. REMOVING_FWD_ADDRS_ST,
  559. NameChangeTransaction::
  560. SERVER_SELECTED_EVT));
  561. // Select a server to satisfy log statements.
  562. ASSERT_TRUE(name_remove->selectFwdServer());
  563. // Run removingFwdAddrsHandler to construct and send the request.
  564. EXPECT_NO_THROW(name_remove->removingFwdAddrsHandler());
  565. // Simulate receiving server rejection response. Per RFC, anything other
  566. // than no error or FQDN not in use is failure. Arbitrarily choosing
  567. // refused.
  568. name_remove->fakeResponse(DNSClient::SUCCESS, dns::Rcode::REFUSED());
  569. // Run removingFwdAddrsHandler again to process the response.
  570. EXPECT_NO_THROW(name_remove->removingFwdAddrsHandler());
  571. // Completion flags should still be false.
  572. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  573. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  574. // We should have failed the transaction. Verify that we transitioned
  575. // correctly.
  576. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  577. name_remove->getCurrState());
  578. EXPECT_EQ(NameChangeTransaction::UPDATE_FAILED_EVT,
  579. name_remove->getNextEvent());
  580. }
  581. // Tests removingFwdAddrsHandler with the following scenario:
  582. //
  583. // The request includes a forward and reverse change.
  584. // Initial posted event is SERVER_SELECTED_EVT.
  585. // The update request send times out MAX_UPDATE_TRIES_PER_SERVER times.
  586. //
  587. TEST_F(NameRemoveTransactionTest, removingFwdAddrsHandler_Timeout) {
  588. NameRemoveStubPtr name_remove;
  589. // Create and prep a transaction, poised to run the handler.
  590. // The log message issued when this test succeeds, displays the
  591. // selected server, so we need to select a server before running this
  592. // test.
  593. ASSERT_NO_THROW(name_remove =
  594. prepHandlerTest(NameRemoveTransaction::
  595. REMOVING_FWD_ADDRS_ST,
  596. NameChangeTransaction::
  597. SERVER_SELECTED_EVT));
  598. // Select a server to satisfy log statements.
  599. ASSERT_TRUE(name_remove->selectFwdServer());
  600. // Verify that we can make maximum number of update attempts permitted
  601. // and then transition to selecting a new server.
  602. int max_tries = NameChangeTransaction::MAX_UPDATE_TRIES_PER_SERVER;
  603. for (int i = 1; i <= max_tries; ++i) {
  604. const D2UpdateMessagePtr prev_msg = name_remove->getDnsUpdateRequest();
  605. // Run removingFwdAddrsHandler to send the request.
  606. EXPECT_NO_THROW(name_remove->removingFwdAddrsHandler());
  607. const D2UpdateMessagePtr curr_msg = name_remove->getDnsUpdateRequest();
  608. if (i == 1) {
  609. // First time around we should build the message.
  610. EXPECT_FALSE(prev_msg);
  611. EXPECT_TRUE(curr_msg);
  612. } else {
  613. // Subsequent passes should reuse the request. We are only
  614. // looking to check that we have not replaced the pointer value
  615. // with a new pointer. This tests the on_entry() logic which
  616. // clears the request ONLY upon initial entry into the state.
  617. EXPECT_TRUE(prev_msg == curr_msg);
  618. }
  619. // Simulate a server IO timeout.
  620. name_remove->setDnsUpdateStatus(DNSClient::TIMEOUT);
  621. name_remove->postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  622. // Run removingFwdAddrsHandler again to process the response.
  623. EXPECT_NO_THROW(name_remove->removingFwdAddrsHandler());
  624. // Completion flags should be false.
  625. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  626. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  627. if (i < max_tries) {
  628. // We should be ready to try again.
  629. EXPECT_EQ(NameRemoveTransaction::REMOVING_FWD_ADDRS_ST,
  630. name_remove->getCurrState());
  631. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  632. name_remove->getNextEvent());
  633. } else {
  634. // Server retries should be exhausted, time for a new server.
  635. EXPECT_EQ(NameRemoveTransaction::SELECTING_FWD_SERVER_ST,
  636. name_remove->getCurrState());
  637. EXPECT_EQ(NameChangeTransaction::SERVER_IO_ERROR_EVT,
  638. name_remove->getNextEvent());
  639. }
  640. }
  641. }
  642. // Tests removingFwdAddrsHandler with the following scenario:
  643. //
  644. // The request includes a forward and reverse change.
  645. // Initial posted event is SERVER_SELECTED_EVT.
  646. // The update request is sent but a corrupt response is received, this occurs
  647. // MAX_UPDATE_TRIES_PER_SERVER times.
  648. //
  649. TEST_F(NameRemoveTransactionTest, removingFwdAddrsHandler_InvalidResponse) {
  650. NameRemoveStubPtr name_remove;
  651. // Create and prep a transaction, poised to run the handler.
  652. // The log message issued when this test succeeds, displays the
  653. // selected server, so we need to select a server before running this
  654. // test.
  655. ASSERT_NO_THROW(name_remove =
  656. prepHandlerTest(NameRemoveTransaction::
  657. REMOVING_FWD_ADDRS_ST,
  658. NameChangeTransaction::
  659. SERVER_SELECTED_EVT));
  660. // Select a server to satisfy log statements.
  661. ASSERT_TRUE(name_remove->selectFwdServer());
  662. // Verify that we can make maximum number of update attempts permitted
  663. // and then transition to selecting a new server.
  664. int max_tries = NameChangeTransaction::MAX_UPDATE_TRIES_PER_SERVER;
  665. for (int i = 1; i <= max_tries; ++i) {
  666. // Run removingFwdAddrsHandler to construct send the request.
  667. EXPECT_NO_THROW(name_remove->removingFwdAddrsHandler());
  668. // Simulate a corrupt server response.
  669. name_remove->setDnsUpdateStatus(DNSClient::INVALID_RESPONSE);
  670. name_remove->postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  671. // Run removingFwdAddrsHandler again to process the response.
  672. EXPECT_NO_THROW(name_remove->removingFwdAddrsHandler());
  673. // Completion flags should be false.
  674. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  675. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  676. if (i < max_tries) {
  677. // We should be ready to try again.
  678. EXPECT_EQ(NameRemoveTransaction::REMOVING_FWD_ADDRS_ST,
  679. name_remove->getCurrState());
  680. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  681. name_remove->getNextEvent());
  682. } else {
  683. // Server retries should be exhausted, time for a new server.
  684. EXPECT_EQ(NameRemoveTransaction::SELECTING_FWD_SERVER_ST,
  685. name_remove->getCurrState());
  686. EXPECT_EQ(NameChangeTransaction::SERVER_IO_ERROR_EVT,
  687. name_remove->getNextEvent());
  688. }
  689. }
  690. }
  691. // ************************ removingFwdRRsHandler Tests *****************
  692. // Tests that removingFwdRRsHandler rejects invalid events.
  693. TEST_F(NameRemoveTransactionTest, removingFwdRRsHandler_InvalidEvent) {
  694. NameRemoveStubPtr name_remove;
  695. // Create and prep a transaction, poised to run the handler but with
  696. // an invalid event.
  697. ASSERT_NO_THROW(name_remove =
  698. prepHandlerTest(NameRemoveTransaction::
  699. REMOVING_FWD_RRS_ST,
  700. StateModel::NOP_EVT));
  701. // Running the handler should throw.
  702. EXPECT_THROW(name_remove->removingFwdRRsHandler(),
  703. NameRemoveTransactionError);
  704. }
  705. // Tests removingFwdRRsHandler with the following scenario:
  706. //
  707. // The request includes only a forward change.
  708. // Initial posted event is UPDATE_OK_EVT.
  709. // The update request is sent without error.
  710. // A server response is received which indicates successful update.
  711. //
  712. TEST_F(NameRemoveTransactionTest, removingFwdRRsHandler_FwdOnlyOK) {
  713. NameRemoveStubPtr name_remove;
  714. // Create and prep a transaction, poised to run the handler.
  715. ASSERT_NO_THROW(name_remove =
  716. prepHandlerTest(NameRemoveTransaction::
  717. REMOVING_FWD_ADDRS_ST,
  718. NameChangeTransaction::
  719. UPDATE_OK_EVT, FORWARD_CHG));
  720. // Should not be an update message yet.
  721. D2UpdateMessagePtr update_msg = name_remove->getDnsUpdateRequest();
  722. ASSERT_FALSE(update_msg);
  723. // At this point completion flags should be false.
  724. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  725. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  726. // Run removingFwdRRsHandler to construct and send the request.
  727. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  728. // Verify that an update message was constructed properly.
  729. checkRemoveFwdRRsRequest(*name_remove);
  730. // Verify that we are still in this state and next event is NOP_EVT.
  731. // This indicates we "sent" the message and are waiting for IO completion.
  732. EXPECT_EQ(NameRemoveTransaction::REMOVING_FWD_ADDRS_ST,
  733. name_remove->getCurrState());
  734. EXPECT_EQ(NameChangeTransaction::NOP_EVT,
  735. name_remove->getNextEvent());
  736. // Simulate receiving a successful update response.
  737. name_remove->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NOERROR());
  738. // Run removingFwdRRsHandler again to process the response.
  739. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  740. // Forward completion should be true, reverse should be false.
  741. EXPECT_TRUE(name_remove->getForwardChangeCompleted());
  742. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  743. // Since it is a forward only change, we should be done.
  744. // Verify that we transitioned correctly.
  745. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  746. name_remove->getCurrState());
  747. EXPECT_EQ(NameChangeTransaction::UPDATE_OK_EVT,
  748. name_remove->getNextEvent());
  749. }
  750. // Tests removingFwdRRsHandler with the following scenario:
  751. //
  752. // The request includes only a forward change.
  753. // Initial posted event is SERVER_SELECTED_EVT.
  754. // The update request is sent without error.
  755. // A server response is received which indicates successful update.
  756. //
  757. TEST_F(NameRemoveTransactionTest, removingFwdRRsHandler_FwdOnlyOK2) {
  758. NameRemoveStubPtr name_remove;
  759. // Create and prep a transaction, poised to run the handler.
  760. ASSERT_NO_THROW(name_remove =
  761. prepHandlerTest(NameRemoveTransaction::
  762. REMOVING_FWD_ADDRS_ST,
  763. NameChangeTransaction::
  764. SERVER_SELECTED_EVT, FORWARD_CHG));
  765. // Run removingFwdRRsHandler to construct and send the request.
  766. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  767. // Simulate receiving a successful update response.
  768. name_remove->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NOERROR());
  769. // Run removingFwdRRsHandler again to process the response.
  770. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  771. // Forward completion should be true, reverse should be false.
  772. EXPECT_TRUE(name_remove->getForwardChangeCompleted());
  773. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  774. // Since it is a forward only change, we should be done.
  775. // Verify that we transitioned correctly.
  776. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  777. name_remove->getCurrState());
  778. EXPECT_EQ(NameChangeTransaction::UPDATE_OK_EVT,
  779. name_remove->getNextEvent());
  780. }
  781. // Tests removingFwdRRsHandler with the following scenario:
  782. //
  783. // The request includes a forward and reverse change.
  784. // Initial posted event is UPDATE_OK_EVT.
  785. // The update request is sent without error.
  786. // A server response is received which indicates successful update.
  787. //
  788. TEST_F(NameRemoveTransactionTest, removingFwdRRsHandler_FwdAndRevOK) {
  789. NameRemoveStubPtr name_remove;
  790. // Create and prep a transaction, poised to run the handler.
  791. ASSERT_NO_THROW(name_remove =
  792. prepHandlerTest(NameRemoveTransaction::
  793. REMOVING_FWD_ADDRS_ST,
  794. NameChangeTransaction::
  795. UPDATE_OK_EVT, FWD_AND_REV_CHG));
  796. // Run removingFwdRRsHandler to construct and send the request.
  797. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  798. // Simulate receiving a successful update response.
  799. name_remove->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NOERROR());
  800. // Run removingFwdRRsHandler again to process the response.
  801. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  802. // Forward change completion should be true, reverse flag should be false.
  803. EXPECT_TRUE(name_remove->getForwardChangeCompleted());
  804. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  805. // Since the request also includes a reverse change we should
  806. // be poised to start it. Verify that we transitioned correctly.
  807. EXPECT_EQ(NameChangeTransaction::SELECTING_REV_SERVER_ST,
  808. name_remove->getCurrState());
  809. EXPECT_EQ(NameChangeTransaction::SELECT_SERVER_EVT,
  810. name_remove->getNextEvent());
  811. }
  812. // Tests removingFwdAddrsHandler with the following scenario:
  813. //
  814. // The request includes a forward and reverse change.
  815. // Initial posted event is UPDATE_OK_EVT.
  816. // The update request is sent without error.
  817. // A server response is received which indicates the FQDN is NOT in use.
  818. //
  819. TEST_F(NameRemoveTransactionTest, removingFwdRRsHandler_FqdnNotInUse) {
  820. NameRemoveStubPtr name_remove;
  821. // Create and prep a transaction, poised to run the handler.
  822. ASSERT_NO_THROW(name_remove =
  823. prepHandlerTest(NameRemoveTransaction::
  824. REMOVING_FWD_ADDRS_ST,
  825. NameChangeTransaction::
  826. UPDATE_OK_EVT, FORWARD_CHG));
  827. // Run removingFwdRRsHandler to construct and send the request.
  828. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  829. // Simulate receiving a RRSET does not exist response.
  830. name_remove->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NXRRSET());
  831. // Run removingFwdRRsHandler again to process the response.
  832. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  833. // Forwad completion flag should be true, reverse should still be false.
  834. EXPECT_TRUE(name_remove->getForwardChangeCompleted());
  835. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  836. // The FQDN is no longer in use, RFC is unclear about this,
  837. // but we will treat this as success.
  838. // Since it is a forward only change, we should be done.
  839. // Verify that we transitioned correctly.
  840. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  841. name_remove->getCurrState());
  842. EXPECT_EQ(NameChangeTransaction::UPDATE_OK_EVT,
  843. name_remove->getNextEvent());
  844. }
  845. // Tests removingFwdRRsHandler with the following scenario:
  846. //
  847. // The request includes a forward and reverse change.
  848. // The update request is sent without error.
  849. // A server response is received which indicates the update was rejected.
  850. //
  851. TEST_F(NameRemoveTransactionTest, removingFwdRRsHandler_OtherRcode) {
  852. NameRemoveStubPtr name_remove;
  853. // Create the transaction.
  854. ASSERT_NO_THROW(name_remove =
  855. prepHandlerTest(NameRemoveTransaction::
  856. REMOVING_FWD_ADDRS_ST,
  857. NameChangeTransaction::
  858. UPDATE_OK_EVT, FWD_AND_REV_CHG));
  859. // Select a server to satisfy log statements.
  860. ASSERT_TRUE(name_remove->selectFwdServer());
  861. // Run removingFwdRRsHandler to construct and send the request.
  862. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  863. // Simulate receiving server rejection response. Per RFC, anything other
  864. // than no error is failure (we are also treating FQDN not in use is
  865. // success). Arbitrarily choosing refused.
  866. name_remove->fakeResponse(DNSClient::SUCCESS, dns::Rcode::REFUSED());
  867. // Run removingFwdRRsHandler again to process the response.
  868. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  869. // Completion flags should still be false.
  870. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  871. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  872. // We should have failed the transaction. Verifiy that we transitioned
  873. // correctly.
  874. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  875. name_remove->getCurrState());
  876. EXPECT_EQ(NameChangeTransaction::UPDATE_FAILED_EVT,
  877. name_remove->getNextEvent());
  878. }
  879. // Tests removingFwdRRsHandler with the following scenario:
  880. //
  881. // The request includes a forward and reverse change.
  882. // Initial posted event is UPDATE_OK_EVT.
  883. // The update request send times out MAX_UPDATE_TRIES_PER_SERVER times.
  884. //
  885. TEST_F(NameRemoveTransactionTest, removingFwdRRsHandler_Timeout) {
  886. NameRemoveStubPtr name_remove;
  887. // Create the transaction.
  888. ASSERT_NO_THROW(name_remove =
  889. prepHandlerTest(NameRemoveTransaction::
  890. REMOVING_FWD_RRS_ST,
  891. NameChangeTransaction::
  892. UPDATE_OK_EVT, FWD_AND_REV_CHG));
  893. // Select a server to satisfy log statements.
  894. ASSERT_TRUE(name_remove->selectFwdServer());
  895. // Verify that we can make maximum number of update attempts permitted
  896. // and then transition to selecting a new server.
  897. int max_tries = NameChangeTransaction::MAX_UPDATE_TRIES_PER_SERVER;
  898. for (int i = 1; i <= max_tries; ++i) {
  899. const D2UpdateMessagePtr prev_msg = name_remove->getDnsUpdateRequest();
  900. // Run removingFwdRRsHandler to send the request.
  901. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  902. const D2UpdateMessagePtr curr_msg = name_remove->getDnsUpdateRequest();
  903. if (i == 1) {
  904. // First time around we should build the message.
  905. EXPECT_FALSE(prev_msg);
  906. EXPECT_TRUE(curr_msg);
  907. } else {
  908. // Subsequent passes should reuse the request. We are only
  909. // looking to check that we have not replaced the pointer value
  910. // with a new pointer. This tests the on_entry() logic which
  911. // clears the request ONLY upon initial entry into the state.
  912. EXPECT_TRUE(prev_msg == curr_msg);
  913. }
  914. // Simulate a server IO timeout.
  915. name_remove->setDnsUpdateStatus(DNSClient::TIMEOUT);
  916. name_remove->postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  917. // Run removingFwdRRsHandler again to process the response.
  918. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  919. // Completion flags should be false.
  920. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  921. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  922. if (i < max_tries) {
  923. // We should be ready to try again.
  924. EXPECT_EQ(NameRemoveTransaction::REMOVING_FWD_RRS_ST,
  925. name_remove->getCurrState());
  926. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  927. name_remove->getNextEvent());
  928. } else {
  929. // Server retries should be exhausted.
  930. // We should abandon the transaction.
  931. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  932. name_remove->getCurrState());
  933. EXPECT_EQ(NameChangeTransaction::SERVER_IO_ERROR_EVT,
  934. name_remove->getNextEvent());
  935. }
  936. }
  937. }
  938. // Tests removingFwdRRsHandler with the following scenario:
  939. //
  940. // The request includes a forward and reverse change.
  941. // Initial posted event is UPDATE_OK_EVT.
  942. // The update request is sent but a corrupt response is received, this occurs
  943. // MAX_UPDATE_TRIES_PER_SERVER times.
  944. //
  945. TEST_F(NameRemoveTransactionTest, removingFwdRRsHandler_InvalidResponse) {
  946. NameRemoveStubPtr name_remove;
  947. // Create the transaction.
  948. ASSERT_NO_THROW(name_remove =
  949. prepHandlerTest(NameRemoveTransaction::
  950. REMOVING_FWD_RRS_ST,
  951. NameChangeTransaction::
  952. UPDATE_OK_EVT, FWD_AND_REV_CHG));
  953. // Select a server to satisfy log statements.
  954. ASSERT_TRUE(name_remove->selectFwdServer());
  955. // Verify that we can make maximum number of update attempts permitted
  956. // and then transition to selecting a new server.
  957. int max_tries = NameChangeTransaction::MAX_UPDATE_TRIES_PER_SERVER;
  958. for (int i = 1; i <= max_tries; ++i) {
  959. const D2UpdateMessagePtr prev_msg = name_remove->getDnsUpdateRequest();
  960. // Run removingFwdRRsHandler to send the request.
  961. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  962. const D2UpdateMessagePtr curr_msg = name_remove->getDnsUpdateRequest();
  963. if (i == 1) {
  964. // First time around we should build the message.
  965. EXPECT_FALSE(prev_msg);
  966. EXPECT_TRUE(curr_msg);
  967. } else {
  968. // Subsequent passes should reuse the request. We are only
  969. // looking to check that we have not replaced the pointer value
  970. // with a new pointer. This tests the on_entry() logic which
  971. // clears the request ONLY upon initial entry into the state.
  972. EXPECT_TRUE(prev_msg == curr_msg);
  973. }
  974. // Simulate a corrupt server response.
  975. name_remove->setDnsUpdateStatus(DNSClient::INVALID_RESPONSE);
  976. name_remove->postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  977. // Run removingFwdRRsHandler again to process the response.
  978. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  979. // Completion flags should be false.
  980. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  981. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  982. if (i < max_tries) {
  983. // We should be ready to try again.
  984. EXPECT_EQ(NameRemoveTransaction::REMOVING_FWD_RRS_ST,
  985. name_remove->getCurrState());
  986. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  987. name_remove->getNextEvent());
  988. } else {
  989. // Server retries should be exhausted.
  990. // We should abandon the transaction.
  991. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  992. name_remove->getCurrState());
  993. EXPECT_EQ(NameChangeTransaction::SERVER_IO_ERROR_EVT,
  994. name_remove->getNextEvent());
  995. }
  996. }
  997. }
  998. // Tests the selectingRevServerHandler functionality.
  999. // It verifies behavior for the following scenarios:
  1000. //
  1001. // 1. Posted event is SELECT_SERVER_EVT
  1002. // 2. Posted event is SERVER_IO_ERROR_EVT
  1003. // 3. Posted event is invalid
  1004. //
  1005. TEST_F(NameRemoveTransactionTest, selectingRevServerHandler) {
  1006. NameRemoveStubPtr name_remove;
  1007. // Create and prep a transaction, poised to run the handler.
  1008. ASSERT_NO_THROW(name_remove =
  1009. prepHandlerTest(NameChangeTransaction::
  1010. SELECTING_REV_SERVER_ST,
  1011. NameChangeTransaction::SELECT_SERVER_EVT));
  1012. // Call selectingRevServerHandler enough times to select all of the
  1013. // servers in it's current domain. The first time, it will be with
  1014. // next event of SELECT_SERVER_EVT. Thereafter it will be with a next
  1015. // event of SERVER_IO_ERROR_EVT.
  1016. int num_servers = name_remove->getReverseDomain()->getServers()->size();
  1017. for (int i = 0; i < num_servers; ++i) {
  1018. // Run selectingRevServerHandler.
  1019. ASSERT_NO_THROW(name_remove->selectingRevServerHandler())
  1020. << " num_servers: " << num_servers
  1021. << " selections: " << i;
  1022. // Verify that a server was selected.
  1023. ASSERT_TRUE(name_remove->getCurrentServer())
  1024. << " num_servers: " << num_servers
  1025. << " selections: " << i;
  1026. // Verify that we transitioned correctly.
  1027. ASSERT_EQ(NameRemoveTransaction::REMOVING_REV_PTRS_ST,
  1028. name_remove->getCurrState())
  1029. << " num_servers: " << num_servers << " selections: " << i;
  1030. ASSERT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  1031. name_remove->getNextEvent())
  1032. << " num_servers: " << num_servers << " selections: " << i;
  1033. // Post a server IO error event. This simulates an IO error occuring
  1034. // and a need to select the new server.
  1035. ASSERT_NO_THROW(name_remove->postNextEvent(NameChangeTransaction::
  1036. SERVER_IO_ERROR_EVT))
  1037. << " num_servers: " << num_servers
  1038. << " selections: " << i;
  1039. }
  1040. // We should have exhausted the list of servers. Processing another
  1041. // SERVER_IO_ERROR_EVT should transition us to failure.
  1042. EXPECT_NO_THROW(name_remove->selectingRevServerHandler());
  1043. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  1044. name_remove->getCurrState());
  1045. EXPECT_EQ(NameChangeTransaction::NO_MORE_SERVERS_EVT,
  1046. name_remove->getNextEvent());
  1047. // Create and prep transaction, poised to run the handler but with an
  1048. // invalid event.
  1049. ASSERT_NO_THROW(name_remove =
  1050. prepHandlerTest(NameChangeTransaction::
  1051. SELECTING_REV_SERVER_ST,
  1052. StateModel::NOP_EVT));
  1053. // Running the handler should throw.
  1054. EXPECT_THROW(name_remove->selectingRevServerHandler(),
  1055. NameRemoveTransactionError);
  1056. }
  1057. //************************** removingRevPtrsHandler tests *****************
  1058. // Tests that removingRevPtrsHandler rejects invalid events.
  1059. TEST_F(NameRemoveTransactionTest, removingRevPtrsHandler_InvalidEvent) {
  1060. NameRemoveStubPtr name_remove;
  1061. // Create and prep a transaction, poised to run the handler but with
  1062. // an invalid event.
  1063. ASSERT_NO_THROW(name_remove =
  1064. prepHandlerTest(NameRemoveTransaction::
  1065. REMOVING_REV_PTRS_ST,
  1066. StateModel::NOP_EVT));
  1067. // Running the handler should throw.
  1068. EXPECT_THROW(name_remove->removingRevPtrsHandler(),
  1069. NameRemoveTransactionError);
  1070. }
  1071. // Tests removingRevPtrsHandler with the following scenario:
  1072. //
  1073. // The request includes only a reverse change.
  1074. // Initial posted event is SERVER_SELECTED_EVT.
  1075. // The update request is sent without error.
  1076. // A server response is received which indicates successful update.
  1077. //
  1078. TEST_F(NameRemoveTransactionTest, removingRevPtrsHandler_RevOnlyOK) {
  1079. NameRemoveStubPtr name_remove;
  1080. // Create and prep a transaction, poised to run the handler.
  1081. ASSERT_NO_THROW(name_remove =
  1082. prepHandlerTest(NameRemoveTransaction::
  1083. REMOVING_REV_PTRS_ST,
  1084. NameChangeTransaction::
  1085. SERVER_SELECTED_EVT, REVERSE_CHG));
  1086. // Should not be an update message yet.
  1087. D2UpdateMessagePtr update_msg = name_remove->getDnsUpdateRequest();
  1088. ASSERT_FALSE(update_msg);
  1089. // At this point completion flags should be false.
  1090. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1091. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  1092. // Run removingRevPtrsHandler to construct and send the request.
  1093. EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
  1094. // Verify that an update message was constructed properly.
  1095. checkRemoveRevPtrsRequest(*name_remove);
  1096. // Verify that we are still in this state and next event is NOP_EVT.
  1097. // This indicates we "sent" the message and are waiting for IO completion.
  1098. EXPECT_EQ(NameRemoveTransaction::REMOVING_REV_PTRS_ST,
  1099. name_remove->getCurrState());
  1100. EXPECT_EQ(StateModel::NOP_EVT,
  1101. name_remove->getNextEvent());
  1102. // Simulate receiving a successful update response.
  1103. name_remove->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NOERROR());
  1104. // Run removingRevPtrsHandler again to process the response.
  1105. EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
  1106. // Forward completion should be false, reverse should be true.
  1107. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1108. EXPECT_TRUE(name_remove->getReverseChangeCompleted());
  1109. // Since it is a reverse change, we should be done.
  1110. // Verify that we transitioned correctly.
  1111. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  1112. name_remove->getCurrState());
  1113. EXPECT_EQ(NameChangeTransaction::UPDATE_OK_EVT,
  1114. name_remove->getNextEvent());
  1115. }
  1116. // Tests removingRevPtrsHandler with the following scenario:
  1117. //
  1118. // The request includes only a reverse change.
  1119. // Initial posted event is SERVER_SELECTED_EVT.
  1120. // The update request is sent without error.
  1121. // A server response is received which indicates FQDN is NOT in use.
  1122. //
  1123. TEST_F(NameRemoveTransactionTest, removingRevPtrsHandler_FqdnNotInUse) {
  1124. NameRemoveStubPtr name_remove;
  1125. // Create and prep a transaction, poised to run the handler.
  1126. ASSERT_NO_THROW(name_remove =
  1127. prepHandlerTest(NameRemoveTransaction::
  1128. REMOVING_REV_PTRS_ST,
  1129. NameChangeTransaction::
  1130. SERVER_SELECTED_EVT, REVERSE_CHG));
  1131. // Should not be an update message yet.
  1132. D2UpdateMessagePtr update_msg = name_remove->getDnsUpdateRequest();
  1133. ASSERT_FALSE(update_msg);
  1134. // At this point completion flags should be false.
  1135. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1136. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  1137. // Run removingRevPtrsHandler to construct and send the request.
  1138. EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
  1139. // Verify that an update message was constructed properly.
  1140. checkRemoveRevPtrsRequest(*name_remove);
  1141. // Verify that we are still in this state and next event is NOP_EVT.
  1142. // This indicates we "sent" the message and are waiting for IO completion.
  1143. EXPECT_EQ(NameRemoveTransaction::REMOVING_REV_PTRS_ST,
  1144. name_remove->getCurrState());
  1145. EXPECT_EQ(StateModel::NOP_EVT,
  1146. name_remove->getNextEvent());
  1147. // Simulate receiving a RRSET does not exist.
  1148. name_remove->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NXRRSET());
  1149. // Run removingRevPtrsHandler again to process the response.
  1150. EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
  1151. // Forward completion should be false, reverse should be true.
  1152. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1153. EXPECT_TRUE(name_remove->getReverseChangeCompleted());
  1154. // Since it is a reverse change, we should be done.
  1155. // Verify that we transitioned correctly.
  1156. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  1157. name_remove->getCurrState());
  1158. EXPECT_EQ(NameChangeTransaction::UPDATE_OK_EVT,
  1159. name_remove->getNextEvent());
  1160. }
  1161. // Tests removingRevPtrsHandler with the following scenario:
  1162. //
  1163. // The request includes only a reverse change.
  1164. // Initial posted event is SERVER_SELECTED_EVT.
  1165. // The update request is sent without error.
  1166. // A server response is received which indicates the update was rejected.
  1167. //
  1168. TEST_F(NameRemoveTransactionTest, removingRevPtrsHandler_OtherRcode) {
  1169. NameRemoveStubPtr name_remove;
  1170. // Create the transaction.
  1171. ASSERT_NO_THROW(name_remove =
  1172. prepHandlerTest(NameRemoveTransaction::
  1173. REMOVING_REV_PTRS_ST,
  1174. NameChangeTransaction::
  1175. SERVER_SELECTED_EVT, REVERSE_CHG));
  1176. // Select a server to satisfy log statements.
  1177. ASSERT_TRUE(name_remove->selectRevServer());
  1178. // Run removingRevPtrsHandler to construct and send the request.
  1179. EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
  1180. // Simulate receiving server rejection response. Per RFC, anything other
  1181. // than no error is failure. Arbitrarily choosing refused.
  1182. name_remove->fakeResponse(DNSClient::SUCCESS, dns::Rcode::REFUSED());
  1183. // Run removingRevPtrsHandler again to process the response.
  1184. EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
  1185. // Completion flags should still be false.
  1186. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1187. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  1188. // We should have failed the transaction. Verify that we transitioned
  1189. // correctly.
  1190. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  1191. name_remove->getCurrState());
  1192. EXPECT_EQ(NameChangeTransaction::UPDATE_FAILED_EVT,
  1193. name_remove->getNextEvent());
  1194. }
  1195. // Tests removingRevPtrsHandler with the following scenario:
  1196. //
  1197. // The request includes only a reverse change.
  1198. // Initial posted event is SERVER_SELECTED_EVT.
  1199. // The update request send times out MAX_UPDATE_TRIES_PER_SERVER times.
  1200. //
  1201. TEST_F(NameRemoveTransactionTest, removingRevPtrsHandler_Timeout) {
  1202. NameRemoveStubPtr name_remove;
  1203. // Create the transaction.
  1204. ASSERT_NO_THROW(name_remove =
  1205. prepHandlerTest(NameRemoveTransaction::
  1206. REMOVING_REV_PTRS_ST,
  1207. NameChangeTransaction::
  1208. SERVER_SELECTED_EVT, REVERSE_CHG));
  1209. // Select a server to satisfy log statements.
  1210. ASSERT_TRUE(name_remove->selectRevServer());
  1211. // Verify that we can make maximum number of update attempts permitted
  1212. // and then transition to selecting a new server.
  1213. int max_tries = NameChangeTransaction::MAX_UPDATE_TRIES_PER_SERVER;
  1214. for (int i = 1; i <= max_tries; ++i) {
  1215. const D2UpdateMessagePtr prev_msg = name_remove->getDnsUpdateRequest();
  1216. // Run removingRevPtrsHandler to send the request.
  1217. EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
  1218. const D2UpdateMessagePtr curr_msg = name_remove->getDnsUpdateRequest();
  1219. if (i == 1) {
  1220. // First time around we should build the message.
  1221. EXPECT_FALSE(prev_msg);
  1222. EXPECT_TRUE(curr_msg);
  1223. } else {
  1224. // Subsequent passes should reuse the request. We are only
  1225. // looking to check that we have not replaced the pointer value
  1226. // with a new pointer. This tests the on_entry() logic which
  1227. // clears the request ONLY upon initial entry into the state.
  1228. EXPECT_TRUE(prev_msg == curr_msg);
  1229. }
  1230. // Simulate a server IO timeout.
  1231. name_remove->setDnsUpdateStatus(DNSClient::TIMEOUT);
  1232. name_remove->postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  1233. // Run removingRevPtrsHandler again to process the response.
  1234. EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
  1235. // Completion flags should be false.
  1236. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1237. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  1238. if (i < max_tries) {
  1239. // We should be ready to try again.
  1240. EXPECT_EQ(NameRemoveTransaction::REMOVING_REV_PTRS_ST,
  1241. name_remove->getCurrState());
  1242. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  1243. name_remove->getNextEvent());
  1244. } else {
  1245. // Server retries should be exhausted, time for a new server.
  1246. EXPECT_EQ(NameChangeTransaction::SELECTING_REV_SERVER_ST,
  1247. name_remove->getCurrState());
  1248. EXPECT_EQ(NameChangeTransaction::SERVER_IO_ERROR_EVT,
  1249. name_remove->getNextEvent());
  1250. }
  1251. }
  1252. }
  1253. // Tests removingRevPtrsHandler with the following scenario:
  1254. //
  1255. // The request includes only a reverse change.
  1256. // Initial posted event is SERVER_SELECTED_EVT.
  1257. // The update request is sent but a corrupt response is received, this occurs
  1258. // MAX_UPDATE_TRIES_PER_SERVER times.
  1259. //
  1260. TEST_F(NameRemoveTransactionTest, removingRevPtrsHandler_CorruptResponse) {
  1261. NameRemoveStubPtr name_remove;
  1262. // Create the transaction.
  1263. ASSERT_NO_THROW(name_remove =
  1264. prepHandlerTest(NameRemoveTransaction::
  1265. REMOVING_REV_PTRS_ST,
  1266. NameChangeTransaction::
  1267. SERVER_SELECTED_EVT, REVERSE_CHG));
  1268. // Select a server to satisfy log statements.
  1269. ASSERT_TRUE(name_remove->selectRevServer());
  1270. // Verify that we can make maximum number of update attempts permitted
  1271. // and then transition to selecting a new server.
  1272. int max_tries = NameChangeTransaction::MAX_UPDATE_TRIES_PER_SERVER;
  1273. for (int i = 1; i <= max_tries; ++i) {
  1274. const D2UpdateMessagePtr prev_msg = name_remove->getDnsUpdateRequest();
  1275. // Run removingRevPtrsHandler to send the request.
  1276. EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
  1277. const D2UpdateMessagePtr curr_msg = name_remove->getDnsUpdateRequest();
  1278. if (i == 1) {
  1279. // First time around we should build the message.
  1280. EXPECT_FALSE(prev_msg);
  1281. EXPECT_TRUE(curr_msg);
  1282. } else {
  1283. // Subsequent passes should reuse the request. We are only
  1284. // looking to check that we have not replaced the pointer value
  1285. // with a new pointer. This tests the on_entry() logic which
  1286. // clears the request ONLY upon initial entry into the state.
  1287. EXPECT_TRUE(prev_msg == curr_msg);
  1288. }
  1289. // Simulate a server corrupt response.
  1290. name_remove->setDnsUpdateStatus(DNSClient::INVALID_RESPONSE);
  1291. name_remove->postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  1292. // Run removingRevPtrsHandler again to process the response.
  1293. EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
  1294. // Completion flags should be false.
  1295. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1296. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  1297. if (i < max_tries) {
  1298. // We should be ready to try again.
  1299. EXPECT_EQ(NameRemoveTransaction::REMOVING_REV_PTRS_ST,
  1300. name_remove->getCurrState());
  1301. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  1302. name_remove->getNextEvent());
  1303. } else {
  1304. // Server retries should be exhausted, time for a new server.
  1305. EXPECT_EQ(NameChangeTransaction::SELECTING_REV_SERVER_ST,
  1306. name_remove->getCurrState());
  1307. EXPECT_EQ(NameChangeTransaction::SERVER_IO_ERROR_EVT,
  1308. name_remove->getNextEvent());
  1309. }
  1310. }
  1311. }
  1312. // Tests the processRemoveOkHandler functionality.
  1313. // It verifies behavior for the following scenarios:
  1314. //
  1315. // 1. Posted event is UPDATE_OK_EVT
  1316. // 2. Posted event is invalid
  1317. //
  1318. TEST_F(NameRemoveTransactionTest, processRemoveOkHandler) {
  1319. NameRemoveStubPtr name_remove;
  1320. // Create and prep a transaction, poised to run the handler.
  1321. ASSERT_NO_THROW(name_remove =
  1322. prepHandlerTest(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  1323. NameChangeTransaction::UPDATE_OK_EVT));
  1324. // Run processRemoveOkHandler.
  1325. EXPECT_NO_THROW(name_remove->processRemoveOkHandler());
  1326. // Verify that a server was selected.
  1327. EXPECT_EQ(dhcp_ddns::ST_COMPLETED, name_remove->getNcrStatus());
  1328. // Verify that the model has ended.
  1329. EXPECT_EQ(StateModel::END_ST, name_remove->getCurrState());
  1330. EXPECT_EQ(StateModel::END_EVT, name_remove->getNextEvent());
  1331. // Create and prep transaction, poised to run the handler but with an
  1332. // invalid event.
  1333. ASSERT_NO_THROW(name_remove =
  1334. prepHandlerTest(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  1335. StateModel::NOP_EVT));
  1336. // Running the handler should throw.
  1337. EXPECT_THROW(name_remove->processRemoveOkHandler(),
  1338. NameRemoveTransactionError);
  1339. }
  1340. // Tests the processRemoveFailedHandler functionality.
  1341. // It verifies behavior for the following scenarios:
  1342. //
  1343. // 1. Posted event is UPDATE_FAILED_EVT
  1344. // 2. Posted event is invalid
  1345. //
  1346. TEST_F(NameRemoveTransactionTest, processRemoveFailedHandler) {
  1347. NameRemoveStubPtr name_remove;
  1348. // Create and prep a transaction, poised to run the handler.
  1349. ASSERT_NO_THROW(name_remove =
  1350. prepHandlerTest(NameChangeTransaction::
  1351. PROCESS_TRANS_FAILED_ST,
  1352. NameChangeTransaction::UPDATE_FAILED_EVT));
  1353. // Run processRemoveFailedHandler.
  1354. EXPECT_NO_THROW(name_remove->processRemoveFailedHandler());
  1355. // Verify that a server was selected.
  1356. EXPECT_EQ(dhcp_ddns::ST_FAILED, name_remove->getNcrStatus());
  1357. // Verify that the model has ended. (Remember, the transaction failed NOT
  1358. // the model. The model should have ended normally.)
  1359. EXPECT_EQ(StateModel::END_ST, name_remove->getCurrState());
  1360. EXPECT_EQ(StateModel::END_EVT, name_remove->getNextEvent());
  1361. // Create and prep transaction, poised to run the handler but with an
  1362. // invalid event.
  1363. ASSERT_NO_THROW(name_remove =
  1364. prepHandlerTest(NameChangeTransaction::
  1365. PROCESS_TRANS_FAILED_ST,
  1366. StateModel::NOP_EVT));
  1367. // Running the handler should throw.
  1368. EXPECT_THROW(name_remove->processRemoveFailedHandler(),
  1369. NameRemoveTransactionError);
  1370. }
  1371. // Tests the processRemoveFailedHandler functionality.
  1372. // It verifies behavior for posted event of NO_MORE_SERVERS_EVT.
  1373. TEST_F(NameRemoveTransactionTest, processRemoveFailedHandler_NoMoreServers) {
  1374. NameRemoveStubPtr name_remove;
  1375. // Create and prep a transaction, poised to run the handler.
  1376. ASSERT_NO_THROW(name_remove =
  1377. prepHandlerTest(NameChangeTransaction::
  1378. PROCESS_TRANS_FAILED_ST,
  1379. NameChangeTransaction::
  1380. NO_MORE_SERVERS_EVT));
  1381. // Run processRemoveFailedHandler.
  1382. EXPECT_NO_THROW(name_remove->processRemoveFailedHandler());
  1383. // Verify that a server was selected.
  1384. EXPECT_EQ(dhcp_ddns::ST_FAILED, name_remove->getNcrStatus());
  1385. // Verify that the model has ended. (Remember, the transaction failed NOT
  1386. // the model. The model should have ended normally.)
  1387. EXPECT_EQ(StateModel::END_ST, name_remove->getCurrState());
  1388. EXPECT_EQ(StateModel::END_EVT, name_remove->getNextEvent());
  1389. }
  1390. // Tests the processRemoveFailedHandler functionality.
  1391. // It verifies behavior for posted event of SERVER_IO_ERROR_EVT.
  1392. TEST_F(NameRemoveTransactionTest, processRemoveFailedHandler_ServerIOError) {
  1393. NameRemoveStubPtr name_remove;
  1394. // Create and prep a transaction, poised to run the handler.
  1395. ASSERT_NO_THROW(name_remove =
  1396. prepHandlerTest(NameChangeTransaction::
  1397. PROCESS_TRANS_FAILED_ST,
  1398. NameChangeTransaction::
  1399. SERVER_IO_ERROR_EVT));
  1400. // Run processRemoveFailedHandler.
  1401. EXPECT_NO_THROW(name_remove->processRemoveFailedHandler());
  1402. // Verify that a server was selected.
  1403. EXPECT_EQ(dhcp_ddns::ST_FAILED, name_remove->getNcrStatus());
  1404. // Verify that the model has ended. (Remember, the transaction failed NOT
  1405. // the model. The model should have ended normally.)
  1406. EXPECT_EQ(StateModel::END_ST, name_remove->getCurrState());
  1407. EXPECT_EQ(StateModel::END_EVT, name_remove->getNextEvent());
  1408. }
  1409. // Tests removingFwdAddrsHandler with the following scenario:
  1410. //
  1411. // The request includes only a forward change.
  1412. // Initial posted event is SERVER_SELECTED_EVT.
  1413. // The send update request fails due to an unexpected exception.
  1414. //
  1415. TEST_F(NameRemoveTransactionTest, removingFwdAddrsHandler_sendUpdateException) {
  1416. NameRemoveStubPtr name_remove;
  1417. // Create and prep a transaction, poised to run the handler.
  1418. ASSERT_NO_THROW(name_remove =
  1419. prepHandlerTest(NameRemoveTransaction::
  1420. REMOVING_FWD_ADDRS_ST,
  1421. NameChangeTransaction::
  1422. SERVER_SELECTED_EVT, FORWARD_CHG));
  1423. name_remove->simulate_send_exception_ = true;
  1424. // Run removingFwdAddrsHandler to construct and send the request.
  1425. EXPECT_NO_THROW(name_remove->removingFwdAddrsHandler());
  1426. // Completion flags should be false.
  1427. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1428. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  1429. // Since IO exceptions should be gracefully handled, any that occur
  1430. // are unanticipated, and deemed unrecoverable, so the transaction should
  1431. // be transitioned to failure.
  1432. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  1433. name_remove->getCurrState());
  1434. EXPECT_EQ(NameChangeTransaction::UPDATE_FAILED_EVT,
  1435. name_remove->getNextEvent());
  1436. }
  1437. // Tests removingFwdRRsHandler with the following scenario:
  1438. //
  1439. // The request includes only a forward change.
  1440. // Initial posted event is SERVER_SELECTED_EVT.
  1441. // The send update request fails due to an unexpected exception.
  1442. //
  1443. TEST_F(NameRemoveTransactionTest, removingFwdRRsHandler_SendUpdateException) {
  1444. NameRemoveStubPtr name_remove;
  1445. // Create and prep a transaction, poised to run the handler.
  1446. ASSERT_NO_THROW(name_remove =
  1447. prepHandlerTest(NameRemoveTransaction::
  1448. REMOVING_FWD_RRS_ST,
  1449. NameChangeTransaction::
  1450. SERVER_SELECTED_EVT, FORWARD_CHG));
  1451. name_remove->simulate_send_exception_ = true;
  1452. // Run removingFwdRRsHandler to construct and send the request.
  1453. EXPECT_NO_THROW(name_remove->removingFwdRRsHandler());
  1454. // Completion flags should be false.
  1455. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1456. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  1457. // Since IO exceptions should be gracefully handled, any that occur
  1458. // are unanticipated, and deemed unrecoverable, so the transaction should
  1459. // be transitioned to failure.
  1460. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  1461. name_remove->getCurrState());
  1462. EXPECT_EQ(NameChangeTransaction::UPDATE_FAILED_EVT,
  1463. name_remove->getNextEvent());
  1464. }
  1465. // Tests removingRevPtrHandler with the following scenario:
  1466. //
  1467. // The request includes only a reverse change.
  1468. // Initial posted event is SERVER_SELECTED_EVT.
  1469. // The send update request fails due to an unexpected exception.
  1470. //
  1471. TEST_F(NameRemoveTransactionTest, removingRevPtrsHandler_SendUpdateException) {
  1472. NameRemoveStubPtr name_remove;
  1473. // Create and prep a transaction, poised to run the handler.
  1474. ASSERT_NO_THROW(name_remove =
  1475. prepHandlerTest(NameRemoveTransaction::
  1476. REMOVING_REV_PTRS_ST,
  1477. NameChangeTransaction::
  1478. SERVER_SELECTED_EVT, REVERSE_CHG));
  1479. name_remove->simulate_send_exception_ = true;
  1480. // Run removingRevPtrsHandler to construct and send the request.
  1481. EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
  1482. // Completion flags should be false.
  1483. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1484. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  1485. // Since IO exceptions should be gracefully handled, any that occur
  1486. // are unanticipated, and deemed unrecoverable, so the transaction should
  1487. // be transitioned to failure.
  1488. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  1489. name_remove->getCurrState());
  1490. EXPECT_EQ(NameChangeTransaction::UPDATE_FAILED_EVT,
  1491. name_remove->getNextEvent());
  1492. }
  1493. // Tests removingFwdAddrsHandler with the following scenario:
  1494. //
  1495. // The request includes only a forward change.
  1496. // Initial posted event is SERVER_SELECTED_EVT.
  1497. // The request build fails due to an unexpected exception.
  1498. //
  1499. TEST_F(NameRemoveTransactionTest,
  1500. removingFwdAddrsHandler_BuildRequestException) {
  1501. NameRemoveStubPtr name_remove;
  1502. // Create and prep a transaction, poised to run the handler.
  1503. ASSERT_NO_THROW(name_remove =
  1504. prepHandlerTest(NameRemoveTransaction::
  1505. REMOVING_FWD_ADDRS_ST,
  1506. NameChangeTransaction::
  1507. SERVER_SELECTED_EVT, FORWARD_CHG));
  1508. // Set the one-shot exception simulation flag.
  1509. name_remove->simulate_build_request_exception_ = true;
  1510. // Run removingFwdAddrsHandler to construct and send the request.
  1511. // This should fail with a build request throw which should be caught
  1512. // in the state handler.
  1513. ASSERT_NO_THROW(name_remove->removingFwdAddrsHandler());
  1514. // Verify we did not attempt to send anything.
  1515. EXPECT_EQ(0, name_remove->getUpdateAttempts());
  1516. // Completion flags should be false.
  1517. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1518. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  1519. // Since IO exceptions should be gracefully handled, any that occur
  1520. // are unanticipated, and deemed unrecoverable, so the transaction should
  1521. // be transitioned to failure.
  1522. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  1523. name_remove->getCurrState());
  1524. EXPECT_EQ(NameChangeTransaction::UPDATE_FAILED_EVT,
  1525. name_remove->getNextEvent());
  1526. }
  1527. // Tests removingFwdRRsHandler with the following scenario:
  1528. //
  1529. // The request includes only a forward change.
  1530. // Initial posted event is SERVER_SELECTED_EVT.
  1531. // The request build fails due to an unexpected exception.
  1532. //
  1533. TEST_F(NameRemoveTransactionTest,
  1534. removingFwdRRsHandler_BuildRequestException) {
  1535. NameRemoveStubPtr name_remove;
  1536. // Create and prep a transaction, poised to run the handler.
  1537. ASSERT_NO_THROW(name_remove =
  1538. prepHandlerTest(NameRemoveTransaction::
  1539. REMOVING_FWD_RRS_ST,
  1540. NameChangeTransaction::
  1541. SERVER_SELECTED_EVT, FORWARD_CHG));
  1542. // Set the one-shot exception simulation flag.
  1543. name_remove->simulate_build_request_exception_ = true;
  1544. // Run removingFwdRRsHandler to construct and send the request.
  1545. // This should fail with a build request throw which should be caught
  1546. // in the state handler.
  1547. ASSERT_NO_THROW(name_remove->removingFwdRRsHandler());
  1548. // Verify we did not attempt to send anything.
  1549. EXPECT_EQ(0, name_remove->getUpdateAttempts());
  1550. // Completion flags should be false.
  1551. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1552. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  1553. // Since IO exceptions should be gracefully handled, any that occur
  1554. // are unanticipated, and deemed unrecoverable, so the transaction should
  1555. // be transitioned to failure.
  1556. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  1557. name_remove->getCurrState());
  1558. EXPECT_EQ(NameChangeTransaction::UPDATE_FAILED_EVT,
  1559. name_remove->getNextEvent());
  1560. }
  1561. // Tests removingRevPTRsHandler with the following scenario:
  1562. //
  1563. // The request includes only a forward change.
  1564. // Initial posted event is SERVER_SELECTED_EVT.
  1565. // The request build fails due to an unexpected exception.
  1566. //
  1567. TEST_F(NameRemoveTransactionTest,
  1568. removingRevPTRsHandler_BuildRequestException) {
  1569. NameRemoveStubPtr name_remove;
  1570. // Create and prep a transaction, poised to run the handler.
  1571. ASSERT_NO_THROW(name_remove =
  1572. prepHandlerTest(NameRemoveTransaction::
  1573. REMOVING_REV_PTRS_ST,
  1574. NameChangeTransaction::
  1575. SERVER_SELECTED_EVT, FORWARD_CHG));
  1576. // Set the one-shot exception simulation flag.
  1577. name_remove->simulate_build_request_exception_ = true;
  1578. // Run removingRevPtrsHandler to construct and send the request.
  1579. // This should fail with a build request throw which should be caught
  1580. // in the state handler.
  1581. ASSERT_NO_THROW(name_remove->removingRevPtrsHandler());
  1582. // Verify we did not attempt to send anything.
  1583. EXPECT_EQ(0, name_remove->getUpdateAttempts());
  1584. // Completion flags should be false.
  1585. EXPECT_FALSE(name_remove->getForwardChangeCompleted());
  1586. EXPECT_FALSE(name_remove->getReverseChangeCompleted());
  1587. // Since IO exceptions should be gracefully handled, any that occur
  1588. // are unanticipated, and deemed unrecoverable, so the transaction should
  1589. // be transitioned to failure.
  1590. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  1591. name_remove->getCurrState());
  1592. EXPECT_EQ(NameChangeTransaction::UPDATE_FAILED_EVT,
  1593. name_remove->getNextEvent());
  1594. }
  1595. }