nc_add_unittests.cc 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449
  1. // Copyright (C) 2013 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/nc_add.h>
  15. #include <boost/function.hpp>
  16. #include <boost/bind.hpp>
  17. #include <gtest/gtest.h>
  18. using namespace std;
  19. using namespace isc;
  20. using namespace isc::d2;
  21. namespace {
  22. /// @brief Test class derived from NameAddTransaction to provide visiblity
  23. // to protected methods.
  24. class NameAddStub : public NameAddTransaction {
  25. public:
  26. NameAddStub(IOServicePtr& io_service,
  27. dhcp_ddns::NameChangeRequestPtr& ncr,
  28. DdnsDomainPtr& forward_domain,
  29. DdnsDomainPtr& reverse_domain)
  30. : NameAddTransaction(io_service, ncr, forward_domain, reverse_domain){
  31. }
  32. virtual ~NameAddStub() {
  33. }
  34. /// @brief Simulates sending update requests to the DNS server
  35. /// Allows state handlers which conduct IO to be tested without a server.
  36. virtual void sendUpdate(bool /* use_tsig_ = false */) {
  37. setUpdateAttempts(getUpdateAttempts() + 1);
  38. postNextEvent(StateModel::NOP_EVT);
  39. }
  40. void fakeResponse(const DNSClient::Status& status,
  41. const dns::Rcode& rcode) {
  42. D2UpdateMessagePtr msg(new D2UpdateMessage(D2UpdateMessage::OUTBOUND));
  43. setDnsUpdateStatus(status);
  44. msg->setRcode(rcode);
  45. setDnsUpdateResponse(msg);
  46. postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  47. }
  48. bool selectFwdServer() {
  49. if (getForwardDomain()) {
  50. initServerSelection(getForwardDomain());
  51. selectNextServer();
  52. return (getCurrentServer());
  53. }
  54. return (false);
  55. }
  56. bool selectRevServer() {
  57. if (getReverseDomain()) {
  58. initServerSelection(getReverseDomain());
  59. selectNextServer();
  60. return (getCurrentServer());
  61. }
  62. return (false);
  63. }
  64. using StateModel::postNextEvent;
  65. using StateModel::setState;
  66. using StateModel::initDictionaries;
  67. using NameAddTransaction::defineEvents;
  68. using NameAddTransaction::verifyEvents;
  69. using NameAddTransaction::defineStates;
  70. using NameAddTransaction::verifyStates;
  71. using NameAddTransaction::readyHandler;
  72. using NameAddTransaction::selectingFwdServerHandler;
  73. using NameAddTransaction::getCurrentServer;
  74. using NameAddTransaction::addingFwdAddrsHandler;
  75. using NameAddTransaction::setDnsUpdateStatus;
  76. using NameAddTransaction::replacingFwdAddrsHandler;
  77. using NameAddTransaction::selectingRevServerHandler;
  78. using NameAddTransaction::replacingRevPtrsHandler;
  79. using NameAddTransaction::processAddOkHandler;
  80. using NameAddTransaction::processAddFailedHandler;
  81. };
  82. typedef boost::shared_ptr<NameAddStub> NameAddStubPtr;
  83. /// @brief Test fixture for testing NameAddTransaction
  84. ///
  85. /// Note this class uses NameAddStub class to exercise non-public
  86. /// aspects of NameAddTransaction.
  87. class NameAddTransactionTest : public ::testing::Test {
  88. public:
  89. IOServicePtr io_service_;
  90. DdnsDomainPtr forward_domain_;
  91. DdnsDomainPtr reverse_domain_;
  92. NameAddTransactionTest() : io_service_(new isc::asiolink::IOService()) {
  93. }
  94. static const unsigned int FORWARD_CHG = 0x01;
  95. static const unsigned int REVERSE_CHG = 0x02;
  96. static const unsigned int FWD_AND_REV_CHG = REVERSE_CHG | FORWARD_CHG;
  97. virtual ~NameAddTransactionTest() {
  98. }
  99. /// @brief Instantiates a NameAddStub test transaction
  100. /// The transaction is constructed around a predefined (i.e "canned")
  101. /// NameChangeRequest. The request has both forward and reverse DNS
  102. /// changes requested. Based upon the change mask, the transaction
  103. /// will have either the forward, reverse, or both domains populated.
  104. ///
  105. /// @param change_mask determines which change directions are requested
  106. NameAddStubPtr makeCannedTransaction(int change_mask=FWD_AND_REV_CHG) {
  107. const char* msg_str =
  108. "{"
  109. " \"change_type\" : 0 , "
  110. " \"forward_change\" : true , "
  111. " \"reverse_change\" : true , "
  112. " \"fqdn\" : \"example.com.\" , "
  113. " \"ip_address\" : \"192.168.2.1\" , "
  114. " \"dhcid\" : \"0102030405060708\" , "
  115. " \"lease_expires_on\" : \"20130121132405\" , "
  116. " \"lease_length\" : 1300 "
  117. "}";
  118. // Create NameChangeRequest from JSON string.
  119. dhcp_ddns::NameChangeRequestPtr ncr = dhcp_ddns::NameChangeRequest::
  120. fromJSON(msg_str);
  121. // If the change mask does not include a forward change clear the
  122. // forward domain; otherise create the domain and its servers.
  123. if (!(change_mask & FORWARD_CHG)) {
  124. ncr->setForwardChange(false);
  125. forward_domain_.reset();
  126. } else {
  127. // Create the forward domain and then its servers.
  128. DnsServerInfoStoragePtr servers(new DnsServerInfoStorage());
  129. DnsServerInfoPtr server(new DnsServerInfo("forward.example.com",
  130. isc::asiolink::IOAddress("1.1.1.1")));
  131. servers->push_back(server);
  132. server.reset(new DnsServerInfo("forward2.example.com",
  133. isc::asiolink::IOAddress("1.1.1.2")));
  134. servers->push_back(server);
  135. forward_domain_.reset(new DdnsDomain("example.com.", "", servers));
  136. }
  137. // If the change mask does not include a reverse change clear the
  138. // reverse domain; otherise create the domain and its servers.
  139. if (!(change_mask & REVERSE_CHG)) {
  140. ncr->setReverseChange(false);
  141. reverse_domain_.reset();
  142. } else {
  143. // Create the reverse domain and its server.
  144. DnsServerInfoStoragePtr servers(new DnsServerInfoStorage());
  145. DnsServerInfoPtr server(new DnsServerInfo("reverse.example.com",
  146. isc::asiolink::
  147. IOAddress("2.2.2.2")));
  148. servers->push_back(server);
  149. server.reset(new DnsServerInfo("reverse2.example.com",
  150. isc::asiolink::
  151. IOAddress("2.2.2.3")));
  152. servers->push_back(server);
  153. reverse_domain_.reset(new DdnsDomain("2.168.192.in.addr.arpa.",
  154. "", servers));
  155. }
  156. // Now create the test transaction as would occur in update manager.
  157. return (NameAddStubPtr(new NameAddStub(io_service_, ncr,
  158. forward_domain_, reverse_domain_)));
  159. }
  160. /// @brief Create a test transaction at a known point in the state model.
  161. ///
  162. /// Method prepares a new test transaction and sets its state and next
  163. /// event values to those given. This makes the transaction appear to
  164. /// be at that point in the state model without having to transition it
  165. /// through prerequiste states. It also provides the ability to set
  166. /// which change directions are requested: forward change only, reverse
  167. /// change only, or both.
  168. ///
  169. /// @param state value to set as the current state
  170. /// @param event value to post as the next event
  171. /// @param change_mask determines which change directions are requested
  172. NameAddStubPtr prepHandlerTest(unsigned int state, unsigned int event,
  173. unsigned int change_mask = FWD_AND_REV_CHG) {
  174. NameAddStubPtr name_add = makeCannedTransaction(change_mask);
  175. name_add->initDictionaries();
  176. name_add->postNextEvent(event);
  177. name_add->setState(state);
  178. return (name_add);
  179. }
  180. };
  181. /// @brief Tests NameAddTransaction construction.
  182. /// This test verifies that:
  183. /// 1. Construction with invalid type of request
  184. /// 2. Valid construction functions properly
  185. TEST(NameAddTransaction, construction) {
  186. IOServicePtr io_service(new isc::asiolink::IOService());
  187. const char* msg_str =
  188. "{"
  189. " \"change_type\" : 1 , "
  190. " \"forward_change\" : true , "
  191. " \"reverse_change\" : true , "
  192. " \"fqdn\" : \"example.com.\" , "
  193. " \"ip_address\" : \"192.168.2.1\" , "
  194. " \"dhcid\" : \"0102030405060708\" , "
  195. " \"lease_expires_on\" : \"20130121132405\" , "
  196. " \"lease_length\" : 1300 "
  197. "}";
  198. dhcp_ddns::NameChangeRequestPtr ncr;
  199. DnsServerInfoStoragePtr servers;
  200. DdnsDomainPtr forward_domain;
  201. DdnsDomainPtr reverse_domain;
  202. DdnsDomainPtr empty_domain;
  203. ASSERT_NO_THROW(ncr = dhcp_ddns::NameChangeRequest::fromJSON(msg_str));
  204. ASSERT_NO_THROW(forward_domain.reset(new DdnsDomain("*", "", servers)));
  205. ASSERT_NO_THROW(reverse_domain.reset(new DdnsDomain("*", "", servers)));
  206. // Verify that construction with wrong change type fails.
  207. EXPECT_THROW(NameAddTransaction(io_service, ncr,
  208. forward_domain, reverse_domain),
  209. NameAddTransactionError);
  210. // Verify that a valid construction attempt works.
  211. ncr->setChangeType(isc::dhcp_ddns::CHG_ADD);
  212. EXPECT_NO_THROW(NameAddTransaction(io_service, ncr,
  213. forward_domain, reverse_domain));
  214. }
  215. /// @brief Tests event and state dictionary construction and verification.
  216. TEST_F(NameAddTransactionTest, dictionaryCheck) {
  217. NameAddStubPtr name_add;
  218. ASSERT_NO_THROW(name_add = makeCannedTransaction());
  219. // Verify that the event and state dictionary validation fails prior
  220. // dictionary construction.
  221. ASSERT_THROW(name_add->verifyEvents(), StateModelError);
  222. ASSERT_THROW(name_add->verifyStates(), StateModelError);
  223. // Construct both dictionaries.
  224. ASSERT_NO_THROW(name_add->defineEvents());
  225. ASSERT_NO_THROW(name_add->defineStates());
  226. // Verify both event and state dictionaries now pass validation.
  227. ASSERT_NO_THROW(name_add->verifyEvents());
  228. ASSERT_NO_THROW(name_add->verifyStates());
  229. }
  230. // Tests the readyHandler functionality.
  231. // It verifies behavior for the following scenarios:
  232. //
  233. // 1. Posted event is START_EVT and request includes only a forward change
  234. // 2. Posted event is START_EVT and request includes both a forward and a
  235. // reverse change
  236. // 3. Posted event is START_EVT and request includes only a reverse change
  237. // 3. Posted event is invalid
  238. //
  239. TEST_F(NameAddTransactionTest, readyHandler) {
  240. NameAddStubPtr name_add;
  241. // Create a transaction which includes only a forward change.
  242. ASSERT_NO_THROW(name_add =
  243. prepHandlerTest(NameChangeTransaction::READY_ST,
  244. StateModel::START_EVT, FORWARD_CHG));
  245. // Run readyHandler.
  246. EXPECT_NO_THROW(name_add->readyHandler());
  247. // Verify that a request requiring only a forward change, transitions to
  248. // selecting a forward server.
  249. EXPECT_EQ(NameChangeTransaction::SELECTING_FWD_SERVER_ST,
  250. name_add->getCurrState());
  251. EXPECT_EQ(NameChangeTransaction::SELECT_SERVER_EVT,
  252. name_add->getNextEvent());
  253. // Create a transaction which includes both a forward and a reverse change.
  254. ASSERT_NO_THROW(name_add =
  255. prepHandlerTest(NameChangeTransaction::READY_ST,
  256. StateModel::START_EVT, FWD_AND_REV_CHG));
  257. // Run readyHandler.
  258. EXPECT_NO_THROW(name_add->readyHandler());
  259. // Verify that a request requiring both forward and reverse, starts with
  260. // the forward change by transitioning to selecting a forward server.
  261. EXPECT_EQ(NameChangeTransaction::SELECTING_FWD_SERVER_ST,
  262. name_add->getCurrState());
  263. EXPECT_EQ(NameChangeTransaction::SELECT_SERVER_EVT,
  264. name_add->getNextEvent());
  265. // Create and prep a reverse only transaction.
  266. ASSERT_NO_THROW(name_add =
  267. prepHandlerTest(NameChangeTransaction::READY_ST,
  268. StateModel::START_EVT, REVERSE_CHG));
  269. // Run readyHandler.
  270. EXPECT_NO_THROW(name_add->readyHandler());
  271. // Verify that a request requiring only a reverse change, transitions to
  272. // selecting a reverse server.
  273. EXPECT_EQ(NameChangeTransaction::SELECTING_REV_SERVER_ST,
  274. name_add->getCurrState());
  275. EXPECT_EQ(NameChangeTransaction::SELECT_SERVER_EVT,
  276. name_add->getNextEvent());
  277. // Create and prep transaction, poised to run the handler but with an
  278. // invalid event.
  279. ASSERT_NO_THROW(name_add =
  280. prepHandlerTest(NameChangeTransaction::READY_ST,
  281. StateModel::NOP_EVT));
  282. // Running the readyHandler should throw.
  283. EXPECT_THROW(name_add->readyHandler(), NameAddTransactionError);
  284. }
  285. // Tests the selectingFwdServerHandler functionality.
  286. // It verifies behavior for the following scenarios:
  287. //
  288. // 1. Posted event is SELECT_SERVER_EVT
  289. // 2. Posted event is SERVER_IO_ERROR_EVT
  290. // 3. Posted event is invalid
  291. //
  292. TEST_F(NameAddTransactionTest, selectingFwdServerHandler) {
  293. NameAddStubPtr name_add;
  294. // Create and prep a transaction, poised to run the handler.
  295. ASSERT_NO_THROW(name_add =
  296. prepHandlerTest(NameChangeTransaction::
  297. SELECTING_FWD_SERVER_ST,
  298. NameChangeTransaction::SELECT_SERVER_EVT));
  299. // Call selectingFwdServerHandler enough times to select all of the
  300. // servers in it's current domain. The first time, it will be with
  301. // next event of SELECT_SERVER_EVT. Thereafter it will be with a next
  302. // event of SERVER_IO_ERROR_EVT.
  303. int num_servers = name_add->getForwardDomain()->getServers()->size();
  304. for (int i = 0; i < num_servers; ++i) {
  305. // Run selectingFwdServerHandler.
  306. ASSERT_NO_THROW(name_add->selectingFwdServerHandler())
  307. << " num_servers: " << num_servers
  308. << " selections: " << i;
  309. // Verify that a server was selected.
  310. ASSERT_TRUE(name_add->getCurrentServer())
  311. << " num_servers: " << num_servers << " selections: " << i;
  312. // Verify that we transitioned correctly.
  313. ASSERT_EQ(NameAddTransaction::ADDING_FWD_ADDRS_ST,
  314. name_add->getCurrState())
  315. << " num_servers: " << num_servers << " selections: " << i;
  316. ASSERT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  317. name_add->getNextEvent())
  318. << " num_servers: " << num_servers << " selections: " << i;
  319. // Post a server IO error event. This simulates an IO error occuring
  320. // and a need to select the new server.
  321. ASSERT_NO_THROW(name_add->postNextEvent(NameChangeTransaction::
  322. SERVER_IO_ERROR_EVT))
  323. << " num_servers: " << num_servers
  324. << " selections: " << i;
  325. }
  326. // We should have exhausted the list of servers. Processing another
  327. // SERVER_IO_ERROR_EVT should transition us to failure.
  328. EXPECT_NO_THROW(name_add->selectingFwdServerHandler());
  329. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  330. name_add->getCurrState());
  331. EXPECT_EQ(NameChangeTransaction::NO_MORE_SERVERS_EVT,
  332. name_add->getNextEvent());
  333. // Create and prep transaction, poised to run the handler but with an
  334. // invalid event.
  335. ASSERT_NO_THROW(name_add =
  336. prepHandlerTest(NameChangeTransaction::
  337. SELECTING_FWD_SERVER_ST,
  338. StateModel::NOP_EVT));
  339. // Running the handler should throw.
  340. EXPECT_THROW(name_add->selectingFwdServerHandler(),
  341. NameAddTransactionError);
  342. }
  343. // ************************ addingFwdAddrHandler Tests *****************
  344. // Tests that addingFwdAddrsHandler rejects invalid events.
  345. TEST_F(NameAddTransactionTest, addingFwdAddrsHandler_InvalidEvent) {
  346. NameAddStubPtr name_add;
  347. // Create and prep a transaction, poised to run the handler but with
  348. // an invalid event.
  349. ASSERT_NO_THROW(name_add =
  350. prepHandlerTest(NameAddTransaction::ADDING_FWD_ADDRS_ST,
  351. NameChangeTransaction::
  352. StateModel::NOP_EVT));
  353. // Running the handler should throw.
  354. EXPECT_THROW(name_add->addingFwdAddrsHandler(),
  355. NameAddTransactionError);
  356. }
  357. // Tests addingFwdAddrsHandler with the following scenario:
  358. //
  359. // The request includes only a forward change.
  360. // Initial posted event is SERVER_SELECTED_EVT.
  361. // The update request is sent without error.
  362. // A server response is received which indicates successful update
  363. //
  364. TEST_F(NameAddTransactionTest, addingFwdAddrsHandler_FwdOnlyAddOK) {
  365. NameAddStubPtr name_add;
  366. // Create and prep a transaction, poised to run the handler.
  367. ASSERT_NO_THROW(name_add =
  368. prepHandlerTest(NameAddTransaction::ADDING_FWD_ADDRS_ST,
  369. NameChangeTransaction::
  370. SERVER_SELECTED_EVT, FORWARD_CHG));
  371. // Should not be an update message yet.
  372. D2UpdateMessagePtr update_msg = name_add->getDnsUpdateRequest();
  373. ASSERT_FALSE(update_msg);
  374. // At this point completion flags should be false.
  375. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  376. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  377. // Run addingFwdAddrsHandler to construct and send the request.
  378. EXPECT_NO_THROW(name_add->addingFwdAddrsHandler());
  379. // Verify that an update message was constructed.
  380. update_msg = name_add->getDnsUpdateRequest();
  381. EXPECT_TRUE(update_msg);
  382. // Verify that we are still in this state and next event is NOP_EVT.
  383. // This indicates we "sent" the message and are waiting for IO completion.
  384. EXPECT_EQ(NameAddTransaction::ADDING_FWD_ADDRS_ST,
  385. name_add->getCurrState());
  386. EXPECT_EQ(NameChangeTransaction::NOP_EVT,
  387. name_add->getNextEvent());
  388. // Simulate receiving a succussful update response.
  389. name_add->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NOERROR());
  390. // Run addingFwdAddrsHandler again to process the response.
  391. EXPECT_NO_THROW(name_add->addingFwdAddrsHandler());
  392. // Forward completion should be true, reverse should be false.
  393. EXPECT_TRUE(name_add->getForwardChangeCompleted());
  394. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  395. // Since it is a forward only change, we should be done.
  396. // Verify that we transitioned correctly.
  397. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  398. name_add->getCurrState());
  399. EXPECT_EQ(NameChangeTransaction::UPDATE_OK_EVT,
  400. name_add->getNextEvent());
  401. }
  402. // Tests addingFwdAddrsHandler with the following scenario:
  403. //
  404. // The request includes a forward and reverse change.
  405. // Initial posted event is SERVER_SELECTED_EVT.
  406. // The update request is sent without error.
  407. // A server response is received which indicates successful update.
  408. //
  409. TEST_F(NameAddTransactionTest, addingFwdAddrsHandler_fwdAndRevAddOK) {
  410. NameAddStubPtr name_add;
  411. // Create and prep a transaction, poised to run the handler.
  412. ASSERT_NO_THROW(name_add =
  413. prepHandlerTest(NameAddTransaction::ADDING_FWD_ADDRS_ST,
  414. NameChangeTransaction::
  415. SERVER_SELECTED_EVT, FWD_AND_REV_CHG));
  416. // Run addingFwdAddrsHandler to construct and send the request.
  417. EXPECT_NO_THROW(name_add->addingFwdAddrsHandler());
  418. // Simulate receiving a succussful update response.
  419. name_add->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NOERROR());
  420. // Run addingFwdAddrsHandler again to process the response.
  421. EXPECT_NO_THROW(name_add->addingFwdAddrsHandler());
  422. // Forward change completion should be true, reverse flag should be false.
  423. EXPECT_TRUE(name_add->getForwardChangeCompleted());
  424. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  425. // Since the request also includes a reverse change we should
  426. // be poised to start it. Verify that we transitioned correctly.
  427. EXPECT_EQ(NameChangeTransaction::SELECTING_REV_SERVER_ST,
  428. name_add->getCurrState());
  429. EXPECT_EQ(NameChangeTransaction::SELECT_SERVER_EVT,
  430. name_add->getNextEvent());
  431. }
  432. // Tests addingFwdAddrsHandler with the following scenario:
  433. //
  434. // The request includes a forward and reverse change.
  435. // Initial posted event is SERVER_SELECTED_EVT.
  436. // The update request is sent without error.
  437. // A server response is received which indicates the FQDN is in use.
  438. //
  439. TEST_F(NameAddTransactionTest, addingFwdAddrsHandler_FqdnInUse) {
  440. NameAddStubPtr name_add;
  441. // Create and prep a transaction, poised to run the handler.
  442. ASSERT_NO_THROW(name_add =
  443. prepHandlerTest(NameAddTransaction::ADDING_FWD_ADDRS_ST,
  444. NameChangeTransaction::
  445. SERVER_SELECTED_EVT));
  446. // Run addingFwdAddrsHandler to construct and send the request.
  447. EXPECT_NO_THROW(name_add->addingFwdAddrsHandler());
  448. // Simulate receiving a FQDN in use response.
  449. name_add->fakeResponse(DNSClient::SUCCESS, dns::Rcode::YXDOMAIN());
  450. // Run addingFwdAddrsHandler again to process the response.
  451. EXPECT_NO_THROW(name_add->addingFwdAddrsHandler());
  452. // Completion flags should still be false.
  453. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  454. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  455. // Since the FQDN is in use, per the RFC we must attempt to replace it.
  456. // Verify that we transitioned correctly.
  457. EXPECT_EQ(NameAddTransaction::REPLACING_FWD_ADDRS_ST,
  458. name_add->getCurrState());
  459. EXPECT_EQ(NameAddTransaction::FQDN_IN_USE_EVT,
  460. name_add->getNextEvent());
  461. }
  462. // Tests addingFwdAddrsHandler with the following scenario:
  463. //
  464. // The request includes a forward and reverse change.
  465. // Initial posted event is SERVER_SELECTED_EVT.
  466. // The update request is sent without error.
  467. // A server response is received which indicates the update was rejected.
  468. //
  469. TEST_F(NameAddTransactionTest, addingFwdAddrsHandler_OtherRcode) {
  470. NameAddStubPtr name_add;
  471. // Create and prep a transaction, poised to run the handler.
  472. ASSERT_NO_THROW(name_add =
  473. prepHandlerTest(NameAddTransaction::ADDING_FWD_ADDRS_ST,
  474. NameChangeTransaction::
  475. SERVER_SELECTED_EVT));
  476. // Select a server to satisfy log statements.
  477. ASSERT_TRUE(name_add->selectFwdServer());
  478. // Run addingFwdAddrsHandler to construct and send the request.
  479. EXPECT_NO_THROW(name_add->addingFwdAddrsHandler());
  480. // Simulate receiving server rejection response. Per RFC, anything other
  481. // than no error or FQDN in use is failure. Arbitrarily choosing refused.
  482. name_add->fakeResponse(DNSClient::SUCCESS, dns::Rcode::REFUSED());
  483. // Run addingFwdAddrsHandler again to process the response.
  484. EXPECT_NO_THROW(name_add->addingFwdAddrsHandler());
  485. // Completion flags should still be false.
  486. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  487. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  488. // We should have failed the transaction. Verifiy that we transitioned
  489. // correctly.
  490. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  491. name_add->getCurrState());
  492. EXPECT_EQ(NameChangeTransaction::UPDATE_FAILED_EVT,
  493. name_add->getNextEvent());
  494. }
  495. // Tests addingFwdAddrsHandler with the following scenario:
  496. //
  497. // The request includes a forward and reverse change.
  498. // Initial posted event is SERVER_SELECTED_EVT.
  499. // The update request send times out MAX_UPDATE_TRIES_PER_SERVER times.
  500. //
  501. TEST_F(NameAddTransactionTest, addingFwdAddrsHandler_Timeout) {
  502. NameAddStubPtr name_add;
  503. // Create and prep a transaction, poised to run the handler.
  504. // The log message issued when this test succeeds, displays the
  505. // selected server, so we need to select a server before running this
  506. // test.
  507. ASSERT_NO_THROW(name_add =
  508. prepHandlerTest(NameAddTransaction::ADDING_FWD_ADDRS_ST,
  509. NameChangeTransaction::
  510. SERVER_SELECTED_EVT));
  511. // Select a server to satisfy log statements.
  512. ASSERT_TRUE(name_add->selectFwdServer());
  513. // Verify that we can make maximum number of update attempts permitted
  514. // and then transition to selecting a new server.
  515. int max_tries = NameChangeTransaction::MAX_UPDATE_TRIES_PER_SERVER;
  516. for (int i = 1; i <= max_tries; ++i) {
  517. const D2UpdateMessagePtr prev_msg = name_add->getDnsUpdateRequest();
  518. // Run addingFwdAddrsHandler to send the request.
  519. EXPECT_NO_THROW(name_add->addingFwdAddrsHandler());
  520. const D2UpdateMessagePtr curr_msg = name_add->getDnsUpdateRequest();
  521. if (i == 1) {
  522. // First time out we should build the message.
  523. EXPECT_FALSE(prev_msg);
  524. EXPECT_TRUE(curr_msg);
  525. } else {
  526. // Subsequent passes should reuse the request. We are only
  527. // looking to check that we have not replaced the pointer value
  528. // with a new pointer. This tests the on_entry() logic which
  529. // clears the request ONLY upon initial entry into the state.
  530. EXPECT_TRUE(prev_msg == curr_msg);
  531. }
  532. // Simulate a server IO timeout.
  533. name_add->setDnsUpdateStatus(DNSClient::TIMEOUT);
  534. name_add->postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  535. // Run addingFwdAddrsHandler again to process the response.
  536. EXPECT_NO_THROW(name_add->addingFwdAddrsHandler());
  537. // Completion flags should be false.
  538. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  539. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  540. if (i < max_tries) {
  541. // We should be ready to try again.
  542. EXPECT_EQ(NameAddTransaction::ADDING_FWD_ADDRS_ST,
  543. name_add->getCurrState());
  544. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  545. name_add->getNextEvent());
  546. } else {
  547. // Server retries should be exhausted, time for a new server.
  548. EXPECT_EQ(NameAddTransaction::SELECTING_FWD_SERVER_ST,
  549. name_add->getCurrState());
  550. EXPECT_EQ(NameChangeTransaction::SERVER_IO_ERROR_EVT,
  551. name_add->getNextEvent());
  552. }
  553. }
  554. }
  555. // Tests addingFwdAddrsHandler with the following scenario:
  556. //
  557. // The request includes a forward and reverse change.
  558. // Initial posted event is SERVER_SELECTED_EVT.
  559. // The update request is sent but a corrupt response is received, this occurs
  560. // MAX_UPDATE_TRIES_PER_SERVER times.
  561. //
  562. TEST_F(NameAddTransactionTest, addingFwdAddrsHandler_InvalidResponse) {
  563. NameAddStubPtr name_add;
  564. // Create and prep a transaction, poised to run the handler.
  565. // The log message issued when this test succeeds, displays the
  566. // selected server, so we need to select a server before running this
  567. // test.
  568. ASSERT_NO_THROW(name_add =
  569. prepHandlerTest(NameAddTransaction::ADDING_FWD_ADDRS_ST,
  570. NameChangeTransaction::
  571. SERVER_SELECTED_EVT));
  572. // Select a server to satisfy log statements.
  573. ASSERT_TRUE(name_add->selectFwdServer());
  574. // Verify that we can make maximum number of update attempts permitted
  575. // and then transition to selecting a new server.
  576. int max_tries = NameChangeTransaction::MAX_UPDATE_TRIES_PER_SERVER;
  577. for (int i = 1; i <= max_tries; ++i) {
  578. // Run addingFwdAddrsHandler to construct send the request.
  579. EXPECT_NO_THROW(name_add->addingFwdAddrsHandler());
  580. // Simulate a server IO timeout.
  581. name_add->setDnsUpdateStatus(DNSClient::INVALID_RESPONSE);
  582. name_add->postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  583. // Run addingFwdAddrsHandler again to process the response.
  584. EXPECT_NO_THROW(name_add->addingFwdAddrsHandler());
  585. // Completion flags should be false.
  586. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  587. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  588. if (i < max_tries) {
  589. // We should be ready to try again.
  590. EXPECT_EQ(NameAddTransaction::ADDING_FWD_ADDRS_ST,
  591. name_add->getCurrState());
  592. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  593. name_add->getNextEvent());
  594. } else {
  595. // Server retries should be exhausted, time for a new server.
  596. EXPECT_EQ(NameAddTransaction::SELECTING_FWD_SERVER_ST,
  597. name_add->getCurrState());
  598. EXPECT_EQ(NameChangeTransaction::SERVER_IO_ERROR_EVT,
  599. name_add->getNextEvent());
  600. }
  601. }
  602. }
  603. // ************************ replacingFwdAddrHandler Tests *****************
  604. // Tests that replacingFwdAddrsHandler rejects invalid events.
  605. TEST_F(NameAddTransactionTest, replacingFwdAddrsHandler_InvalidEvent) {
  606. NameAddStubPtr name_add;
  607. // Create and prep a transaction, poised to run the handler but with
  608. // an invalid event.
  609. ASSERT_NO_THROW(name_add =
  610. prepHandlerTest(NameAddTransaction::REPLACING_FWD_ADDRS_ST,
  611. NameChangeTransaction::
  612. StateModel::NOP_EVT));
  613. // Running the handler should throw.
  614. EXPECT_THROW(name_add->replacingFwdAddrsHandler(),
  615. NameAddTransactionError);
  616. }
  617. // Tests replacingFwdAddrsHandler with the following scenario:
  618. //
  619. // The request includes only a forward change.
  620. // Initial posted event is FQDN_IN_USE_EVT.
  621. // The update request is sent without error.
  622. // A server response is received which indicates successful update.
  623. //
  624. TEST_F(NameAddTransactionTest, replacingFwdAddrsHandler_FwdOnlyAddOK) {
  625. NameAddStubPtr name_add;
  626. // Create and prep a transaction, poised to run the handler.
  627. ASSERT_NO_THROW(name_add =
  628. prepHandlerTest(NameAddTransaction::REPLACING_FWD_ADDRS_ST,
  629. NameAddTransaction::
  630. FQDN_IN_USE_EVT, FORWARD_CHG));
  631. // Should not be an update message yet.
  632. D2UpdateMessagePtr update_msg = name_add->getDnsUpdateRequest();
  633. ASSERT_FALSE(update_msg);
  634. // At this point completion flags should be false.
  635. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  636. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  637. // Run replacingFwdAddrsHandler to construct and send the request.
  638. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  639. // Verify that an update message was constructed.
  640. update_msg = name_add->getDnsUpdateRequest();
  641. EXPECT_TRUE(update_msg);
  642. // Verify that we are still in this state and next event is NOP_EVT.
  643. // This indicates we "sent" the message and are waiting for IO completion.
  644. EXPECT_EQ(NameAddTransaction::REPLACING_FWD_ADDRS_ST,
  645. name_add->getCurrState());
  646. EXPECT_EQ(NameChangeTransaction::NOP_EVT,
  647. name_add->getNextEvent());
  648. // Simulate receiving a succussful update response.
  649. name_add->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NOERROR());
  650. // Run replacingFwdAddrsHandler again to process the response.
  651. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  652. // Forward completion should be true, reverse should be false.
  653. EXPECT_TRUE(name_add->getForwardChangeCompleted());
  654. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  655. // Since it is a forward only change, we should be done.
  656. // Verify that we transitioned correctly.
  657. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  658. name_add->getCurrState());
  659. EXPECT_EQ(NameChangeTransaction::UPDATE_OK_EVT,
  660. name_add->getNextEvent());
  661. }
  662. // Tests replacingFwdAddrsHandler with the following scenario:
  663. //
  664. // The request includes only a forward change.
  665. // Initial posted event is SERVER_SELECTED_EVT.
  666. // The update request is sent without error.
  667. // A server response is received which indicates successful update.
  668. //
  669. TEST_F(NameAddTransactionTest, replacingFwdAddrsHandler_FwdOnlyAddOK2) {
  670. NameAddStubPtr name_add;
  671. // Create and prep a transaction, poised to run the handler.
  672. ASSERT_NO_THROW(name_add =
  673. prepHandlerTest(NameAddTransaction::REPLACING_FWD_ADDRS_ST,
  674. NameChangeTransaction::
  675. SERVER_SELECTED_EVT, FORWARD_CHG));
  676. // Run replacingFwdAddrsHandler to construct and send the request.
  677. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  678. // Simulate receiving a succussful update response.
  679. name_add->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NOERROR());
  680. // Run replacingFwdAddrsHandler again to process the response.
  681. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  682. // Forward completion should be true, reverse should be false.
  683. EXPECT_TRUE(name_add->getForwardChangeCompleted());
  684. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  685. // Since it is a forward only change, we should be done.
  686. // Verify that we transitioned correctly.
  687. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  688. name_add->getCurrState());
  689. EXPECT_EQ(NameChangeTransaction::UPDATE_OK_EVT,
  690. name_add->getNextEvent());
  691. }
  692. // Tests replacingFwdAddrsHandler with the following scenario:
  693. //
  694. // The request includes a forward and reverse change.
  695. // Initial posted event is FQDN_IN_USE_EVT.
  696. // The update request is sent without error.
  697. // A server response is received which indicates successful update.
  698. //
  699. TEST_F(NameAddTransactionTest, replacingFwdAddrsHandler_FwdAndRevAddOK) {
  700. NameAddStubPtr name_add;
  701. // Create and prep a transaction, poised to run the handler.
  702. ASSERT_NO_THROW(name_add =
  703. prepHandlerTest(NameAddTransaction::REPLACING_FWD_ADDRS_ST,
  704. NameAddTransaction::
  705. FQDN_IN_USE_EVT, FWD_AND_REV_CHG));
  706. // Run replacingFwdAddrsHandler to construct and send the request.
  707. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  708. // Simulate receiving a succussful update response.
  709. name_add->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NOERROR());
  710. // Run replacingFwdAddrsHandler again to process the response.
  711. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  712. // Forward change completion should be true, reverse flag should be false.
  713. EXPECT_TRUE(name_add->getForwardChangeCompleted());
  714. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  715. // Since the request also includes a reverse change we should
  716. // be poised to start it. Verify that we transitioned correctly.
  717. EXPECT_EQ(NameChangeTransaction::SELECTING_REV_SERVER_ST,
  718. name_add->getCurrState());
  719. EXPECT_EQ(NameChangeTransaction::SELECT_SERVER_EVT,
  720. name_add->getNextEvent());
  721. }
  722. // Tests addingFwdAddrsHandler with the following scenario:
  723. //
  724. // The request includes a forward and reverse change.
  725. // Initial posted event is FQDN_IN_USE_EVT.
  726. // The update request is sent without error.
  727. // A server response is received which indicates the FQDN is NOT in use.
  728. //
  729. TEST_F(NameAddTransactionTest, addingFwdAddrsHandler_FqdnNotInUse) {
  730. NameAddStubPtr name_add;
  731. // Create and prep a transaction, poised to run the handler.
  732. ASSERT_NO_THROW(name_add =
  733. prepHandlerTest(NameAddTransaction::REPLACING_FWD_ADDRS_ST,
  734. NameAddTransaction::
  735. FQDN_IN_USE_EVT, FWD_AND_REV_CHG));
  736. // Run replacingFwdAddrsHandler to construct and send the request.
  737. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  738. // Simulate receiving a FQDN not in use response.
  739. name_add->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NXDOMAIN());
  740. // Run replacingFwdAddrsHandler again to process the response.
  741. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  742. // Completion flags should still be false.
  743. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  744. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  745. // Since the FQDN is no longer in use, per the RFC, try to add it.
  746. // Verify that we transitioned correctly.
  747. EXPECT_EQ(NameAddTransaction::ADDING_FWD_ADDRS_ST,
  748. name_add->getCurrState());
  749. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  750. name_add->getNextEvent());
  751. }
  752. // Tests replacingFwdAddrsHandler with the following scenario:
  753. //
  754. // The request includes a forward and reverse change.
  755. // The update request is sent without error.
  756. // A server response is received which indicates the update was rejected.
  757. //
  758. TEST_F(NameAddTransactionTest, replacingFwdAddrsHandler_OtherRcode) {
  759. NameAddStubPtr name_add;
  760. // Create the transaction.
  761. ASSERT_NO_THROW(name_add =
  762. prepHandlerTest(NameAddTransaction::REPLACING_FWD_ADDRS_ST,
  763. NameAddTransaction::
  764. FQDN_IN_USE_EVT, FWD_AND_REV_CHG));
  765. // Select a server to satisfy log statements.
  766. ASSERT_TRUE(name_add->selectFwdServer());
  767. // Run replacingFwdAddrsHandler to construct and send the request.
  768. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  769. // Simulate receiving server rejection response. Per RFC, anything other
  770. // than no error or FQDN in use is failure. Arbitrarily choosing refused.
  771. name_add->fakeResponse(DNSClient::SUCCESS, dns::Rcode::REFUSED());
  772. // Run replacingFwdAddrsHandler again to process the response.
  773. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  774. // Completion flags should still be false.
  775. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  776. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  777. // We should have failed the transaction. Verifiy that we transitioned
  778. // correctly.
  779. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  780. name_add->getCurrState());
  781. EXPECT_EQ(NameChangeTransaction::UPDATE_FAILED_EVT,
  782. name_add->getNextEvent());
  783. }
  784. // Tests replacingFwdAddrsHandler with the following scenario:
  785. //
  786. // The request includes a forward and reverse change.
  787. // Initial posted event is FQDN_IN_USE_EVT.
  788. // The update request send times out MAX_UPDATE_TRIES_PER_SERVER times.
  789. //
  790. TEST_F(NameAddTransactionTest, replacingFwdAddrsHandler_Timeout) {
  791. NameAddStubPtr name_add;
  792. // Create the transaction.
  793. ASSERT_NO_THROW(name_add =
  794. prepHandlerTest(NameAddTransaction::REPLACING_FWD_ADDRS_ST,
  795. NameAddTransaction::
  796. FQDN_IN_USE_EVT, FWD_AND_REV_CHG));
  797. // Select a server to satisfy log statements.
  798. ASSERT_TRUE(name_add->selectFwdServer());
  799. // Verify that we can make maximum number of update attempts permitted
  800. // and then transition to selecting a new server.
  801. int max_tries = NameChangeTransaction::MAX_UPDATE_TRIES_PER_SERVER;
  802. for (int i = 1; i <= max_tries; ++i) {
  803. const D2UpdateMessagePtr prev_msg = name_add->getDnsUpdateRequest();
  804. // Run replacingFwdAddrsHandler to send the request.
  805. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  806. const D2UpdateMessagePtr curr_msg = name_add->getDnsUpdateRequest();
  807. if (i == 1) {
  808. // First time out we should build the message.
  809. EXPECT_FALSE(prev_msg);
  810. EXPECT_TRUE(curr_msg);
  811. } else {
  812. // Subsequent passes should reuse the request. We are only
  813. // looking to check that we have not replaced the pointer value
  814. // with a new pointer. This tests the on_entry() logic which
  815. // clears the request ONLY upon initial entry into the state.
  816. EXPECT_TRUE(prev_msg == curr_msg);
  817. }
  818. // Simulate a server IO timeout.
  819. name_add->setDnsUpdateStatus(DNSClient::TIMEOUT);
  820. name_add->postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  821. // Run replacingFwdAddrsHandler again to process the response.
  822. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  823. // Completion flags should be false.
  824. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  825. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  826. if (i < max_tries) {
  827. // We should be ready to try again.
  828. EXPECT_EQ(NameAddTransaction::REPLACING_FWD_ADDRS_ST,
  829. name_add->getCurrState());
  830. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  831. name_add->getNextEvent());
  832. } else {
  833. // Server retries should be exhausted, time for a new server.
  834. EXPECT_EQ(NameAddTransaction::SELECTING_FWD_SERVER_ST,
  835. name_add->getCurrState());
  836. EXPECT_EQ(NameChangeTransaction::SERVER_IO_ERROR_EVT,
  837. name_add->getNextEvent());
  838. }
  839. }
  840. }
  841. // Tests replacingFwdAddrsHandler with the following scenario:
  842. //
  843. // The request includes a forward and reverse change.
  844. // Initial posted event is FQDN_IN_USE_EVT.
  845. // The update request is sent but a corrupt response is received, this occurs
  846. // MAX_UPDATE_TRIES_PER_SERVER times.
  847. //
  848. TEST_F(NameAddTransactionTest, replacingFwdAddrsHandler_CorruptResponse) {
  849. NameAddStubPtr name_add;
  850. // Create the transaction.
  851. ASSERT_NO_THROW(name_add =
  852. prepHandlerTest(NameAddTransaction::REPLACING_FWD_ADDRS_ST,
  853. NameAddTransaction::
  854. FQDN_IN_USE_EVT, FWD_AND_REV_CHG));
  855. // Select a server to satisfy log statements.
  856. ASSERT_TRUE(name_add->selectFwdServer());
  857. // Verify that we can make maximum number of update attempts permitted
  858. // and then transition to selecting a new server.
  859. int max_tries = NameChangeTransaction::MAX_UPDATE_TRIES_PER_SERVER;
  860. for (int i = 1; i <= max_tries; ++i) {
  861. const D2UpdateMessagePtr prev_msg = name_add->getDnsUpdateRequest();
  862. // Run replacingFwdAddrsHandler to send the request.
  863. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  864. const D2UpdateMessagePtr curr_msg = name_add->getDnsUpdateRequest();
  865. if (i == 1) {
  866. // First time out we should build the message.
  867. EXPECT_FALSE(prev_msg);
  868. EXPECT_TRUE(curr_msg);
  869. } else {
  870. // Subsequent passes should reuse the request. We are only
  871. // looking to check that we have not replaced the pointer value
  872. // with a new pointer. This tests the on_entry() logic which
  873. // clears the request ONLY upon initial entry into the state.
  874. EXPECT_TRUE(prev_msg == curr_msg);
  875. }
  876. // Simulate a server corrupt response.
  877. name_add->setDnsUpdateStatus(DNSClient::INVALID_RESPONSE);
  878. name_add->postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  879. // Run replacingFwdAddrsHandler again to process the response.
  880. EXPECT_NO_THROW(name_add->replacingFwdAddrsHandler());
  881. // Completion flags should be false.
  882. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  883. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  884. if (i < max_tries) {
  885. // We should be ready to try again.
  886. EXPECT_EQ(NameAddTransaction::REPLACING_FWD_ADDRS_ST,
  887. name_add->getCurrState());
  888. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  889. name_add->getNextEvent());
  890. } else {
  891. // Server retries should be exhausted, time for a new server.
  892. EXPECT_EQ(NameAddTransaction::SELECTING_FWD_SERVER_ST,
  893. name_add->getCurrState());
  894. EXPECT_EQ(NameChangeTransaction::SERVER_IO_ERROR_EVT,
  895. name_add->getNextEvent());
  896. }
  897. }
  898. }
  899. // Tests the selectingRevServerHandler functionality.
  900. // It verifies behavior for the following scenarios:
  901. //
  902. // 1. Posted event is SELECT_SERVER_EVT
  903. // 2. Posted event is SERVER_IO_ERROR_EVT
  904. // 3. Posted event is invalid
  905. //
  906. TEST_F(NameAddTransactionTest, selectingRevServerHandler) {
  907. NameAddStubPtr name_add;
  908. // Create and prep a transaction, poised to run the handler.
  909. ASSERT_NO_THROW(name_add =
  910. prepHandlerTest(NameChangeTransaction::
  911. SELECTING_REV_SERVER_ST,
  912. NameChangeTransaction::SELECT_SERVER_EVT));
  913. // Call selectingRevServerHandler enough times to select all of the
  914. // servers in it's current domain. The first time, it will be with
  915. // next event of SELECT_SERVER_EVT. Thereafter it will be with a next
  916. // event of SERVER_IO_ERROR_EVT.
  917. int num_servers = name_add->getReverseDomain()->getServers()->size();
  918. for (int i = 0; i < num_servers; ++i) {
  919. // Run selectingRevServerHandler.
  920. ASSERT_NO_THROW(name_add->selectingRevServerHandler())
  921. << " num_servers: " << num_servers
  922. << " selections: " << i;
  923. // Verify that a server was selected.
  924. ASSERT_TRUE(name_add->getCurrentServer())
  925. << " num_servers: " << num_servers
  926. << " selections: " << i;
  927. // Verify that we transitioned correctly.
  928. ASSERT_EQ(NameAddTransaction::REPLACING_REV_PTRS_ST,
  929. name_add->getCurrState())
  930. << " num_servers: " << num_servers << " selections: " << i;
  931. ASSERT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  932. name_add->getNextEvent())
  933. << " num_servers: " << num_servers << " selections: " << i;
  934. // Post a server IO error event. This simulates an IO error occuring
  935. // and a need to select the new server.
  936. ASSERT_NO_THROW(name_add->postNextEvent(NameChangeTransaction::
  937. SERVER_IO_ERROR_EVT))
  938. << " num_servers: " << num_servers
  939. << " selections: " << i;
  940. }
  941. // We should have exhausted the list of servers. Processing another
  942. // SERVER_IO_ERROR_EVT should transition us to failure.
  943. EXPECT_NO_THROW(name_add->selectingRevServerHandler());
  944. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  945. name_add->getCurrState());
  946. EXPECT_EQ(NameChangeTransaction::NO_MORE_SERVERS_EVT,
  947. name_add->getNextEvent());
  948. // Create and prep transaction, poised to run the handler but with an
  949. // invalid event.
  950. ASSERT_NO_THROW(name_add =
  951. prepHandlerTest(NameChangeTransaction::
  952. SELECTING_REV_SERVER_ST,
  953. StateModel::NOP_EVT));
  954. // Running the handler should throw.
  955. EXPECT_THROW(name_add->selectingRevServerHandler(),
  956. NameAddTransactionError);
  957. }
  958. //************************** replacingRevPtrsHandler tests *****************
  959. // Tests that replacingRevPtrsHandler rejects invalid events.
  960. TEST_F(NameAddTransactionTest, replacingRevPtrsHandler_InvalidEvent) {
  961. NameAddStubPtr name_add;
  962. // Create and prep a transaction, poised to run the handler but with
  963. // an invalid event.
  964. ASSERT_NO_THROW(name_add =
  965. prepHandlerTest(NameAddTransaction::REPLACING_REV_PTRS_ST,
  966. NameChangeTransaction::
  967. StateModel::NOP_EVT));
  968. // Running the handler should throw.
  969. EXPECT_THROW(name_add->replacingRevPtrsHandler(),
  970. NameAddTransactionError);
  971. }
  972. // Tests replacingRevPtrsHandler with the following scenario:
  973. //
  974. // The request includes only a reverse change.
  975. // Initial posted event is SERVER_SELECTED_EVT.
  976. // The update request is sent without error.
  977. // A server response is received which indicates successful update.
  978. //
  979. TEST_F(NameAddTransactionTest, replacingRevPtrsHandler_FwdOnlyAddOK) {
  980. NameAddStubPtr name_add;
  981. // Create and prep a transaction, poised to run the handler.
  982. ASSERT_NO_THROW(name_add =
  983. prepHandlerTest(NameAddTransaction::REPLACING_REV_PTRS_ST,
  984. NameAddTransaction::
  985. SERVER_SELECTED_EVT, REVERSE_CHG));
  986. // Should not be an update message yet.
  987. D2UpdateMessagePtr update_msg = name_add->getDnsUpdateRequest();
  988. ASSERT_FALSE(update_msg);
  989. // At this point completion flags should be false.
  990. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  991. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  992. // Run replacingRevPtrsHandler to construct and send the request.
  993. EXPECT_NO_THROW(name_add->replacingRevPtrsHandler());
  994. // Verify that an update message was constructed.
  995. update_msg = name_add->getDnsUpdateRequest();
  996. EXPECT_TRUE(update_msg);
  997. // Verify that we are still in this state and next event is NOP_EVT.
  998. // This indicates we "sent" the message and are waiting for IO completion.
  999. EXPECT_EQ(NameAddTransaction::REPLACING_REV_PTRS_ST,
  1000. name_add->getCurrState());
  1001. EXPECT_EQ(NameChangeTransaction::NOP_EVT,
  1002. name_add->getNextEvent());
  1003. // Simulate receiving a succussful update response.
  1004. name_add->fakeResponse(DNSClient::SUCCESS, dns::Rcode::NOERROR());
  1005. // Run replacingRevPtrsHandler again to process the response.
  1006. EXPECT_NO_THROW(name_add->replacingRevPtrsHandler());
  1007. // Forward completion should be false, reverse should be true.
  1008. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  1009. EXPECT_TRUE(name_add->getReverseChangeCompleted());
  1010. // Since it is a reverse change, we should be done.
  1011. // Verify that we transitioned correctly.
  1012. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  1013. name_add->getCurrState());
  1014. EXPECT_EQ(NameChangeTransaction::UPDATE_OK_EVT,
  1015. name_add->getNextEvent());
  1016. }
  1017. // Tests replacingRevPtrsHandler with the following scenario:
  1018. //
  1019. // The request includes only a reverse change.
  1020. // Initial posted event is SERVER_SELECTED_EVT.
  1021. // The update request is sent without error.
  1022. // A server response is received which indicates the update was rejected.
  1023. //
  1024. TEST_F(NameAddTransactionTest, replacingRevPtrsHandler_OtherRcode) {
  1025. NameAddStubPtr name_add;
  1026. // Create the transaction.
  1027. ASSERT_NO_THROW(name_add =
  1028. prepHandlerTest(NameAddTransaction::REPLACING_REV_PTRS_ST,
  1029. NameAddTransaction::
  1030. SERVER_SELECTED_EVT, REVERSE_CHG));
  1031. // Select a server to satisfy log statements.
  1032. ASSERT_TRUE(name_add->selectRevServer());
  1033. // Run replacingRevPtrsHandler to construct and send the request.
  1034. EXPECT_NO_THROW(name_add->replacingRevPtrsHandler());
  1035. // Simulate receiving server rejection response. Per RFC, anything other
  1036. // than no error is failure. Arbitrarily choosing refused.
  1037. name_add->fakeResponse(DNSClient::SUCCESS, dns::Rcode::REFUSED());
  1038. // Run replacingRevPtrsHandler again to process the response.
  1039. //EXPECT_NO_THROW(name_add->replacingRevPtrsHandler());
  1040. (name_add->replacingRevPtrsHandler());
  1041. // Completion flags should still be false.
  1042. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  1043. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  1044. // We should have failed the transaction. Verifiy that we transitioned
  1045. // correctly.
  1046. EXPECT_EQ(NameChangeTransaction::PROCESS_TRANS_FAILED_ST,
  1047. name_add->getCurrState());
  1048. EXPECT_EQ(NameChangeTransaction::UPDATE_FAILED_EVT,
  1049. name_add->getNextEvent());
  1050. }
  1051. // Tests replacingRevPtrsHandler with the following scenario:
  1052. //
  1053. // The request includes only a reverse change.
  1054. // Initial posted event is SERVER_SELECTED_EVT.
  1055. // The update request send times out MAX_UPDATE_TRIES_PER_SERVER times.
  1056. //
  1057. TEST_F(NameAddTransactionTest, replacingRevPtrsHandler_Timeout) {
  1058. NameAddStubPtr name_add;
  1059. // Create the transaction.
  1060. ASSERT_NO_THROW(name_add =
  1061. prepHandlerTest(NameAddTransaction::REPLACING_REV_PTRS_ST,
  1062. NameAddTransaction::
  1063. SERVER_SELECTED_EVT, REVERSE_CHG));
  1064. // Select a server to satisfy log statements.
  1065. ASSERT_TRUE(name_add->selectRevServer());
  1066. // Verify that we can make maximum number of update attempts permitted
  1067. // and then transition to selecting a new server.
  1068. int max_tries = NameChangeTransaction::MAX_UPDATE_TRIES_PER_SERVER;
  1069. for (int i = 1; i <= max_tries; ++i) {
  1070. const D2UpdateMessagePtr prev_msg = name_add->getDnsUpdateRequest();
  1071. // Run replacingRevPtrsHandler to send the request.
  1072. EXPECT_NO_THROW(name_add->replacingRevPtrsHandler());
  1073. const D2UpdateMessagePtr curr_msg = name_add->getDnsUpdateRequest();
  1074. if (i == 1) {
  1075. // First time out we should build the message.
  1076. EXPECT_FALSE(prev_msg);
  1077. EXPECT_TRUE(curr_msg);
  1078. } else {
  1079. // Subsequent passes should reuse the request. We are only
  1080. // looking to check that we have not replaced the pointer value
  1081. // with a new pointer. This tests the on_entry() logic which
  1082. // clears the request ONLY upon initial entry into the state.
  1083. EXPECT_TRUE(prev_msg == curr_msg);
  1084. }
  1085. // Simulate a server IO timeout.
  1086. name_add->setDnsUpdateStatus(DNSClient::TIMEOUT);
  1087. name_add->postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  1088. // Run replacingRevPtrsHandler again to process the response.
  1089. EXPECT_NO_THROW(name_add->replacingRevPtrsHandler());
  1090. // Completion flags should be false.
  1091. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  1092. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  1093. if (i < max_tries) {
  1094. // We should be ready to try again.
  1095. EXPECT_EQ(NameAddTransaction::REPLACING_REV_PTRS_ST,
  1096. name_add->getCurrState());
  1097. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  1098. name_add->getNextEvent());
  1099. } else {
  1100. // Server retries should be exhausted, time for a new server.
  1101. EXPECT_EQ(NameAddTransaction::SELECTING_REV_SERVER_ST,
  1102. name_add->getCurrState());
  1103. EXPECT_EQ(NameChangeTransaction::SERVER_IO_ERROR_EVT,
  1104. name_add->getNextEvent());
  1105. }
  1106. }
  1107. }
  1108. // Tests replacingRevPtrsHandler with the following scenario:
  1109. //
  1110. // The request includes only a reverse change.
  1111. // Initial posted event is SERVER_SELECTED_EVT.
  1112. // The update request is sent but a corrupt response is received, this occurs
  1113. // MAX_UPDATE_TRIES_PER_SERVER times.
  1114. //
  1115. TEST_F(NameAddTransactionTest, replacingRevPtrsHandler_CorruptResponse) {
  1116. NameAddStubPtr name_add;
  1117. // Create the transaction.
  1118. ASSERT_NO_THROW(name_add =
  1119. prepHandlerTest(NameAddTransaction::REPLACING_REV_PTRS_ST,
  1120. NameAddTransaction::
  1121. SERVER_SELECTED_EVT, REVERSE_CHG));
  1122. // Select a server to satisfy log statements.
  1123. ASSERT_TRUE(name_add->selectRevServer());
  1124. // Verify that we can make maximum number of update attempts permitted
  1125. // and then transition to selecting a new server.
  1126. int max_tries = NameChangeTransaction::MAX_UPDATE_TRIES_PER_SERVER;
  1127. for (int i = 1; i <= max_tries; ++i) {
  1128. const D2UpdateMessagePtr prev_msg = name_add->getDnsUpdateRequest();
  1129. // Run replacingRevPtrsHandler to send the request.
  1130. EXPECT_NO_THROW(name_add->replacingRevPtrsHandler());
  1131. const D2UpdateMessagePtr curr_msg = name_add->getDnsUpdateRequest();
  1132. if (i == 1) {
  1133. // First time out we should build the message.
  1134. EXPECT_FALSE(prev_msg);
  1135. EXPECT_TRUE(curr_msg);
  1136. } else {
  1137. // Subsequent passes should reuse the request. We are only
  1138. // looking to check that we have not replaced the pointer value
  1139. // with a new pointer. This tests the on_entry() logic which
  1140. // clears the request ONLY upon initial entry into the state.
  1141. EXPECT_TRUE(prev_msg == curr_msg);
  1142. }
  1143. // Simulate a server corrupt response.
  1144. name_add->setDnsUpdateStatus(DNSClient::INVALID_RESPONSE);
  1145. name_add->postNextEvent(NameChangeTransaction::IO_COMPLETED_EVT);
  1146. // Run replacingRevPtrsHandler again to process the response.
  1147. EXPECT_NO_THROW(name_add->replacingRevPtrsHandler());
  1148. // Completion flags should be false.
  1149. EXPECT_FALSE(name_add->getForwardChangeCompleted());
  1150. EXPECT_FALSE(name_add->getReverseChangeCompleted());
  1151. if (i < max_tries) {
  1152. // We should be ready to try again.
  1153. EXPECT_EQ(NameAddTransaction::REPLACING_REV_PTRS_ST,
  1154. name_add->getCurrState());
  1155. EXPECT_EQ(NameChangeTransaction::SERVER_SELECTED_EVT,
  1156. name_add->getNextEvent());
  1157. } else {
  1158. // Server retries should be exhausted, time for a new server.
  1159. EXPECT_EQ(NameAddTransaction::SELECTING_REV_SERVER_ST,
  1160. name_add->getCurrState());
  1161. EXPECT_EQ(NameChangeTransaction::SERVER_IO_ERROR_EVT,
  1162. name_add->getNextEvent());
  1163. }
  1164. }
  1165. }
  1166. // Tests the processAddOkHandler functionality.
  1167. // It verifies behavior for the following scenarios:
  1168. //
  1169. // 1. Posted event is UPDATE_OK_EVT
  1170. // 2. Posted event is invalid
  1171. //
  1172. TEST_F(NameAddTransactionTest, processAddOkHandler) {
  1173. NameAddStubPtr name_add;
  1174. // Create and prep a transaction, poised to run the handler.
  1175. ASSERT_NO_THROW(name_add =
  1176. prepHandlerTest(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  1177. NameChangeTransaction::UPDATE_OK_EVT));
  1178. // Run processAddOkHandler.
  1179. EXPECT_NO_THROW(name_add->processAddOkHandler());
  1180. // Verify that a server was selected.
  1181. EXPECT_EQ(dhcp_ddns::ST_COMPLETED, name_add->getNcrStatus());
  1182. // Verify that the model has ended.
  1183. EXPECT_EQ(StateModel::END_ST, name_add->getCurrState());
  1184. EXPECT_EQ(StateModel::END_EVT, name_add->getNextEvent());
  1185. // Create and prep transaction, poised to run the handler but with an
  1186. // invalid event.
  1187. ASSERT_NO_THROW(name_add =
  1188. prepHandlerTest(NameChangeTransaction::PROCESS_TRANS_OK_ST,
  1189. StateModel::NOP_EVT));
  1190. // Running the handler should throw.
  1191. EXPECT_THROW(name_add->processAddOkHandler(), NameAddTransactionError);
  1192. }
  1193. // Tests the processAddFailedHandler functionality.
  1194. // It verifies behavior for the following scenarios:
  1195. //
  1196. // 1. Posted event is UPDATE_FAILED_EVT
  1197. // 2. Posted event is invalid
  1198. //
  1199. TEST_F(NameAddTransactionTest, processAddFailedHandler) {
  1200. NameAddStubPtr name_add;
  1201. // Create and prep a transaction, poised to run the handler.
  1202. ASSERT_NO_THROW(name_add =
  1203. prepHandlerTest(NameChangeTransaction::
  1204. PROCESS_TRANS_FAILED_ST,
  1205. NameChangeTransaction::UPDATE_FAILED_EVT));
  1206. // Run processAddFailedHandler.
  1207. EXPECT_NO_THROW(name_add->processAddFailedHandler());
  1208. // Verify that a server was selected.
  1209. EXPECT_EQ(dhcp_ddns::ST_FAILED, name_add->getNcrStatus());
  1210. // Verify that the model has ended. (Remember, the transaction failed NOT
  1211. // the model. The model should have ended normally.)
  1212. EXPECT_EQ(StateModel::END_ST, name_add->getCurrState());
  1213. EXPECT_EQ(StateModel::END_EVT, name_add->getNextEvent());
  1214. // Create and prep transaction, poised to run the handler but with an
  1215. // invalid event.
  1216. ASSERT_NO_THROW(name_add =
  1217. prepHandlerTest(NameChangeTransaction::
  1218. PROCESS_TRANS_FAILED_ST,
  1219. StateModel::NOP_EVT));
  1220. // Running the handler should throw.
  1221. EXPECT_THROW(name_add->processAddFailedHandler(), NameAddTransactionError);
  1222. }
  1223. }