sqlite3_connection_unittest.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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 <datasrc/sqlite3_connection.h>
  15. #include <datasrc/data_source.h>
  16. #include <dns/rrclass.h>
  17. #include <gtest/gtest.h>
  18. #include <boost/shared_ptr.hpp>
  19. #include <boost/scoped_ptr.hpp>
  20. using namespace isc::datasrc;
  21. using isc::data::ConstElementPtr;
  22. using isc::data::Element;
  23. using isc::dns::RRClass;
  24. using isc::dns::Name;
  25. namespace {
  26. // Some test data
  27. std::string SQLITE_DBFILE_EXAMPLE = TEST_DATA_DIR "/test.sqlite3";
  28. std::string SQLITE_DBFILE_EXAMPLE2 = TEST_DATA_DIR "/example2.com.sqlite3";
  29. std::string SQLITE_DBFILE_EXAMPLE_ROOT = TEST_DATA_DIR "/test-root.sqlite3";
  30. std::string SQLITE_DBFILE_BROKENDB = TEST_DATA_DIR "/brokendb.sqlite3";
  31. std::string SQLITE_DBFILE_MEMORY = ":memory:";
  32. // The following file must be non existent and must be non"creatable";
  33. // the sqlite3 library will try to create a new DB file if it doesn't exist,
  34. // so to test a failure case the create operation should also fail.
  35. // The "nodir", a non existent directory, is inserted for this purpose.
  36. std::string SQLITE_DBFILE_NOTEXIST = TEST_DATA_DIR "/nodir/notexist";
  37. // Opening works (the content is tested in different tests)
  38. TEST(SQLite3Open, common) {
  39. EXPECT_NO_THROW(SQLite3Connection conn(SQLITE_DBFILE_EXAMPLE,
  40. RRClass::IN()));
  41. }
  42. // The file can't be opened
  43. TEST(SQLite3Open, notExist) {
  44. EXPECT_THROW(SQLite3Connection conn(SQLITE_DBFILE_NOTEXIST,
  45. RRClass::IN()), SQLite3Error);
  46. }
  47. // It rejects broken DB
  48. TEST(SQLite3Open, brokenDB) {
  49. EXPECT_THROW(SQLite3Connection conn(SQLITE_DBFILE_BROKENDB,
  50. RRClass::IN()), SQLite3Error);
  51. }
  52. // Test we can create the schema on the fly
  53. TEST(SQLite3Open, memoryDB) {
  54. EXPECT_NO_THROW(SQLite3Connection conn(SQLITE_DBFILE_MEMORY,
  55. RRClass::IN()));
  56. }
  57. // Test fixture for querying the connection
  58. class SQLite3Conn : public ::testing::Test {
  59. public:
  60. SQLite3Conn() {
  61. initConn(SQLITE_DBFILE_EXAMPLE, RRClass::IN());
  62. }
  63. // So it can be re-created with different data
  64. void initConn(const std::string& filename, const RRClass& rrclass) {
  65. conn.reset(new SQLite3Connection(filename, rrclass));
  66. }
  67. // The tested connection
  68. boost::scoped_ptr<SQLite3Connection> conn;
  69. };
  70. // This zone exists in the data, so it should be found
  71. TEST_F(SQLite3Conn, getZone) {
  72. std::pair<bool, int> result(conn->getZone(Name("example.com")));
  73. EXPECT_TRUE(result.first);
  74. EXPECT_EQ(1, result.second);
  75. }
  76. // But it should find only the zone, nothing below it
  77. TEST_F(SQLite3Conn, subZone) {
  78. EXPECT_FALSE(conn->getZone(Name("sub.example.com")).first);
  79. }
  80. // This zone is not there at all
  81. TEST_F(SQLite3Conn, noZone) {
  82. EXPECT_FALSE(conn->getZone(Name("example.org")).first);
  83. }
  84. // This zone is there, but in different class
  85. TEST_F(SQLite3Conn, noClass) {
  86. initConn(SQLITE_DBFILE_EXAMPLE, RRClass::CH());
  87. EXPECT_FALSE(conn->getZone(Name("example.com")).first);
  88. }
  89. // Simple function to cound the number of records for
  90. // any name
  91. void
  92. checkRecordRow(const std::string columns[],
  93. const std::string& field0,
  94. const std::string& field1,
  95. const std::string& field2,
  96. const std::string& field3)
  97. {
  98. EXPECT_EQ(field0, columns[0]);
  99. EXPECT_EQ(field1, columns[1]);
  100. EXPECT_EQ(field2, columns[2]);
  101. EXPECT_EQ(field3, columns[3]);
  102. }
  103. TEST_F(SQLite3Conn, getRecords) {
  104. const std::pair<bool, int> zone_info(conn->getZone(Name("example.com")));
  105. ASSERT_TRUE(zone_info.first);
  106. const int zone_id = zone_info.second;
  107. ASSERT_EQ(1, zone_id);
  108. const size_t column_count = DatabaseConnection::RecordColumnCount;
  109. std::string columns[column_count];
  110. // without search, getNext() should return false
  111. EXPECT_FALSE(conn->getNextRecord(columns,
  112. column_count));
  113. checkRecordRow(columns, "", "", "", "");
  114. conn->searchForRecords(zone_id, "foo.bar.");
  115. EXPECT_FALSE(conn->getNextRecord(columns, column_count));
  116. checkRecordRow(columns, "", "", "", "");
  117. conn->searchForRecords(zone_id, "");
  118. EXPECT_FALSE(conn->getNextRecord(columns, column_count));
  119. checkRecordRow(columns, "", "", "", "");
  120. // Should error on a bad number of columns
  121. EXPECT_THROW(conn->getNextRecord(columns, 3), DataSourceError);
  122. EXPECT_THROW(conn->getNextRecord(columns, 5), DataSourceError);
  123. // now try some real searches
  124. conn->searchForRecords(zone_id, "foo.example.com.");
  125. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  126. checkRecordRow(columns, "CNAME", "3600", "",
  127. "cnametest.example.org.");
  128. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  129. checkRecordRow(columns, "RRSIG", "3600", "CNAME",
  130. "CNAME 5 3 3600 20100322084538 20100220084538 33495 "
  131. "example.com. FAKEFAKEFAKEFAKE");
  132. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  133. checkRecordRow(columns, "NSEC", "7200", "",
  134. "mail.example.com. CNAME RRSIG NSEC");
  135. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  136. checkRecordRow(columns, "RRSIG", "7200", "NSEC",
  137. "NSEC 5 3 7200 20100322084538 20100220084538 33495 "
  138. "example.com. FAKEFAKEFAKEFAKE");
  139. EXPECT_FALSE(conn->getNextRecord(columns, column_count));
  140. // with no more records, the array should not have been modified
  141. checkRecordRow(columns, "RRSIG", "7200", "NSEC",
  142. "NSEC 5 3 7200 20100322084538 20100220084538 33495 "
  143. "example.com. FAKEFAKEFAKEFAKE");
  144. conn->searchForRecords(zone_id, "example.com.");
  145. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  146. checkRecordRow(columns, "SOA", "3600", "",
  147. "master.example.com. admin.example.com. "
  148. "1234 3600 1800 2419200 7200");
  149. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  150. checkRecordRow(columns, "RRSIG", "3600", "SOA",
  151. "SOA 5 2 3600 20100322084538 20100220084538 "
  152. "33495 example.com. FAKEFAKEFAKEFAKE");
  153. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  154. checkRecordRow(columns, "NS", "1200", "", "dns01.example.com.");
  155. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  156. checkRecordRow(columns, "NS", "3600", "", "dns02.example.com.");
  157. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  158. checkRecordRow(columns, "NS", "1800", "", "dns03.example.com.");
  159. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  160. checkRecordRow(columns, "RRSIG", "3600", "NS",
  161. "NS 5 2 3600 20100322084538 20100220084538 "
  162. "33495 example.com. FAKEFAKEFAKEFAKE");
  163. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  164. checkRecordRow(columns, "MX", "3600", "", "10 mail.example.com.");
  165. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  166. checkRecordRow(columns, "MX", "3600", "",
  167. "20 mail.subzone.example.com.");
  168. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  169. checkRecordRow(columns, "RRSIG", "3600", "MX",
  170. "MX 5 2 3600 20100322084538 20100220084538 "
  171. "33495 example.com. FAKEFAKEFAKEFAKE");
  172. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  173. checkRecordRow(columns, "NSEC", "7200", "",
  174. "cname-ext.example.com. NS SOA MX RRSIG NSEC DNSKEY");
  175. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  176. checkRecordRow(columns, "RRSIG", "7200", "NSEC",
  177. "NSEC 5 2 7200 20100322084538 20100220084538 "
  178. "33495 example.com. FAKEFAKEFAKEFAKE");
  179. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  180. checkRecordRow(columns, "DNSKEY", "3600", "",
  181. "256 3 5 AwEAAcOUBllYc1hf7ND9uDy+Yz1BF3sI0m4q NGV7W"
  182. "cTD0WEiuV7IjXgHE36fCmS9QsUxSSOV o1I/FMxI2PJVqTYHkX"
  183. "FBS7AzLGsQYMU7UjBZ SotBJ6Imt5pXMu+lEDNy8TOUzG3xm7g"
  184. "0qcbW YF6qCEfvZoBtAqi5Rk7Mlrqs8agxYyMx");
  185. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  186. checkRecordRow(columns, "DNSKEY", "3600", "",
  187. "257 3 5 AwEAAe5WFbxdCPq2jZrZhlMj7oJdff3W7syJ tbvzg"
  188. "62tRx0gkoCDoBI9DPjlOQG0UAbj+xUV 4HQZJStJaZ+fHU5AwV"
  189. "NT+bBZdtV+NujSikhd THb4FYLg2b3Cx9NyJvAVukHp/91HnWu"
  190. "G4T36 CzAFrfPwsHIrBz9BsaIQ21VRkcmj7DswfI/i DGd8j6b"
  191. "qiODyNZYQ+ZrLmF0KIJ2yPN3iO6Zq 23TaOrVTjB7d1a/h31OD"
  192. "fiHAxFHrkY3t3D5J R9Nsl/7fdRmSznwtcSDgLXBoFEYmw6p86"
  193. "Acv RyoYNcL1SXjaKVLG5jyU3UR+LcGZT5t/0xGf oIK/aKwEN"
  194. "rsjcKZZj660b1M=");
  195. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  196. checkRecordRow(columns, "RRSIG", "3600", "DNSKEY",
  197. "DNSKEY 5 2 3600 20100322084538 20100220084538 "
  198. "4456 example.com. FAKEFAKEFAKEFAKE");
  199. ASSERT_TRUE(conn->getNextRecord(columns, column_count));
  200. checkRecordRow(columns, "RRSIG", "3600", "DNSKEY",
  201. "DNSKEY 5 2 3600 20100322084538 20100220084538 "
  202. "33495 example.com. FAKEFAKEFAKEFAKE");
  203. EXPECT_FALSE(conn->getNextRecord(columns, column_count));
  204. // getnextrecord returning false should mean array is not altered
  205. checkRecordRow(columns, "RRSIG", "3600", "DNSKEY",
  206. "DNSKEY 5 2 3600 20100322084538 20100220084538 "
  207. "33495 example.com. FAKEFAKEFAKEFAKE");
  208. }
  209. } // end anonymous namespace