Browse Source

[master] Merge branch 'trac2679'

JINMEI Tatuya 12 years ago
parent
commit
6699e12852

+ 2 - 1
src/lib/datasrc/tests/Makefile.am

@@ -50,7 +50,8 @@ run_unittests_SOURCES = $(common_sources)
 run_unittests_SOURCES += test_client.h test_client.cc
 run_unittests_SOURCES += logger_unittest.cc
 run_unittests_SOURCES += client_unittest.cc
-run_unittests_SOURCES += database_unittest.cc
+run_unittests_SOURCES += database_unittest.h database_unittest.cc
+run_unittests_SOURCES += database_sqlite3_unittest.cc
 run_unittests_SOURCES += sqlite3_accessor_unittest.cc
 run_unittests_SOURCES += zone_finder_context_unittest.cc
 run_unittests_SOURCES += faked_nsec3.h faked_nsec3.cc

+ 68 - 0
src/lib/datasrc/tests/database_sqlite3_unittest.cc

@@ -0,0 +1,68 @@
+// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <datasrc/tests/database_unittest.h>
+
+#include <datasrc/database.h>
+#include <datasrc/sqlite3_accessor.h>
+
+#include <exceptions/exceptions.h>
+
+#include <gtest/gtest.h>
+
+#include <boost/shared_ptr.hpp>
+
+#include <cstdlib>
+#include <string>
+
+using std::string;
+
+using namespace isc::datasrc;
+using namespace isc::datasrc::test;
+
+namespace {
+boost::shared_ptr<DatabaseAccessor>
+createSQLite3Accessor() {
+    // To make sure we always have empty diffs table at the beginning of
+    // each test, we re-install the writable data source here.
+    const char* const install_cmd = INSTALL_PROG " -c " TEST_DATA_COMMONDIR
+        "/rwtest.sqlite3 " TEST_DATA_BUILDDIR "/rwtest.sqlite3.copied";
+    if (std::system(install_cmd) != 0) {
+        // any exception will do, this is failure in test setup, but nice
+        // to show the command that fails, and shouldn't be caught
+        isc_throw(isc::Unexpected,
+                  "Error setting up; command failed: " << install_cmd);
+    }
+
+    // The SQLite accessor implements all API, so we can use the generic
+    // loadTestDataGeneric once accessor is created.
+    boost::shared_ptr<DatabaseAccessor> accessor(
+        new SQLite3Accessor(TEST_DATA_BUILDDIR "/rwtest.sqlite3.copied",
+                            "IN"));
+    loadTestDataGeneric(*accessor);
+
+    return (accessor);
+}
+
+// The test parameter for the SQLite3 accessor.  We can use enableNSEC3Generic
+// as this accessor fully supports NSEC3 related APIs.
+const DatabaseClientTestParam sqlite3_param = { createSQLite3Accessor,
+                                                enableNSEC3Generic };
+
+INSTANTIATE_TEST_CASE_P(SQLite3, DatabaseClientTest,
+                        ::testing::Values(&sqlite3_param));
+
+INSTANTIATE_TEST_CASE_P(SQLite3, RRsetCollectionTest,
+                        ::testing::Values(&sqlite3_param));
+}

File diff suppressed because it is too large
+ 1622 - 1844
src/lib/datasrc/tests/database_unittest.cc


+ 278 - 0
src/lib/datasrc/tests/database_unittest.h

@@ -0,0 +1,278 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <datasrc/database.h>
+#include <datasrc/tests/faked_nsec3.h>
+
+#include <dns/name.h>
+#include <dns/rrclass.h>
+#include <dns/rrtype.h>
+#include <dns/rrttl.h>
+#include <dns/rrset.h>
+#include <dns/rrset_collection_base.h>
+#include <dns/nsec3hash.h>
+
+#include <gtest/gtest.h>
+
+#include <boost/shared_ptr.hpp>
+
+#include <string>
+#include <vector>
+
+namespace isc {
+namespace datasrc {
+namespace test {
+
+/// \brief Commonly used test data.
+///
+/// This is an array of 5 C-string tuples, each of the tuples has the
+/// following semantics.
+/// [0] textual form of fully qualified, dot-terminated domain name
+///     (NAME_COLUMN).
+/// [1] textual form of RR type, such as "AAAA" (TYPE_COLUMN)
+/// [2] textual numeric form of RR TTL (TTL_COLUMN)
+/// [3] textual form of RR type, intended to be used to represent the
+///     "covered type" of RRSIG RRs, but actually not used at the moment.
+///     (SIGTYPE_COLUMN)
+/// [4] textual form of RDATA of the type, e.g., "2001:db8::1" for AAAA
+///     (RDATA_COLUMN)
+///
+/// These correspond to the array fields returned by
+/// \c DatabaseAccessor::IteratorContext::getNext().  The upper-cased names
+/// surrounded by parentheses specify the corresponding field for the specific
+/// entry.
+///
+/// It ends with a special entry of an all-NULL tuple.
+///
+/// For testing a custom accessor, it's expected to "load" the data of these
+/// records on a call to \c accessor_creator member of
+/// \c DatabaseClientTestParam (see the structure description).  In tests,
+/// the loaded data should be able to be retrieved by subsequent
+/// \c getRecords() or \c getNSEC3Records() calls.  The specific realization
+/// of the load can be specific to the accessor implementation, but if it
+/// conforms to the API of the following methods of \c DatabaseAccessor,
+/// it can be done by calling \c loadTestDataGeneric():
+/// - startUpdateZone()
+/// - addRecordToZone()
+/// - commit()
+extern const char* const TEST_RECORDS[][5];
+
+/// \brief NSEC3PARAM at the zone origin and its RRSIG.
+///
+/// The semantics of the data is the same as that for TEST_RECORDS.
+///
+/// These will be "loaded" on a call to
+/// \c DatabaseClientTestParam::enable_nsec3_fn for some tests that tests
+/// NSEC3 related behavior.  If the tested accessor skips the support for
+/// NSEC3, this data ban be ignored.
+extern const char* TEST_NSEC3PARAM_RECORDS[][5];
+
+/// \brief NSEC3 RR data commonly used for NSEC3-related tests.
+///
+/// This is similar to TEST_RECORDS, but the first entry is base32-hex encoded
+/// hash value (which is expected to appear as the first label of NSEC3
+/// owner names), not an FQDN.
+///
+/// These will be "loaded" on a call to
+/// \c DatabaseClientTestParam::enable_nsec3_fn for some tests that tests
+/// NSEC3 related behavior.  If the tested accessor skips the support for
+/// NSEC3, this data ban be ignored.  The loaded data are expected to be
+/// retrievable by subsequent \c getNSEC3Records() calls on the tested
+/// accessor.
+///
+/// The specific realization of the load can be specific to the accessor
+/// implementation, but if it conforms to the API of the following methods
+/// of \c DatabaseAccessor, it can be done by calling \c enableNSEC3Generic():
+/// - startUpdateZone()
+/// - addRecordToZone()
+/// - addNSEC3RecordToZone()
+/// - commit()
+extern const char* TEST_NSEC3_RECORDS[][5];
+
+/// \brief Test parameter for DatabaseClientTest.
+///
+/// This is the type of the parameter for the parameterized DatabaseClientTest
+/// and its derived variants.  It consists of a set of function pointers,
+/// including the factory of tested accessor.  A specific accessor
+/// implementation is expected to specify an instance of this structure,
+/// filling the members with appropriate functions for that accessor
+/// implementation.
+///
+/// Note that this is intentionally defined to be of plain old type (a plain
+/// structure whose members are bare function pointers); otherwise it could
+/// cause initialization fiasco at the instantiation time.
+struct DatabaseClientTestParam {
+    /// \brief The factory of the tested accessor.
+    ///
+    /// DatabaseClientTest will call this as part of the initialization of
+    /// each test case.  This function is expected to "load" the data
+    /// specified in TEST_RECORDS so they can be used in the tests.
+    ///
+    /// The creation of the accessor will be inherently implementation
+    /// dependent, but for loading the data it may be sufficient to call
+    /// \c loadTestDataGeneric.  See TEST_RECORDS for the condition.
+    boost::shared_ptr<DatabaseAccessor> (*accessor_creator)();
+
+    /// \brief Make NSEC3 records for the test.
+    ///
+    /// Some test cases call this function when they need to test NSEC3-related
+    /// scenarios.  It's expected to "load" the data specified in
+    /// TEST_NSEC3PARAM_RECORDS and TEST_NSEC3_RECORDS.
+    ///
+    /// The passed accessor will be the one created by the preceding call
+    /// to \c accessor_creator.
+    ///
+    /// If the accessor implementation meets some condition, this member can
+    /// be the generic \c enableNSEC3Generic function.  See TEST_RECORDS
+    /// and TEST_NSEC3_RECORDS for the condition.
+    void (*enable_nsec3_fn)(DatabaseAccessor& accessor);
+};
+
+// forward declaration, needed in the definition of DatabaseClientTest.
+// this is private to the test implementation internal otherwise.
+struct JournalEntry;
+
+/// \brief Test fixture class for the DatabaseClient implementation.
+///
+/// The primary purpose of this fixture is to test the implementation of
+/// the DatabaseClient with an internal mock DatabaseAccessor accessor.
+/// But the test cases can also be used to check specific accessor
+/// implementations.  It will be convenient for implementors of new types of
+/// accessor.
+///
+/// This fixture is therefore parameterized so that a specific accessor
+/// implementation can customize accessor-specific data of the test
+/// (most notably the accessor itself, and also the way to make test data
+/// available through the accessor).
+///
+/// See database_sqlite3_unittest.cc for how to use this test with a specific
+/// accessor implementation.
+class DatabaseClientTest :
+        public ::testing::TestWithParam<const DatabaseClientTestParam*>
+{
+protected:
+    DatabaseClientTest();
+
+    // We create accessor and other objects that depend on it in SetUp, not
+    // in the constructor, so derived test classes can override the behavior.
+    virtual void SetUp() {
+        createClient(GetParam());
+    }
+
+    ~DatabaseClientTest() {
+        // Make sure we return the default creator no matter if we set it or
+        // not
+        dns::setNSEC3HashCreator(NULL);
+    }
+
+    // We initialize the client from a function, so we can call it multiple
+    // times per test.
+    void createClient(const DatabaseClientTestParam* test_param);
+
+    /// Check the zone finder is a valid one and references the zone ID and
+    /// database available here.
+    void checkZoneFinder(const DataSourceClient::FindResult& zone);
+
+    boost::shared_ptr<DatabaseClient::Finder> getFinder();
+
+    // Helper methods for update tests
+    bool isRollbacked(bool expected = false) const;
+
+    void checkLastAdded(const char* const expected[]) const;
+
+    void setUpdateAccessor();
+
+    void checkJournal(const std::vector<JournalEntry>& expected);
+
+    // Mock-only; control whether to allow subsequent transaction.
+    void allowMoreTransaction(bool is_allowed);
+
+    // Some tests only work for MockAccessor.  We remember whether our accessor
+    // is of that type.
+    bool is_mock_;
+
+    boost::shared_ptr<DatabaseAccessor> current_accessor_;
+    boost::shared_ptr<DatabaseClient> client_;
+    const std::string database_name_;
+
+    // The zone finder of the test zone commonly used in various tests.
+    boost::shared_ptr<DatabaseClient::Finder> finder_;
+
+    // Some shortcut variables for commonly used test parameters
+    const dns::Name zname_; // the zone name stored in the test data source
+    const dns::Name qname_; // commonly used name to be found
+    const dns::RRClass qclass_;      // commonly used RR class used with qname
+    const dns::RRType qtype_;        // commonly used RR type used with qname
+    const dns::RRTTL rrttl_;         // commonly used RR TTL
+    dns::RRsetPtr rrset_;            // for adding/deleting an RRset
+    dns::RRsetPtr rrsigset_;         // for adding/deleting an RRset
+    dns::RRsetPtr soa_;              // for adding/deleting an RRset
+
+    // update related objects to be tested
+    ZoneUpdaterPtr updater_;
+    boost::shared_ptr<const DatabaseAccessor> update_accessor_;
+
+    // placeholders
+    const std::vector<std::string> empty_rdatas_; // for NXRRSET/NXDOMAIN
+    std::vector<std::string> expected_rdatas_;
+    std::vector<std::string> expected_sig_rdatas_;
+
+    // A creator for use in several NSEC3 related tests.
+    TestNSEC3HashCreator test_nsec3_hash_creator_;
+};
+
+/// \brief Test fixture for RRsetCollectionTest with database updater.
+///
+/// Inherited from DatabaseClientTest to reuse some of the setup.
+/// This test fixture is parameterized just like DatabaseClientTest.
+class RRsetCollectionTest : public DatabaseClientTest {
+protected:
+    RRsetCollectionTest() {}
+
+    virtual void SetUp() {
+        DatabaseClientTest::SetUp();
+        updater = client_->getUpdater(zname_, false);
+    }
+
+    ZoneUpdaterPtr updater;
+};
+
+/// \brief Generic test data loader.
+///
+/// This function is intended to be used within the accessor_creator function
+/// of DatabaseClientTestParam for tested accessor that implements the
+/// following methods:
+/// - startUpdateZone()
+/// - addRecordToZone()
+/// - commit()
+void loadTestDataGeneric(DatabaseAccessor& accessor);
+
+/// \brief Generic helper to prepare NSEC3 related test data.
+///
+/// This function can be specified for the enable_nsec3_fn member
+/// of DatabaseClientTestParam if the tested accessor implements the
+/// following methods:
+/// - startUpdateZone()
+/// - addRecordToZone()
+/// - addNSEC3RecordToZone()
+/// - commit()
+void enableNSEC3Generic(DatabaseAccessor& accessor);
+
+} // namespace test
+} // namespace datasrc
+} // namespace isc
+
+// Local Variables:
+// mode: c++
+// End: