nc_add_unittests.cc 75 KB

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