From: JINMEI Tatuya Date: Tue, 17 Apr 2012 22:44:40 +0000 (-0700) Subject: [1891] implemented addNSEC3RecordToZone, 1st step. X-Git-Tag: trac2351_base~226^2~116^2~25^2~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7aac25a59bfb9dbdbdbc4c8334204d24f7e0b131;p=thirdparty%2Fkea.git [1891] implemented addNSEC3RecordToZone, 1st step. defined a new statement for updating the nsec3 table, and used it from addNSEC3RecordToZone. some validation checks are still missing. also made simple cleanup of removing unnecessary namespace qualifiers. --- diff --git a/src/lib/datasrc/sqlite3_accessor.cc b/src/lib/datasrc/sqlite3_accessor.cc index cbc30117b0..e5a22f4ebe 100644 --- a/src/lib/datasrc/sqlite3_accessor.cc +++ b/src/lib/datasrc/sqlite3_accessor.cc @@ -73,7 +73,8 @@ enum StatementID { NSEC3 = 16, NSEC3_PREVIOUS = 17, NSEC3_LAST = 18, - NUM_STATEMENTS = 19 + ADD_NSEC3_RECORD = 19, + NUM_STATEMENTS = 20 }; const char* const text_statements[NUM_STATEMENTS] = { @@ -135,19 +136,22 @@ const char* const text_statements[NUM_STATEMENTS] = { "WHERE zone_id=?1 AND id>=?2 and id<=?3 " "ORDER BY id ASC", - // Query to get the NSEC3 records + // NSEC3: Query to get the NSEC3 records // // The "1" in SELECT is for positioning the rdata column to the // expected position, so we can reuse the same code as for other // lookups. "SELECT rdtype, ttl, 1, rdata FROM nsec3 WHERE zone_id=?1 AND " "hash=?2", - // For getting the previous NSEC3 hash + // NSEC3_PREVIOUS: For getting the previous NSEC3 hash "SELECT DISTINCT hash FROM nsec3 WHERE zone_id=?1 AND hash < ?2 " "ORDER BY hash DESC LIMIT 1", - // And for wrap-around + // NSEC3_LAST: And for wrap-around "SELECT DISTINCT hash FROM nsec3 WHERE zone_id=?1 " "ORDER BY hash DESC LIMIT 1", + // ADD_NSEC3_RECORD: Add NSEC3-related (NSEC3 or NSEC3-covering RRSIG) RR + "INSERT INTO nsec3 (zone_id, hash, owner, ttl, rdtype, rdata) " + "VALUES (?1, ?2, '', ?3, ?4, ?5)" }; struct SQLite3Parameters { @@ -1128,15 +1132,17 @@ SQLite3Accessor::addRecordToZone(const string (&columns)[ADD_COLUMN_COUNT]) { isc_throw(DataSourceError, "adding record to SQLite3 " "data source without transaction"); } - doUpdate( + doUpdate( *dbparameters_, ADD_RECORD, columns, "add record to zone"); } void SQLite3Accessor::addNSEC3RecordToZone( - const string (&/*columns*/)[ADD_NSEC3_COLUMN_COUNT]) + const string (&columns)[ADD_NSEC3_COLUMN_COUNT]) { - isc_throw(NotImplemented, "not yet implemented"); + // TODO: no transaction case + doUpdate( + *dbparameters_, ADD_NSEC3_RECORD, columns, "add NSEC3 record to zone"); } void @@ -1145,7 +1151,7 @@ SQLite3Accessor::deleteRecordInZone(const string (¶ms)[DEL_PARAM_COUNT]) { isc_throw(DataSourceError, "deleting record in SQLite3 " "data source without transaction"); } - doUpdate( + doUpdate( *dbparameters_, DEL_RECORD, params, "delete record from zone"); } diff --git a/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc b/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc index f3aea4e225..12f7b395ff 100644 --- a/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc +++ b/src/lib/datasrc/tests/sqlite3_accessor_unittest.cc @@ -12,8 +12,7 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. -#include -#include +#include "faked_nsec3.h" #include @@ -21,14 +20,20 @@ #include +#include + #include + #include #include + +#include +#include #include -#include using namespace std; using namespace isc::datasrc; +using namespace isc::datasrc::test; using boost::lexical_cast; using isc::data::ConstElementPtr; using isc::data::Element; @@ -463,11 +468,11 @@ TEST(SQLite3Open, getDBNameExampleROOT) { // Simple function to match records void checkRecordRow(const std::string columns[], - const std::string& field0, - const std::string& field1, - const std::string& field2, - const std::string& field3, - const std::string& field4) + const std::string& field0, // for type + const std::string& field1, // for TTL + const std::string& field2, // for "sigtype" + const std::string& field3, // for rdata + const std::string& field4) // for name { EXPECT_EQ(field0, columns[DatabaseAccessor::TYPE_COLUMN]); EXPECT_EQ(field1, columns[DatabaseAccessor::TTL_COLUMN]); @@ -736,6 +741,18 @@ const char* const deleted_data[] = { // Existing data to be removed commonly used by some of the tests below "foo.bar.example.com.", "A", "192.0.2.1" }; +const char* const nsec3_data[DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT] = { + // example NSEC parameters. Using "apex_hash" just as a convenient + // shortcut; otherwise it has nothing to do with the zone apex for the + // purpose of this test. + apex_hash, "3600", "NSEC3", + "1 1 12 AABBCCDD 2T7B4G4VSA5SMI47K61MV5BV1A22BOJR NS SOA" +}; +const char* const nsec3_sig_data[DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT] = { + ns1_hash, "3600", "RRSIG", + "NSEC3 5 3 3600 20000101000000 20000201000000 12345 " + "example.com. FAKEFAKEFAKE" +}; class SQLite3Update : public SQLite3AccessorTest { protected: @@ -762,6 +779,7 @@ protected: int zone_id; std::string get_columns[DatabaseAccessor::COLUMN_COUNT]; std::string add_columns[DatabaseAccessor::ADD_COLUMN_COUNT]; + std::string add_nsec3_columns[DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT]; std::string del_params[DatabaseAccessor::DEL_PARAM_COUNT]; std::string diff_params[DatabaseAccessor::DIFF_PARAM_COUNT]; @@ -789,6 +807,28 @@ checkRecords(SQLite3Accessor& accessor, int zone_id, const std::string& name, EXPECT_TRUE(it == expected_rows.end()); } +// Similar to the previous one, but checking transactions on the nsec3 table. +void +checkNSEC3Records(SQLite3Accessor& accessor, int zone_id, + const std::string& hash, + vector expected_rows) +{ + DatabaseAccessor::IteratorContextPtr iterator = + accessor.getNSEC3Records(hash, zone_id); + std::string columns[DatabaseAccessor::COLUMN_COUNT]; + vector::const_iterator it = expected_rows.begin(); + while (iterator->getNext(columns)) { + ASSERT_TRUE(it != expected_rows.end()); + checkRecordRow(columns, (*it)[DatabaseAccessor::ADD_NSEC3_TYPE], + (*it)[DatabaseAccessor::ADD_NSEC3_TTL], + "", // sigtype, should always be empty + (*it)[DatabaseAccessor::ADD_NSEC3_RDATA], + ""); // name, always empty + ++it; + } + EXPECT_TRUE(it == expected_rows.end()); +} + TEST_F(SQLite3Update, emptyUpdate) { // If we do nothing between start and commit, the zone content // should be intact. @@ -924,6 +964,38 @@ TEST_F(SQLite3Update, addRecord) { checkRecords(*accessor, zone_id, "newdata.example.com.", expected_stored); } +TEST_F(SQLite3Update, addNSEC3Record) { + // Similar to the previous test, but for NSEC3-related records + checkRecords(*accessor, zone_id, apex_hash, empty_stored); + checkRecords(*accessor, zone_id, ns1_hash, empty_stored); + + zone_id = accessor->startUpdateZone("example.com.", false).second; + // Add an NSEC3 + copy(nsec3_data, nsec3_data + DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT, + add_nsec3_columns); + accessor->addNSEC3RecordToZone(add_nsec3_columns); + // Add an RRSIG for NSEC3 + copy(nsec3_sig_data, + nsec3_sig_data + DatabaseAccessor::ADD_NSEC3_COLUMN_COUNT, + add_nsec3_columns); + accessor->addNSEC3RecordToZone(add_nsec3_columns); + + // Check the stored data, before and after commit(). + for (size_t i = 0; i < 2; ++i) { + expected_stored.clear(); + expected_stored.push_back(nsec3_data); + checkNSEC3Records(*accessor, zone_id, apex_hash, expected_stored); + + expected_stored.clear(); + expected_stored.push_back(nsec3_sig_data); + checkNSEC3Records(*accessor, zone_id, ns1_hash, expected_stored); + + if (i == 0) { // make sure commit() happens only once + accessor->commit(); + } + } +} + TEST_F(SQLite3Update, addThenRollback) { zone_id = accessor->startUpdateZone("example.com.", false).second; copy(new_data, new_data + DatabaseAccessor::ADD_COLUMN_COUNT,