sqlite3_accessor_unittest.cc 64 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577
  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 "faked_nsec3.h"
  15. #include <datasrc/sqlite3_accessor.h>
  16. #include <datasrc/data_source.h>
  17. #include <dns/rrclass.h>
  18. #include <sqlite3.h>
  19. #include <gtest/gtest.h>
  20. #include <boost/lexical_cast.hpp>
  21. #include <boost/scoped_ptr.hpp>
  22. #include <algorithm>
  23. #include <vector>
  24. #include <fstream>
  25. using namespace std;
  26. using namespace isc::datasrc;
  27. using namespace isc::datasrc::test;
  28. using boost::lexical_cast;
  29. using isc::data::ConstElementPtr;
  30. using isc::data::Element;
  31. using isc::dns::RRClass;
  32. using isc::dns::Name;
  33. namespace {
  34. // Some test data
  35. const char* const SQLITE_DBFILE_EXAMPLE = TEST_DATA_DIR "/test.sqlite3";
  36. const char* const SQLITE_DBFILE_EXAMPLE2 =
  37. TEST_DATA_DIR "/example2.com.sqlite3";
  38. const char* const SQLITE_DBNAME_EXAMPLE2 = "sqlite3_example2.com.sqlite3";
  39. const char* const SQLITE_DBFILE_EXAMPLE_ROOT =
  40. TEST_DATA_DIR "/test-root.sqlite3";
  41. const char* const SQLITE_DBNAME_EXAMPLE_ROOT = "sqlite3_test-root.sqlite3";
  42. const char* const SQLITE_DBFILE_BROKENDB = TEST_DATA_DIR "/brokendb.sqlite3";
  43. const char* const SQLITE_DBFILE_MEMORY = ":memory:";
  44. const char* const SQLITE_DBFILE_EXAMPLE_ORG =
  45. TEST_DATA_DIR "/example.org.sqlite3";
  46. const char* const SQLITE_DBFILE_DIFFS = TEST_DATA_DIR "/diffs.sqlite3";
  47. const char* const SQLITE_DBFILE_NEWSCHEMA = TEST_DATA_DIR "/newschema.sqlite3";
  48. const char* const SQLITE_DBFILE_OLDSCHEMA = TEST_DATA_DIR "/oldschema.sqlite3";
  49. const char* const SQLITE_DBFILE_NEW_MINOR_SCHEMA =
  50. TEST_DATA_DIR "/new_minor_schema.sqlite3";
  51. // The following file must be non existent and must be non"creatable";
  52. // the sqlite3 library will try to create a new DB file if it doesn't exist,
  53. // so to test a failure case the create operation should also fail.
  54. // The "nodir", a non existent directory, is inserted for this purpose.
  55. std::string SQLITE_DBFILE_NOTEXIST = TEST_DATA_DIR "/nodir/notexist";
  56. // new db file, we don't need this to be a std::string, and given the
  57. // raw calls we use it in a const char* is more convenient
  58. const char* SQLITE_NEW_DBFILE = TEST_DATA_BUILDDIR "/newdb.sqlite3";
  59. // Opening works (the content is tested in different tests)
  60. TEST(SQLite3Open, common) {
  61. EXPECT_NO_THROW(SQLite3Accessor accessor(SQLITE_DBFILE_EXAMPLE, "IN"));
  62. }
  63. // The file can't be opened
  64. TEST(SQLite3Open, notExist) {
  65. EXPECT_THROW(SQLite3Accessor accessor(SQLITE_DBFILE_NOTEXIST, "IN"),
  66. SQLite3Error);
  67. }
  68. // It rejects broken DB
  69. TEST(SQLite3Open, brokenDB) {
  70. EXPECT_THROW(SQLite3Accessor accessor(SQLITE_DBFILE_BROKENDB, "IN"),
  71. SQLite3Error);
  72. }
  73. // Different schema versions
  74. TEST(SQLite3Open, differentSchemaVersions) {
  75. // If the major version is different from the current one, it should fail.
  76. EXPECT_THROW(SQLite3Accessor(SQLITE_DBFILE_NEWSCHEMA, "IN"),
  77. IncompatibleDbVersion);
  78. EXPECT_THROW(SQLite3Accessor(SQLITE_DBFILE_OLDSCHEMA, "IN"),
  79. IncompatibleDbVersion);
  80. // Difference in the minor version is okay (as of this test written
  81. // the current minor version is 0, so we can only test the case with a
  82. // higher minor version).
  83. EXPECT_NO_THROW(SQLite3Accessor(SQLITE_DBFILE_NEW_MINOR_SCHEMA, "IN"));
  84. }
  85. // Test we can create the schema on the fly
  86. TEST(SQLite3Open, memoryDB) {
  87. EXPECT_NO_THROW(SQLite3Accessor accessor(SQLITE_DBFILE_MEMORY, "IN"));
  88. }
  89. // Test fixture for querying the db
  90. class SQLite3AccessorTest : public ::testing::Test {
  91. public:
  92. SQLite3AccessorTest() {
  93. initAccessor(SQLITE_DBFILE_EXAMPLE, "IN");
  94. }
  95. // So it can be re-created with different data
  96. void initAccessor(const std::string& filename, const string& rrclass) {
  97. accessor.reset(new SQLite3Accessor(filename, rrclass));
  98. }
  99. // The tested accessor
  100. boost::shared_ptr<SQLite3Accessor> accessor;
  101. };
  102. // This zone exists in the data, so it should be found
  103. TEST_F(SQLite3AccessorTest, getZone) {
  104. std::pair<bool, int> result(accessor->getZone("example.com."));
  105. EXPECT_TRUE(result.first);
  106. EXPECT_EQ(1, result.second);
  107. }
  108. // But it should find only the zone, nothing below it
  109. TEST_F(SQLite3AccessorTest, subZone) {
  110. EXPECT_FALSE(accessor->getZone("sub.example.com.").first);
  111. }
  112. // This zone is not there at all
  113. TEST_F(SQLite3AccessorTest, noZone) {
  114. EXPECT_FALSE(accessor->getZone("example.org.").first);
  115. }
  116. // This zone is there, but in different class
  117. TEST_F(SQLite3AccessorTest, noClass) {
  118. initAccessor(SQLITE_DBFILE_EXAMPLE, "CH");
  119. EXPECT_FALSE(accessor->getZone("example.com.").first);
  120. }
  121. // Simple check to test that the sequence is valid. It gets the next record
  122. // from the iterator, checks that it is not null, then checks the data.
  123. void checkRR(DatabaseAccessor::IteratorContextPtr& context,
  124. std::string name, std::string ttl, std::string type, std::string rdata) {
  125. // Mark where we are in the text
  126. SCOPED_TRACE(name + " " + ttl + " " + type + " " + rdata);
  127. std::string data[DatabaseAccessor::COLUMN_COUNT];
  128. // Get next record
  129. EXPECT_TRUE(context->getNext(data));
  130. // ... and check expected values
  131. EXPECT_EQ(name, data[DatabaseAccessor::NAME_COLUMN]);
  132. EXPECT_EQ(ttl, data[DatabaseAccessor::TTL_COLUMN]);
  133. EXPECT_EQ(type, data[DatabaseAccessor::TYPE_COLUMN]);
  134. EXPECT_EQ(rdata, data[DatabaseAccessor::RDATA_COLUMN]);
  135. }
  136. // This tests the iterator context
  137. TEST_F(SQLite3AccessorTest, iterator) {
  138. // Our test zone is conveniently small, but not empty
  139. initAccessor(SQLITE_DBFILE_EXAMPLE_ORG, "IN");
  140. const std::pair<bool, int> zone_info(accessor->getZone("example.org."));
  141. ASSERT_TRUE(zone_info.first);
  142. // Get the iterator context
  143. DatabaseAccessor::IteratorContextPtr
  144. context(accessor->getAllRecords(zone_info.second));
  145. ASSERT_NE(DatabaseAccessor::IteratorContextPtr(), context);
  146. std::string data[DatabaseAccessor::COLUMN_COUNT];
  147. checkRR(context, "example.org.", "3600", "MX", "10 mail.example.org.");
  148. checkRR(context, "example.org.", "3600", "NS", "ns1.example.org.");
  149. checkRR(context, "example.org.", "3600", "NS", "ns2.example.org.");
  150. checkRR(context, "example.org.", "3600", "NS", "ns3.example.org.");
  151. checkRR(context, "example.org.", "3600", "SOA",
  152. "ns1.example.org. admin.example.org. 1234 3600 1800 2419200 7200");
  153. checkRR(context, "dname.example.org.", "3600", "DNAME",
  154. "dname.example.info.");
  155. checkRR(context, "dname2.foo.example.org.", "3600", "DNAME",
  156. "dname2.example.info.");
  157. checkRR(context, "mail.example.org.", "3600", "A", "192.0.2.10");
  158. checkRR(context, "sub.example.org.", "3600", "NS", "ns.sub.example.org.");
  159. checkRR(context, "ns.sub.example.org.", "3600", "A", "192.0.2.101");
  160. checkRR(context, "www.example.org.", "3600", "A", "192.0.2.1");
  161. checkRR(context, "ns3.example.org.", "3600", "NSEC3",
  162. "1 1 12 aabbccdd 2T7B4G4VSA5SMI47K61MV5BV1A22BOJR A RRSIG");
  163. checkRR(context, "ns3.example.org.", "3600", "RRSIG",
  164. "NSEC3 5 3 3600 20000101000000 20000201000000 "
  165. "12345 ns3.example.org. FAKEFAKEFAKE");
  166. // Check there's no other
  167. EXPECT_FALSE(context->getNext(data));
  168. // And make sure calling it again won't cause problems.
  169. EXPECT_FALSE(context->getNext(data));
  170. }
  171. // This tests the iterator through the whole zone returns NSEC3 records as
  172. // well. We test this specifically, as it lives in separate table and needs
  173. // extra handling.
  174. TEST_F(SQLite3AccessorTest, nsec3Iterator) {
  175. // Get the zone
  176. const std::pair<bool, int>
  177. zone_info(accessor->getZone("sql2.example.com."));
  178. ASSERT_TRUE(zone_info.first);
  179. // Iterate through it
  180. DatabaseAccessor::IteratorContextPtr
  181. context(accessor->getAllRecords(zone_info.second));
  182. // We just pick a random NSEC3 to check, the check of complete iterator
  183. // is in the above test. In addition, we count the number of NSEC3, RRSIG
  184. // and all records, as some kind of check it returns all the data.
  185. std::string data[DatabaseAccessor::COLUMN_COUNT];
  186. size_t nsec3count(0), rrsigcount(0), recordcount(0);
  187. bool nsec3match(false);
  188. while (context->getNext(data)) {
  189. if (data[DatabaseAccessor::TYPE_COLUMN] == "NSEC3") {
  190. nsec3count ++;
  191. if (data[DatabaseAccessor::NAME_COLUMN] ==
  192. "1BB7SO0452U1QHL98UISNDD9218GELR5.sql2.example.com.") {
  193. nsec3match = true;
  194. EXPECT_EQ("7200", data[DatabaseAccessor::TTL_COLUMN]);
  195. EXPECT_EQ("1 0 10 FEEDABEE 4KLSVDE8KH8G95VU68R7AHBE1CPQN38J",
  196. data[DatabaseAccessor::RDATA_COLUMN]);
  197. }
  198. } else if (data[DatabaseAccessor::TYPE_COLUMN] == "RRSIG") {
  199. rrsigcount ++;
  200. }
  201. recordcount ++;
  202. }
  203. // We counted everything now, so check there's nothing else to count
  204. EXPECT_EQ(11, nsec3count);
  205. EXPECT_EQ(22, rrsigcount);
  206. EXPECT_EQ(46, recordcount);
  207. EXPECT_TRUE(nsec3match) << "No NSEC3 found when iterating the zone";
  208. }
  209. // This tests getting NSEC3 records
  210. TEST_F(SQLite3AccessorTest, nsec3) {
  211. const std::pair<bool, int>
  212. zone_info(accessor->getZone("sql2.example.com."));
  213. ASSERT_TRUE(zone_info.first);
  214. DatabaseAccessor::IteratorContextPtr
  215. context(accessor->getNSEC3Records("1BB7SO0452U1QHL98UISNDD9218GELR5",
  216. zone_info.second));
  217. // This relies on specific ordering in the DB. Is it OK?
  218. // The name field is empty, as well as the sigtype one. This is OK, as
  219. // both are not needed and the interface allows it.
  220. checkRR(context, "", "7200", "NSEC3",
  221. "1 0 10 FEEDABEE 4KLSVDE8KH8G95VU68R7AHBE1CPQN38J");
  222. checkRR(context, "", "7200", "RRSIG",
  223. "NSEC3 5 4 7200 20100410172647 20100311172647 63192 "
  224. "sql2.example.com. gNIVj4T8t51fEU6kOPpvK7HOGBFZGbalN5ZK "
  225. "mInyrww6UWZsUNdw07ge6/U6HfG+/s61RZ/L is2M6yUWHyXbNbj/"
  226. "QqwqgadG5dhxTArfuR02 xP600x0fWX8LXzW4yLMdKVxGbzYT+vvGz71o "
  227. "8gHSY5vYTtothcZQa4BMKhmGQEk=");
  228. // And that's all
  229. std::string data[DatabaseAccessor::COLUMN_COUNT];
  230. EXPECT_FALSE(context->getNext(data));
  231. // Calling again won't hurt
  232. EXPECT_FALSE(context->getNext(data));
  233. // This one should be empty ‒ no data here
  234. context = accessor->getNSEC3Records("NO_SUCH_HASH", zone_info.second);
  235. EXPECT_FALSE(context->getNext(data));
  236. // Still nothing? ;-)
  237. EXPECT_FALSE(context->getNext(data));
  238. }
  239. // This tests getting a previoeus hash in the NSEC3 namespace of a zone,
  240. // including a wrap-around and asking for a hash that does not exist in the.
  241. // zone at all.
  242. TEST_F(SQLite3AccessorTest, nsec3Previous) {
  243. // Get the zone
  244. const std::pair<bool, int>
  245. zone_info(accessor->getZone("sql2.example.com."));
  246. ASSERT_TRUE(zone_info.first);
  247. std::string data[DatabaseAccessor::COLUMN_COUNT];
  248. // Test a previous hash for something that is in the zone
  249. // (ensuring it is really there)
  250. DatabaseAccessor::IteratorContextPtr
  251. context(accessor->getNSEC3Records("703OOGCKF8VEV1N7U64D1JG19URETN8N",
  252. zone_info.second));
  253. EXPECT_TRUE(context->getNext(data));
  254. EXPECT_EQ("56IEQ664LHDAKVPE2FL179MSM3QAOFVC", accessor->
  255. findPreviousNSEC3Hash(zone_info.second,
  256. "703OOGCKF8VEV1N7U64D1JG19URETN8N"));
  257. // Test a previous hash for something that is not in the
  258. // zone
  259. context = accessor->getNSEC3Records("702OOGCKF8VEV1N7U64D1JG19URETN8N",
  260. zone_info.second);
  261. EXPECT_FALSE(context->getNext(data));
  262. EXPECT_EQ("56IEQ664LHDAKVPE2FL179MSM3QAOFVC", accessor->
  263. findPreviousNSEC3Hash(zone_info.second,
  264. "702OOGCKF8VEV1N7U64D1JG19URETN8N"));
  265. // Search at the first item, should wrap around
  266. context = accessor->getNSEC3Records("1BB7SO0452U1QHL98UISNDD9218GELR5",
  267. zone_info.second);
  268. EXPECT_TRUE(context->getNext(data));
  269. EXPECT_EQ("RKBUCQT8T78GV6QBCGBHCHC019LG73SJ", accessor->
  270. findPreviousNSEC3Hash(zone_info.second,
  271. "1BB7SO0452U1QHL98UISNDD9218GELR5"));
  272. // Search before the first item, should wrap around
  273. context = accessor->getNSEC3Records("0BB7SO0452U1QHL98UISNDD9218GELR5",
  274. zone_info.second);
  275. EXPECT_FALSE(context->getNext(data));
  276. EXPECT_EQ("RKBUCQT8T78GV6QBCGBHCHC019LG73SJ", accessor->
  277. findPreviousNSEC3Hash(zone_info.second,
  278. "0BB7SO0452U1QHL98UISNDD9218GELR5"));
  279. // Search after the last item (should return the last one)
  280. context = accessor->getNSEC3Records("RRBUCQT8T78GV6QBCGBHCHC019LG73SJ",
  281. zone_info.second);
  282. EXPECT_FALSE(context->getNext(data));
  283. EXPECT_EQ("RKBUCQT8T78GV6QBCGBHCHC019LG73SJ", accessor->
  284. findPreviousNSEC3Hash(zone_info.second,
  285. "RRBUCQT8T78GV6QBCGBHCHC019LG73SJ"));
  286. }
  287. // Check it throws when we want a previous NSEC3 hash in an unsigned zone
  288. TEST_F(SQLite3AccessorTest, nsec3PreviousUnsigned) {
  289. // This zone did not look signed in the test file.
  290. const std::pair<bool, int>
  291. unsigned_zone_info(accessor->getZone("example.com."));
  292. EXPECT_THROW(accessor->
  293. findPreviousNSEC3Hash(unsigned_zone_info.second,
  294. "0BB7SO0452U1QHL98UISNDD9218GELR5"),
  295. DataSourceError);
  296. }
  297. // This tests the difference iterator context
  298. // Test that at attempt to create a difference iterator for a serial number
  299. // that does not exist throws an exception.
  300. TEST_F(SQLite3AccessorTest, diffIteratorNoRecords) {
  301. // Our test zone is conveniently small, but not empty
  302. initAccessor(SQLITE_DBFILE_DIFFS, "IN");
  303. const std::pair<bool, int> zone_info(accessor->getZone("example.org."));
  304. ASSERT_TRUE(zone_info.first);
  305. // Get the iterator context. Difference of version 1 does not exist, so
  306. // this should throw an exception.
  307. EXPECT_THROW(accessor->getDiffs(zone_info.second, 1, 1234),
  308. isc::datasrc::NoSuchSerial);
  309. // Check that an invalid high version number also throws an exception.
  310. EXPECT_THROW(accessor->getDiffs(zone_info.second, 1231, 2234),
  311. NoSuchSerial);
  312. // Check that valid versions - but for the wrong zone which does not hold
  313. // any records - also throws this exception.
  314. EXPECT_THROW(accessor->getDiffs(zone_info.second + 42, 1231, 1234),
  315. NoSuchSerial);
  316. }
  317. // Try to iterate through a valid sets of differences
  318. TEST_F(SQLite3AccessorTest, diffIteratorSequences) {
  319. std::string data[DatabaseAccessor::COLUMN_COUNT];
  320. // Our test zone is conveniently small, but not empty
  321. initAccessor(SQLITE_DBFILE_DIFFS, "IN");
  322. const std::pair<bool, int> zone_info(accessor->getZone("example.org."));
  323. ASSERT_TRUE(zone_info.first);
  324. // Check the difference sequence 1230-1231 (two adjacent differences)
  325. // Get the iterator context
  326. DatabaseAccessor::IteratorContextPtr
  327. context1(accessor->getDiffs(zone_info.second, 1230, 1231));
  328. ASSERT_NE(DatabaseAccessor::IteratorContextPtr(), context1);
  329. // Change: 1230-1231
  330. checkRR(context1, "example.org.", "1800", "SOA",
  331. "ns1.example.org. admin.example.org. 1230 3600 1800 2419200 7200");
  332. checkRR(context1, "example.org.", "3600", "SOA",
  333. "ns1.example.org. admin.example.org. 1231 3600 1800 2419200 7200");
  334. // Check there's no other and that calling it again after no records doesn't
  335. // cause problems.
  336. EXPECT_FALSE(context1->getNext(data));
  337. EXPECT_FALSE(context1->getNext(data));
  338. // Check that the difference sequence 1231-1233 (two separate difference
  339. // sequences) is OK.
  340. DatabaseAccessor::IteratorContextPtr
  341. context2(accessor->getDiffs(zone_info.second, 1231, 1233));
  342. ASSERT_NE(DatabaseAccessor::IteratorContextPtr(), context2);
  343. // Change 1231-1232
  344. checkRR(context2, "example.org.", "3600", "SOA",
  345. "ns1.example.org. admin.example.org. 1231 3600 1800 2419200 7200");
  346. checkRR(context2, "unused.example.org.", "3600", "A", "192.0.2.102");
  347. checkRR(context2, "example.org.", "3600", "SOA",
  348. "ns1.example.org. admin.example.org. 1232 3600 1800 2419200 7200");
  349. // Change: 1232-1233
  350. checkRR(context2, "example.org.", "3600", "SOA",
  351. "ns1.example.org. admin.example.org. 1232 3600 1800 2419200 7200");
  352. checkRR(context2, "example.org.", "3600", "SOA",
  353. "ns1.example.org. admin.example.org. 1233 3600 1800 2419200 7200");
  354. checkRR(context2, "sub.example.org.", "3600", "NS", "ns.sub.example.org.");
  355. checkRR(context2, "ns.sub.example.org.", "3600", "A", "192.0.2.101");
  356. // Check there's no other and that calling it again after no records doesn't
  357. // cause problems.
  358. EXPECT_FALSE(context2->getNext(data));
  359. EXPECT_FALSE(context2->getNext(data));
  360. // Check that the difference sequence 4294967280 to 1230 (serial number
  361. // rollover) is OK
  362. DatabaseAccessor::IteratorContextPtr
  363. context3(accessor->getDiffs(zone_info.second, 4294967280U, 1230));
  364. ASSERT_NE(DatabaseAccessor::IteratorContextPtr(), context3);
  365. // Change 4294967280 to 1230.
  366. checkRR(context3, "example.org.", "3600", "SOA",
  367. "ns1.example.org. admin.example.org. 4294967280 3600 1800 2419200 7200");
  368. checkRR(context3, "www.example.org.", "3600", "A", "192.0.2.31");
  369. checkRR(context3, "example.org.", "1800", "SOA",
  370. "ns1.example.org. admin.example.org. 1230 3600 1800 2419200 7200");
  371. checkRR(context3, "www.example.org.", "3600", "A", "192.0.2.21");
  372. EXPECT_FALSE(context3->getNext(data));
  373. EXPECT_FALSE(context3->getNext(data));
  374. // Check the difference sequence 1233-1231 (versions in wrong order). This
  375. // should give an empty difference set.
  376. DatabaseAccessor::IteratorContextPtr
  377. context4(accessor->getDiffs(zone_info.second, 1233, 1231));
  378. ASSERT_NE(DatabaseAccessor::IteratorContextPtr(), context2);
  379. EXPECT_FALSE(context4->getNext(data));
  380. EXPECT_FALSE(context4->getNext(data));
  381. }
  382. TEST(SQLite3Open, getDBNameExample2) {
  383. SQLite3Accessor accessor(SQLITE_DBFILE_EXAMPLE2, "IN");
  384. EXPECT_EQ(SQLITE_DBNAME_EXAMPLE2, accessor.getDBName());
  385. }
  386. TEST(SQLite3Open, getDBNameExampleROOT) {
  387. SQLite3Accessor accessor(SQLITE_DBFILE_EXAMPLE_ROOT, "IN");
  388. EXPECT_EQ(SQLITE_DBNAME_EXAMPLE_ROOT, accessor.getDBName());
  389. }
  390. // Simple function to match records
  391. void
  392. checkRecordRow(const std::string columns[],
  393. const std::string& field0, // for type
  394. const std::string& field1, // for TTL
  395. const std::string& field2, // for "sigtype"
  396. const std::string& field3, // for rdata
  397. const std::string& field4) // for name
  398. {
  399. EXPECT_EQ(field0, columns[DatabaseAccessor::TYPE_COLUMN]);
  400. EXPECT_EQ(field1, columns[DatabaseAccessor::TTL_COLUMN]);
  401. EXPECT_EQ(field2, columns[DatabaseAccessor::SIGTYPE_COLUMN]);
  402. EXPECT_EQ(field3, columns[DatabaseAccessor::RDATA_COLUMN]);
  403. EXPECT_EQ(field4, columns[DatabaseAccessor::NAME_COLUMN]);
  404. }
  405. TEST_F(SQLite3AccessorTest, getRecords) {
  406. const std::pair<bool, int> zone_info(accessor->getZone("example.com."));
  407. ASSERT_TRUE(zone_info.first);
  408. const int zone_id = zone_info.second;
  409. ASSERT_EQ(1, zone_id);
  410. std::string columns[DatabaseAccessor::COLUMN_COUNT];
  411. DatabaseAccessor::IteratorContextPtr
  412. context(accessor->getRecords("foo.bar", 1));
  413. ASSERT_NE(DatabaseAccessor::IteratorContextPtr(),
  414. context);
  415. EXPECT_FALSE(context->getNext(columns));
  416. checkRecordRow(columns, "", "", "", "", "");
  417. // now try some real searches
  418. context = accessor->getRecords("foo.example.com.", zone_id);
  419. ASSERT_TRUE(context->getNext(columns));
  420. checkRecordRow(columns, "CNAME", "3600", "",
  421. "cnametest.example.org.", "");
  422. ASSERT_TRUE(context->getNext(columns));
  423. checkRecordRow(columns, "RRSIG", "3600", "CNAME",
  424. "CNAME 5 3 3600 20100322084538 20100220084538 33495 "
  425. "example.com. FAKEFAKEFAKEFAKE", "");
  426. ASSERT_TRUE(context->getNext(columns));
  427. checkRecordRow(columns, "NSEC", "7200", "",
  428. "mail.example.com. CNAME RRSIG NSEC", "");
  429. ASSERT_TRUE(context->getNext(columns));
  430. checkRecordRow(columns, "RRSIG", "7200", "NSEC",
  431. "NSEC 5 3 7200 20100322084538 20100220084538 33495 "
  432. "example.com. FAKEFAKEFAKEFAKE", "");
  433. EXPECT_FALSE(context->getNext(columns));
  434. // with no more records, the array should not have been modified
  435. checkRecordRow(columns, "RRSIG", "7200", "NSEC",
  436. "NSEC 5 3 7200 20100322084538 20100220084538 33495 "
  437. "example.com. FAKEFAKEFAKEFAKE", "");
  438. context = accessor->getRecords("example.com.", zone_id);
  439. ASSERT_TRUE(context->getNext(columns));
  440. checkRecordRow(columns, "SOA", "3600", "",
  441. "master.example.com. admin.example.com. "
  442. "1234 3600 1800 2419200 7200", "");
  443. ASSERT_TRUE(context->getNext(columns));
  444. checkRecordRow(columns, "RRSIG", "3600", "SOA",
  445. "SOA 5 2 3600 20100322084538 20100220084538 "
  446. "33495 example.com. FAKEFAKEFAKEFAKE", "");
  447. ASSERT_TRUE(context->getNext(columns));
  448. checkRecordRow(columns, "NS", "1200", "", "dns01.example.com.", "");
  449. ASSERT_TRUE(context->getNext(columns));
  450. checkRecordRow(columns, "NS", "3600", "", "dns02.example.com.", "");
  451. ASSERT_TRUE(context->getNext(columns));
  452. checkRecordRow(columns, "NS", "1800", "", "dns03.example.com.", "");
  453. ASSERT_TRUE(context->getNext(columns));
  454. checkRecordRow(columns, "RRSIG", "3600", "NS",
  455. "NS 5 2 3600 20100322084538 20100220084538 "
  456. "33495 example.com. FAKEFAKEFAKEFAKE", "");
  457. ASSERT_TRUE(context->getNext(columns));
  458. checkRecordRow(columns, "MX", "3600", "", "10 mail.example.com.", "");
  459. ASSERT_TRUE(context->getNext(columns));
  460. checkRecordRow(columns, "MX", "3600", "",
  461. "20 mail.subzone.example.com.", "");
  462. ASSERT_TRUE(context->getNext(columns));
  463. checkRecordRow(columns, "RRSIG", "3600", "MX",
  464. "MX 5 2 3600 20100322084538 20100220084538 "
  465. "33495 example.com. FAKEFAKEFAKEFAKE", "");
  466. ASSERT_TRUE(context->getNext(columns));
  467. checkRecordRow(columns, "NSEC", "7200", "",
  468. "cname-ext.example.com. NS SOA MX RRSIG NSEC DNSKEY", "");
  469. ASSERT_TRUE(context->getNext(columns));
  470. checkRecordRow(columns, "RRSIG", "7200", "NSEC",
  471. "NSEC 5 2 7200 20100322084538 20100220084538 "
  472. "33495 example.com. FAKEFAKEFAKEFAKE", "");
  473. ASSERT_TRUE(context->getNext(columns));
  474. checkRecordRow(columns, "DNSKEY", "3600", "",
  475. "256 3 5 AwEAAcOUBllYc1hf7ND9uDy+Yz1BF3sI0m4q NGV7W"
  476. "cTD0WEiuV7IjXgHE36fCmS9QsUxSSOV o1I/FMxI2PJVqTYHkX"
  477. "FBS7AzLGsQYMU7UjBZ SotBJ6Imt5pXMu+lEDNy8TOUzG3xm7g"
  478. "0qcbW YF6qCEfvZoBtAqi5Rk7Mlrqs8agxYyMx", "");
  479. ASSERT_TRUE(context->getNext(columns));
  480. checkRecordRow(columns, "DNSKEY", "3600", "",
  481. "257 3 5 AwEAAe5WFbxdCPq2jZrZhlMj7oJdff3W7syJ tbvzg"
  482. "62tRx0gkoCDoBI9DPjlOQG0UAbj+xUV 4HQZJStJaZ+fHU5AwV"
  483. "NT+bBZdtV+NujSikhd THb4FYLg2b3Cx9NyJvAVukHp/91HnWu"
  484. "G4T36 CzAFrfPwsHIrBz9BsaIQ21VRkcmj7DswfI/i DGd8j6b"
  485. "qiODyNZYQ+ZrLmF0KIJ2yPN3iO6Zq 23TaOrVTjB7d1a/h31OD"
  486. "fiHAxFHrkY3t3D5J R9Nsl/7fdRmSznwtcSDgLXBoFEYmw6p86"
  487. "Acv RyoYNcL1SXjaKVLG5jyU3UR+LcGZT5t/0xGf oIK/aKwEN"
  488. "rsjcKZZj660b1M=", "");
  489. ASSERT_TRUE(context->getNext(columns));
  490. checkRecordRow(columns, "RRSIG", "3600", "DNSKEY",
  491. "DNSKEY 5 2 3600 20100322084538 20100220084538 "
  492. "4456 example.com. FAKEFAKEFAKEFAKE", "");
  493. ASSERT_TRUE(context->getNext(columns));
  494. checkRecordRow(columns, "RRSIG", "3600", "DNSKEY",
  495. "DNSKEY 5 2 3600 20100322084538 20100220084538 "
  496. "33495 example.com. FAKEFAKEFAKEFAKE", "");
  497. EXPECT_FALSE(context->getNext(columns));
  498. // getnextrecord returning false should mean array is not altered
  499. checkRecordRow(columns, "RRSIG", "3600", "DNSKEY",
  500. "DNSKEY 5 2 3600 20100322084538 20100220084538 "
  501. "33495 example.com. FAKEFAKEFAKEFAKE", "");
  502. // check that another getNext does not cause problems
  503. EXPECT_FALSE(context->getNext(columns));
  504. // Try searching for subdomain
  505. // There's foo.bar.example.com in the data
  506. context = accessor->getRecords("bar.example.com.", zone_id, true);
  507. ASSERT_TRUE(context->getNext(columns));
  508. checkRecordRow(columns, "A", "3600", "", "192.0.2.1", "");
  509. EXPECT_FALSE(context->getNext(columns));
  510. // But we shouldn't match mix.example.com here
  511. context = accessor->getRecords("ix.example.com.", zone_id, true);
  512. EXPECT_FALSE(context->getNext(columns));
  513. }
  514. TEST_F(SQLite3AccessorTest, findPrevious) {
  515. EXPECT_EQ("dns01.example.com.",
  516. accessor->findPreviousName(1, "com.example.dns02."));
  517. // A name that doesn't exist
  518. EXPECT_EQ("dns01.example.com.",
  519. accessor->findPreviousName(1, "com.example.dns01x."));
  520. // Largest name
  521. EXPECT_EQ("www.example.com.",
  522. accessor->findPreviousName(1, "com.example.wwww"));
  523. // Out of zone after the last name
  524. EXPECT_EQ("www.example.com.",
  525. accessor->findPreviousName(1, "org.example."));
  526. // Case insensitive?
  527. EXPECT_EQ("dns01.example.com.",
  528. accessor->findPreviousName(1, "com.exaMple.DNS02."));
  529. // A name that doesn't exist
  530. EXPECT_EQ("dns01.example.com.",
  531. accessor->findPreviousName(1, "com.exaMple.DNS01X."));
  532. // The DB contains foo.bar.example.com., which would be in between
  533. // these two names. However, that one does not have an NSEC record,
  534. // which is how this database recognizes glue data, so it should
  535. // be skipped.
  536. EXPECT_EQ("example.com.",
  537. accessor->findPreviousName(1, "com.example.cname-ext."));
  538. // Throw when we are before the origin
  539. EXPECT_THROW(accessor->findPreviousName(1, "com.example."),
  540. isc::NotImplemented);
  541. EXPECT_THROW(accessor->findPreviousName(1, "a.example."),
  542. isc::NotImplemented);
  543. }
  544. TEST_F(SQLite3AccessorTest, findPreviousNoData) {
  545. // This one doesn't hold any NSEC records, so it shouldn't work
  546. // The underlying DB/data don't support DNSSEC, so it's not implemented
  547. // (does it make sense? Or different exception here?)
  548. EXPECT_THROW(accessor->findPreviousName(3, "com.example.sql2.www."),
  549. isc::NotImplemented);
  550. }
  551. // Test fixture for creating a db that automatically deletes it before start,
  552. // and when done
  553. class SQLite3Create : public ::testing::Test {
  554. public:
  555. SQLite3Create() {
  556. remove(SQLITE_NEW_DBFILE);
  557. }
  558. ~SQLite3Create() {
  559. remove(SQLITE_NEW_DBFILE);
  560. }
  561. };
  562. bool isReadable(const char* filename) {
  563. return (std::ifstream(filename).is_open());
  564. }
  565. TEST_F(SQLite3Create, creationtest) {
  566. ASSERT_FALSE(isReadable(SQLITE_NEW_DBFILE));
  567. // Should simply be created
  568. SQLite3Accessor accessor(SQLITE_NEW_DBFILE, "IN");
  569. ASSERT_TRUE(isReadable(SQLITE_NEW_DBFILE));
  570. }
  571. // Test addZone works. This is done on the 'createtest' fixture so we
  572. // can easily be sure it does not exist yet.
  573. TEST_F(SQLite3Create, addZone) {
  574. // Need shared_ptr for the getAllRecords at the end of the test
  575. boost::shared_ptr<SQLite3Accessor> accessor(
  576. new SQLite3Accessor(SQLITE_NEW_DBFILE, "IN"));
  577. const std::string zone_name("example.com");
  578. const std::pair<bool, int> zone_info(accessor->getZone(zone_name));
  579. ASSERT_FALSE(zone_info.first);
  580. // Calling addZone without transaction should fail
  581. ASSERT_THROW(accessor->addZone(zone_name), DataSourceError);
  582. // Add the zone. Since it does not exist yet, it should return true
  583. accessor->startTransaction();
  584. const int new_zone_id = accessor->addZone(zone_name);
  585. accessor->commit();
  586. // Calling addZone again should return the same zone id
  587. accessor->startTransaction();
  588. ASSERT_EQ(new_zone_id, accessor->addZone(zone_name));
  589. accessor->rollback();
  590. // Check that it exists now, but has no records at this point
  591. const std::pair<bool, int> zone_info2(accessor->getZone(zone_name));
  592. ASSERT_TRUE(zone_info2.first);
  593. ASSERT_EQ(new_zone_id, zone_info2.second);
  594. DatabaseAccessor::IteratorContextPtr context =
  595. accessor->getAllRecords(zone_info2.second);
  596. string data[DatabaseAccessor::COLUMN_COUNT];
  597. ASSERT_NE(DatabaseAccessor::IteratorContextPtr(), context);
  598. EXPECT_FALSE(context->getNext(data));
  599. }
  600. TEST_F(SQLite3Create, emptytest) {
  601. ASSERT_FALSE(isReadable(SQLITE_NEW_DBFILE));
  602. // open one manually
  603. sqlite3* db;
  604. ASSERT_EQ(SQLITE_OK, sqlite3_open(SQLITE_NEW_DBFILE, &db));
  605. // empty, but not locked, so creating another accessor should work
  606. SQLite3Accessor accessor2(SQLITE_NEW_DBFILE, "IN");
  607. sqlite3_close(db);
  608. // should still work now that we closed it
  609. SQLite3Accessor accessor3(SQLITE_NEW_DBFILE, "IN");
  610. }
  611. TEST_F(SQLite3Create, lockedtest) {
  612. ASSERT_FALSE(isReadable(SQLITE_NEW_DBFILE));
  613. // open one manually
  614. sqlite3* db;
  615. ASSERT_EQ(SQLITE_OK, sqlite3_open(SQLITE_NEW_DBFILE, &db));
  616. sqlite3_exec(db, "BEGIN EXCLUSIVE TRANSACTION", NULL, NULL, NULL);
  617. // should not be able to open it
  618. EXPECT_THROW(SQLite3Accessor accessor2(SQLITE_NEW_DBFILE, "IN"),
  619. SQLite3Error);
  620. sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL);
  621. // should work now that the transaction has been rolled back
  622. SQLite3Accessor accessor3(SQLITE_NEW_DBFILE, "IN");
  623. ASSERT_EQ(SQLITE_OK, sqlite3_close(db));
  624. }
  625. TEST_F(SQLite3AccessorTest, clone) {
  626. boost::shared_ptr<DatabaseAccessor> cloned = accessor->clone();
  627. EXPECT_EQ(accessor->getDBName(), cloned->getDBName());
  628. // The cloned accessor should have a separate connection and search
  629. // context, so it should be able to perform search in concurrent with
  630. // the original accessor.
  631. string columns1[DatabaseAccessor::COLUMN_COUNT];
  632. string columns2[DatabaseAccessor::COLUMN_COUNT];
  633. const std::pair<bool, int> zone_info1(
  634. accessor->getZone("example.com."));
  635. DatabaseAccessor::IteratorContextPtr iterator1 =
  636. accessor->getRecords("foo.example.com.", zone_info1.second);
  637. const std::pair<bool, int> zone_info2(
  638. accessor->getZone("example.com."));
  639. DatabaseAccessor::IteratorContextPtr iterator2 =
  640. cloned->getRecords("foo.example.com.", zone_info2.second);
  641. ASSERT_TRUE(iterator1->getNext(columns1));
  642. checkRecordRow(columns1, "CNAME", "3600", "", "cnametest.example.org.",
  643. "");
  644. ASSERT_TRUE(iterator2->getNext(columns2));
  645. checkRecordRow(columns2, "CNAME", "3600", "", "cnametest.example.org.",
  646. "");
  647. }
  648. //
  649. // Commonly used data for update tests
  650. //
  651. const char* const common_expected_data[] = {
  652. // Test record already stored in the tested sqlite3 DB file.
  653. "foo.bar.example.com.", "com.example.bar.foo.", "3600", "A", "",
  654. "192.0.2.1"
  655. };
  656. const char* const new_data[] = {
  657. // Newly added data commonly used by some of the tests below
  658. "newdata.example.com.", "com.example.newdata.", "3600", "A", "",
  659. "192.0.2.1"
  660. };
  661. const char* const deleted_data[] = {
  662. // Existing data to be removed commonly used by some of the tests below
  663. "foo.bar.example.com.", "A", "192.0.2.1"
  664. };
  665. const char* const nsec3_data[DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT] = {
  666. // example NSEC3 parameters. Using "apex_hash" just as a convenient
  667. // shortcut; otherwise it has nothing to do with the zone apex for the
  668. // purpose of this test.
  669. apex_hash, "3600", "NSEC3",
  670. "1 1 12 AABBCCDD 2T7B4G4VSA5SMI47K61MV5BV1A22BOJR NS SOA"
  671. };
  672. const char* const nsec3_sig_data[DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT] = {
  673. ns1_hash, "3600", "RRSIG",
  674. "NSEC3 5 3 3600 20000101000000 20000201000000 12345 "
  675. "example.com. FAKEFAKEFAKE"
  676. };
  677. const char* const nsec3_deleted_data[] = {
  678. // Delete parameters for nsec3_data
  679. apex_hash, nsec3_data[DatabaseAccessor::ADD_NSEC3_TYPE],
  680. nsec3_data[DatabaseAccessor::ADD_NSEC3_RDATA]
  681. };
  682. class SQLite3Update : public SQLite3AccessorTest {
  683. protected:
  684. SQLite3Update() {
  685. // Note: if "installing" the test file fails some of the subsequent
  686. // tests would fail.
  687. const char *install_cmd = INSTALL_PROG " -c " TEST_DATA_DIR
  688. "/test.sqlite3 " TEST_DATA_BUILDDIR
  689. "/test.sqlite3.copied";
  690. if (system(install_cmd) != 0) {
  691. // any exception will do, this is failure in test setup, but nice
  692. // to show the command that fails, and shouldn't be caught
  693. isc_throw(isc::Exception,
  694. "Error setting up; command failed: " << install_cmd);
  695. };
  696. initAccessor(TEST_DATA_BUILDDIR "/test.sqlite3.copied", "IN");
  697. zone_id = accessor->getZone("example.com.").second;
  698. another_accessor.reset(new SQLite3Accessor(
  699. TEST_DATA_BUILDDIR "/test.sqlite3.copied",
  700. "IN"));
  701. expected_stored.push_back(common_expected_data);
  702. }
  703. int zone_id;
  704. std::string get_columns[DatabaseAccessor::COLUMN_COUNT];
  705. std::string add_columns[DatabaseAccessor::ADD_COLUMN_COUNT];
  706. std::string add_nsec3_columns[DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT];
  707. std::string del_params[DatabaseAccessor::DEL_PARAM_COUNT];
  708. std::string diff_params[DatabaseAccessor::DIFF_PARAM_COUNT];
  709. vector<const char* const*> expected_stored; // placeholder for checkRecords
  710. vector<const char* const*> empty_stored; // indicate no corresponding data
  711. // Another accessor, emulating one running on a different process/thread
  712. boost::shared_ptr<SQLite3Accessor> another_accessor;
  713. DatabaseAccessor::IteratorContextPtr iterator;
  714. };
  715. void
  716. checkRecords(SQLite3Accessor& accessor, int zone_id, const std::string& name,
  717. vector<const char* const*> expected_rows)
  718. {
  719. DatabaseAccessor::IteratorContextPtr iterator =
  720. accessor.getRecords(name, zone_id);
  721. std::string columns[DatabaseAccessor::COLUMN_COUNT];
  722. vector<const char* const*>::const_iterator it = expected_rows.begin();
  723. while (iterator->getNext(columns)) {
  724. ASSERT_TRUE(it != expected_rows.end());
  725. checkRecordRow(columns, (*it)[3], (*it)[2], (*it)[4], (*it)[5], "");
  726. ++it;
  727. }
  728. EXPECT_TRUE(it == expected_rows.end());
  729. }
  730. // Similar to the previous one, but checking transactions on the nsec3 table.
  731. void
  732. checkNSEC3Records(SQLite3Accessor& accessor, int zone_id,
  733. const std::string& hash,
  734. vector<const char* const*> expected_rows)
  735. {
  736. DatabaseAccessor::IteratorContextPtr iterator =
  737. accessor.getNSEC3Records(hash, zone_id);
  738. std::string columns[DatabaseAccessor::COLUMN_COUNT];
  739. vector<const char* const*>::const_iterator it = expected_rows.begin();
  740. while (iterator->getNext(columns)) {
  741. ASSERT_TRUE(it != expected_rows.end());
  742. checkRecordRow(columns, (*it)[DatabaseAccessor::ADD_NSEC3_TYPE],
  743. (*it)[DatabaseAccessor::ADD_NSEC3_TTL],
  744. "", // sigtype, should always be empty
  745. (*it)[DatabaseAccessor::ADD_NSEC3_RDATA],
  746. ""); // name, always empty
  747. ++it;
  748. }
  749. EXPECT_TRUE(it == expected_rows.end());
  750. }
  751. TEST_F(SQLite3Update, emptyUpdate) {
  752. // If we do nothing between start and commit, the zone content
  753. // should be intact.
  754. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  755. zone_id = accessor->startUpdateZone("example.com.", false).second;
  756. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  757. accessor->commit();
  758. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  759. }
  760. TEST_F(SQLite3Update, flushZone) {
  761. // With 'replace' being true startUpdateZone() will flush the existing
  762. // zone content.
  763. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  764. zone_id = accessor->startUpdateZone("example.com.", true).second;
  765. checkRecords(*accessor, zone_id, "foo.bar.example.com.", empty_stored);
  766. accessor->commit();
  767. checkRecords(*accessor, zone_id, "foo.bar.example.com.", empty_stored);
  768. }
  769. TEST_F(SQLite3Update, flushZoneWithNSEC3) {
  770. // Similar to the previous case, but make sure the separate nsec3 table
  771. // is also cleared. We first need to add something to the table.
  772. zone_id = accessor->startUpdateZone("example.com.", false).second;
  773. copy(nsec3_data, nsec3_data + DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT,
  774. add_nsec3_columns);
  775. accessor->addNSEC3RecordToZone(add_nsec3_columns);
  776. accessor->commit();
  777. // Confirm it surely exists.
  778. expected_stored.clear();
  779. expected_stored.push_back(nsec3_data);
  780. checkNSEC3Records(*accessor, zone_id, apex_hash, expected_stored);
  781. // Then starting zone replacement. the NSEC3 record should have been
  782. // removed.
  783. zone_id = accessor->startUpdateZone("example.com.", true).second;
  784. checkNSEC3Records(*accessor, zone_id, apex_hash, empty_stored);
  785. }
  786. TEST_F(SQLite3Update, readWhileUpdate) {
  787. zone_id = accessor->startUpdateZone("example.com.", true).second;
  788. checkRecords(*accessor, zone_id, "foo.bar.example.com.", empty_stored);
  789. // Until commit is done, the other accessor should see the old data
  790. checkRecords(*another_accessor, zone_id, "foo.bar.example.com.",
  791. expected_stored);
  792. // Once the changes are committed, the other accessor will see the new
  793. // data.
  794. accessor->commit();
  795. checkRecords(*another_accessor, zone_id, "foo.bar.example.com.",
  796. empty_stored);
  797. }
  798. TEST_F(SQLite3Update, rollback) {
  799. zone_id = accessor->startUpdateZone("example.com.", true).second;
  800. checkRecords(*accessor, zone_id, "foo.bar.example.com.", empty_stored);
  801. // Rollback will revert the change made by startUpdateZone(, true).
  802. accessor->rollback();
  803. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  804. }
  805. TEST_F(SQLite3Update, rollbackFailure) {
  806. // This test emulates a rare scenario of making rollback attempt fail.
  807. // The iterator is paused in the middle of getting records, which prevents
  808. // the rollback operation at the end of the test.
  809. // Since SQLite3 version 3.7.11, rollbacks do not fail on pending
  810. // transactions anymore, making this test fail (and moot), but the
  811. // transactions will fail after it, so, depending on version,
  812. // we test whether that happens and is caught
  813. string columns[DatabaseAccessor::COLUMN_COUNT];
  814. iterator = accessor->getRecords("example.com.", zone_id);
  815. EXPECT_TRUE(iterator->getNext(columns));
  816. accessor->startUpdateZone("example.com.", true);
  817. #if SQLITE_VERSION_NUMBER < 3007011
  818. EXPECT_THROW(accessor->rollback(), DataSourceError);
  819. EXPECT_NO_THROW(iterator->getNext(columns));
  820. #else
  821. EXPECT_NO_THROW(accessor->rollback());
  822. EXPECT_THROW(iterator->getNext(columns), DataSourceError);
  823. #endif
  824. }
  825. TEST_F(SQLite3Update, commitConflict) {
  826. // Start reading the DB by another accessor. We should stop at a single
  827. // call to getNextRecord() to keep holding the lock.
  828. iterator = another_accessor->getRecords("foo.example.com.", zone_id);
  829. EXPECT_TRUE(iterator->getNext(get_columns));
  830. // Due to getNextRecord() above, the other accessor holds a DB lock,
  831. // which will prevent commit.
  832. zone_id = accessor->startUpdateZone("example.com.", true).second;
  833. checkRecords(*accessor, zone_id, "foo.bar.example.com.", empty_stored);
  834. EXPECT_THROW(accessor->commit(), DataSourceError);
  835. accessor->rollback(); // rollback should still succeed
  836. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  837. }
  838. TEST_F(SQLite3Update, updateConflict) {
  839. // Similar to the previous case, but this is a conflict with another
  840. // update attempt. Note that these two accessors modify disjoint sets
  841. // of data; sqlite3 only has a coarse-grained lock so we cannot allow
  842. // these updates to run concurrently.
  843. EXPECT_TRUE(another_accessor->startUpdateZone("sql1.example.com.",
  844. true).first);
  845. EXPECT_THROW(accessor->startUpdateZone("example.com.", true),
  846. DataSourceError);
  847. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  848. // Once we rollback the other attempt of change, we should be able to
  849. // start and commit the transaction using the main accessor.
  850. another_accessor->rollback();
  851. accessor->startUpdateZone("example.com.", true);
  852. accessor->commit();
  853. }
  854. TEST_F(SQLite3Update, duplicateUpdate) {
  855. accessor->startUpdateZone("example.com.", false);
  856. EXPECT_THROW(accessor->startUpdateZone("example.com.", false),
  857. DataSourceError);
  858. }
  859. TEST_F(SQLite3Update, commitWithoutTransaction) {
  860. EXPECT_THROW(accessor->commit(), DataSourceError);
  861. }
  862. TEST_F(SQLite3Update, rollbackWithoutTransaction) {
  863. EXPECT_THROW(accessor->rollback(), DataSourceError);
  864. }
  865. TEST_F(SQLite3Update, addRecord) {
  866. // Before update, there should be no record for this name
  867. checkRecords(*accessor, zone_id, "newdata.example.com.", empty_stored);
  868. zone_id = accessor->startUpdateZone("example.com.", false).second;
  869. copy(new_data, new_data + DatabaseAccessor::ADD_COLUMN_COUNT,
  870. add_columns);
  871. accessor->addRecordToZone(add_columns);
  872. expected_stored.clear();
  873. expected_stored.push_back(new_data);
  874. checkRecords(*accessor, zone_id, "newdata.example.com.", expected_stored);
  875. // Commit the change, and confirm the new data is still there.
  876. accessor->commit();
  877. checkRecords(*accessor, zone_id, "newdata.example.com.", expected_stored);
  878. }
  879. TEST_F(SQLite3Update, addNSEC3Record) {
  880. // Similar to the previous test, but for NSEC3-related records
  881. checkRecords(*accessor, zone_id, apex_hash, empty_stored);
  882. checkRecords(*accessor, zone_id, ns1_hash, empty_stored);
  883. zone_id = accessor->startUpdateZone("example.com.", false).second;
  884. // Add an NSEC3
  885. copy(nsec3_data, nsec3_data + DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT,
  886. add_nsec3_columns);
  887. accessor->addNSEC3RecordToZone(add_nsec3_columns);
  888. // Add an RRSIG for NSEC3
  889. copy(nsec3_sig_data,
  890. nsec3_sig_data + DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT,
  891. add_nsec3_columns);
  892. accessor->addNSEC3RecordToZone(add_nsec3_columns);
  893. // Check the stored data, before and after commit().
  894. for (size_t i = 0; i < 2; ++i) {
  895. expected_stored.clear();
  896. expected_stored.push_back(nsec3_data);
  897. checkNSEC3Records(*accessor, zone_id, apex_hash, expected_stored);
  898. expected_stored.clear();
  899. expected_stored.push_back(nsec3_sig_data);
  900. checkNSEC3Records(*accessor, zone_id, ns1_hash, expected_stored);
  901. if (i == 0) { // make sure commit() happens only once
  902. accessor->commit();
  903. }
  904. }
  905. }
  906. TEST_F(SQLite3Update, nsec3IteratorOnAdd) {
  907. // This test checks if an added NSEC3 record will appear in the iterator
  908. // result, meeting the expectation of addNSEC3RecordToZone.
  909. // Specifically, it checks if the name column is filled with the complete
  910. // owner name.
  911. // We'll replace the zone, and add one NSEC3 record, and only that one.
  912. zone_id = accessor->startUpdateZone("example.com.", true).second;
  913. copy(nsec3_data, nsec3_data + DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT,
  914. add_nsec3_columns);
  915. accessor->addNSEC3RecordToZone(add_nsec3_columns);
  916. accessor->commit();
  917. // the zone should contain only one record we just added.
  918. DatabaseAccessor::IteratorContextPtr context =
  919. accessor->getAllRecords(zone_id);
  920. string data[DatabaseAccessor::COLUMN_COUNT];
  921. EXPECT_TRUE(context->getNext(data));
  922. EXPECT_EQ(string(apex_hash) + ".example.com.",
  923. data[DatabaseAccessor::NAME_COLUMN]);
  924. EXPECT_FALSE(context->getNext(data));
  925. }
  926. TEST_F(SQLite3Update, addThenRollback) {
  927. zone_id = accessor->startUpdateZone("example.com.", false).second;
  928. copy(new_data, new_data + DatabaseAccessor::ADD_COLUMN_COUNT,
  929. add_columns);
  930. accessor->addRecordToZone(add_columns);
  931. expected_stored.clear();
  932. expected_stored.push_back(new_data);
  933. checkRecords(*accessor, zone_id, "newdata.example.com.", expected_stored);
  934. // Rollback the transaction, and confirm the zone reverts to the previous
  935. // state. We also start another update to check if the accessor can be
  936. // reused for a new update after rollback.
  937. accessor->rollback();
  938. zone_id = accessor->startUpdateZone("example.com.", false).second;
  939. checkRecords(*accessor, zone_id, "newdata.example.com.", empty_stored);
  940. }
  941. TEST_F(SQLite3Update, duplicateAdd) {
  942. const char* const dup_data[] = {
  943. "foo.bar.example.com.", "com.example.bar.foo.", "3600", "A", "",
  944. "192.0.2.1"
  945. };
  946. expected_stored.clear();
  947. expected_stored.push_back(dup_data);
  948. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  949. // Adding exactly the same data. As this backend is "dumb", another
  950. // row of the same content will be inserted.
  951. copy(dup_data, dup_data + DatabaseAccessor::ADD_COLUMN_COUNT,
  952. add_columns);
  953. zone_id = accessor->startUpdateZone("example.com.", false).second;
  954. accessor->addRecordToZone(add_columns);
  955. expected_stored.push_back(dup_data);
  956. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  957. }
  958. TEST_F(SQLite3Update, invalidAdd) {
  959. // An attempt of add before an explicit start of transaction
  960. EXPECT_THROW(accessor->addRecordToZone(add_columns), DataSourceError);
  961. // Same for addNSEC3.
  962. copy(nsec3_data, nsec3_data + DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT,
  963. add_nsec3_columns);
  964. EXPECT_THROW(accessor->addNSEC3RecordToZone(add_nsec3_columns),
  965. DataSourceError);
  966. }
  967. TEST_F(SQLite3Update, deleteRecord) {
  968. zone_id = accessor->startUpdateZone("example.com.", false).second;
  969. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  970. copy(deleted_data, deleted_data + DatabaseAccessor::DEL_PARAM_COUNT,
  971. del_params);
  972. accessor->deleteRecordInZone(del_params);
  973. checkRecords(*accessor, zone_id, "foo.bar.example.com.", empty_stored);
  974. // Commit the change, and confirm the deleted data still isn't there.
  975. accessor->commit();
  976. checkRecords(*accessor, zone_id, "foo.bar.example.com.", empty_stored);
  977. }
  978. TEST_F(SQLite3Update, deleteNSEC3Record) {
  979. // Similar to the previous test, but for NSEC3.
  980. zone_id = accessor->startUpdateZone("example.com.", false).second;
  981. checkNSEC3Records(*accessor, zone_id, apex_hash, empty_stored);
  982. // We first need to add some record.
  983. copy(nsec3_data, nsec3_data + DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT,
  984. add_nsec3_columns);
  985. accessor->addNSEC3RecordToZone(add_nsec3_columns);
  986. // Now it should exist.
  987. expected_stored.clear();
  988. expected_stored.push_back(nsec3_data);
  989. checkNSEC3Records(*accessor, zone_id, apex_hash, expected_stored);
  990. // Delete it, and confirm that.
  991. copy(nsec3_deleted_data,
  992. nsec3_deleted_data + DatabaseAccessor::DEL_PARAM_COUNT, del_params);
  993. accessor->deleteNSEC3RecordInZone(del_params);
  994. checkNSEC3Records(*accessor, zone_id, apex_hash, empty_stored);
  995. // Commit the change, and confirm the deleted data still isn't there.
  996. accessor->commit();
  997. checkNSEC3Records(*accessor, zone_id, apex_hash, empty_stored);
  998. }
  999. TEST_F(SQLite3Update, deleteThenRollback) {
  1000. zone_id = accessor->startUpdateZone("example.com.", false).second;
  1001. copy(deleted_data, deleted_data + DatabaseAccessor::DEL_PARAM_COUNT,
  1002. del_params);
  1003. accessor->deleteRecordInZone(del_params);
  1004. checkRecords(*accessor, zone_id, "foo.bar.example.com.", empty_stored);
  1005. // Rollback the change, and confirm the data still exists.
  1006. accessor->rollback();
  1007. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  1008. }
  1009. TEST_F(SQLite3Update, deleteNonexistent) {
  1010. zone_id = accessor->startUpdateZone("example.com.", false).second;
  1011. copy(deleted_data, deleted_data + DatabaseAccessor::DEL_PARAM_COUNT,
  1012. del_params);
  1013. // Replace the name with a non existent one, then try to delete it.
  1014. // nothing should happen.
  1015. del_params[DatabaseAccessor::DEL_NAME] = "no-such-name.example.com.";
  1016. checkRecords(*accessor, zone_id, "no-such-name.example.com.",
  1017. empty_stored);
  1018. accessor->deleteRecordInZone(del_params);
  1019. checkRecords(*accessor, zone_id, "no-such-name.example.com.",
  1020. empty_stored);
  1021. // Name exists but the RR type is different. Delete attempt shouldn't
  1022. // delete only by name.
  1023. copy(deleted_data, deleted_data + DatabaseAccessor::DEL_PARAM_COUNT,
  1024. del_params);
  1025. del_params[DatabaseAccessor::DEL_TYPE] = "AAAA";
  1026. accessor->deleteRecordInZone(del_params);
  1027. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  1028. // Similar to the previous case, but RDATA is different.
  1029. copy(deleted_data, deleted_data + DatabaseAccessor::DEL_PARAM_COUNT,
  1030. del_params);
  1031. del_params[DatabaseAccessor::DEL_RDATA] = "192.0.2.2";
  1032. accessor->deleteRecordInZone(del_params);
  1033. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  1034. }
  1035. TEST_F(SQLite3Update, invalidDelete) {
  1036. // An attempt of delete before an explicit start of transaction
  1037. EXPECT_THROW(accessor->deleteRecordInZone(del_params), DataSourceError);
  1038. // Same for NSEC3.
  1039. EXPECT_THROW(accessor->deleteNSEC3RecordInZone(del_params),
  1040. DataSourceError);
  1041. }
  1042. TEST_F(SQLite3Update, emptyTransaction) {
  1043. // A generic transaction without doing anything inside it. Just check
  1044. // it doesn't throw or break the database.
  1045. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  1046. accessor->startTransaction();
  1047. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  1048. accessor->commit();
  1049. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  1050. }
  1051. TEST_F(SQLite3Update, duplicateTransaction) {
  1052. accessor->startTransaction();
  1053. EXPECT_THROW(accessor->startTransaction(), DataSourceError);
  1054. }
  1055. TEST_F(SQLite3Update, transactionInUpdate) {
  1056. accessor->startUpdateZone("example.com.", true);
  1057. EXPECT_THROW(accessor->startTransaction(), DataSourceError);
  1058. }
  1059. TEST_F(SQLite3Update, updateInTransaction) {
  1060. accessor->startTransaction();
  1061. EXPECT_THROW(accessor->startUpdateZone("example.com.", true),
  1062. DataSourceError);
  1063. }
  1064. TEST_F(SQLite3Update, updateWithTransaction) {
  1065. // Start a read-only transaction, wherein we execute two reads.
  1066. // Meanwhile we start a write (update) transaction. The commit attempt
  1067. // for the write transaction will due to the lock held by the read
  1068. // transaction. The database should be intact.
  1069. another_accessor->startTransaction();
  1070. checkRecords(*another_accessor, zone_id, "foo.bar.example.com.",
  1071. expected_stored);
  1072. ASSERT_TRUE(accessor->startUpdateZone("example.com.", true).first);
  1073. EXPECT_THROW(accessor->commit(), DataSourceError);
  1074. checkRecords(*another_accessor, zone_id, "foo.bar.example.com.",
  1075. expected_stored);
  1076. another_accessor->commit(); // this shouldn't throw
  1077. }
  1078. TEST_F(SQLite3Update, updateWithoutTransaction) {
  1079. // Similar to the previous test, but reads are not protected in a
  1080. // transaction. So the write transaction will succeed and flush the DB,
  1081. // and the result of the second read is different from the first.
  1082. checkRecords(*another_accessor, zone_id, "foo.bar.example.com.",
  1083. expected_stored);
  1084. ASSERT_TRUE(accessor->startUpdateZone("example.com.", true).first);
  1085. accessor->commit();
  1086. checkRecords(*another_accessor, zone_id, "foo.bar.example.com.",
  1087. empty_stored);
  1088. }
  1089. TEST_F(SQLite3Update, concurrentTransactions) {
  1090. // Two read-only transactions coexist (unlike the read vs write)
  1091. // Start one transaction.
  1092. accessor->startTransaction();
  1093. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  1094. // Start a new one.
  1095. another_accessor->startTransaction();
  1096. // The second transaction doesn't affect the first or vice versa.
  1097. checkRecords(*accessor, zone_id, "foo.bar.example.com.", expected_stored);
  1098. checkRecords(*another_accessor, zone_id, "foo.bar.example.com.",
  1099. expected_stored);
  1100. // Commit should be successful for both transactions.
  1101. accessor->commit();
  1102. another_accessor->commit();
  1103. }
  1104. //
  1105. // Commonly used data for diff related tests. The last two entries are
  1106. // a textual representation of "version" and a textual representation of
  1107. // diff operation (either DIFF_ADD_TEXT or DIFF_DELETE_TEXT). We use this
  1108. // format for the convenience of generating test data and checking the results.
  1109. //
  1110. const char* const DIFF_ADD_TEXT = "0";
  1111. const char* const DIFF_DELETE_TEXT = "1";
  1112. const char* const diff_begin_data[] = {
  1113. "example.com.", "SOA", "3600",
  1114. "ns.example.com. admin.example.com. 1234 3600 1800 2419200 7200",
  1115. "1234", DIFF_DELETE_TEXT
  1116. };
  1117. const char* const diff_del_a_data[] = {
  1118. "dns01.example.com.", "A", "3600", "192.0.2.1", "1234", DIFF_DELETE_TEXT
  1119. };
  1120. const char* const diff_end_data[] = {
  1121. "example.com.", "SOA", "3600",
  1122. "ns.example.com. admin.example.com. 1300 3600 1800 2419200 7200",
  1123. "1300", DIFF_ADD_TEXT
  1124. };
  1125. const char* const diff_add_a_data[] = {
  1126. "dns01.example.com.", "A", "3600", "192.0.2.10", "1300", DIFF_ADD_TEXT
  1127. };
  1128. // The following two are helper functions to convert textual test data
  1129. // to integral zone ID and diff operation.
  1130. int
  1131. getVersion(const char* const diff_data[]) {
  1132. return (lexical_cast<int>(diff_data[DatabaseAccessor::DIFF_PARAM_COUNT]));
  1133. }
  1134. DatabaseAccessor::DiffOperation
  1135. getOperation(const char* const diff_data[]) {
  1136. return (static_cast<DatabaseAccessor::DiffOperation>(
  1137. lexical_cast<int>(
  1138. diff_data[DatabaseAccessor::DIFF_PARAM_COUNT + 1])));
  1139. }
  1140. // Common checker function that compares expected and actual sequence of
  1141. // diffs.
  1142. void
  1143. checkDiffs(const vector<const char* const*>& expected,
  1144. DatabaseAccessor::IteratorContextPtr rr_iterator)
  1145. {
  1146. vector<vector<string> > actual;
  1147. string columns_holder[DatabaseAccessor::COLUMN_COUNT];
  1148. while (rr_iterator->getNext(columns_holder)) {
  1149. // Reorder the 'actual' vector to be compatible with the expected one.
  1150. vector<string> columns;
  1151. columns.push_back(columns_holder[DatabaseAccessor::NAME_COLUMN]);
  1152. columns.push_back(columns_holder[DatabaseAccessor::TYPE_COLUMN]);
  1153. columns.push_back(columns_holder[DatabaseAccessor::TTL_COLUMN]);
  1154. columns.push_back(columns_holder[DatabaseAccessor::RDATA_COLUMN]);
  1155. actual.push_back(columns);
  1156. }
  1157. EXPECT_EQ(expected.size(), actual.size());
  1158. const size_t n_diffs = std::min(expected.size(), actual.size());
  1159. for (size_t i = 0; i < n_diffs; ++i) {
  1160. for (int j = 0; j < actual[i].size(); ++j) {
  1161. EXPECT_EQ(expected[i][j], actual[i][j]);
  1162. }
  1163. }
  1164. }
  1165. TEST_F(SQLite3Update, addRecordDiff) {
  1166. // A simple case of adding diffs: just changing the SOA, and confirm
  1167. // the diffs are stored as expected.
  1168. zone_id = accessor->startUpdateZone("example.com.", false).second;
  1169. copy(diff_begin_data, diff_begin_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1170. diff_params);
  1171. accessor->addRecordDiff(zone_id, getVersion(diff_begin_data),
  1172. getOperation(diff_begin_data), diff_params);
  1173. copy(diff_end_data, diff_end_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1174. diff_params);
  1175. accessor->addRecordDiff(zone_id, getVersion(diff_end_data),
  1176. getOperation(diff_end_data), diff_params);
  1177. // Until the diffs are committed, they are not visible to other accessors.
  1178. EXPECT_THROW(another_accessor->getDiffs(zone_id, 1234, 1300),
  1179. NoSuchSerial);
  1180. accessor->commit();
  1181. expected_stored.clear();
  1182. expected_stored.push_back(diff_begin_data);
  1183. expected_stored.push_back(diff_end_data);
  1184. checkDiffs(expected_stored, accessor->getDiffs(zone_id, 1234, 1300));
  1185. // Now it should be visible to others, too.
  1186. checkDiffs(expected_stored, another_accessor->getDiffs(zone_id, 1234,
  1187. 1300));
  1188. }
  1189. TEST_F(SQLite3Update, addRecordOfLargeSerial) {
  1190. // This is essentially the same as the previous test, but using a
  1191. // very large "version" (SOA serial), which is actually the possible
  1192. // largest value to confirm the internal code doesn't have an overflow bug
  1193. // or other failure due to the larger value.
  1194. zone_id = accessor->startUpdateZone("example.com.", false).second;
  1195. const char* const begin_data[] = {
  1196. "example.com.", "SOA", "3600",
  1197. "ns.example.com. admin.example.com. 4294967295 3600 1800 2419200 7200",
  1198. "4294967295", DIFF_DELETE_TEXT
  1199. };
  1200. copy(begin_data, begin_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1201. diff_params);
  1202. // For "serial" parameter, we intentionally hardcode the value rather
  1203. // than converting it from the data.
  1204. accessor->addRecordDiff(zone_id, 0xffffffff, getOperation(diff_begin_data),
  1205. diff_params);
  1206. copy(diff_end_data, diff_end_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1207. diff_params);
  1208. accessor->addRecordDiff(zone_id, getVersion(diff_end_data),
  1209. getOperation(diff_end_data), diff_params);
  1210. accessor->commit();
  1211. expected_stored.clear();
  1212. expected_stored.push_back(begin_data);
  1213. expected_stored.push_back(diff_end_data);
  1214. checkDiffs(expected_stored, accessor->getDiffs(zone_id, 4294967295U, 1300));
  1215. }
  1216. TEST_F(SQLite3Update, addDiffWithoutUpdate) {
  1217. // Right now we require startUpdateZone() prior to performing
  1218. // addRecordDiff.
  1219. copy(diff_begin_data, diff_begin_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1220. diff_params);
  1221. EXPECT_THROW(accessor->addRecordDiff(0, getVersion(diff_begin_data),
  1222. getOperation(diff_begin_data),
  1223. diff_params),
  1224. DataSourceError);
  1225. // For now, we don't allow adding diffs in a general transaction either.
  1226. accessor->startTransaction();
  1227. EXPECT_THROW(accessor->addRecordDiff(0, getVersion(diff_begin_data),
  1228. getOperation(diff_begin_data),
  1229. diff_params),
  1230. DataSourceError);
  1231. }
  1232. TEST_F(SQLite3Update, addDiffWithBadZoneID) {
  1233. // For now, we require zone ID passed to addRecordDiff be equal to
  1234. // that for the zone being updated.
  1235. zone_id = accessor->startUpdateZone("example.com.", false).second;
  1236. copy(diff_begin_data, diff_begin_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1237. diff_params);
  1238. EXPECT_THROW(accessor->addRecordDiff(zone_id + 1,
  1239. getVersion(diff_begin_data),
  1240. getOperation(diff_begin_data),
  1241. diff_params),
  1242. DataSourceError);
  1243. }
  1244. TEST_F(SQLite3Update, addDiffRollback) {
  1245. // Rollback tentatively added diffs. This is no different from the
  1246. // update case, but we test it explicitly just in case.
  1247. zone_id = accessor->startUpdateZone("example.com.", false).second;
  1248. copy(diff_begin_data, diff_begin_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1249. diff_params);
  1250. accessor->addRecordDiff(zone_id, getVersion(diff_begin_data),
  1251. getOperation(diff_begin_data), diff_params);
  1252. accessor->rollback();
  1253. EXPECT_THROW(accessor->getDiffs(zone_id, 1234, 1234), NoSuchSerial);
  1254. }
  1255. TEST_F(SQLite3Update, addDiffInBadOrder) {
  1256. // At this level, the API is naive, and doesn't care if the diff sequence
  1257. // is a valid IXFR order.
  1258. zone_id = accessor->startUpdateZone("example.com.", false).second;
  1259. // Add diff of 'end', then 'begin'
  1260. copy(diff_end_data, diff_end_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1261. diff_params);
  1262. accessor->addRecordDiff(zone_id, getVersion(diff_end_data),
  1263. static_cast<DatabaseAccessor::DiffOperation>(
  1264. lexical_cast<int>(DIFF_DELETE_TEXT)),
  1265. diff_params);
  1266. copy(diff_begin_data, diff_begin_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1267. diff_params);
  1268. accessor->addRecordDiff(zone_id, getVersion(diff_begin_data),
  1269. static_cast<DatabaseAccessor::DiffOperation>(
  1270. lexical_cast<int>(DIFF_ADD_TEXT)),
  1271. diff_params);
  1272. accessor->commit();
  1273. expected_stored.clear();
  1274. expected_stored.push_back(diff_end_data);
  1275. expected_stored.push_back(diff_begin_data);
  1276. checkDiffs(expected_stored, accessor->getDiffs(zone_id, 1300, 1234));
  1277. }
  1278. TEST_F(SQLite3Update, addDiffWithUpdate) {
  1279. // A more realistic example: add corresponding diffs while updating zone.
  1280. // Implementation wise, there should be no reason this could fail if
  1281. // the basic tests so far pass. But we check it in case we miss something.
  1282. const char* const old_a_record[] = {
  1283. "dns01.example.com.", "A", "192.0.2.1"
  1284. };
  1285. const char* const new_a_record[] = {
  1286. "dns01.example.com.", "com.example.dns01.", "3600", "A", "",
  1287. "192.0.2.10"
  1288. };
  1289. const char* const old_soa_record[] = {
  1290. "example.com.", "SOA",
  1291. "ns.example.com. admin.example.com. 1234 3600 1800 2419200 7200",
  1292. };
  1293. const char* const new_soa_record[] = {
  1294. "dns01.example.com.", "com.example.dns01.", "3600", "A", "",
  1295. "ns.example.com. admin.example.com. 1300 3600 1800 2419200 7200",
  1296. };
  1297. zone_id = accessor->startUpdateZone("example.com.", false).second;
  1298. // Delete SOA (and add that diff)
  1299. copy(old_soa_record, old_soa_record + DatabaseAccessor::DEL_PARAM_COUNT,
  1300. del_params);
  1301. accessor->deleteRecordInZone(del_params);
  1302. copy(diff_begin_data, diff_begin_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1303. diff_params);
  1304. accessor->addRecordDiff(zone_id, getVersion(diff_begin_data),
  1305. getOperation(diff_begin_data), diff_params);
  1306. // Delete A
  1307. copy(old_a_record, old_a_record + DatabaseAccessor::DEL_PARAM_COUNT,
  1308. del_params);
  1309. accessor->deleteRecordInZone(del_params);
  1310. copy(diff_del_a_data, diff_del_a_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1311. diff_params);
  1312. accessor->addRecordDiff(zone_id, getVersion(diff_del_a_data),
  1313. getOperation(diff_del_a_data), diff_params);
  1314. // Add SOA
  1315. copy(new_soa_record, new_soa_record + DatabaseAccessor::ADD_COLUMN_COUNT,
  1316. add_columns);
  1317. accessor->addRecordToZone(add_columns);
  1318. copy(diff_end_data, diff_end_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1319. diff_params);
  1320. accessor->addRecordDiff(zone_id, getVersion(diff_end_data),
  1321. getOperation(diff_end_data), diff_params);
  1322. // Add A
  1323. copy(new_a_record, new_a_record + DatabaseAccessor::ADD_COLUMN_COUNT,
  1324. add_columns);
  1325. accessor->addRecordToZone(add_columns);
  1326. copy(diff_add_a_data, diff_add_a_data + DatabaseAccessor::DIFF_PARAM_COUNT,
  1327. diff_params);
  1328. accessor->addRecordDiff(zone_id, getVersion(diff_add_a_data),
  1329. getOperation(diff_add_a_data), diff_params);
  1330. accessor->commit();
  1331. expected_stored.clear();
  1332. expected_stored.push_back(diff_begin_data);
  1333. expected_stored.push_back(diff_del_a_data);
  1334. expected_stored.push_back(diff_end_data);
  1335. expected_stored.push_back(diff_add_a_data);
  1336. checkDiffs(expected_stored, accessor->getDiffs(zone_id, 1234, 1300));
  1337. }
  1338. } // end anonymous namespace