database_unittest.cc 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955
  1. // Copyright (C) 2011 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 <boost/foreach.hpp>
  15. #include <gtest/gtest.h>
  16. #include <dns/name.h>
  17. #include <dns/rrttl.h>
  18. #include <dns/rrset.h>
  19. #include <exceptions/exceptions.h>
  20. #include <datasrc/database.h>
  21. #include <datasrc/zone.h>
  22. #include <datasrc/data_source.h>
  23. #include <datasrc/iterator.h>
  24. #include <testutils/dnsmessage_test.h>
  25. #include <map>
  26. using namespace isc::datasrc;
  27. using namespace std;
  28. using namespace boost;
  29. using namespace isc::dns;
  30. namespace {
  31. // Imaginary zone IDs used in the mock accessor below.
  32. const int READONLY_ZONE_ID = 42;
  33. const int WRITABLE_ZONE_ID = 4200;
  34. /*
  35. * An accessor with minimum implementation, keeping the original
  36. * "NotImplemented" methods.
  37. */
  38. class NopAccessor : public DatabaseAccessor {
  39. public:
  40. NopAccessor() : database_name_("mock_database")
  41. { }
  42. virtual std::pair<bool, int> getZone(const std::string& name) const {
  43. if (name == "example.org.") {
  44. return (std::pair<bool, int>(true, READONLY_ZONE_ID));
  45. } else if (name == "null.example.org.") {
  46. return (std::pair<bool, int>(true, 13));
  47. } else if (name == "empty.example.org.") {
  48. return (std::pair<bool, int>(true, 0));
  49. } else if (name == "bad.example.org.") {
  50. return (std::pair<bool, int>(true, -1));
  51. } else {
  52. return (std::pair<bool, int>(false, 0));
  53. }
  54. }
  55. virtual shared_ptr<DatabaseAccessor> clone() {
  56. return (shared_ptr<DatabaseAccessor>()); // bogus data, but unused
  57. }
  58. virtual std::pair<bool, int> startUpdateZone(const std::string&, bool) {
  59. // return dummy value. unused anyway.
  60. return (pair<bool, int>(true, 0));
  61. }
  62. virtual void commitUpdateZone() {}
  63. virtual void rollbackUpdateZone() {}
  64. virtual void addRecordToZone(const string (&)[ADD_COLUMN_COUNT]) {}
  65. virtual void deleteRecordInZone(const string (&)[DEL_PARAM_COUNT]) {}
  66. virtual const std::string& getDBName() const {
  67. return (database_name_);
  68. }
  69. virtual IteratorContextPtr getRecords(const std::string&, int, bool)
  70. const
  71. {
  72. isc_throw(isc::NotImplemented,
  73. "This database datasource can't be iterated");
  74. }
  75. virtual IteratorContextPtr getAllRecords(int) const {
  76. isc_throw(isc::NotImplemented,
  77. "This database datasource can't be iterated");
  78. }
  79. private:
  80. const std::string database_name_;
  81. };
  82. /*
  83. * A virtual database accessor that pretends it contains single zone --
  84. * example.org.
  85. *
  86. * It has the same getZone method as NopConnection, but it provides
  87. * implementation of the optional functionality.
  88. */
  89. class MockAccessor : public NopAccessor {
  90. // Type of mock database "row"s
  91. typedef std::map<std::string, std::vector< std::vector<std::string> > >
  92. Domains;
  93. public:
  94. MockAccessor() : rollbacked_(false) {
  95. readonly_records_ = &readonly_records_master_;
  96. update_records_ = &update_records_master_;
  97. empty_records_ = &empty_records_master_;
  98. fillData();
  99. }
  100. virtual shared_ptr<DatabaseAccessor> clone() {
  101. shared_ptr<MockAccessor> cloned_accessor(new MockAccessor());
  102. cloned_accessor->readonly_records_ = &readonly_records_master_;
  103. cloned_accessor->update_records_ = &update_records_master_;
  104. cloned_accessor->empty_records_ = &empty_records_master_;
  105. latest_clone_ = cloned_accessor;
  106. return (cloned_accessor);
  107. }
  108. private:
  109. class MockNameIteratorContext : public IteratorContext {
  110. public:
  111. MockNameIteratorContext(const MockAccessor& mock_accessor, int zone_id,
  112. const std::string& name, bool subdomains) :
  113. searched_name_(name), cur_record_(0)
  114. {
  115. // 'hardcoded' names to trigger exceptions
  116. // On these names some exceptions are thrown, to test the robustness
  117. // of the find() method.
  118. if (searched_name_ == "dsexception.in.search.") {
  119. isc_throw(DataSourceError, "datasource exception on search");
  120. } else if (searched_name_ == "iscexception.in.search.") {
  121. isc_throw(isc::Exception, "isc exception on search");
  122. } else if (searched_name_ == "basicexception.in.search.") {
  123. throw std::exception();
  124. }
  125. cur_record_ = 0;
  126. const Domains& cur_records = mock_accessor.getMockRecords(zone_id);
  127. if (cur_records.count(name) > 0) {
  128. // we're not aiming for efficiency in this test, simply
  129. // copy the relevant vector from records
  130. cur_name = cur_records.find(name)->second;
  131. } else if (subdomains) {
  132. cur_name.clear();
  133. // Just walk everything and check if it is a subdomain.
  134. // If it is, just copy all data from there.
  135. for (Domains::const_iterator i(cur_records.begin());
  136. i != cur_records.end(); ++i) {
  137. const Name local(i->first);
  138. if (local.compare(Name(name)).getRelation() ==
  139. isc::dns::NameComparisonResult::SUBDOMAIN) {
  140. cur_name.insert(cur_name.end(), i->second.begin(),
  141. i->second.end());
  142. }
  143. }
  144. } else {
  145. cur_name.clear();
  146. }
  147. }
  148. virtual bool getNext(std::string (&columns)[COLUMN_COUNT]) {
  149. if (searched_name_ == "dsexception.in.getnext.") {
  150. isc_throw(DataSourceError, "datasource exception on getnextrecord");
  151. } else if (searched_name_ == "iscexception.in.getnext.") {
  152. isc_throw(isc::Exception, "isc exception on getnextrecord");
  153. } else if (searched_name_ == "basicexception.in.getnext.") {
  154. throw std::exception();
  155. }
  156. if (cur_record_ < cur_name.size()) {
  157. for (size_t i = 0; i < COLUMN_COUNT; ++i) {
  158. columns[i] = cur_name[cur_record_][i];
  159. }
  160. cur_record_++;
  161. return (true);
  162. } else {
  163. return (false);
  164. }
  165. }
  166. private:
  167. const std::string searched_name_;
  168. int cur_record_;
  169. std::vector< std::vector<std::string> > cur_name;
  170. };
  171. class MockIteratorContext : public IteratorContext {
  172. private:
  173. int step;
  174. public:
  175. MockIteratorContext() :
  176. step(0)
  177. { }
  178. virtual bool getNext(string (&data)[COLUMN_COUNT]) {
  179. switch (step ++) {
  180. case 0:
  181. data[DatabaseAccessor::NAME_COLUMN] = "example.org";
  182. data[DatabaseAccessor::TYPE_COLUMN] = "SOA";
  183. data[DatabaseAccessor::TTL_COLUMN] = "300";
  184. data[DatabaseAccessor::RDATA_COLUMN] = "ns1.example.org. admin.example.org. "
  185. "1234 3600 1800 2419200 7200";
  186. return (true);
  187. case 1:
  188. data[DatabaseAccessor::NAME_COLUMN] = "x.example.org";
  189. data[DatabaseAccessor::TYPE_COLUMN] = "A";
  190. data[DatabaseAccessor::TTL_COLUMN] = "300";
  191. data[DatabaseAccessor::RDATA_COLUMN] = "192.0.2.1";
  192. return (true);
  193. case 2:
  194. data[DatabaseAccessor::NAME_COLUMN] = "x.example.org";
  195. data[DatabaseAccessor::TYPE_COLUMN] = "A";
  196. data[DatabaseAccessor::TTL_COLUMN] = "300";
  197. data[DatabaseAccessor::RDATA_COLUMN] = "192.0.2.2";
  198. return (true);
  199. case 3:
  200. data[DatabaseAccessor::NAME_COLUMN] = "x.example.org";
  201. data[DatabaseAccessor::TYPE_COLUMN] = "AAAA";
  202. data[DatabaseAccessor::TTL_COLUMN] = "300";
  203. data[DatabaseAccessor::RDATA_COLUMN] = "2001:db8::1";
  204. return (true);
  205. case 4:
  206. data[DatabaseAccessor::NAME_COLUMN] = "x.example.org";
  207. data[DatabaseAccessor::TYPE_COLUMN] = "AAAA";
  208. data[DatabaseAccessor::TTL_COLUMN] = "300";
  209. data[DatabaseAccessor::RDATA_COLUMN] = "2001:db8::2";
  210. return (true);
  211. default:
  212. ADD_FAILURE() <<
  213. "Request past the end of iterator context";
  214. case 5:
  215. return (false);
  216. }
  217. }
  218. };
  219. class EmptyIteratorContext : public IteratorContext {
  220. public:
  221. virtual bool getNext(string(&)[COLUMN_COUNT]) {
  222. return (false);
  223. }
  224. };
  225. class BadIteratorContext : public IteratorContext {
  226. private:
  227. int step;
  228. public:
  229. BadIteratorContext() :
  230. step(0)
  231. { }
  232. virtual bool getNext(string (&data)[COLUMN_COUNT]) {
  233. switch (step ++) {
  234. case 0:
  235. data[DatabaseAccessor::NAME_COLUMN] = "x.example.org";
  236. data[DatabaseAccessor::TYPE_COLUMN] = "A";
  237. data[DatabaseAccessor::TTL_COLUMN] = "300";
  238. data[DatabaseAccessor::RDATA_COLUMN] = "192.0.2.1";
  239. return (true);
  240. case 1:
  241. data[DatabaseAccessor::NAME_COLUMN] = "x.example.org";
  242. data[DatabaseAccessor::TYPE_COLUMN] = "A";
  243. data[DatabaseAccessor::TTL_COLUMN] = "301";
  244. data[DatabaseAccessor::RDATA_COLUMN] = "192.0.2.2";
  245. return (true);
  246. default:
  247. ADD_FAILURE() <<
  248. "Request past the end of iterator context";
  249. case 2:
  250. return (false);
  251. }
  252. }
  253. };
  254. public:
  255. virtual IteratorContextPtr getAllRecords(int id) const {
  256. if (id == READONLY_ZONE_ID) {
  257. return (IteratorContextPtr(new MockIteratorContext()));
  258. } else if (id == 13) {
  259. return (IteratorContextPtr());
  260. } else if (id == 0) {
  261. return (IteratorContextPtr(new EmptyIteratorContext()));
  262. } else if (id == -1) {
  263. return (IteratorContextPtr(new BadIteratorContext()));
  264. } else {
  265. isc_throw(isc::Unexpected, "Unknown zone ID");
  266. }
  267. }
  268. virtual IteratorContextPtr getRecords(const std::string& name, int id,
  269. bool subdomains) const
  270. {
  271. if (id == READONLY_ZONE_ID || id == WRITABLE_ZONE_ID) {
  272. return (IteratorContextPtr(
  273. new MockNameIteratorContext(*this, id, name,
  274. subdomains)));
  275. } else {
  276. isc_throw(isc::Unexpected, "Unknown zone ID");
  277. }
  278. }
  279. virtual pair<bool, int> startUpdateZone(const std::string& zone_name,
  280. bool replace)
  281. {
  282. const pair<bool, int> zone_info = getZone(zone_name);
  283. if (!zone_info.first) {
  284. return (pair<bool, int>(false, 0));
  285. }
  286. // Prepare the record set for update. If replacing the existing one,
  287. // we use an empty set; otherwise we use a writable copy of the
  288. // original.
  289. if (replace) {
  290. update_records_->clear();
  291. } else {
  292. *update_records_ = *readonly_records_;
  293. }
  294. return (pair<bool, int>(true, WRITABLE_ZONE_ID));
  295. }
  296. virtual void commitUpdateZone() {
  297. *readonly_records_ = *update_records_;
  298. }
  299. virtual void rollbackUpdateZone() {
  300. // Special hook: if something with a name of "throw.example.org"
  301. // has been added, trigger an imaginary unexpected event with an
  302. // exception.
  303. if (update_records_->count("throw.example.org.") > 0) {
  304. isc_throw(DataSourceError, "unexpected failure in rollback");
  305. }
  306. rollbacked_ = true;
  307. }
  308. virtual void addRecordToZone(const string (&columns)[ADD_COLUMN_COUNT]) {
  309. // Copy the current value to cur_name. If it doesn't exist,
  310. // operator[] will create a new one.
  311. cur_name_ = (*update_records_)[columns[DatabaseAccessor::ADD_NAME]];
  312. vector<string> record_columns;
  313. record_columns.push_back(columns[DatabaseAccessor::ADD_TYPE]);
  314. record_columns.push_back(columns[DatabaseAccessor::ADD_TTL]);
  315. record_columns.push_back(columns[DatabaseAccessor::ADD_SIGTYPE]);
  316. record_columns.push_back(columns[DatabaseAccessor::ADD_RDATA]);
  317. record_columns.push_back(columns[DatabaseAccessor::ADD_NAME]);
  318. // copy back the added entry
  319. cur_name_.push_back(record_columns);
  320. (*update_records_)[columns[DatabaseAccessor::ADD_NAME]] = cur_name_;
  321. // remember this one so that test cases can check it.
  322. copy(columns, columns + DatabaseAccessor::ADD_COLUMN_COUNT,
  323. columns_lastadded_);
  324. }
  325. // Helper predicate class used in deleteRecordInZone().
  326. struct deleteMatch {
  327. deleteMatch(const string& type, const string& rdata) :
  328. type_(type), rdata_(rdata)
  329. {}
  330. bool operator()(const vector<string>& row) const {
  331. return (row[0] == type_ && row[3] == rdata_);
  332. }
  333. const string& type_;
  334. const string& rdata_;
  335. };
  336. virtual void deleteRecordInZone(const string (&params)[DEL_PARAM_COUNT]) {
  337. vector<vector<string> >& records =
  338. (*update_records_)[params[DatabaseAccessor::DEL_NAME]];
  339. records.erase(remove_if(records.begin(), records.end(),
  340. deleteMatch(
  341. params[DatabaseAccessor::DEL_TYPE],
  342. params[DatabaseAccessor::DEL_RDATA])),
  343. records.end());
  344. if (records.empty()) {
  345. (*update_records_).erase(params[DatabaseAccessor::DEL_NAME]);
  346. }
  347. }
  348. //
  349. // Helper methods to keep track of some update related activities
  350. //
  351. bool isRollbacked() const {
  352. return (rollbacked_);
  353. }
  354. const string* getLastAdded() const {
  355. return (columns_lastadded_);
  356. }
  357. // This allows the test code to get the accessor used in an update context
  358. shared_ptr<const MockAccessor> getLatestClone() const {
  359. return (latest_clone_);
  360. }
  361. private:
  362. // The following member variables are storage and/or update work space
  363. // of the test zone. The "master"s are the real objects that contain
  364. // the data, and they are shared among by all accessors cloned from
  365. // an initially created one. The pointer members allow the sharing.
  366. // "readonly" is for normal lookups. "update" is the workspace for
  367. // updates. When update starts it will be initialized either as an
  368. // empty set (when replacing the entire zone) or as a copy of the
  369. // "readonly" one. "empty" is a sentinel to produce negative results.
  370. Domains readonly_records_master_;
  371. Domains* readonly_records_;
  372. Domains update_records_master_;
  373. Domains* update_records_;
  374. const Domains empty_records_master_;
  375. const Domains* empty_records_;
  376. // used as temporary storage during the building of the fake data
  377. //Domains records;
  378. // used as temporary storage after searchForRecord() and during
  379. // getNextRecord() calls, as well as during the building of the
  380. // fake data
  381. std::vector< std::vector<std::string> > cur_name_;
  382. // The columns that were most recently added via addRecordToZone()
  383. string columns_lastadded_[ADD_COLUMN_COUNT];
  384. // Whether rollback operation has been performed for the database.
  385. // Not useful except for purely testing purpose.
  386. bool rollbacked_;
  387. // Remember the mock accessor that was last cloned
  388. boost::shared_ptr<MockAccessor> latest_clone_;
  389. const Domains& getMockRecords(int zone_id) const {
  390. if (zone_id == READONLY_ZONE_ID) {
  391. return (*readonly_records_);
  392. } else if (zone_id == WRITABLE_ZONE_ID) {
  393. return (*update_records_);
  394. }
  395. return (*empty_records_);
  396. }
  397. // Adds one record to the current name in the database
  398. // The actual data will not be added to 'records' until
  399. // addCurName() is called
  400. void addRecord(const std::string& type,
  401. const std::string& ttl,
  402. const std::string& sigtype,
  403. const std::string& rdata) {
  404. std::vector<std::string> columns;
  405. columns.push_back(type);
  406. columns.push_back(ttl);
  407. columns.push_back(sigtype);
  408. columns.push_back(rdata);
  409. cur_name_.push_back(columns);
  410. }
  411. // Adds all records we just built with calls to addRecords
  412. // to the actual fake database. This will clear cur_name_,
  413. // so we can immediately start adding new records.
  414. void addCurName(const std::string& name) {
  415. ASSERT_EQ(0, readonly_records_->count(name));
  416. // Append the name to all of them
  417. for (std::vector<std::vector<std::string> >::iterator
  418. i(cur_name_.begin()); i != cur_name_.end(); ++ i) {
  419. i->push_back(name);
  420. }
  421. (*readonly_records_)[name] = cur_name_;
  422. cur_name_.clear();
  423. }
  424. // Fills the database with zone data.
  425. // This method constructs a number of resource records (with addRecord),
  426. // which will all be added for one domain name to the fake database
  427. // (with addCurName). So for instance the first set of calls create
  428. // data for the name 'www.example.org', which will consist of one A RRset
  429. // of one record, and one AAAA RRset of two records.
  430. // The order in which they are added is the order in which getNextRecord()
  431. // will return them (so we can test whether find() etc. support data that
  432. // might not come in 'normal' order)
  433. // It shall immediately fail if you try to add the same name twice.
  434. void fillData() {
  435. // some plain data
  436. addRecord("A", "3600", "", "192.0.2.1");
  437. addRecord("AAAA", "3600", "", "2001:db8::1");
  438. addRecord("AAAA", "3600", "", "2001:db8::2");
  439. addCurName("www.example.org.");
  440. addRecord("A", "3600", "", "192.0.2.1");
  441. addRecord("AAAA", "3600", "", "2001:db8::1");
  442. addRecord("A", "3600", "", "192.0.2.2");
  443. addCurName("www2.example.org.");
  444. addRecord("CNAME", "3600", "", "www.example.org.");
  445. addCurName("cname.example.org.");
  446. // some DNSSEC-'signed' data
  447. addRecord("A", "3600", "", "192.0.2.1");
  448. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  449. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12346 example.org. FAKEFAKEFAKE");
  450. addRecord("AAAA", "3600", "", "2001:db8::1");
  451. addRecord("AAAA", "3600", "", "2001:db8::2");
  452. addRecord("RRSIG", "3600", "", "AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  453. addCurName("signed1.example.org.");
  454. addRecord("CNAME", "3600", "", "www.example.org.");
  455. addRecord("RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  456. addCurName("signedcname1.example.org.");
  457. // special case might fail; sig is for cname, which isn't there (should be ignored)
  458. // (ignoring of 'normal' other type is done above by www.)
  459. addRecord("A", "3600", "", "192.0.2.1");
  460. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  461. addRecord("RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  462. addCurName("acnamesig1.example.org.");
  463. // let's pretend we have a database that is not careful
  464. // about the order in which it returns data
  465. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  466. addRecord("AAAA", "3600", "", "2001:db8::2");
  467. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12346 example.org. FAKEFAKEFAKE");
  468. addRecord("A", "3600", "", "192.0.2.1");
  469. addRecord("RRSIG", "3600", "", "AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  470. addRecord("AAAA", "3600", "", "2001:db8::1");
  471. addCurName("signed2.example.org.");
  472. addRecord("RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  473. addRecord("CNAME", "3600", "", "www.example.org.");
  474. addCurName("signedcname2.example.org.");
  475. addRecord("RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  476. addRecord("A", "3600", "", "192.0.2.1");
  477. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  478. addCurName("acnamesig2.example.org.");
  479. addRecord("RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  480. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  481. addRecord("A", "3600", "", "192.0.2.1");
  482. addCurName("acnamesig3.example.org.");
  483. addRecord("A", "3600", "", "192.0.2.1");
  484. addRecord("A", "360", "", "192.0.2.2");
  485. addCurName("ttldiff1.example.org.");
  486. addRecord("A", "360", "", "192.0.2.1");
  487. addRecord("A", "3600", "", "192.0.2.2");
  488. addCurName("ttldiff2.example.org.");
  489. // also add some intentionally bad data
  490. addRecord("A", "3600", "", "192.0.2.1");
  491. addRecord("CNAME", "3600", "", "www.example.org.");
  492. addCurName("badcname1.example.org.");
  493. addRecord("CNAME", "3600", "", "www.example.org.");
  494. addRecord("A", "3600", "", "192.0.2.1");
  495. addCurName("badcname2.example.org.");
  496. addRecord("CNAME", "3600", "", "www.example.org.");
  497. addRecord("CNAME", "3600", "", "www.example2.org.");
  498. addCurName("badcname3.example.org.");
  499. addRecord("A", "3600", "", "bad");
  500. addCurName("badrdata.example.org.");
  501. addRecord("BAD_TYPE", "3600", "", "192.0.2.1");
  502. addCurName("badtype.example.org.");
  503. addRecord("A", "badttl", "", "192.0.2.1");
  504. addCurName("badttl.example.org.");
  505. addRecord("A", "badttl", "", "192.0.2.1");
  506. addRecord("RRSIG", "3600", "", "A 5 3 3600 somebaddata 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  507. addCurName("badsig.example.org.");
  508. addRecord("A", "3600", "", "192.0.2.1");
  509. addRecord("RRSIG", "3600", "TXT", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  510. addCurName("badsigtype.example.org.");
  511. // Data for testing delegation (with NS and DNAME)
  512. addRecord("NS", "3600", "", "ns.example.com.");
  513. addRecord("NS", "3600", "", "ns.delegation.example.org.");
  514. addRecord("RRSIG", "3600", "", "NS 5 3 3600 20000101000000 "
  515. "20000201000000 12345 example.org. FAKEFAKEFAKE");
  516. addCurName("delegation.example.org.");
  517. addRecord("A", "3600", "", "192.0.2.1");
  518. addCurName("ns.delegation.example.org.");
  519. addRecord("A", "3600", "", "192.0.2.1");
  520. addCurName("deep.below.delegation.example.org.");
  521. addRecord("A", "3600", "", "192.0.2.1");
  522. addRecord("DNAME", "3600", "", "dname.example.com.");
  523. addRecord("RRSIG", "3600", "", "DNAME 5 3 3600 20000101000000 "
  524. "20000201000000 12345 example.org. FAKEFAKEFAKE");
  525. addCurName("dname.example.org.");
  526. addRecord("A", "3600", "", "192.0.2.1");
  527. addCurName("below.dname.example.org.");
  528. // Broken NS
  529. addRecord("A", "3600", "", "192.0.2.1");
  530. addRecord("NS", "3600", "", "ns.example.com.");
  531. addCurName("brokenns1.example.org.");
  532. addRecord("NS", "3600", "", "ns.example.com.");
  533. addRecord("A", "3600", "", "192.0.2.1");
  534. addCurName("brokenns2.example.org.");
  535. // Now double DNAME, to test failure mode
  536. addRecord("DNAME", "3600", "", "dname1.example.com.");
  537. addRecord("DNAME", "3600", "", "dname2.example.com.");
  538. addCurName("baddname.example.org.");
  539. // Put some data into apex (including NS) so we can check our NS
  540. // doesn't break anything
  541. addRecord("NS", "3600", "", "ns.example.com.");
  542. addRecord("A", "3600", "", "192.0.2.1");
  543. addRecord("RRSIG", "3600", "", "NS 5 3 3600 20000101000000 "
  544. "20000201000000 12345 example.org. FAKEFAKEFAKE");
  545. addCurName("example.org.");
  546. // This is because of empty domain test
  547. addRecord("A", "3600", "", "192.0.2.1");
  548. addCurName("a.b.example.org.");
  549. // Something for wildcards
  550. addRecord("A", "3600", "", "192.0.2.5");
  551. addCurName("*.wild.example.org.");
  552. addRecord("AAAA", "3600", "", "2001:db8::5");
  553. addCurName("cancel.here.wild.example.org.");
  554. addRecord("NS", "3600", "", "ns.example.com.");
  555. addCurName("delegatedwild.example.org.");
  556. addRecord("A", "3600", "", "192.0.2.5");
  557. addCurName("*.delegatedwild.example.org.");
  558. addRecord("A", "3600", "", "192.0.2.5");
  559. addCurName("wild.*.foo.example.org.");
  560. addRecord("A", "3600", "", "192.0.2.5");
  561. addCurName("wild.*.foo.*.bar.example.org.");
  562. }
  563. };
  564. // This tests the default getRecords behaviour, throwing NotImplemented
  565. TEST(DatabaseConnectionTest, getRecords) {
  566. EXPECT_THROW(NopAccessor().getRecords(".", 1, false),
  567. isc::NotImplemented);
  568. }
  569. // This tests the default getAllRecords behaviour, throwing NotImplemented
  570. TEST(DatabaseConnectionTest, getAllRecords) {
  571. // The parameters don't matter
  572. EXPECT_THROW(NopAccessor().getAllRecords(1),
  573. isc::NotImplemented);
  574. }
  575. class DatabaseClientTest : public ::testing::Test {
  576. public:
  577. DatabaseClientTest() : zname_("example.org"), qname_("www.example.org"),
  578. qclass_(RRClass::IN()), qtype_(RRType::A()),
  579. rrttl_(3600)
  580. {
  581. createClient();
  582. // set up the commonly used finder.
  583. DataSourceClient::FindResult zone(client_->findZone(zname_));
  584. assert(zone.code == result::SUCCESS);
  585. finder_ = dynamic_pointer_cast<DatabaseClient::Finder>(
  586. zone.zone_finder);
  587. // Test IN/A RDATA to be added in update tests. Intentionally using
  588. // different data than the initial data configured in the MockAccessor.
  589. rrset_.reset(new RRset(qname_, qclass_, qtype_, rrttl_));
  590. rrset_->addRdata(rdata::createRdata(rrset_->getType(),
  591. rrset_->getClass(), "192.0.2.2"));
  592. // And its RRSIG. Also different from the configured one.
  593. rrsigset_.reset(new RRset(qname_, qclass_, RRType::RRSIG(),
  594. rrttl_));
  595. rrsigset_->addRdata(rdata::createRdata(rrsigset_->getType(),
  596. rrsigset_->getClass(),
  597. "A 5 3 0 20000101000000 "
  598. "20000201000000 0 example.org. "
  599. "FAKEFAKEFAKE"));
  600. }
  601. /*
  602. * We initialize the client from a function, so we can call it multiple
  603. * times per test.
  604. */
  605. void createClient() {
  606. current_accessor_ = new MockAccessor();
  607. client_.reset(new DatabaseClient(qclass_,
  608. shared_ptr<DatabaseAccessor>(
  609. current_accessor_)));
  610. }
  611. /**
  612. * Check the zone finder is a valid one and references the zone ID and
  613. * database available here.
  614. */
  615. void checkZoneFinder(const DataSourceClient::FindResult& zone) {
  616. ASSERT_NE(ZoneFinderPtr(), zone.zone_finder) << "No zone finder";
  617. shared_ptr<DatabaseClient::Finder> finder(
  618. dynamic_pointer_cast<DatabaseClient::Finder>(zone.zone_finder));
  619. ASSERT_NE(shared_ptr<DatabaseClient::Finder>(), finder) <<
  620. "Wrong type of finder";
  621. EXPECT_EQ(READONLY_ZONE_ID, finder->zone_id());
  622. EXPECT_EQ(current_accessor_, &finder->getAccessor());
  623. }
  624. shared_ptr<DatabaseClient::Finder> getFinder() {
  625. DataSourceClient::FindResult zone(client_->findZone(zname_));
  626. EXPECT_EQ(result::SUCCESS, zone.code);
  627. shared_ptr<DatabaseClient::Finder> finder(
  628. dynamic_pointer_cast<DatabaseClient::Finder>(zone.zone_finder));
  629. EXPECT_EQ(READONLY_ZONE_ID, finder->zone_id());
  630. return (finder);
  631. }
  632. // Helper methods for update tests
  633. //bool isRollbacked(bool expected = false) const {
  634. bool isRollbacked() const {
  635. return (update_accessor_->isRollbacked());
  636. }
  637. void checkLastAdded(const char* const expected[]) const {
  638. for (int i = 0; i < DatabaseAccessor::ADD_COLUMN_COUNT; ++i) {
  639. EXPECT_EQ(expected[i],
  640. current_accessor_->getLatestClone()->getLastAdded()[i]);
  641. }
  642. }
  643. void setUpdateAccessor() {
  644. update_accessor_ = current_accessor_->getLatestClone();
  645. }
  646. // Will be deleted by client_, just keep the current value for comparison.
  647. MockAccessor* current_accessor_;
  648. shared_ptr<DatabaseClient> client_;
  649. const std::string database_name_;
  650. // The zone finder of the test zone commonly used in various tests.
  651. shared_ptr<DatabaseClient::Finder> finder_;
  652. // Some shortcut variables for commonly used test parameters
  653. const Name zname_; // the zone name stored in the test data source
  654. const Name qname_; // commonly used name to be found
  655. const RRClass qclass_; // commonly used RR class used with qname
  656. const RRType qtype_; // commonly used RR type used with qname
  657. const RRTTL rrttl_; // commonly used RR TTL
  658. RRsetPtr rrset_; // for adding/deleting an RRset
  659. RRsetPtr rrsigset_; // for adding/deleting an RRset
  660. // update related objects to be tested
  661. ZoneUpdaterPtr updater_;
  662. shared_ptr<const MockAccessor> update_accessor_;
  663. // placeholders
  664. const std::vector<std::string> empty_rdatas_; // for NXRRSET/NXDOMAIN
  665. std::vector<std::string> expected_rdatas_;
  666. std::vector<std::string> expected_sig_rdatas_;
  667. };
  668. TEST_F(DatabaseClientTest, zoneNotFound) {
  669. DataSourceClient::FindResult zone(client_->findZone(Name("example.com")));
  670. EXPECT_EQ(result::NOTFOUND, zone.code);
  671. }
  672. TEST_F(DatabaseClientTest, exactZone) {
  673. DataSourceClient::FindResult zone(client_->findZone(Name("example.org")));
  674. EXPECT_EQ(result::SUCCESS, zone.code);
  675. checkZoneFinder(zone);
  676. }
  677. TEST_F(DatabaseClientTest, superZone) {
  678. DataSourceClient::FindResult zone(client_->findZone(Name(
  679. "sub.example.org")));
  680. EXPECT_EQ(result::PARTIALMATCH, zone.code);
  681. checkZoneFinder(zone);
  682. }
  683. TEST_F(DatabaseClientTest, noAccessorException) {
  684. // We need a dummy variable here; some compiler would regard it a mere
  685. // declaration instead of an instantiation and make the test fail.
  686. EXPECT_THROW(DatabaseClient dummy(RRClass::IN(),
  687. shared_ptr<DatabaseAccessor>()),
  688. isc::InvalidParameter);
  689. }
  690. // If the zone doesn't exist, exception is thrown
  691. TEST_F(DatabaseClientTest, noZoneIterator) {
  692. EXPECT_THROW(client_->getIterator(Name("example.com")), DataSourceError);
  693. }
  694. // If the zone doesn't exist and iteration is not implemented, it still throws
  695. // the exception it doesn't exist
  696. TEST_F(DatabaseClientTest, noZoneNotImplementedIterator) {
  697. EXPECT_THROW(DatabaseClient(RRClass::IN(),
  698. boost::shared_ptr<DatabaseAccessor>(
  699. new NopAccessor())).getIterator(
  700. Name("example.com")),
  701. DataSourceError);
  702. }
  703. TEST_F(DatabaseClientTest, notImplementedIterator) {
  704. EXPECT_THROW(DatabaseClient(RRClass::IN(), shared_ptr<DatabaseAccessor>(
  705. new NopAccessor())).getIterator(Name("example.org")),
  706. isc::NotImplemented);
  707. }
  708. // Pretend a bug in the connection and pass NULL as the context
  709. // Should not crash, but gracefully throw
  710. TEST_F(DatabaseClientTest, nullIteratorContext) {
  711. EXPECT_THROW(client_->getIterator(Name("null.example.org")),
  712. isc::Unexpected);
  713. }
  714. // It doesn't crash or anything if the zone is completely empty
  715. TEST_F(DatabaseClientTest, emptyIterator) {
  716. ZoneIteratorPtr it(client_->getIterator(Name("empty.example.org")));
  717. EXPECT_EQ(ConstRRsetPtr(), it->getNextRRset());
  718. // This is past the end, it should throw
  719. EXPECT_THROW(it->getNextRRset(), isc::Unexpected);
  720. }
  721. // Iterate trough a zone
  722. TEST_F(DatabaseClientTest, iterator) {
  723. ZoneIteratorPtr it(client_->getIterator(Name("example.org")));
  724. ConstRRsetPtr rrset(it->getNextRRset());
  725. ASSERT_NE(ConstRRsetPtr(), rrset);
  726. EXPECT_EQ(Name("example.org"), rrset->getName());
  727. EXPECT_EQ(RRClass::IN(), rrset->getClass());
  728. EXPECT_EQ(RRType::SOA(), rrset->getType());
  729. EXPECT_EQ(RRTTL(300), rrset->getTTL());
  730. RdataIteratorPtr rit(rrset->getRdataIterator());
  731. ASSERT_FALSE(rit->isLast());
  732. rit->next();
  733. EXPECT_TRUE(rit->isLast());
  734. rrset = it->getNextRRset();
  735. ASSERT_NE(ConstRRsetPtr(), rrset);
  736. EXPECT_EQ(Name("x.example.org"), rrset->getName());
  737. EXPECT_EQ(RRClass::IN(), rrset->getClass());
  738. EXPECT_EQ(RRType::A(), rrset->getType());
  739. EXPECT_EQ(RRTTL(300), rrset->getTTL());
  740. rit = rrset->getRdataIterator();
  741. ASSERT_FALSE(rit->isLast());
  742. EXPECT_EQ("192.0.2.1", rit->getCurrent().toText());
  743. rit->next();
  744. ASSERT_FALSE(rit->isLast());
  745. EXPECT_EQ("192.0.2.2", rit->getCurrent().toText());
  746. rit->next();
  747. EXPECT_TRUE(rit->isLast());
  748. rrset = it->getNextRRset();
  749. ASSERT_NE(ConstRRsetPtr(), rrset);
  750. EXPECT_EQ(Name("x.example.org"), rrset->getName());
  751. EXPECT_EQ(RRClass::IN(), rrset->getClass());
  752. EXPECT_EQ(RRType::AAAA(), rrset->getType());
  753. EXPECT_EQ(RRTTL(300), rrset->getTTL());
  754. EXPECT_EQ(ConstRRsetPtr(), it->getNextRRset());
  755. rit = rrset->getRdataIterator();
  756. ASSERT_FALSE(rit->isLast());
  757. EXPECT_EQ("2001:db8::1", rit->getCurrent().toText());
  758. rit->next();
  759. ASSERT_FALSE(rit->isLast());
  760. EXPECT_EQ("2001:db8::2", rit->getCurrent().toText());
  761. rit->next();
  762. EXPECT_TRUE(rit->isLast());
  763. }
  764. // This has inconsistent TTL in the set (the rest, like nonsense in
  765. // the data is handled in rdata itself).
  766. TEST_F(DatabaseClientTest, badIterator) {
  767. // It should not throw, but get the lowest one of them
  768. ZoneIteratorPtr it(client_->getIterator(Name("bad.example.org")));
  769. EXPECT_EQ(it->getNextRRset()->getTTL(), isc::dns::RRTTL(300));
  770. }
  771. // checks if the given rrset matches the
  772. // given name, class, type and rdatas
  773. void
  774. checkRRset(isc::dns::ConstRRsetPtr rrset,
  775. const isc::dns::Name& name,
  776. const isc::dns::RRClass& rrclass,
  777. const isc::dns::RRType& rrtype,
  778. const isc::dns::RRTTL& rrttl,
  779. const std::vector<std::string>& rdatas) {
  780. isc::dns::RRsetPtr expected_rrset(
  781. new isc::dns::RRset(name, rrclass, rrtype, rrttl));
  782. for (unsigned int i = 0; i < rdatas.size(); ++i) {
  783. expected_rrset->addRdata(
  784. isc::dns::rdata::createRdata(rrtype, rrclass,
  785. rdatas[i]));
  786. }
  787. isc::testutils::rrsetCheck(expected_rrset, rrset);
  788. }
  789. void
  790. doFindTest(ZoneFinder& finder,
  791. const isc::dns::Name& name,
  792. const isc::dns::RRType& type,
  793. const isc::dns::RRType& expected_type,
  794. const isc::dns::RRTTL expected_ttl,
  795. ZoneFinder::Result expected_result,
  796. const std::vector<std::string>& expected_rdatas,
  797. const std::vector<std::string>& expected_sig_rdatas,
  798. const isc::dns::Name& expected_name = isc::dns::Name::ROOT_NAME(),
  799. const ZoneFinder::FindOptions options = ZoneFinder::FIND_DEFAULT)
  800. {
  801. SCOPED_TRACE("doFindTest " + name.toText() + " " + type.toText());
  802. ZoneFinder::FindResult result =
  803. finder.find(name, type, NULL, options);
  804. ASSERT_EQ(expected_result, result.code) << name << " " << type;
  805. if (!expected_rdatas.empty()) {
  806. checkRRset(result.rrset, expected_name != Name(".") ? expected_name :
  807. name, finder.getClass(), expected_type, expected_ttl,
  808. expected_rdatas);
  809. if (!expected_sig_rdatas.empty()) {
  810. checkRRset(result.rrset->getRRsig(), expected_name != Name(".") ?
  811. expected_name : name, finder.getClass(),
  812. isc::dns::RRType::RRSIG(), expected_ttl,
  813. expected_sig_rdatas);
  814. } else {
  815. EXPECT_EQ(isc::dns::RRsetPtr(), result.rrset->getRRsig());
  816. }
  817. } else {
  818. EXPECT_EQ(isc::dns::RRsetPtr(), result.rrset);
  819. }
  820. }
  821. TEST_F(DatabaseClientTest, find) {
  822. shared_ptr<DatabaseClient::Finder> finder(getFinder());
  823. expected_rdatas_.clear();
  824. expected_sig_rdatas_.clear();
  825. expected_rdatas_.push_back("192.0.2.1");
  826. doFindTest(*finder, isc::dns::Name("www.example.org."),
  827. isc::dns::RRType::A(), isc::dns::RRType::A(),
  828. isc::dns::RRTTL(3600),
  829. ZoneFinder::SUCCESS,
  830. expected_rdatas_, expected_sig_rdatas_);
  831. expected_rdatas_.clear();
  832. expected_sig_rdatas_.clear();
  833. expected_rdatas_.push_back("192.0.2.1");
  834. expected_rdatas_.push_back("192.0.2.2");
  835. doFindTest(*finder, isc::dns::Name("www2.example.org."),
  836. isc::dns::RRType::A(), isc::dns::RRType::A(),
  837. isc::dns::RRTTL(3600),
  838. ZoneFinder::SUCCESS,
  839. expected_rdatas_, expected_sig_rdatas_);
  840. expected_rdatas_.clear();
  841. expected_sig_rdatas_.clear();
  842. expected_rdatas_.push_back("2001:db8::1");
  843. expected_rdatas_.push_back("2001:db8::2");
  844. doFindTest(*finder, isc::dns::Name("www.example.org."),
  845. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  846. isc::dns::RRTTL(3600),
  847. ZoneFinder::SUCCESS,
  848. expected_rdatas_, expected_sig_rdatas_);
  849. expected_rdatas_.clear();
  850. expected_sig_rdatas_.clear();
  851. doFindTest(*finder, isc::dns::Name("www.example.org."),
  852. isc::dns::RRType::TXT(), isc::dns::RRType::TXT(),
  853. isc::dns::RRTTL(3600),
  854. ZoneFinder::NXRRSET,
  855. expected_rdatas_, expected_sig_rdatas_);
  856. expected_rdatas_.clear();
  857. expected_sig_rdatas_.clear();
  858. expected_rdatas_.push_back("www.example.org.");
  859. doFindTest(*finder, isc::dns::Name("cname.example.org."),
  860. isc::dns::RRType::A(), isc::dns::RRType::CNAME(),
  861. isc::dns::RRTTL(3600),
  862. ZoneFinder::CNAME,
  863. expected_rdatas_, expected_sig_rdatas_);
  864. expected_rdatas_.clear();
  865. expected_sig_rdatas_.clear();
  866. expected_rdatas_.push_back("www.example.org.");
  867. doFindTest(*finder, isc::dns::Name("cname.example.org."),
  868. isc::dns::RRType::CNAME(), isc::dns::RRType::CNAME(),
  869. isc::dns::RRTTL(3600),
  870. ZoneFinder::SUCCESS,
  871. expected_rdatas_, expected_sig_rdatas_);
  872. expected_rdatas_.clear();
  873. expected_sig_rdatas_.clear();
  874. doFindTest(*finder, isc::dns::Name("doesnotexist.example.org."),
  875. isc::dns::RRType::A(), isc::dns::RRType::A(),
  876. isc::dns::RRTTL(3600),
  877. ZoneFinder::NXDOMAIN,
  878. expected_rdatas_, expected_sig_rdatas_);
  879. expected_rdatas_.clear();
  880. expected_sig_rdatas_.clear();
  881. expected_rdatas_.push_back("192.0.2.1");
  882. expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  883. expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12346 example.org. FAKEFAKEFAKE");
  884. doFindTest(*finder, isc::dns::Name("signed1.example.org."),
  885. isc::dns::RRType::A(), isc::dns::RRType::A(),
  886. isc::dns::RRTTL(3600),
  887. ZoneFinder::SUCCESS,
  888. expected_rdatas_, expected_sig_rdatas_);
  889. expected_rdatas_.clear();
  890. expected_sig_rdatas_.clear();
  891. expected_rdatas_.push_back("2001:db8::1");
  892. expected_rdatas_.push_back("2001:db8::2");
  893. expected_sig_rdatas_.push_back("AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  894. doFindTest(*finder, isc::dns::Name("signed1.example.org."),
  895. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  896. isc::dns::RRTTL(3600),
  897. ZoneFinder::SUCCESS,
  898. expected_rdatas_, expected_sig_rdatas_);
  899. expected_rdatas_.clear();
  900. expected_sig_rdatas_.clear();
  901. doFindTest(*finder, isc::dns::Name("signed1.example.org."),
  902. isc::dns::RRType::TXT(), isc::dns::RRType::TXT(),
  903. isc::dns::RRTTL(3600),
  904. ZoneFinder::NXRRSET,
  905. expected_rdatas_, expected_sig_rdatas_);
  906. expected_rdatas_.clear();
  907. expected_sig_rdatas_.clear();
  908. expected_rdatas_.push_back("www.example.org.");
  909. expected_sig_rdatas_.push_back("CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  910. doFindTest(*finder, isc::dns::Name("signedcname1.example.org."),
  911. isc::dns::RRType::A(), isc::dns::RRType::CNAME(),
  912. isc::dns::RRTTL(3600),
  913. ZoneFinder::CNAME,
  914. expected_rdatas_, expected_sig_rdatas_);
  915. expected_rdatas_.clear();
  916. expected_sig_rdatas_.clear();
  917. expected_rdatas_.push_back("192.0.2.1");
  918. expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  919. expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12346 example.org. FAKEFAKEFAKE");
  920. doFindTest(*finder, isc::dns::Name("signed2.example.org."),
  921. isc::dns::RRType::A(), isc::dns::RRType::A(),
  922. isc::dns::RRTTL(3600),
  923. ZoneFinder::SUCCESS,
  924. expected_rdatas_, expected_sig_rdatas_);
  925. expected_rdatas_.clear();
  926. expected_sig_rdatas_.clear();
  927. expected_rdatas_.push_back("2001:db8::2");
  928. expected_rdatas_.push_back("2001:db8::1");
  929. expected_sig_rdatas_.push_back("AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  930. doFindTest(*finder, isc::dns::Name("signed2.example.org."),
  931. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  932. isc::dns::RRTTL(3600),
  933. ZoneFinder::SUCCESS,
  934. expected_rdatas_, expected_sig_rdatas_);
  935. expected_rdatas_.clear();
  936. expected_sig_rdatas_.clear();
  937. doFindTest(*finder, isc::dns::Name("signed2.example.org."),
  938. isc::dns::RRType::TXT(), isc::dns::RRType::TXT(),
  939. isc::dns::RRTTL(3600),
  940. ZoneFinder::NXRRSET,
  941. expected_rdatas_, expected_sig_rdatas_);
  942. expected_rdatas_.clear();
  943. expected_sig_rdatas_.clear();
  944. expected_rdatas_.push_back("www.example.org.");
  945. expected_sig_rdatas_.push_back("CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  946. doFindTest(*finder, isc::dns::Name("signedcname2.example.org."),
  947. isc::dns::RRType::A(), isc::dns::RRType::CNAME(),
  948. isc::dns::RRTTL(3600),
  949. ZoneFinder::CNAME,
  950. expected_rdatas_, expected_sig_rdatas_);
  951. expected_rdatas_.clear();
  952. expected_sig_rdatas_.clear();
  953. expected_rdatas_.push_back("192.0.2.1");
  954. expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  955. doFindTest(*finder, isc::dns::Name("acnamesig1.example.org."),
  956. isc::dns::RRType::A(), isc::dns::RRType::A(),
  957. isc::dns::RRTTL(3600),
  958. ZoneFinder::SUCCESS,
  959. expected_rdatas_, expected_sig_rdatas_);
  960. expected_rdatas_.clear();
  961. expected_sig_rdatas_.clear();
  962. expected_rdatas_.push_back("192.0.2.1");
  963. expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  964. doFindTest(*finder, isc::dns::Name("acnamesig2.example.org."),
  965. isc::dns::RRType::A(), isc::dns::RRType::A(),
  966. isc::dns::RRTTL(3600),
  967. ZoneFinder::SUCCESS,
  968. expected_rdatas_, expected_sig_rdatas_);
  969. expected_rdatas_.clear();
  970. expected_sig_rdatas_.clear();
  971. expected_rdatas_.push_back("192.0.2.1");
  972. expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  973. doFindTest(*finder, isc::dns::Name("acnamesig3.example.org."),
  974. isc::dns::RRType::A(), isc::dns::RRType::A(),
  975. isc::dns::RRTTL(3600),
  976. ZoneFinder::SUCCESS,
  977. expected_rdatas_, expected_sig_rdatas_);
  978. expected_rdatas_.clear();
  979. expected_sig_rdatas_.clear();
  980. expected_rdatas_.push_back("192.0.2.1");
  981. expected_rdatas_.push_back("192.0.2.2");
  982. doFindTest(*finder, isc::dns::Name("ttldiff1.example.org."),
  983. isc::dns::RRType::A(), isc::dns::RRType::A(),
  984. isc::dns::RRTTL(360),
  985. ZoneFinder::SUCCESS,
  986. expected_rdatas_, expected_sig_rdatas_);
  987. expected_rdatas_.clear();
  988. expected_sig_rdatas_.clear();
  989. expected_rdatas_.push_back("192.0.2.1");
  990. expected_rdatas_.push_back("192.0.2.2");
  991. doFindTest(*finder, isc::dns::Name("ttldiff2.example.org."),
  992. isc::dns::RRType::A(), isc::dns::RRType::A(),
  993. isc::dns::RRTTL(360),
  994. ZoneFinder::SUCCESS,
  995. expected_rdatas_, expected_sig_rdatas_);
  996. EXPECT_THROW(finder->find(isc::dns::Name("badcname1.example.org."),
  997. isc::dns::RRType::A(),
  998. NULL, ZoneFinder::FIND_DEFAULT),
  999. DataSourceError);
  1000. EXPECT_THROW(finder->find(isc::dns::Name("badcname2.example.org."),
  1001. isc::dns::RRType::A(),
  1002. NULL, ZoneFinder::FIND_DEFAULT),
  1003. DataSourceError);
  1004. EXPECT_THROW(finder->find(isc::dns::Name("badcname3.example.org."),
  1005. isc::dns::RRType::A(),
  1006. NULL, ZoneFinder::FIND_DEFAULT),
  1007. DataSourceError);
  1008. EXPECT_THROW(finder->find(isc::dns::Name("badrdata.example.org."),
  1009. isc::dns::RRType::A(),
  1010. NULL, ZoneFinder::FIND_DEFAULT),
  1011. DataSourceError);
  1012. EXPECT_THROW(finder->find(isc::dns::Name("badtype.example.org."),
  1013. isc::dns::RRType::A(),
  1014. NULL, ZoneFinder::FIND_DEFAULT),
  1015. DataSourceError);
  1016. EXPECT_THROW(finder->find(isc::dns::Name("badttl.example.org."),
  1017. isc::dns::RRType::A(),
  1018. NULL, ZoneFinder::FIND_DEFAULT),
  1019. DataSourceError);
  1020. EXPECT_THROW(finder->find(isc::dns::Name("badsig.example.org."),
  1021. isc::dns::RRType::A(),
  1022. NULL, ZoneFinder::FIND_DEFAULT),
  1023. DataSourceError);
  1024. // Trigger the hardcoded exceptions and see if find() has cleaned up
  1025. EXPECT_THROW(finder->find(isc::dns::Name("dsexception.in.search."),
  1026. isc::dns::RRType::A(),
  1027. NULL, ZoneFinder::FIND_DEFAULT),
  1028. DataSourceError);
  1029. EXPECT_THROW(finder->find(isc::dns::Name("iscexception.in.search."),
  1030. isc::dns::RRType::A(),
  1031. NULL, ZoneFinder::FIND_DEFAULT),
  1032. isc::Exception);
  1033. EXPECT_THROW(finder->find(isc::dns::Name("basicexception.in.search."),
  1034. isc::dns::RRType::A(),
  1035. NULL, ZoneFinder::FIND_DEFAULT),
  1036. std::exception);
  1037. EXPECT_THROW(finder->find(isc::dns::Name("dsexception.in.getnext."),
  1038. isc::dns::RRType::A(),
  1039. NULL, ZoneFinder::FIND_DEFAULT),
  1040. DataSourceError);
  1041. EXPECT_THROW(finder->find(isc::dns::Name("iscexception.in.getnext."),
  1042. isc::dns::RRType::A(),
  1043. NULL, ZoneFinder::FIND_DEFAULT),
  1044. isc::Exception);
  1045. EXPECT_THROW(finder->find(isc::dns::Name("basicexception.in.getnext."),
  1046. isc::dns::RRType::A(),
  1047. NULL, ZoneFinder::FIND_DEFAULT),
  1048. std::exception);
  1049. // This RRSIG has the wrong sigtype field, which should be
  1050. // an error if we decide to keep using that field
  1051. // Right now the field is ignored, so it does not error
  1052. expected_rdatas_.clear();
  1053. expected_sig_rdatas_.clear();
  1054. expected_rdatas_.push_back("192.0.2.1");
  1055. expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  1056. doFindTest(*finder, isc::dns::Name("badsigtype.example.org."),
  1057. isc::dns::RRType::A(), isc::dns::RRType::A(),
  1058. isc::dns::RRTTL(3600),
  1059. ZoneFinder::SUCCESS,
  1060. expected_rdatas_, expected_sig_rdatas_);
  1061. }
  1062. TEST_F(DatabaseClientTest, findDelegation) {
  1063. shared_ptr<DatabaseClient::Finder> finder(getFinder());
  1064. // The apex should not be considered delegation point and we can access
  1065. // data
  1066. expected_rdatas_.clear();
  1067. expected_sig_rdatas_.clear();
  1068. expected_rdatas_.push_back("192.0.2.1");
  1069. doFindTest(*finder, isc::dns::Name("example.org."),
  1070. isc::dns::RRType::A(), isc::dns::RRType::A(),
  1071. isc::dns::RRTTL(3600), ZoneFinder::SUCCESS, expected_rdatas_,
  1072. expected_sig_rdatas_);
  1073. expected_rdatas_.clear();
  1074. expected_rdatas_.push_back("ns.example.com.");
  1075. expected_sig_rdatas_.push_back("NS 5 3 3600 20000101000000 20000201000000 "
  1076. "12345 example.org. FAKEFAKEFAKE");
  1077. doFindTest(*finder, isc::dns::Name("example.org."),
  1078. isc::dns::RRType::NS(), isc::dns::RRType::NS(),
  1079. isc::dns::RRTTL(3600), ZoneFinder::SUCCESS, expected_rdatas_,
  1080. expected_sig_rdatas_);
  1081. // Check when we ask for something below delegation point, we get the NS
  1082. // (Both when the RRset there exists and doesn't)
  1083. expected_rdatas_.clear();
  1084. expected_sig_rdatas_.clear();
  1085. expected_rdatas_.push_back("ns.example.com.");
  1086. expected_rdatas_.push_back("ns.delegation.example.org.");
  1087. expected_sig_rdatas_.push_back("NS 5 3 3600 20000101000000 20000201000000 "
  1088. "12345 example.org. FAKEFAKEFAKE");
  1089. doFindTest(*finder, isc::dns::Name("ns.delegation.example.org."),
  1090. isc::dns::RRType::A(), isc::dns::RRType::NS(),
  1091. isc::dns::RRTTL(3600), ZoneFinder::DELEGATION, expected_rdatas_,
  1092. expected_sig_rdatas_,
  1093. isc::dns::Name("delegation.example.org."));
  1094. doFindTest(*finder, isc::dns::Name("ns.delegation.example.org."),
  1095. isc::dns::RRType::AAAA(), isc::dns::RRType::NS(),
  1096. isc::dns::RRTTL(3600), ZoneFinder::DELEGATION, expected_rdatas_,
  1097. expected_sig_rdatas_,
  1098. isc::dns::Name("delegation.example.org."));
  1099. doFindTest(*finder, isc::dns::Name("deep.below.delegation.example.org."),
  1100. isc::dns::RRType::AAAA(), isc::dns::RRType::NS(),
  1101. isc::dns::RRTTL(3600), ZoneFinder::DELEGATION, expected_rdatas_,
  1102. expected_sig_rdatas_,
  1103. isc::dns::Name("delegation.example.org."));
  1104. // Even when we check directly at the delegation point, we should get
  1105. // the NS
  1106. doFindTest(*finder, isc::dns::Name("delegation.example.org."),
  1107. isc::dns::RRType::AAAA(), isc::dns::RRType::NS(),
  1108. isc::dns::RRTTL(3600), ZoneFinder::DELEGATION, expected_rdatas_,
  1109. expected_sig_rdatas_);
  1110. // And when we ask direcly for the NS, we should still get delegation
  1111. doFindTest(*finder, isc::dns::Name("delegation.example.org."),
  1112. isc::dns::RRType::NS(), isc::dns::RRType::NS(),
  1113. isc::dns::RRTTL(3600), ZoneFinder::DELEGATION, expected_rdatas_,
  1114. expected_sig_rdatas_);
  1115. // Now test delegation. If it is below the delegation point, we should get
  1116. // the DNAME (the one with data under DNAME is invalid zone, but we test
  1117. // the behaviour anyway just to make sure)
  1118. expected_rdatas_.clear();
  1119. expected_rdatas_.push_back("dname.example.com.");
  1120. expected_sig_rdatas_.clear();
  1121. expected_sig_rdatas_.push_back("DNAME 5 3 3600 20000101000000 "
  1122. "20000201000000 12345 example.org. "
  1123. "FAKEFAKEFAKE");
  1124. doFindTest(*finder, isc::dns::Name("below.dname.example.org."),
  1125. isc::dns::RRType::A(), isc::dns::RRType::DNAME(),
  1126. isc::dns::RRTTL(3600), ZoneFinder::DNAME, expected_rdatas_,
  1127. expected_sig_rdatas_, isc::dns::Name("dname.example.org."));
  1128. doFindTest(*finder, isc::dns::Name("below.dname.example.org."),
  1129. isc::dns::RRType::AAAA(), isc::dns::RRType::DNAME(),
  1130. isc::dns::RRTTL(3600), ZoneFinder::DNAME, expected_rdatas_,
  1131. expected_sig_rdatas_, isc::dns::Name("dname.example.org."));
  1132. doFindTest(*finder, isc::dns::Name("really.deep.below.dname.example.org."),
  1133. isc::dns::RRType::AAAA(), isc::dns::RRType::DNAME(),
  1134. isc::dns::RRTTL(3600), ZoneFinder::DNAME, expected_rdatas_,
  1135. expected_sig_rdatas_, isc::dns::Name("dname.example.org."));
  1136. // Asking direcly for DNAME should give SUCCESS
  1137. doFindTest(*finder, isc::dns::Name("dname.example.org."),
  1138. isc::dns::RRType::DNAME(), isc::dns::RRType::DNAME(),
  1139. isc::dns::RRTTL(3600), ZoneFinder::SUCCESS, expected_rdatas_,
  1140. expected_sig_rdatas_);
  1141. // But we don't delegate at DNAME point
  1142. expected_rdatas_.clear();
  1143. expected_rdatas_.push_back("192.0.2.1");
  1144. expected_sig_rdatas_.clear();
  1145. doFindTest(*finder, isc::dns::Name("dname.example.org."),
  1146. isc::dns::RRType::A(), isc::dns::RRType::A(),
  1147. isc::dns::RRTTL(3600), ZoneFinder::SUCCESS, expected_rdatas_,
  1148. expected_sig_rdatas_);
  1149. expected_rdatas_.clear();
  1150. doFindTest(*finder, isc::dns::Name("dname.example.org."),
  1151. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1152. isc::dns::RRTTL(3600), ZoneFinder::NXRRSET, expected_rdatas_,
  1153. expected_sig_rdatas_);
  1154. // This is broken dname, it contains two targets
  1155. EXPECT_THROW(finder->find(isc::dns::Name("below.baddname.example.org."),
  1156. isc::dns::RRType::A(), NULL,
  1157. ZoneFinder::FIND_DEFAULT),
  1158. DataSourceError);
  1159. // Broken NS - it lives together with something else
  1160. EXPECT_THROW(finder->find(isc::dns::Name("brokenns1.example.org."),
  1161. isc::dns::RRType::A(), NULL,
  1162. ZoneFinder::FIND_DEFAULT),
  1163. DataSourceError);
  1164. EXPECT_THROW(finder->find(isc::dns::Name("brokenns2.example.org."),
  1165. isc::dns::RRType::A(), NULL,
  1166. ZoneFinder::FIND_DEFAULT),
  1167. DataSourceError);
  1168. }
  1169. TEST_F(DatabaseClientTest, emptyDomain) {
  1170. shared_ptr<DatabaseClient::Finder> finder(getFinder());
  1171. // This domain doesn't exist, but a subdomain of it does.
  1172. // Therefore we should pretend the domain is there, but contains no RRsets
  1173. doFindTest(*finder, isc::dns::Name("b.example.org."), isc::dns::RRType::A(),
  1174. isc::dns::RRType::A(), isc::dns::RRTTL(3600),
  1175. ZoneFinder::NXRRSET, expected_rdatas_, expected_sig_rdatas_);
  1176. }
  1177. // Glue-OK mode. Just go trough NS delegations down (but not trough
  1178. // DNAME) and pretend it is not there.
  1179. TEST_F(DatabaseClientTest, glueOK) {
  1180. shared_ptr<DatabaseClient::Finder> finder(getFinder());
  1181. expected_rdatas_.clear();
  1182. expected_sig_rdatas_.clear();
  1183. doFindTest(*finder, isc::dns::Name("ns.delegation.example.org."),
  1184. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1185. isc::dns::RRTTL(3600), ZoneFinder::NXRRSET,
  1186. expected_rdatas_, expected_sig_rdatas_,
  1187. isc::dns::Name("ns.delegation.example.org."),
  1188. ZoneFinder::FIND_GLUE_OK);
  1189. doFindTest(*finder, isc::dns::Name("nothere.delegation.example.org."),
  1190. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1191. isc::dns::RRTTL(3600), ZoneFinder::NXDOMAIN,
  1192. expected_rdatas_, expected_sig_rdatas_,
  1193. isc::dns::Name("nothere.delegation.example.org."),
  1194. ZoneFinder::FIND_GLUE_OK);
  1195. expected_rdatas_.push_back("192.0.2.1");
  1196. doFindTest(*finder, isc::dns::Name("ns.delegation.example.org."),
  1197. isc::dns::RRType::A(), isc::dns::RRType::A(),
  1198. isc::dns::RRTTL(3600), ZoneFinder::SUCCESS,
  1199. expected_rdatas_, expected_sig_rdatas_,
  1200. isc::dns::Name("ns.delegation.example.org."),
  1201. ZoneFinder::FIND_GLUE_OK);
  1202. expected_rdatas_.clear();
  1203. expected_rdatas_.push_back("ns.example.com.");
  1204. expected_rdatas_.push_back("ns.delegation.example.org.");
  1205. expected_sig_rdatas_.clear();
  1206. expected_sig_rdatas_.push_back("NS 5 3 3600 20000101000000 "
  1207. "20000201000000 12345 example.org. "
  1208. "FAKEFAKEFAKE");
  1209. // When we request the NS, it should be SUCCESS, not DELEGATION
  1210. // (different in GLUE_OK)
  1211. doFindTest(*finder, isc::dns::Name("delegation.example.org."),
  1212. isc::dns::RRType::NS(), isc::dns::RRType::NS(),
  1213. isc::dns::RRTTL(3600), ZoneFinder::SUCCESS,
  1214. expected_rdatas_, expected_sig_rdatas_,
  1215. isc::dns::Name("delegation.example.org."),
  1216. ZoneFinder::FIND_GLUE_OK);
  1217. expected_rdatas_.clear();
  1218. expected_rdatas_.push_back("dname.example.com.");
  1219. expected_sig_rdatas_.clear();
  1220. expected_sig_rdatas_.push_back("DNAME 5 3 3600 20000101000000 "
  1221. "20000201000000 12345 example.org. "
  1222. "FAKEFAKEFAKE");
  1223. doFindTest(*finder, isc::dns::Name("below.dname.example.org."),
  1224. isc::dns::RRType::A(), isc::dns::RRType::DNAME(),
  1225. isc::dns::RRTTL(3600), ZoneFinder::DNAME, expected_rdatas_,
  1226. expected_sig_rdatas_, isc::dns::Name("dname.example.org."),
  1227. ZoneFinder::FIND_GLUE_OK);
  1228. doFindTest(*finder, isc::dns::Name("below.dname.example.org."),
  1229. isc::dns::RRType::AAAA(), isc::dns::RRType::DNAME(),
  1230. isc::dns::RRTTL(3600), ZoneFinder::DNAME, expected_rdatas_,
  1231. expected_sig_rdatas_, isc::dns::Name("dname.example.org."),
  1232. ZoneFinder::FIND_GLUE_OK);
  1233. }
  1234. TEST_F(DatabaseClientTest, wildcard) {
  1235. shared_ptr<DatabaseClient::Finder> finder(getFinder());
  1236. // First, simple wildcard match
  1237. expected_rdatas_.push_back("192.0.2.5");
  1238. doFindTest(*finder, isc::dns::Name("a.wild.example.org"),
  1239. isc::dns::RRType::A(), isc::dns::RRType::A(),
  1240. isc::dns::RRTTL(3600), ZoneFinder::SUCCESS, expected_rdatas_,
  1241. expected_sig_rdatas_);
  1242. doFindTest(*finder, isc::dns::Name("b.a.wild.example.org"),
  1243. isc::dns::RRType::A(), isc::dns::RRType::A(),
  1244. isc::dns::RRTTL(3600), ZoneFinder::SUCCESS, expected_rdatas_,
  1245. expected_sig_rdatas_);
  1246. expected_rdatas_.clear();
  1247. doFindTest(*finder, isc::dns::Name("a.wild.example.org"),
  1248. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1249. isc::dns::RRTTL(3600), ZoneFinder::NXRRSET, expected_rdatas_,
  1250. expected_sig_rdatas_);
  1251. doFindTest(*finder, isc::dns::Name("b.a.wild.example.org"),
  1252. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1253. isc::dns::RRTTL(3600), ZoneFinder::NXRRSET, expected_rdatas_,
  1254. expected_sig_rdatas_);
  1255. // Direct request for thi wildcard
  1256. expected_rdatas_.push_back("192.0.2.5");
  1257. doFindTest(*finder, isc::dns::Name("*.wild.example.org"),
  1258. isc::dns::RRType::A(), isc::dns::RRType::A(),
  1259. isc::dns::RRTTL(3600), ZoneFinder::SUCCESS, expected_rdatas_,
  1260. expected_sig_rdatas_);
  1261. expected_rdatas_.clear();
  1262. doFindTest(*finder, isc::dns::Name("*.wild.example.org"),
  1263. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1264. isc::dns::RRTTL(3600), ZoneFinder::NXRRSET, expected_rdatas_,
  1265. expected_sig_rdatas_);
  1266. // This is nonsense, but check it doesn't match by some stupid accident
  1267. doFindTest(*finder, isc::dns::Name("a.*.wild.example.org"),
  1268. isc::dns::RRType::A(), isc::dns::RRType::A(),
  1269. isc::dns::RRTTL(3600), ZoneFinder::NXDOMAIN,
  1270. expected_rdatas_, expected_sig_rdatas_);
  1271. // These should be canceled, since it is below a domain which exitsts
  1272. doFindTest(*finder, isc::dns::Name("nothing.here.wild.example.org"),
  1273. isc::dns::RRType::A(), isc::dns::RRType::A(),
  1274. isc::dns::RRTTL(3600), ZoneFinder::NXDOMAIN,
  1275. expected_rdatas_, expected_sig_rdatas_);
  1276. doFindTest(*finder, isc::dns::Name("cancel.here.wild.example.org"),
  1277. isc::dns::RRType::A(), isc::dns::RRType::A(),
  1278. isc::dns::RRTTL(3600), ZoneFinder::NXRRSET,
  1279. expected_rdatas_, expected_sig_rdatas_);
  1280. doFindTest(*finder,
  1281. isc::dns::Name("below.cancel.here.wild.example.org"),
  1282. isc::dns::RRType::A(), isc::dns::RRType::A(),
  1283. isc::dns::RRTTL(3600), ZoneFinder::NXDOMAIN,
  1284. expected_rdatas_, expected_sig_rdatas_);
  1285. // And this should be just plain empty non-terminal domain, check
  1286. // the wildcard doesn't hurt it
  1287. doFindTest(*finder, isc::dns::Name("here.wild.example.org"),
  1288. isc::dns::RRType::A(), isc::dns::RRType::A(),
  1289. isc::dns::RRTTL(3600), ZoneFinder::NXRRSET, expected_rdatas_,
  1290. expected_sig_rdatas_);
  1291. // Also make sure that the wildcard doesn't hurt the original data
  1292. // below the wildcard
  1293. expected_rdatas_.push_back("2001:db8::5");
  1294. doFindTest(*finder, isc::dns::Name("cancel.here.wild.example.org"),
  1295. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1296. isc::dns::RRTTL(3600), ZoneFinder::SUCCESS,
  1297. expected_rdatas_, expected_sig_rdatas_);
  1298. expected_rdatas_.clear();
  1299. // How wildcard go together with delegation
  1300. expected_rdatas_.push_back("ns.example.com.");
  1301. doFindTest(*finder, isc::dns::Name("below.delegatedwild.example.org"),
  1302. isc::dns::RRType::A(), isc::dns::RRType::NS(),
  1303. isc::dns::RRTTL(3600), ZoneFinder::DELEGATION, expected_rdatas_,
  1304. expected_sig_rdatas_,
  1305. isc::dns::Name("delegatedwild.example.org"));
  1306. // FIXME: This doesn't look logically OK, GLUE_OK should make it transparent,
  1307. // so the match should either work or be canceled, but return NXDOMAIN
  1308. doFindTest(*finder, isc::dns::Name("below.delegatedwild.example.org"),
  1309. isc::dns::RRType::A(), isc::dns::RRType::NS(),
  1310. isc::dns::RRTTL(3600), ZoneFinder::DELEGATION, expected_rdatas_,
  1311. expected_sig_rdatas_,
  1312. isc::dns::Name("delegatedwild.example.org"),
  1313. ZoneFinder::FIND_GLUE_OK);
  1314. expected_rdatas_.clear();
  1315. expected_rdatas_.push_back("192.0.2.5");
  1316. // These are direct matches
  1317. const char* positive_names[] = {
  1318. "wild.*.foo.example.org.",
  1319. "wild.*.foo.*.bar.example.org.",
  1320. NULL
  1321. };
  1322. for (const char** name(positive_names); *name != NULL; ++ name) {
  1323. doFindTest(*finder, isc::dns::Name(*name), isc::dns::RRType::A(),
  1324. isc::dns::RRType::A(), isc::dns::RRTTL(3600),
  1325. ZoneFinder::SUCCESS, expected_rdatas_,
  1326. expected_sig_rdatas_);
  1327. }
  1328. // These are wildcard matches against empty nonterminal asterisk
  1329. expected_rdatas_.clear();
  1330. const char* negative_names[] = {
  1331. "a.foo.example.org.",
  1332. "*.foo.example.org.",
  1333. "foo.example.org.",
  1334. "wild.bar.foo.example.org.",
  1335. "baz.foo.*.bar.example.org",
  1336. "baz.foo.baz.bar.example.org",
  1337. "*.foo.baz.bar.example.org",
  1338. "*.foo.*.bar.example.org",
  1339. "foo.*.bar.example.org",
  1340. "*.bar.example.org",
  1341. "bar.example.org",
  1342. NULL
  1343. };
  1344. for (const char** name(negative_names); *name != NULL; ++ name) {
  1345. doFindTest(*finder, isc::dns::Name(*name), isc::dns::RRType::A(),
  1346. isc::dns::RRType::A(), isc::dns::RRTTL(3600),
  1347. ZoneFinder::NXRRSET, expected_rdatas_,
  1348. expected_sig_rdatas_);
  1349. }
  1350. }
  1351. TEST_F(DatabaseClientTest, getOrigin) {
  1352. DataSourceClient::FindResult zone(client_->findZone(Name("example.org")));
  1353. ASSERT_EQ(result::SUCCESS, zone.code);
  1354. shared_ptr<DatabaseClient::Finder> finder(
  1355. dynamic_pointer_cast<DatabaseClient::Finder>(zone.zone_finder));
  1356. EXPECT_EQ(READONLY_ZONE_ID, finder->zone_id());
  1357. EXPECT_EQ(isc::dns::Name("example.org"), finder->getOrigin());
  1358. }
  1359. TEST_F(DatabaseClientTest, updaterFinder) {
  1360. updater_ = client_->getUpdater(zname_, false);
  1361. ASSERT_TRUE(updater_);
  1362. // If this update isn't replacing the zone, the finder should work
  1363. // just like the normal find() case.
  1364. EXPECT_EQ(WRITABLE_ZONE_ID, dynamic_cast<DatabaseClient::Finder&>(
  1365. updater_->getFinder()).zone_id());
  1366. expected_rdatas_.clear();
  1367. expected_rdatas_.push_back("192.0.2.1");
  1368. doFindTest(updater_->getFinder(), qname_,
  1369. qtype_, qtype_, rrttl_, ZoneFinder::SUCCESS,
  1370. expected_rdatas_, empty_rdatas_);
  1371. // When replacing the zone, the updater's finder shouldn't see anything
  1372. // in the zone until something is added.
  1373. updater_.reset();
  1374. updater_ = client_->getUpdater(zname_, true);
  1375. ASSERT_TRUE(updater_);
  1376. EXPECT_EQ(WRITABLE_ZONE_ID, dynamic_cast<DatabaseClient::Finder&>(
  1377. updater_->getFinder()).zone_id());
  1378. doFindTest(updater_->getFinder(), qname_, qtype_, qtype_, rrttl_,
  1379. ZoneFinder::NXDOMAIN, empty_rdatas_, empty_rdatas_);
  1380. }
  1381. TEST_F(DatabaseClientTest, flushZone) {
  1382. // A simple update case: flush the entire zone
  1383. shared_ptr<DatabaseClient::Finder> finder(getFinder());
  1384. // Before update, the name exists.
  1385. EXPECT_EQ(ZoneFinder::SUCCESS, finder->find(qname_, qtype_).code);
  1386. // start update in the replace mode. the normal finder should still
  1387. // be able to see the record, but the updater's finder shouldn't.
  1388. updater_ = client_->getUpdater(zname_, true);
  1389. setUpdateAccessor();
  1390. EXPECT_EQ(ZoneFinder::SUCCESS,
  1391. finder->find(qname_, qtype_).code);
  1392. EXPECT_EQ(ZoneFinder::NXDOMAIN,
  1393. updater_->getFinder().find(qname_, qtype_).code);
  1394. // commit the update. now the normal finder shouldn't see it.
  1395. updater_->commit();
  1396. EXPECT_EQ(ZoneFinder::NXDOMAIN, finder->find(qname_, qtype_).code);
  1397. // Check rollback wasn't accidentally performed.
  1398. EXPECT_FALSE(isRollbacked());
  1399. }
  1400. TEST_F(DatabaseClientTest, updateCancel) {
  1401. // similar to the previous test, but destruct the updater before commit.
  1402. ZoneFinderPtr finder = client_->findZone(zname_).zone_finder;
  1403. EXPECT_EQ(ZoneFinder::SUCCESS, finder->find(qname_, qtype_).code);
  1404. updater_ = client_->getUpdater(zname_, true);
  1405. setUpdateAccessor();
  1406. EXPECT_EQ(ZoneFinder::NXDOMAIN,
  1407. updater_->getFinder().find(qname_, qtype_).code);
  1408. // DB should not have been rolled back yet.
  1409. EXPECT_FALSE(isRollbacked());
  1410. updater_.reset(); // destruct without commit
  1411. // reset() should have triggered rollback (although it doesn't affect
  1412. // anything to the mock accessor implementation except for the result of
  1413. // isRollbacked())
  1414. EXPECT_TRUE(isRollbacked());
  1415. EXPECT_EQ(ZoneFinder::SUCCESS, finder->find(qname_, qtype_).code);
  1416. }
  1417. TEST_F(DatabaseClientTest, exceptionFromRollback) {
  1418. updater_ = client_->getUpdater(zname_, true);
  1419. rrset_.reset(new RRset(Name("throw.example.org"), qclass_, qtype_,
  1420. rrttl_));
  1421. rrset_->addRdata(rdata::createRdata(rrset_->getType(),
  1422. rrset_->getClass(), "192.0.2.1"));
  1423. updater_->addRRset(*rrset_);
  1424. // destruct without commit. The added name will result in an exception
  1425. // in the MockAccessor's rollback method. It shouldn't be propagated.
  1426. EXPECT_NO_THROW(updater_.reset());
  1427. }
  1428. TEST_F(DatabaseClientTest, duplicateCommit) {
  1429. // duplicate commit. should result in exception.
  1430. updater_ = client_->getUpdater(zname_, true);
  1431. updater_->commit();
  1432. EXPECT_THROW(updater_->commit(), DataSourceError);
  1433. }
  1434. TEST_F(DatabaseClientTest, addRRsetToNewZone) {
  1435. // Add a single RRset to a fresh empty zone
  1436. updater_ = client_->getUpdater(zname_, true);
  1437. updater_->addRRset(*rrset_);
  1438. expected_rdatas_.clear();
  1439. expected_rdatas_.push_back("192.0.2.2");
  1440. {
  1441. SCOPED_TRACE("add RRset");
  1442. doFindTest(updater_->getFinder(), qname_, qtype_,
  1443. qtype_, rrttl_, ZoneFinder::SUCCESS,
  1444. expected_rdatas_, empty_rdatas_);
  1445. }
  1446. // Similar to the previous case, but with RRSIG
  1447. updater_.reset();
  1448. updater_ = client_->getUpdater(zname_, true);
  1449. updater_->addRRset(*rrset_);
  1450. updater_->addRRset(*rrsigset_);
  1451. // confirm the expected columns were passed to the accessor (if checkable).
  1452. const char* const rrsig_added[] = {
  1453. "www.example.org.", "org.example.www.", "3600", "RRSIG", "A",
  1454. "A 5 3 0 20000101000000 20000201000000 0 example.org. FAKEFAKEFAKE"
  1455. };
  1456. checkLastAdded(rrsig_added);
  1457. expected_sig_rdatas_.clear();
  1458. expected_sig_rdatas_.push_back(rrsig_added[DatabaseAccessor::ADD_RDATA]);
  1459. {
  1460. SCOPED_TRACE("add RRset with RRSIG");
  1461. doFindTest(updater_->getFinder(), qname_, qtype_,
  1462. qtype_, rrttl_, ZoneFinder::SUCCESS,
  1463. expected_rdatas_, expected_sig_rdatas_);
  1464. }
  1465. }
  1466. TEST_F(DatabaseClientTest, addRRsetToCurrentZone) {
  1467. // Similar to the previous test, but not replacing the existing data.
  1468. shared_ptr<DatabaseClient::Finder> finder(getFinder());
  1469. updater_ = client_->getUpdater(zname_, false);
  1470. updater_->addRRset(*rrset_);
  1471. // We should see both old and new data.
  1472. expected_rdatas_.clear();
  1473. expected_rdatas_.push_back("192.0.2.1");
  1474. expected_rdatas_.push_back("192.0.2.2");
  1475. {
  1476. SCOPED_TRACE("add RRset");
  1477. doFindTest(updater_->getFinder(), qname_, qtype_,
  1478. qtype_, rrttl_, ZoneFinder::SUCCESS,
  1479. expected_rdatas_, empty_rdatas_);
  1480. }
  1481. updater_->commit();
  1482. {
  1483. SCOPED_TRACE("add RRset after commit");
  1484. doFindTest(*finder, qname_, qtype_, qtype_,
  1485. rrttl_, ZoneFinder::SUCCESS, expected_rdatas_,
  1486. empty_rdatas_);
  1487. }
  1488. }
  1489. TEST_F(DatabaseClientTest, addMultipleRRs) {
  1490. // Similar to the previous case, but the added RRset contains multiple
  1491. // RRs.
  1492. updater_ = client_->getUpdater(zname_, false);
  1493. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1494. "192.0.2.3"));
  1495. updater_->addRRset(*rrset_);
  1496. expected_rdatas_.clear();
  1497. expected_rdatas_.push_back("192.0.2.1");
  1498. expected_rdatas_.push_back("192.0.2.2");
  1499. expected_rdatas_.push_back("192.0.2.3");
  1500. {
  1501. SCOPED_TRACE("add multiple RRs");
  1502. doFindTest(updater_->getFinder(), qname_, qtype_,
  1503. qtype_, rrttl_, ZoneFinder::SUCCESS,
  1504. expected_rdatas_, empty_rdatas_);
  1505. }
  1506. }
  1507. TEST_F(DatabaseClientTest, addRRsetOfLargerTTL) {
  1508. // Similar to the previous one, but the TTL of the added RRset is larger
  1509. // than that of the existing record. The finder should use the smaller
  1510. // one.
  1511. updater_ = client_->getUpdater(zname_, false);
  1512. rrset_->setTTL(RRTTL(7200));
  1513. updater_->addRRset(*rrset_);
  1514. expected_rdatas_.clear();
  1515. expected_rdatas_.push_back("192.0.2.1");
  1516. expected_rdatas_.push_back("192.0.2.2");
  1517. {
  1518. SCOPED_TRACE("add RRset of larger TTL");
  1519. doFindTest(updater_->getFinder(), qname_, qtype_,
  1520. qtype_, rrttl_, ZoneFinder::SUCCESS,
  1521. expected_rdatas_, empty_rdatas_);
  1522. }
  1523. }
  1524. TEST_F(DatabaseClientTest, addRRsetOfSmallerTTL) {
  1525. // Similar to the previous one, but the added RRset has a smaller TTL.
  1526. // The added TTL should be used by the finder.
  1527. updater_ = client_->getUpdater(zname_, false);
  1528. rrset_->setTTL(RRTTL(1800));
  1529. updater_->addRRset(*rrset_);
  1530. expected_rdatas_.clear();
  1531. expected_rdatas_.push_back("192.0.2.1");
  1532. expected_rdatas_.push_back("192.0.2.2");
  1533. {
  1534. SCOPED_TRACE("add RRset of smaller TTL");
  1535. doFindTest(updater_->getFinder(), qname_, qtype_,
  1536. qtype_, RRTTL(1800), ZoneFinder::SUCCESS,
  1537. expected_rdatas_, empty_rdatas_);
  1538. }
  1539. }
  1540. TEST_F(DatabaseClientTest, addSameRR) {
  1541. // Add the same RR as that is already in the data source.
  1542. // Currently the add interface doesn't try to suppress the duplicate,
  1543. // neither does the finder. We may want to revisit it in future versions.
  1544. updater_ = client_->getUpdater(zname_, false);
  1545. rrset_.reset(new RRset(qname_, qclass_, qtype_, rrttl_));
  1546. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1547. "192.0.2.1"));
  1548. updater_->addRRset(*rrset_);
  1549. expected_rdatas_.clear();
  1550. expected_rdatas_.push_back("192.0.2.1");
  1551. expected_rdatas_.push_back("192.0.2.1");
  1552. {
  1553. SCOPED_TRACE("add same RR");
  1554. doFindTest(updater_->getFinder(), qname_, qtype_,
  1555. qtype_, rrttl_, ZoneFinder::SUCCESS,
  1556. expected_rdatas_, empty_rdatas_);
  1557. }
  1558. }
  1559. TEST_F(DatabaseClientTest, addDeviantRR) {
  1560. updater_ = client_->getUpdater(zname_, false);
  1561. // RR class mismatch. This should be detected and rejected.
  1562. rrset_.reset(new RRset(qname_, RRClass::CH(), RRType::TXT(), rrttl_));
  1563. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1564. "test text"));
  1565. EXPECT_THROW(updater_->addRRset(*rrset_), DataSourceError);
  1566. // Out-of-zone owner name. At a higher level this should be rejected,
  1567. // but it doesn't happen in this interface.
  1568. rrset_.reset(new RRset(Name("example.com"), qclass_, qtype_, rrttl_));
  1569. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1570. "192.0.2.100"));
  1571. updater_->addRRset(*rrset_);
  1572. expected_rdatas_.clear();
  1573. expected_rdatas_.push_back("192.0.2.100");
  1574. {
  1575. // Note: with the find() implementation being more strict about
  1576. // zone cuts, this test may fail. Then the test should be updated.
  1577. SCOPED_TRACE("add out-of-zone RR");
  1578. doFindTest(updater_->getFinder(), Name("example.com"),
  1579. qtype_, qtype_, rrttl_, ZoneFinder::SUCCESS,
  1580. expected_rdatas_, empty_rdatas_);
  1581. }
  1582. }
  1583. TEST_F(DatabaseClientTest, addEmptyRRset) {
  1584. updater_ = client_->getUpdater(zname_, false);
  1585. rrset_.reset(new RRset(qname_, qclass_, qtype_, rrttl_));
  1586. EXPECT_THROW(updater_->addRRset(*rrset_), DataSourceError);
  1587. }
  1588. TEST_F(DatabaseClientTest, addAfterCommit) {
  1589. updater_ = client_->getUpdater(zname_, false);
  1590. updater_->commit();
  1591. EXPECT_THROW(updater_->addRRset(*rrset_), DataSourceError);
  1592. }
  1593. TEST_F(DatabaseClientTest, deleteRRset) {
  1594. shared_ptr<DatabaseClient::Finder> finder(getFinder());
  1595. rrset_.reset(new RRset(qname_, qclass_, qtype_, rrttl_));
  1596. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1597. "192.0.2.1"));
  1598. // Delete one RR from an RRset
  1599. updater_ = client_->getUpdater(zname_, false);
  1600. updater_->deleteRRset(*rrset_);
  1601. // Delete the only RR of a name
  1602. rrset_.reset(new RRset(Name("cname.example.org"), qclass_,
  1603. RRType::CNAME(), rrttl_));
  1604. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1605. "www.example.org"));
  1606. updater_->deleteRRset(*rrset_);
  1607. // The updater_ finder should immediately see the deleted results.
  1608. {
  1609. SCOPED_TRACE("delete RRset");
  1610. doFindTest(updater_->getFinder(), qname_, qtype_,
  1611. qtype_, rrttl_, ZoneFinder::NXRRSET,
  1612. empty_rdatas_, empty_rdatas_);
  1613. doFindTest(updater_->getFinder(), Name("cname.example.org"),
  1614. qtype_, qtype_, rrttl_, ZoneFinder::NXDOMAIN,
  1615. empty_rdatas_, empty_rdatas_);
  1616. }
  1617. // before committing the change, the original finder should see the
  1618. // original record.
  1619. {
  1620. SCOPED_TRACE("delete RRset before commit");
  1621. expected_rdatas_.push_back("192.0.2.1");
  1622. doFindTest(*finder, qname_, qtype_, qtype_,
  1623. rrttl_, ZoneFinder::SUCCESS, expected_rdatas_,
  1624. empty_rdatas_);
  1625. expected_rdatas_.clear();
  1626. expected_rdatas_.push_back("www.example.org.");
  1627. doFindTest(*finder, Name("cname.example.org"), qtype_,
  1628. RRType::CNAME(), rrttl_, ZoneFinder::CNAME,
  1629. expected_rdatas_, empty_rdatas_);
  1630. }
  1631. // once committed, the record should be removed from the original finder's
  1632. // view, too.
  1633. updater_->commit();
  1634. {
  1635. SCOPED_TRACE("delete RRset after commit");
  1636. doFindTest(*finder, qname_, qtype_, qtype_,
  1637. rrttl_, ZoneFinder::NXRRSET, empty_rdatas_,
  1638. empty_rdatas_);
  1639. doFindTest(*finder, Name("cname.example.org"),
  1640. qtype_, qtype_, rrttl_, ZoneFinder::NXDOMAIN,
  1641. empty_rdatas_, empty_rdatas_);
  1642. }
  1643. }
  1644. TEST_F(DatabaseClientTest, deleteRRsetToNXDOMAIN) {
  1645. // similar to the previous case, but it removes the only record of the
  1646. // given name. a subsequent find() should result in NXDOMAIN.
  1647. rrset_.reset(new RRset(Name("cname.example.org"), qclass_,
  1648. RRType::CNAME(), rrttl_));
  1649. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1650. "www.example.org"));
  1651. updater_ = client_->getUpdater(zname_, false);
  1652. updater_->deleteRRset(*rrset_);
  1653. {
  1654. SCOPED_TRACE("delete RRset to NXDOMAIN");
  1655. doFindTest(updater_->getFinder(), Name("cname.example.org"),
  1656. qtype_, qtype_, rrttl_, ZoneFinder::NXDOMAIN,
  1657. empty_rdatas_, empty_rdatas_);
  1658. }
  1659. }
  1660. TEST_F(DatabaseClientTest, deleteMultipleRRs) {
  1661. rrset_.reset(new RRset(qname_, qclass_, RRType::AAAA(), rrttl_));
  1662. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1663. "2001:db8::1"));
  1664. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1665. "2001:db8::2"));
  1666. updater_ = client_->getUpdater(zname_, false);
  1667. updater_->deleteRRset(*rrset_);
  1668. {
  1669. SCOPED_TRACE("delete multiple RRs");
  1670. doFindTest(updater_->getFinder(), qname_, RRType::AAAA(),
  1671. qtype_, rrttl_, ZoneFinder::NXRRSET,
  1672. empty_rdatas_, empty_rdatas_);
  1673. }
  1674. }
  1675. TEST_F(DatabaseClientTest, partialDelete) {
  1676. rrset_.reset(new RRset(qname_, qclass_, RRType::AAAA(), rrttl_));
  1677. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1678. "2001:db8::1"));
  1679. // This does not exist in the test data source:
  1680. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1681. "2001:db8::3"));
  1682. // deleteRRset should succeed "silently", and subsequent find() should
  1683. // find the remaining RR.
  1684. updater_ = client_->getUpdater(zname_, false);
  1685. updater_->deleteRRset(*rrset_);
  1686. {
  1687. SCOPED_TRACE("partial delete");
  1688. expected_rdatas_.push_back("2001:db8::2");
  1689. doFindTest(updater_->getFinder(), qname_, RRType::AAAA(),
  1690. RRType::AAAA(), rrttl_, ZoneFinder::SUCCESS,
  1691. expected_rdatas_, empty_rdatas_);
  1692. }
  1693. }
  1694. TEST_F(DatabaseClientTest, deleteNoMatch) {
  1695. // similar to the previous test, but there's not even a match in the
  1696. // specified RRset. Essentially there's no difference in the result.
  1697. updater_ = client_->getUpdater(zname_, false);
  1698. updater_->deleteRRset(*rrset_);
  1699. {
  1700. SCOPED_TRACE("delete no match");
  1701. expected_rdatas_.push_back("192.0.2.1");
  1702. doFindTest(updater_->getFinder(), qname_, qtype_,
  1703. qtype_, rrttl_, ZoneFinder::SUCCESS,
  1704. expected_rdatas_, empty_rdatas_);
  1705. }
  1706. }
  1707. TEST_F(DatabaseClientTest, deleteWithDifferentTTL) {
  1708. // Our delete interface simply ignores TTL (may change in a future version)
  1709. rrset_.reset(new RRset(qname_, qclass_, qtype_, RRTTL(1800)));
  1710. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1711. "192.0.2.1"));
  1712. updater_ = client_->getUpdater(zname_, false);
  1713. updater_->deleteRRset(*rrset_);
  1714. {
  1715. SCOPED_TRACE("delete RRset with a different TTL");
  1716. doFindTest(updater_->getFinder(), qname_, qtype_,
  1717. qtype_, rrttl_, ZoneFinder::NXRRSET,
  1718. empty_rdatas_, empty_rdatas_);
  1719. }
  1720. }
  1721. TEST_F(DatabaseClientTest, deleteDeviantRR) {
  1722. updater_ = client_->getUpdater(zname_, false);
  1723. // RR class mismatch. This should be detected and rejected.
  1724. rrset_.reset(new RRset(qname_, RRClass::CH(), RRType::TXT(), rrttl_));
  1725. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1726. "test text"));
  1727. EXPECT_THROW(updater_->deleteRRset(*rrset_), DataSourceError);
  1728. // Out-of-zone owner name. At a higher level this should be rejected,
  1729. // but it doesn't happen in this interface.
  1730. rrset_.reset(new RRset(Name("example.com"), qclass_, qtype_, rrttl_));
  1731. rrset_->addRdata(rdata::createRdata(rrset_->getType(), rrset_->getClass(),
  1732. "192.0.2.100"));
  1733. EXPECT_NO_THROW(updater_->deleteRRset(*rrset_));
  1734. }
  1735. TEST_F(DatabaseClientTest, deleteAfterCommit) {
  1736. updater_ = client_->getUpdater(zname_, false);
  1737. updater_->commit();
  1738. EXPECT_THROW(updater_->deleteRRset(*rrset_), DataSourceError);
  1739. }
  1740. TEST_F(DatabaseClientTest, deleteEmptyRRset) {
  1741. updater_ = client_->getUpdater(zname_, false);
  1742. rrset_.reset(new RRset(qname_, qclass_, qtype_, rrttl_));
  1743. EXPECT_THROW(updater_->deleteRRset(*rrset_), DataSourceError);
  1744. }
  1745. }