sqlite3_accessor_unittest.cc 53 KB

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