diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h index e949ec3cb7..e2ff407984 100644 --- a/src/lib/datasrc/database.h +++ b/src/lib/datasrc/database.h @@ -70,7 +70,7 @@ public: * be returned - the ID is only passed back to the connection as * an opaque handle. */ - virtual std::pair getZone(const isc::dns::Name& name) const; + virtual std::pair getZone(const isc::dns::Name& name) const = 0; }; /** @@ -146,6 +146,24 @@ public: isc::dns::RRsetList* target = NULL, const FindOptions options = FIND_DEFAULT) const = 0; + /** + * \brief The zone ID + * + * This function provides the stored zone ID as passed to the + * constructor. This is meant for testing purposes and normal + * applications shouldn't need it. + */ + int zone_id() const { return (zone_id_); } + /** + * \brief The database connection. + * + * This function provides the database connection stored inside as + * passed to the constructor. This is meant for testing purposes and + * normal applications shouldn't need it. + */ + const DatabaseConnection& connection() const { + return (connection_); + } private: DatabaseConnection& connection_; const int zone_id_; diff --git a/src/lib/datasrc/tests/Makefile.am b/src/lib/datasrc/tests/Makefile.am index fbcf9c95c0..9cfd0d8c29 100644 --- a/src/lib/datasrc/tests/Makefile.am +++ b/src/lib/datasrc/tests/Makefile.am @@ -28,6 +28,7 @@ run_unittests_SOURCES += rbtree_unittest.cc run_unittests_SOURCES += zonetable_unittest.cc run_unittests_SOURCES += memory_datasrc_unittest.cc run_unittests_SOURCES += logger_unittest.cc +run_unittests_SOURCES += database_unittest.cc run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) diff --git a/src/lib/datasrc/tests/database_unittest.cc b/src/lib/datasrc/tests/database_unittest.cc new file mode 100644 index 0000000000..45e445905f --- /dev/null +++ b/src/lib/datasrc/tests/database_unittest.cc @@ -0,0 +1,93 @@ +// 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 + +#include + +#include + +using namespace isc::datasrc; +using namespace std; +using namespace boost; +using isc::dns::Name; + +namespace { + +/* + * A virtual database connection that pretends it contains single zone -- + * example.org. + */ +class MockConnection : public DatabaseConnection { +public: + virtual std::pair getZone(const Name& name) const { + if (name == Name("zone.example.org")) { + return (std::pair(true, 42)); + } else { + return (std::pair(false, 0)); + } + } +}; + +class DatabaseClientTest : public ::testing::Test { +public: + DatabaseClientTest() { + createClient(); + } + /* + * We initialize the client from a function, so we can call it multiple + * times per test. + */ + void createClient() { + current_connection_ = new MockConnection(); + client_.reset(new DatabaseClient(auto_ptr( + current_connection_))); + } + // Will be deleted by client_, just keep the current value for comparison. + MockConnection* current_connection_; + auto_ptr client_; + /** + * Check the zone finder is a valid one and references the zone ID and + * connection available here. + */ + void checkZoneFinder(const DataSourceClient::FindResult& zone) { + ASSERT_NE(ZoneFinderPtr(), zone.zone_finder) << "No zone finder"; + shared_ptr finder( + dynamic_pointer_cast(zone.zone_finder)); + ASSERT_NE(shared_ptr(), finder) << + "Wrong type of finder"; + EXPECT_EQ(42, finder->zone_id()); + EXPECT_EQ(current_connection_, &finder->connection()); + } +}; + +TEST_F(DatabaseClientTest, zoneNotFound) { + DataSourceClient::FindResult zone(client_->findZone(Name("example.com"))); + EXPECT_EQ(result::NOTFOUND, zone.code); +} + +TEST_F(DatabaseClientTest, exactZone) { + DataSourceClient::FindResult zone(client_->findZone(Name("example.org"))); + EXPECT_EQ(result::SUCCESS, zone.code); + checkZoneFinder(zone); +} + +TEST_F(DatabaseClientTest, superZone) { + DataSourceClient::FindResult zone(client_->findZone(Name( + "sub.example.org"))); + EXPECT_EQ(result::PARTIALMATCH, zone.code); + checkZoneFinder(zone); +} + +}