Browse Source

[2834] supported CacheConfig::getLoadAction for MasterFiles.

functor was copied from client_list.cc (the latter should eventually be
removed in this branch)
JINMEI Tatuya 12 years ago
parent
commit
962447aa16

+ 35 - 0
src/lib/datasrc/cache_config.cc

@@ -15,10 +15,18 @@
 #include <datasrc/cache_config.h>
 #include <datasrc/client.h>
 #include <datasrc/memory/load_action.h>
+#include <datasrc/memory/zone_data_loader.h>
+
+#include <util/memory_segment.h>
+
 #include <dns/name.h>
+#include <dns/rrclass.h>
+
 #include <cc/data.h>
 #include <exceptions/exceptions.h>
 
+#include <boost/bind.hpp>
+
 #include <map>
 #include <string>
 
@@ -108,6 +116,33 @@ CacheConfig::CacheConfig(const std::string& datasrc_type,
     }
 }
 
+namespace {
+
+// We can't use the loadZoneData function directly in boost::bind, since
+// it is overloaded and the compiler can't choose the correct version
+// reliably and fails. So we simply wrap it into an unique name.
+memory::ZoneData*
+loadZoneDataFromFile(util::MemorySegment& segment, const dns::RRClass& rrclass,
+                     const dns::Name& name, const std::string& filename)
+{
+    return (memory::loadZoneData(segment, rrclass, name, filename));
+}
+
+} // unnamed namespace
+
+memory::LoadAction
+CacheConfig::getLoadAction(const dns::RRClass& rrclass,
+                           const dns::Name& zone_name) const
+{
+    Zones::const_iterator found = zone_config_.find(zone_name);
+    if (found == zone_config_.end()) {
+        isc_throw(Unexpected, "zone not found for getting LoadAction: "
+                  << zone_name);
+    }
+    return (boost::bind(loadZoneDataFromFile, _1, rrclass, zone_name,
+                        found->second));
+}
+
 } // namespace internal
 } // namespace datasrc
 } // namespace isc

+ 4 - 1
src/lib/datasrc/cache_config.h

@@ -17,7 +17,7 @@
 
 #include <exceptions/exceptions.h>
 
-#include <dns/name.h>
+#include <dns/dns_fwd.h>
 #include <cc/data.h>
 #include <datasrc/memory/load_action.h>
 
@@ -144,6 +144,9 @@ public:
     /// \throw None
     const std::string& getSegmentType() const { return (segment_type_); }
 
+    memory::LoadAction getLoadAction(const dns::RRClass& rrlcass,
+                                     const dns::Name& zone_name) const;
+
     /// \todo the following definition is tentative, mainly for tests.
     /// In #2834 we'll (probably) extend it to be a custom iterator so
     /// the caller can iterate over the whole set of zones, loading the

+ 34 - 0
src/lib/datasrc/tests/cache_config_unittest.cc

@@ -13,10 +13,14 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <datasrc/cache_config.h>
+#include <datasrc/memory/load_action.h>
+#include <datasrc/memory/zone_data.h>
 #include <datasrc/tests/mock_client.h>
 
 #include <cc/data.h>
+#include <util/memory_segment_local.h>
 #include <dns/name.h>
+#include <dns/rrclass.h>
 
 #include <gtest/gtest.h>
 
@@ -28,6 +32,8 @@ using namespace isc::dns;
 using isc::datasrc::unittest::MockDataSourceClient;
 using isc::datasrc::internal::CacheConfig;
 using isc::datasrc::internal::CacheConfigError;
+using isc::datasrc::memory::LoadAction;
+using isc::datasrc::memory::ZoneData;
 
 namespace {
 
@@ -50,9 +56,14 @@ protected:
                                        " \"cache-zones\": [\".\"]}"))
     {}
 
+    virtual void TearDown() {
+        EXPECT_TRUE(msgmt_.allMemoryDeallocated());
+    }
+
     MockDataSourceClient mock_client_;
     const ConstElementPtr master_config_; // valid config for MasterFiles
     const ConstElementPtr mock_config_; // valid config for MasterFiles
+    isc::util::MemorySegmentLocal msgmt_;
 };
 
 size_t
@@ -139,6 +150,29 @@ TEST_F(CacheConfigTest, badConstructMasterFiles) {
                  isc::InvalidParameter);
 }
 
+TEST_F(CacheConfigTest, getLoadActionWithMasterFiles) {
+    uint8_t labels_buf[LabelSequence::MAX_SERIALIZED_LENGTH];
+
+    const CacheConfig cache_conf("MasterFiles", 0, *master_config_, true);
+
+    // Check getLoadAction.  Since it returns a mere functor, we can only
+    // check the behavior by actually calling it.  For the purpose of this
+    // test, it should suffice if we confirm the call succeeds and shows
+    // some reasonably valid behavior (we'll check the origin name for that).
+    LoadAction action = cache_conf.getLoadAction(RRClass::IN(),
+                                                 Name::ROOT_NAME());
+    ZoneData* zone_data = action(msgmt_);
+    ASSERT_TRUE(zone_data);
+    EXPECT_EQ(".", zone_data->getOriginNode()->
+              getAbsoluteLabels(labels_buf).toText());
+    ZoneData::destroy(msgmt_, zone_data, RRClass::IN());
+
+    // If the specified zone name is not configured to be cached,
+    // getLoadAction should result in exception.
+    EXPECT_THROW(cache_conf.getLoadAction(RRClass::IN(), Name("example.com")),
+                 isc::Unexpected);
+}
+
 TEST_F(CacheConfigTest, constructWithMock) {
     // Performing equivalent set of tests as constructMasterFiles