nc_add_unittests.cc 74 KB

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