nc_add_unittests.cc 74 KB

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