database_unittest.cc 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  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 <gtest/gtest.h>
  15. #include <dns/name.h>
  16. #include <dns/rrttl.h>
  17. #include <dns/rrset.h>
  18. #include <exceptions/exceptions.h>
  19. #include <datasrc/database.h>
  20. #include <datasrc/zone.h>
  21. #include <datasrc/data_source.h>
  22. #include <testutils/dnsmessage_test.h>
  23. #include <map>
  24. using namespace isc::datasrc;
  25. using namespace std;
  26. using namespace boost;
  27. using isc::dns::Name;
  28. using isc::dns::RRType;
  29. using isc::dns::RRTTL;
  30. namespace {
  31. const int READONLY_ZONE_ID = 42;
  32. const int WRITABLE_ZONE_ID = 4200;
  33. /*
  34. * A virtual database database that pretends it contains single zone --
  35. * example.org.
  36. */
  37. class MockAccessor : public DatabaseAccessor {
  38. typedef std::map<std::string, std::vector< std::vector<std::string> > >
  39. RECORDS;
  40. public:
  41. MockAccessor() : search_running_(false),
  42. database_name_("mock_database")
  43. {
  44. fillData();
  45. }
  46. virtual pair<bool, int> getZone(const Name& name) const {
  47. return (getZone(name.toText()));
  48. }
  49. pair<bool, int> getZone(const string& name) const {
  50. if (name == "example.org.") {
  51. return (std::pair<bool, int>(true, READONLY_ZONE_ID));
  52. } else {
  53. return (std::pair<bool, int>(false, 0));
  54. }
  55. }
  56. virtual void searchForRecords(int zone_id, const std::string& name) {
  57. search_running_ = true;
  58. // 'hardcoded' name to trigger exceptions (for testing
  59. // the error handling of find() (the other on is below in
  60. // if the name is "exceptiononsearch" it'll raise an exception here
  61. if (name == "dsexception.in.search.") {
  62. isc_throw(DataSourceError, "datasource exception on search");
  63. } else if (name == "iscexception.in.search.") {
  64. isc_throw(isc::Exception, "isc exception on search");
  65. } else if (name == "basicexception.in.search.") {
  66. throw std::exception();
  67. }
  68. searched_name_ = name;
  69. // we're not aiming for efficiency in this test, simply
  70. // copy the relevant vector from records
  71. cur_record = 0;
  72. const RECORDS& cur_records = getRecords(zone_id);
  73. if (cur_records.count(name) > 0) {
  74. cur_name = cur_records.find(name)->second;
  75. } else {
  76. cur_name.clear();
  77. }
  78. }
  79. virtual bool getNextRecord(std::string columns[], size_t column_count) {
  80. if (searched_name_ == "dsexception.in.getnext.") {
  81. isc_throw(DataSourceError, "datasource exception on getnextrecord");
  82. } else if (searched_name_ == "iscexception.in.getnext.") {
  83. isc_throw(isc::Exception, "isc exception on getnextrecord");
  84. } else if (searched_name_ == "basicexception.in.getnext.") {
  85. throw std::exception();
  86. }
  87. if (column_count != DatabaseAccessor::COLUMN_COUNT) {
  88. isc_throw(DataSourceError, "Wrong column count in getNextRecord");
  89. }
  90. if (cur_record < cur_name.size()) {
  91. for (size_t i = 0; i < column_count; ++i) {
  92. columns[i] = cur_name[cur_record][i];
  93. }
  94. cur_record++;
  95. return (true);
  96. } else {
  97. resetSearch();
  98. return (false);
  99. }
  100. };
  101. virtual void resetSearch() {
  102. search_running_ = false;
  103. };
  104. bool searchRunning() const {
  105. return (search_running_);
  106. }
  107. virtual const std::string& getDBName() const {
  108. return (database_name_);
  109. }
  110. private:
  111. RECORDS readonly_records;
  112. RECORDS update_records;
  113. RECORDS empty_records;
  114. // used as internal index for getNextRecord()
  115. size_t cur_record;
  116. // used as temporary storage after searchForRecord() and during
  117. // getNextRecord() calls, as well as during the building of the
  118. // fake data
  119. std::vector< std::vector<std::string> > cur_name;
  120. // This boolean is used to make sure find() calls resetSearch
  121. // when it encounters an error
  122. bool search_running_;
  123. // We store the name passed to searchForRecords, so we can
  124. // hardcode some exceptions into getNextRecord
  125. std::string searched_name_;
  126. const std::string database_name_;
  127. const RECORDS& getRecords(int zone_id) const {
  128. if (zone_id == READONLY_ZONE_ID) {
  129. return (readonly_records);
  130. } else if (zone_id == WRITABLE_ZONE_ID) {
  131. return (update_records);
  132. }
  133. return (empty_records);
  134. }
  135. // Adds one record to the current name in the database
  136. // The actual data will not be added to 'records' until
  137. // addCurName() is called
  138. void addRecord(const std::string& name,
  139. const std::string& type,
  140. const std::string& sigtype,
  141. const std::string& rdata) {
  142. std::vector<std::string> columns;
  143. columns.push_back(name);
  144. columns.push_back(type);
  145. columns.push_back(sigtype);
  146. columns.push_back(rdata);
  147. cur_name.push_back(columns);
  148. }
  149. // Adds all records we just built with calls to addRecords
  150. // to the actual fake database. This will clear cur_name,
  151. // so we can immediately start adding new records.
  152. void addCurName(const std::string& name) {
  153. ASSERT_EQ(0, readonly_records.count(name));
  154. readonly_records[name] = cur_name;
  155. cur_name.clear();
  156. }
  157. // Fills the database with zone data.
  158. // This method constructs a number of resource records (with addRecord),
  159. // which will all be added for one domain name to the fake database
  160. // (with addCurName). So for instance the first set of calls create
  161. // data for the name 'www.example.org', which will consist of one A RRset
  162. // of one record, and one AAAA RRset of two records.
  163. // The order in which they are added is the order in which getNextRecord()
  164. // will return them (so we can test whether find() etc. support data that
  165. // might not come in 'normal' order)
  166. // It shall immediately fail if you try to add the same name twice.
  167. void fillData() {
  168. // some plain data
  169. addRecord("A", "3600", "", "192.0.2.1");
  170. addRecord("AAAA", "3600", "", "2001:db8::1");
  171. addRecord("AAAA", "3600", "", "2001:db8::2");
  172. addCurName("www.example.org.");
  173. addRecord("A", "3600", "", "192.0.2.1");
  174. addRecord("AAAA", "3600", "", "2001:db8::1");
  175. addRecord("A", "3600", "", "192.0.2.2");
  176. addCurName("www2.example.org.");
  177. addRecord("CNAME", "3600", "", "www.example.org.");
  178. addCurName("cname.example.org.");
  179. // some DNSSEC-'signed' data
  180. addRecord("A", "3600", "", "192.0.2.1");
  181. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  182. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12346 example.org. FAKEFAKEFAKE");
  183. addRecord("AAAA", "3600", "", "2001:db8::1");
  184. addRecord("AAAA", "3600", "", "2001:db8::2");
  185. addRecord("RRSIG", "3600", "", "AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  186. addCurName("signed1.example.org.");
  187. addRecord("CNAME", "3600", "", "www.example.org.");
  188. addRecord("RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  189. addCurName("signedcname1.example.org.");
  190. // special case might fail; sig is for cname, which isn't there (should be ignored)
  191. // (ignoring of 'normal' other type is done above by www.)
  192. addRecord("A", "3600", "", "192.0.2.1");
  193. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  194. addRecord("RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  195. addCurName("acnamesig1.example.org.");
  196. // let's pretend we have a database that is not careful
  197. // about the order in which it returns data
  198. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  199. addRecord("AAAA", "3600", "", "2001:db8::2");
  200. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12346 example.org. FAKEFAKEFAKE");
  201. addRecord("A", "3600", "", "192.0.2.1");
  202. addRecord("RRSIG", "3600", "", "AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  203. addRecord("AAAA", "3600", "", "2001:db8::1");
  204. addCurName("signed2.example.org.");
  205. addRecord("RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  206. addRecord("CNAME", "3600", "", "www.example.org.");
  207. addCurName("signedcname2.example.org.");
  208. addRecord("RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  209. addRecord("A", "3600", "", "192.0.2.1");
  210. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  211. addCurName("acnamesig2.example.org.");
  212. addRecord("RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  213. addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  214. addRecord("A", "3600", "", "192.0.2.1");
  215. addCurName("acnamesig3.example.org.");
  216. addRecord("A", "3600", "", "192.0.2.1");
  217. addRecord("A", "360", "", "192.0.2.2");
  218. addCurName("ttldiff1.example.org.");
  219. addRecord("A", "360", "", "192.0.2.1");
  220. addRecord("A", "3600", "", "192.0.2.2");
  221. addCurName("ttldiff2.example.org.");
  222. // also add some intentionally bad data
  223. addRecord("A", "3600", "", "192.0.2.1");
  224. addRecord("CNAME", "3600", "", "www.example.org.");
  225. addCurName("badcname1.example.org.");
  226. addRecord("CNAME", "3600", "", "www.example.org.");
  227. addRecord("A", "3600", "", "192.0.2.1");
  228. addCurName("badcname2.example.org.");
  229. addRecord("CNAME", "3600", "", "www.example.org.");
  230. addRecord("CNAME", "3600", "", "www.example2.org.");
  231. addCurName("badcname3.example.org.");
  232. addRecord("A", "3600", "", "bad");
  233. addCurName("badrdata.example.org.");
  234. addRecord("BAD_TYPE", "3600", "", "192.0.2.1");
  235. addCurName("badtype.example.org.");
  236. addRecord("A", "badttl", "", "192.0.2.1");
  237. addCurName("badttl.example.org.");
  238. addRecord("A", "badttl", "", "192.0.2.1");
  239. addRecord("RRSIG", "3600", "", "A 5 3 3600 somebaddata 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  240. addCurName("badsig.example.org.");
  241. addRecord("A", "3600", "", "192.0.2.1");
  242. addRecord("RRSIG", "3600", "TXT", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  243. addCurName("badsigtype.example.org.");
  244. }
  245. virtual pair<bool, int> startUpdateZone(const std::string& zone_name,
  246. bool replace)
  247. {
  248. const pair<bool, int> zone_info = getZone(zone_name);
  249. if (!zone_info.first) {
  250. return (pair<bool, int>(false, 0));
  251. }
  252. // Prepare the record set for update. If replacing the existing one,
  253. // we use an empty set; otherwise we use a writable copy of the
  254. // original.
  255. if (replace) {
  256. update_records.clear();
  257. } else {
  258. update_records = readonly_records;
  259. }
  260. return (pair<bool, int>(true, WRITABLE_ZONE_ID));
  261. }
  262. virtual void commitUpdateZone() {}
  263. virtual void rollbackUpdateZone() {}
  264. virtual void addRecordToZone(const vector<string>&) {}
  265. virtual void deleteRecordInZone(const vector<string>&) {}
  266. };
  267. class DatabaseClientTest : public ::testing::Test {
  268. protected:
  269. DatabaseClientTest() {
  270. createClient();
  271. }
  272. /*
  273. * We initialize the client from a function, so we can call it multiple
  274. * times per test.
  275. */
  276. void createClient() {
  277. current_accessor_ = new MockAccessor();
  278. client_.reset(new DatabaseClient(shared_ptr<DatabaseAccessor>(
  279. current_accessor_)));
  280. }
  281. // Will be deleted by client_, just keep the current value for comparison.
  282. MockAccessor* current_accessor_;
  283. shared_ptr<DatabaseClient> client_;
  284. const std::string database_name_;
  285. const std::vector<std::string> empty_rdatas; // for NXRRSET/NXDOMAIN
  286. std::vector<std::string> expected_rdatas;
  287. std::vector<std::string> expected_sig_rdatas;
  288. /**
  289. * Check the zone finder is a valid one and references the zone ID and
  290. * database available here.
  291. */
  292. void checkZoneFinder(const DataSourceClient::FindResult& zone) {
  293. ASSERT_NE(ZoneFinderPtr(), zone.zone_finder) << "No zone finder";
  294. shared_ptr<DatabaseClient::Finder> finder(
  295. dynamic_pointer_cast<DatabaseClient::Finder>(zone.zone_finder));
  296. ASSERT_NE(shared_ptr<DatabaseClient::Finder>(), finder) <<
  297. "Wrong type of finder";
  298. EXPECT_EQ(READONLY_ZONE_ID, finder->zone_id());
  299. EXPECT_EQ(current_accessor_, &finder->getAccessor());
  300. }
  301. };
  302. TEST_F(DatabaseClientTest, zoneNotFound) {
  303. DataSourceClient::FindResult zone(client_->findZone(Name("example.com")));
  304. EXPECT_EQ(result::NOTFOUND, zone.code);
  305. }
  306. TEST_F(DatabaseClientTest, exactZone) {
  307. DataSourceClient::FindResult zone(client_->findZone(Name("example.org")));
  308. EXPECT_EQ(result::SUCCESS, zone.code);
  309. checkZoneFinder(zone);
  310. }
  311. TEST_F(DatabaseClientTest, superZone) {
  312. DataSourceClient::FindResult zone(client_->findZone(Name(
  313. "sub.example.org")));
  314. EXPECT_EQ(result::PARTIALMATCH, zone.code);
  315. checkZoneFinder(zone);
  316. }
  317. TEST_F(DatabaseClientTest, noAccessorException) {
  318. // We need a dummy variable here; some compiler would regard it a mere
  319. // declaration instead of an instantiation and make the test fail.
  320. EXPECT_THROW(DatabaseClient dummy((shared_ptr<DatabaseAccessor>())),
  321. isc::InvalidParameter);
  322. }
  323. TEST_F(DatabaseClientTest, startUpdate) {
  324. // startUpdate will succeed only when there's an exact match zone.
  325. EXPECT_EQ(ZoneUpdaterPtr(),
  326. client_->startUpdateZone(Name("example.com"), false));
  327. EXPECT_NE(ZoneUpdaterPtr(),
  328. client_->startUpdateZone(Name("example.org"), false));
  329. EXPECT_EQ(ZoneUpdaterPtr(),
  330. client_->startUpdateZone(Name("sub.example.org"), false));
  331. }
  332. namespace {
  333. // checks if the given rrset matches the
  334. // given name, class, type and rdatas
  335. void
  336. checkRRset(isc::dns::ConstRRsetPtr rrset,
  337. const isc::dns::Name& name,
  338. const isc::dns::RRClass& rrclass,
  339. const isc::dns::RRType& rrtype,
  340. const isc::dns::RRTTL& rrttl,
  341. const std::vector<std::string>& rdatas) {
  342. isc::dns::RRsetPtr expected_rrset(
  343. new isc::dns::RRset(name, rrclass, rrtype, rrttl));
  344. for (unsigned int i = 0; i < rdatas.size(); ++i) {
  345. expected_rrset->addRdata(
  346. isc::dns::rdata::createRdata(rrtype, rrclass,
  347. rdatas[i]));
  348. }
  349. isc::testutils::rrsetCheck(expected_rrset, rrset);
  350. }
  351. void
  352. doFindTest(ZoneFinder& finder,
  353. const isc::dns::Name& name,
  354. const isc::dns::RRType& type,
  355. const isc::dns::RRType& expected_type,
  356. const isc::dns::RRTTL expected_ttl,
  357. ZoneFinder::Result expected_result,
  358. const std::vector<std::string>& expected_rdatas,
  359. const std::vector<std::string>& expected_sig_rdatas)
  360. {
  361. ZoneFinder::FindResult result =
  362. finder.find(name, type, NULL, ZoneFinder::FIND_DEFAULT);
  363. ASSERT_EQ(expected_result, result.code) << name << " " << type;
  364. if (expected_rdatas.size() > 0) {
  365. checkRRset(result.rrset, name, finder.getClass(),
  366. expected_type, expected_ttl, expected_rdatas);
  367. if (expected_sig_rdatas.size() > 0) {
  368. checkRRset(result.rrset->getRRsig(), name,
  369. finder.getClass(), isc::dns::RRType::RRSIG(),
  370. expected_ttl, expected_sig_rdatas);
  371. } else {
  372. EXPECT_EQ(isc::dns::RRsetPtr(), result.rrset->getRRsig());
  373. }
  374. } else {
  375. EXPECT_EQ(isc::dns::RRsetPtr(), result.rrset);
  376. }
  377. }
  378. } // end anonymous namespace
  379. TEST_F(DatabaseClientTest, find) {
  380. DataSourceClient::FindResult zone(client_->findZone(Name("example.org")));
  381. ASSERT_EQ(result::SUCCESS, zone.code);
  382. shared_ptr<DatabaseClient::Finder> finder(
  383. dynamic_pointer_cast<DatabaseClient::Finder>(zone.zone_finder));
  384. EXPECT_EQ(READONLY_ZONE_ID, finder->zone_id());
  385. EXPECT_FALSE(current_accessor_->searchRunning());
  386. expected_rdatas.clear();
  387. expected_sig_rdatas.clear();
  388. expected_rdatas.push_back("192.0.2.1");
  389. doFindTest(*finder, isc::dns::Name("www.example.org."),
  390. isc::dns::RRType::A(), isc::dns::RRType::A(),
  391. isc::dns::RRTTL(3600),
  392. ZoneFinder::SUCCESS,
  393. expected_rdatas, expected_sig_rdatas);
  394. EXPECT_FALSE(current_accessor_->searchRunning());
  395. expected_rdatas.clear();
  396. expected_sig_rdatas.clear();
  397. expected_rdatas.push_back("192.0.2.1");
  398. expected_rdatas.push_back("192.0.2.2");
  399. doFindTest(*finder, isc::dns::Name("www2.example.org."),
  400. isc::dns::RRType::A(), isc::dns::RRType::A(),
  401. isc::dns::RRTTL(3600),
  402. ZoneFinder::SUCCESS,
  403. expected_rdatas, expected_sig_rdatas);
  404. EXPECT_FALSE(current_accessor_->searchRunning());
  405. expected_rdatas.clear();
  406. expected_sig_rdatas.clear();
  407. expected_rdatas.push_back("2001:db8::1");
  408. expected_rdatas.push_back("2001:db8::2");
  409. doFindTest(*finder, isc::dns::Name("www.example.org."),
  410. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  411. isc::dns::RRTTL(3600),
  412. ZoneFinder::SUCCESS,
  413. expected_rdatas, expected_sig_rdatas);
  414. EXPECT_FALSE(current_accessor_->searchRunning());
  415. expected_rdatas.clear();
  416. expected_sig_rdatas.clear();
  417. doFindTest(*finder, isc::dns::Name("www.example.org."),
  418. isc::dns::RRType::TXT(), isc::dns::RRType::TXT(),
  419. isc::dns::RRTTL(3600),
  420. ZoneFinder::NXRRSET,
  421. expected_rdatas, expected_sig_rdatas);
  422. EXPECT_FALSE(current_accessor_->searchRunning());
  423. expected_rdatas.clear();
  424. expected_sig_rdatas.clear();
  425. expected_rdatas.push_back("www.example.org.");
  426. doFindTest(*finder, isc::dns::Name("cname.example.org."),
  427. isc::dns::RRType::A(), isc::dns::RRType::CNAME(),
  428. isc::dns::RRTTL(3600),
  429. ZoneFinder::CNAME,
  430. expected_rdatas, expected_sig_rdatas);
  431. EXPECT_FALSE(current_accessor_->searchRunning());
  432. expected_rdatas.clear();
  433. expected_sig_rdatas.clear();
  434. expected_rdatas.push_back("www.example.org.");
  435. doFindTest(*finder, isc::dns::Name("cname.example.org."),
  436. isc::dns::RRType::CNAME(), isc::dns::RRType::CNAME(),
  437. isc::dns::RRTTL(3600),
  438. ZoneFinder::SUCCESS,
  439. expected_rdatas, expected_sig_rdatas);
  440. EXPECT_FALSE(current_accessor_->searchRunning());
  441. expected_rdatas.clear();
  442. expected_sig_rdatas.clear();
  443. doFindTest(*finder, isc::dns::Name("doesnotexist.example.org."),
  444. isc::dns::RRType::A(), isc::dns::RRType::A(),
  445. isc::dns::RRTTL(3600),
  446. ZoneFinder::NXDOMAIN,
  447. expected_rdatas, expected_sig_rdatas);
  448. EXPECT_FALSE(current_accessor_->searchRunning());
  449. expected_rdatas.clear();
  450. expected_sig_rdatas.clear();
  451. expected_rdatas.push_back("192.0.2.1");
  452. expected_sig_rdatas.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  453. expected_sig_rdatas.push_back("A 5 3 3600 20000101000000 20000201000000 12346 example.org. FAKEFAKEFAKE");
  454. doFindTest(*finder, isc::dns::Name("signed1.example.org."),
  455. isc::dns::RRType::A(), isc::dns::RRType::A(),
  456. isc::dns::RRTTL(3600),
  457. ZoneFinder::SUCCESS,
  458. expected_rdatas, expected_sig_rdatas);
  459. EXPECT_FALSE(current_accessor_->searchRunning());
  460. expected_rdatas.clear();
  461. expected_sig_rdatas.clear();
  462. expected_rdatas.push_back("2001:db8::1");
  463. expected_rdatas.push_back("2001:db8::2");
  464. expected_sig_rdatas.push_back("AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  465. doFindTest(*finder, isc::dns::Name("signed1.example.org."),
  466. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  467. isc::dns::RRTTL(3600),
  468. ZoneFinder::SUCCESS,
  469. expected_rdatas, expected_sig_rdatas);
  470. EXPECT_FALSE(current_accessor_->searchRunning());
  471. expected_rdatas.clear();
  472. expected_sig_rdatas.clear();
  473. doFindTest(*finder, isc::dns::Name("signed1.example.org."),
  474. isc::dns::RRType::TXT(), isc::dns::RRType::TXT(),
  475. isc::dns::RRTTL(3600),
  476. ZoneFinder::NXRRSET,
  477. expected_rdatas, expected_sig_rdatas);
  478. EXPECT_FALSE(current_accessor_->searchRunning());
  479. expected_rdatas.clear();
  480. expected_sig_rdatas.clear();
  481. expected_rdatas.push_back("www.example.org.");
  482. expected_sig_rdatas.push_back("CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  483. doFindTest(*finder, isc::dns::Name("signedcname1.example.org."),
  484. isc::dns::RRType::A(), isc::dns::RRType::CNAME(),
  485. isc::dns::RRTTL(3600),
  486. ZoneFinder::CNAME,
  487. expected_rdatas, expected_sig_rdatas);
  488. EXPECT_FALSE(current_accessor_->searchRunning());
  489. expected_rdatas.clear();
  490. expected_sig_rdatas.clear();
  491. expected_rdatas.push_back("192.0.2.1");
  492. expected_sig_rdatas.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  493. expected_sig_rdatas.push_back("A 5 3 3600 20000101000000 20000201000000 12346 example.org. FAKEFAKEFAKE");
  494. doFindTest(*finder, isc::dns::Name("signed2.example.org."),
  495. isc::dns::RRType::A(), isc::dns::RRType::A(),
  496. isc::dns::RRTTL(3600),
  497. ZoneFinder::SUCCESS,
  498. expected_rdatas, expected_sig_rdatas);
  499. EXPECT_FALSE(current_accessor_->searchRunning());
  500. expected_rdatas.clear();
  501. expected_sig_rdatas.clear();
  502. expected_rdatas.push_back("2001:db8::2");
  503. expected_rdatas.push_back("2001:db8::1");
  504. expected_sig_rdatas.push_back("AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  505. doFindTest(*finder, isc::dns::Name("signed2.example.org."),
  506. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  507. isc::dns::RRTTL(3600),
  508. ZoneFinder::SUCCESS,
  509. expected_rdatas, expected_sig_rdatas);
  510. EXPECT_FALSE(current_accessor_->searchRunning());
  511. expected_rdatas.clear();
  512. expected_sig_rdatas.clear();
  513. doFindTest(*finder, isc::dns::Name("signed2.example.org."),
  514. isc::dns::RRType::TXT(), isc::dns::RRType::TXT(),
  515. isc::dns::RRTTL(3600),
  516. ZoneFinder::NXRRSET,
  517. expected_rdatas, expected_sig_rdatas);
  518. EXPECT_FALSE(current_accessor_->searchRunning());
  519. expected_rdatas.clear();
  520. expected_sig_rdatas.clear();
  521. expected_rdatas.push_back("www.example.org.");
  522. expected_sig_rdatas.push_back("CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  523. doFindTest(*finder, isc::dns::Name("signedcname2.example.org."),
  524. isc::dns::RRType::A(), isc::dns::RRType::CNAME(),
  525. isc::dns::RRTTL(3600),
  526. ZoneFinder::CNAME,
  527. expected_rdatas, expected_sig_rdatas);
  528. EXPECT_FALSE(current_accessor_->searchRunning());
  529. expected_rdatas.clear();
  530. expected_sig_rdatas.clear();
  531. expected_rdatas.push_back("192.0.2.1");
  532. expected_sig_rdatas.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  533. doFindTest(*finder, isc::dns::Name("acnamesig1.example.org."),
  534. isc::dns::RRType::A(), isc::dns::RRType::A(),
  535. isc::dns::RRTTL(3600),
  536. ZoneFinder::SUCCESS,
  537. expected_rdatas, expected_sig_rdatas);
  538. EXPECT_FALSE(current_accessor_->searchRunning());
  539. expected_rdatas.clear();
  540. expected_sig_rdatas.clear();
  541. expected_rdatas.push_back("192.0.2.1");
  542. expected_sig_rdatas.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  543. doFindTest(*finder, isc::dns::Name("acnamesig2.example.org."),
  544. isc::dns::RRType::A(), isc::dns::RRType::A(),
  545. isc::dns::RRTTL(3600),
  546. ZoneFinder::SUCCESS,
  547. expected_rdatas, expected_sig_rdatas);
  548. EXPECT_FALSE(current_accessor_->searchRunning());
  549. expected_rdatas.clear();
  550. expected_sig_rdatas.clear();
  551. expected_rdatas.push_back("192.0.2.1");
  552. expected_sig_rdatas.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  553. doFindTest(*finder, isc::dns::Name("acnamesig3.example.org."),
  554. isc::dns::RRType::A(), isc::dns::RRType::A(),
  555. isc::dns::RRTTL(3600),
  556. ZoneFinder::SUCCESS,
  557. expected_rdatas, expected_sig_rdatas);
  558. EXPECT_FALSE(current_accessor_->searchRunning());
  559. expected_rdatas.clear();
  560. expected_sig_rdatas.clear();
  561. expected_rdatas.push_back("192.0.2.1");
  562. expected_rdatas.push_back("192.0.2.2");
  563. doFindTest(*finder, isc::dns::Name("ttldiff1.example.org."),
  564. isc::dns::RRType::A(), isc::dns::RRType::A(),
  565. isc::dns::RRTTL(360),
  566. ZoneFinder::SUCCESS,
  567. expected_rdatas, expected_sig_rdatas);
  568. EXPECT_FALSE(current_accessor_->searchRunning());
  569. expected_rdatas.clear();
  570. expected_sig_rdatas.clear();
  571. expected_rdatas.push_back("192.0.2.1");
  572. expected_rdatas.push_back("192.0.2.2");
  573. doFindTest(*finder, isc::dns::Name("ttldiff2.example.org."),
  574. isc::dns::RRType::A(), isc::dns::RRType::A(),
  575. isc::dns::RRTTL(360),
  576. ZoneFinder::SUCCESS,
  577. expected_rdatas, expected_sig_rdatas);
  578. EXPECT_FALSE(current_accessor_->searchRunning());
  579. EXPECT_THROW(finder->find(isc::dns::Name("badcname1.example.org."),
  580. isc::dns::RRType::A(),
  581. NULL, ZoneFinder::FIND_DEFAULT),
  582. DataSourceError);
  583. EXPECT_FALSE(current_accessor_->searchRunning());
  584. EXPECT_THROW(finder->find(isc::dns::Name("badcname2.example.org."),
  585. isc::dns::RRType::A(),
  586. NULL, ZoneFinder::FIND_DEFAULT),
  587. DataSourceError);
  588. EXPECT_FALSE(current_accessor_->searchRunning());
  589. EXPECT_THROW(finder->find(isc::dns::Name("badcname3.example.org."),
  590. isc::dns::RRType::A(),
  591. NULL, ZoneFinder::FIND_DEFAULT),
  592. DataSourceError);
  593. EXPECT_FALSE(current_accessor_->searchRunning());
  594. EXPECT_THROW(finder->find(isc::dns::Name("badrdata.example.org."),
  595. isc::dns::RRType::A(),
  596. NULL, ZoneFinder::FIND_DEFAULT),
  597. DataSourceError);
  598. EXPECT_FALSE(current_accessor_->searchRunning());
  599. EXPECT_THROW(finder->find(isc::dns::Name("badtype.example.org."),
  600. isc::dns::RRType::A(),
  601. NULL, ZoneFinder::FIND_DEFAULT),
  602. DataSourceError);
  603. EXPECT_FALSE(current_accessor_->searchRunning());
  604. EXPECT_THROW(finder->find(isc::dns::Name("badttl.example.org."),
  605. isc::dns::RRType::A(),
  606. NULL, ZoneFinder::FIND_DEFAULT),
  607. DataSourceError);
  608. EXPECT_FALSE(current_accessor_->searchRunning());
  609. EXPECT_THROW(finder->find(isc::dns::Name("badsig.example.org."),
  610. isc::dns::RRType::A(),
  611. NULL, ZoneFinder::FIND_DEFAULT),
  612. DataSourceError);
  613. EXPECT_FALSE(current_accessor_->searchRunning());
  614. // Trigger the hardcoded exceptions and see if find() has cleaned up
  615. EXPECT_THROW(finder->find(isc::dns::Name("dsexception.in.search."),
  616. isc::dns::RRType::A(),
  617. NULL, ZoneFinder::FIND_DEFAULT),
  618. DataSourceError);
  619. EXPECT_FALSE(current_accessor_->searchRunning());
  620. EXPECT_THROW(finder->find(isc::dns::Name("iscexception.in.search."),
  621. isc::dns::RRType::A(),
  622. NULL, ZoneFinder::FIND_DEFAULT),
  623. DataSourceError);
  624. EXPECT_FALSE(current_accessor_->searchRunning());
  625. EXPECT_THROW(finder->find(isc::dns::Name("basicexception.in.search."),
  626. isc::dns::RRType::A(),
  627. NULL, ZoneFinder::FIND_DEFAULT),
  628. std::exception);
  629. EXPECT_FALSE(current_accessor_->searchRunning());
  630. EXPECT_THROW(finder->find(isc::dns::Name("dsexception.in.getnext."),
  631. isc::dns::RRType::A(),
  632. NULL, ZoneFinder::FIND_DEFAULT),
  633. DataSourceError);
  634. EXPECT_FALSE(current_accessor_->searchRunning());
  635. EXPECT_THROW(finder->find(isc::dns::Name("iscexception.in.getnext."),
  636. isc::dns::RRType::A(),
  637. NULL, ZoneFinder::FIND_DEFAULT),
  638. DataSourceError);
  639. EXPECT_FALSE(current_accessor_->searchRunning());
  640. EXPECT_THROW(finder->find(isc::dns::Name("basicexception.in.getnext."),
  641. isc::dns::RRType::A(),
  642. NULL, ZoneFinder::FIND_DEFAULT),
  643. std::exception);
  644. EXPECT_FALSE(current_accessor_->searchRunning());
  645. // This RRSIG has the wrong sigtype field, which should be
  646. // an error if we decide to keep using that field
  647. // Right now the field is ignored, so it does not error
  648. expected_rdatas.clear();
  649. expected_sig_rdatas.clear();
  650. expected_rdatas.push_back("192.0.2.1");
  651. expected_sig_rdatas.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  652. doFindTest(*finder, isc::dns::Name("badsigtype.example.org."),
  653. isc::dns::RRType::A(), isc::dns::RRType::A(),
  654. isc::dns::RRTTL(3600),
  655. ZoneFinder::SUCCESS,
  656. expected_rdatas, expected_sig_rdatas);
  657. EXPECT_FALSE(current_accessor_->searchRunning());
  658. }
  659. TEST_F(DatabaseClientTest, updaterFinder) {
  660. ZoneUpdaterPtr updater = client_->startUpdateZone(Name("example.org"),
  661. false);
  662. ASSERT_TRUE(updater);
  663. // If this update isn't replacing the zone, the finder should work
  664. // just like the normal find() case.
  665. EXPECT_EQ(WRITABLE_ZONE_ID, dynamic_cast<DatabaseClient::Finder&>(
  666. updater->getFinder()).zone_id());
  667. expected_rdatas.clear();
  668. expected_rdatas.push_back("192.0.2.1");
  669. doFindTest(updater->getFinder(), Name("www.example.org."),
  670. RRType::A(), RRType::A(), RRTTL(3600), ZoneFinder::SUCCESS,
  671. expected_rdatas, empty_rdatas);
  672. // When replacing the zone, the updater's finder shouldn't see anything
  673. // in the zone until something is added.
  674. updater = client_->startUpdateZone(Name("example.org"), true);
  675. ASSERT_TRUE(updater);
  676. EXPECT_EQ(WRITABLE_ZONE_ID, dynamic_cast<DatabaseClient::Finder&>(
  677. updater->getFinder()).zone_id());
  678. doFindTest(updater->getFinder(), Name("www.example.org."),
  679. RRType::A(), RRType::A(), RRTTL(3600), ZoneFinder::NXDOMAIN,
  680. empty_rdatas, empty_rdatas);
  681. }
  682. }