Parcourir la source

[2209] Merge trac2208

Compiles, but tests don't pass. There's something rotten in there.

Conflicts:
	src/lib/datasrc/memory/memory_client.cc
	src/lib/datasrc/memory/memory_client.h
	src/lib/datasrc/memory/zone_table_segment_local.h
	src/lib/datasrc/tests/memory/memory_client_unittest.cc
	src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc
Michal 'vorner' Vaner il y a 12 ans
Parent
commit
b77e7ed31d

+ 7 - 4
src/bin/auth/tests/auth_srv_unittest.cc

@@ -15,7 +15,6 @@
 #include <config.h>
 
 #include <util/io/sockaddr_util.h>
-#include <util/memory_segment_local.h>
 
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
@@ -74,6 +73,7 @@ using namespace isc::asiodns;
 using namespace isc::asiolink;
 using namespace isc::testutils;
 using namespace isc::server_common::portconfig;
+using isc::datasrc::memory::ZoneTableSegment;
 using isc::UnitTestUtil;
 using boost::scoped_ptr;
 
@@ -1401,7 +1401,9 @@ public:
              real_list, ThrowWhen throw_when, bool isc_exception,
              ConstRRsetPtr fake_rrset = ConstRRsetPtr()) :
         ConfigurableClientList(RRClass::IN()),
-        real_(real_list)
+        real_(real_list),
+        config_(Element::fromJSON("{}")),
+        ztable_segment_(ZoneTableSegment::create(*config_, RRClass::IN()))
     {
         BOOST_FOREACH(const DataSourceInfo& info, real_->getDataSources()) {
              const isc::datasrc::DataSourceClientPtr
@@ -1413,13 +1415,14 @@ public:
              data_sources_.push_back(
                  DataSourceInfo(client.get(),
                                 isc::datasrc::DataSourceClientContainerPtr(),
-                                false, RRClass::IN(), mem_sgmt_));
+                                false, RRClass::IN(), ztable_segment_));
         }
     }
 private:
     const boost::shared_ptr<isc::datasrc::ConfigurableClientList> real_;
+    const ConstElementPtr config_;
+    boost::shared_ptr<ZoneTableSegment> ztable_segment_;
     vector<isc::datasrc::DataSourceClientPtr> clients_;
-    MemorySegmentLocal mem_sgmt_;
 };
 
 } // end anonymous namespace for throwing proxy classes

+ 11 - 6
src/lib/datasrc/client_list.cc

@@ -36,6 +36,7 @@ using boost::lexical_cast;
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 using isc::datasrc::memory::InMemoryClient;
+using isc::datasrc::memory::ZoneTableSegment;
 
 namespace isc {
 namespace datasrc {
@@ -43,21 +44,22 @@ namespace datasrc {
 ConfigurableClientList::DataSourceInfo::DataSourceInfo(
     DataSourceClient* data_src_client,
     const DataSourceClientContainerPtr& container, bool has_cache,
-    const RRClass& rrclass, MemorySegment& mem_sgmt) :
+    const RRClass& rrclass, shared_ptr<ZoneTableSegment>& segment) :
     data_src_client_(data_src_client),
     container_(container)
 {
     if (has_cache) {
-        cache_.reset(new InMemoryClient(mem_sgmt, rrclass));
+        cache_.reset(new InMemoryClient(segment, rrclass));
     }
 }
 
 ConfigurableClientList::DataSourceInfo::DataSourceInfo(
-    const RRClass& rrclass, MemorySegment& mem_sgmt, bool has_cache) :
+    const RRClass& rrclass, shared_ptr<ZoneTableSegment>& segment,
+    bool has_cache) :
     data_src_client_(NULL)
 {
     if (has_cache) {
-        cache_.reset(new InMemoryClient(mem_sgmt, rrclass));
+        cache_.reset(new InMemoryClient(segment, rrclass));
     }
 }
 
@@ -94,6 +96,8 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
     size_t i(0); // Outside of the try to be able to access it in the catch
     try {
         vector<DataSourceInfo> new_data_sources;
+        shared_ptr<ZoneTableSegment> ztable_segment(
+            ZoneTableSegment::create(*config, rrclass_));
         for (; i < config->size(); ++i) {
             // Extract the parameters
             const ConstElementPtr dconf(config->get(i));
@@ -130,7 +134,8 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
                     isc_throw(ConfigurationError, "The cache must be enabled "
                               "for the MasterFiles type");
                 }
-                new_data_sources.push_back(DataSourceInfo(rrclass_, *mem_sgmt_,
+                new_data_sources.push_back(DataSourceInfo(rrclass_,
+                                                          ztable_segment,
                                                           true));
             } else {
                 // Ask the factory to create the data source for us
@@ -139,7 +144,7 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
                 // And put it into the vector
                 new_data_sources.push_back(DataSourceInfo(ds.first, ds.second,
                                                           want_cache, rrclass_,
-                                                          *mem_sgmt_));
+                                                          ztable_segment));
             }
 
             if (want_cache) {

+ 7 - 2
src/lib/datasrc/client_list.h

@@ -21,6 +21,7 @@
 #include <dns/rrclass.h>
 #include <cc/data.h>
 #include <exceptions/exceptions.h>
+#include "memory/zone_table_segment.h"
 
 #include <vector>
 #include <boost/shared_ptr.hpp>
@@ -332,12 +333,16 @@ public:
     struct DataSourceInfo {
         // Plays a role of default constructor too (for vector)
         DataSourceInfo(const dns::RRClass& rrclass,
-                       util::MemorySegment& mem_sgmt,
+                       boost::shared_ptr
+                           <isc::datasrc::memory::ZoneTableSegment>&
+                               ztable_segment,
                        bool has_cache = false);
         DataSourceInfo(DataSourceClient* data_src_client,
                        const DataSourceClientContainerPtr& container,
                        bool has_cache, const dns::RRClass& rrclass,
-                       util::MemorySegment& mem_sgmt);
+                       boost::shared_ptr
+                           <isc::datasrc::memory::ZoneTableSegment>&
+                               ztable_segment);
         DataSourceClient* data_src_client_;
         DataSourceClientContainerPtr container_;
 

+ 28 - 38
src/lib/datasrc/memory/memory_client.cc

@@ -43,12 +43,14 @@ using namespace std;
 using namespace isc::dns;
 using namespace isc::dns::rdata;
 using namespace isc::datasrc::memory;
+using namespace isc::util;
 
 namespace isc {
 namespace datasrc {
 namespace memory {
 
 using detail::SegmentObjectHolder;
+using boost::shared_ptr;
 
 namespace { // unnamed namespace
 
@@ -65,38 +67,19 @@ public:
 
 } // end of unnamed namespace
 
-InMemoryClient::InMemoryClient(util::MemorySegment& mem_sgmt,
+InMemoryClient::InMemoryClient(shared_ptr<ZoneTableSegment> ztable_segment,
                                RRClass rrclass) :
-    // FIXME: We currently use the temporary and "unsupported"
-    // constructor of the zone table segment. Once we clarify
-    // how the config thing, we want to change it.
-    zone_table_segment_(ZoneTableSegment::create(mem_sgmt)),
-    // Use the memory segment from the zone table segment. Currently,
-    // it is the same one as the one in parameter, but that will
-    // probably change.
-    mem_sgmt_(zone_table_segment_->getMemorySegment()),
+    ztable_segment_(ztable_segment),
     rrclass_(rrclass),
-    zone_count_(0)
-{
-    SegmentObjectHolder<ZoneTable, RRClass> holder(
-        mem_sgmt_, ZoneTable::create(mem_sgmt_, rrclass), rrclass_);
-
-    file_name_tree_ = FileNameTree::create(mem_sgmt_, false);
-
-    zone_table_ = holder.release();
-    // TODO: Once the table is created inside the zone table segment, use that
-    // one.
-    zone_table_segment_->getHeader().setTable(zone_table_);
-}
+    zone_count_(0),
+    file_name_tree_(FileNameTree::create(
+        ztable_segment_->getMemorySegment(), false))
+{}
 
 InMemoryClient::~InMemoryClient() {
+    MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
     FileNameDeleter deleter;
-    FileNameTree::destroy(mem_sgmt_, file_name_tree_, deleter);
-
-    // TODO: Once the table is created inside the zone table segment, do not
-    // destroy it here.
-    ZoneTable::destroy(mem_sgmt_, zone_table_, rrclass_);
-    ZoneTableSegment::destroy(zone_table_segment_);
+    FileNameTree::destroy(mem_sgmt, file_name_tree_, deleter);
 }
 
 result::Result
@@ -104,8 +87,9 @@ InMemoryClient::loadInternal(const isc::dns::Name& zone_name,
                              const std::string& filename,
                              ZoneData* zone_data)
 {
+    MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
     SegmentObjectHolder<ZoneData, RRClass> holder(
-        mem_sgmt_, zone_data, rrclass_);
+        mem_sgmt, zone_data, rrclass_);
 
     LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEMORY_MEM_ADD_ZONE).
         arg(zone_name).arg(rrclass_);
@@ -113,7 +97,7 @@ InMemoryClient::loadInternal(const isc::dns::Name& zone_name,
     // Set the filename in file_name_tree_ now, so that getFileName()
     // can use it (during zone reloading).
     FileNameNode* node(NULL);
-    switch (file_name_tree_->insert(mem_sgmt_, zone_name, &node)) {
+    switch (file_name_tree_->insert(mem_sgmt, zone_name, &node)) {
     case FileNameTree::SUCCESS:
     case FileNameTree::ALREADYEXISTS:
         // These are OK
@@ -128,9 +112,10 @@ InMemoryClient::loadInternal(const isc::dns::Name& zone_name,
     const std::string* tstr = node->setData(new std::string(filename));
     delete tstr;
 
-    const ZoneTable::AddResult result(zone_table_->addZone(mem_sgmt_, rrclass_,
-                                                           zone_name,
-                                                           holder.release()));
+    ZoneTable* zone_table = ztable_segment_->getHeader().getTable();
+    const ZoneTable::AddResult result(zone_table->addZone(mem_sgmt, rrclass_,
+                                                          zone_name,
+                                                          holder.release()));
     if (result.code == result::SUCCESS) {
         // Only increment the zone count if the zone doesn't already
         // exist.
@@ -138,7 +123,7 @@ InMemoryClient::loadInternal(const isc::dns::Name& zone_name,
     }
     // Destroy the old instance of the zone if there was any
     if (result.zone_data != NULL) {
-        ZoneData::destroy(mem_sgmt_, result.zone_data, rrclass_);
+        ZoneData::destroy(mem_sgmt, result.zone_data, rrclass_);
     }
 
     return (result.code);
@@ -159,7 +144,8 @@ InMemoryClient::findZone(const isc::dns::Name& zone_name) const {
     LOG_DEBUG(logger, DBG_TRACE_DATA,
               DATASRC_MEMORY_MEM_FIND_ZONE).arg(zone_name);
 
-    ZoneTable::FindResult result(zone_table_->findZone(zone_name));
+    const ZoneTable* zone_table = ztable_segment_->getHeader().getTable();
+    const ZoneTable::FindResult result(zone_table->findZone(zone_name));
 
     ZoneFinderPtr finder;
     if (result.code != result::NOTFOUND) {
@@ -171,7 +157,8 @@ InMemoryClient::findZone(const isc::dns::Name& zone_name) const {
 
 const ZoneData*
 InMemoryClient::findZoneData(const isc::dns::Name& zone_name) {
-    ZoneTable::FindResult result(zone_table_->findZone(zone_name));
+    const ZoneTable* zone_table = ztable_segment_->getHeader().getTable();
+    const ZoneTable::FindResult result(zone_table->findZone(zone_name));
     return (result.zone_data);
 }
 
@@ -182,14 +169,16 @@ InMemoryClient::load(const isc::dns::Name& zone_name,
     LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEMORY_MEM_LOAD).arg(zone_name).
         arg(filename);
 
-    ZoneData* zone_data = loadZoneData(mem_sgmt_, rrclass_, zone_name,
+    MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
+    ZoneData* zone_data = loadZoneData(mem_sgmt, rrclass_, zone_name,
                                        filename);
     return (loadInternal(zone_name, filename, zone_data));
 }
 
 result::Result
 InMemoryClient::load(const isc::dns::Name& zone_name, ZoneIterator& iterator) {
-    ZoneData* zone_data = loadZoneData(mem_sgmt_, rrclass_, zone_name,
+    MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
+    ZoneData* zone_data = loadZoneData(mem_sgmt, rrclass_, zone_name,
                                        iterator);
     return (loadInternal(zone_name, string(), zone_data));
 }
@@ -320,7 +309,8 @@ public:
 
 ZoneIteratorPtr
 InMemoryClient::getIterator(const Name& name, bool separate_rrs) const {
-    ZoneTable::FindResult result(zone_table_->findZone(name));
+    const ZoneTable* zone_table = ztable_segment_->getHeader().getTable();
+    const ZoneTable::FindResult result(zone_table->findZone(name));
     if (result.code != result::SUCCESS) {
         isc_throw(DataSourceError, "No such zone: " + name.toText());
     }

+ 5 - 5
src/lib/datasrc/memory/memory_client.h

@@ -22,6 +22,8 @@
 #include <datasrc/memory/zone_table.h>
 #include <datasrc/memory/zone_data.h>
 
+#include <boost/shared_ptr.hpp>
+
 #include <string>
 
 namespace isc {
@@ -62,7 +64,7 @@ public:
     /// This constructor internally involves resource allocation, and if
     /// it fails, a corresponding standard exception will be thrown.
     /// It never throws an exception otherwise.
-    InMemoryClient(util::MemorySegment& mem_sgmt,
+    InMemoryClient(boost::shared_ptr<ZoneTableSegment> ztable_segment,
                    isc::dns::RRClass rrclass);
 
     /// The destructor.
@@ -186,7 +188,7 @@ public:
     /// \todo Consider making this private and add a friend declaration
     ///     for the ClientList.
     ZoneTableSegment& getZoneTableSegment() {
-        return (*zone_table_segment_);
+        return (*ztable_segment_);
     }
 
 private:
@@ -200,11 +202,9 @@ private:
                                 const std::string& filename,
                                 ZoneData* zone_data);
 
-    ZoneTableSegment* zone_table_segment_;
-    util::MemorySegment& mem_sgmt_;
+    boost::shared_ptr<ZoneTableSegment> ztable_segment_;
     const isc::dns::RRClass rrclass_;
     unsigned int zone_count_;
-    ZoneTable* zone_table_;
     FileNameTree* file_name_tree_;
 };
 

+ 4 - 5
src/lib/datasrc/memory/zone_table.cc

@@ -47,23 +47,22 @@ typedef boost::function<void(ZoneData*)> ZoneDataDeleterType;
 }
 
 ZoneTable*
-ZoneTable::create(util::MemorySegment& mem_sgmt, RRClass zone_class) {
+ZoneTable::create(util::MemorySegment& mem_sgmt, const RRClass& zone_class) {
     SegmentObjectHolder<ZoneTableTree, ZoneDataDeleterType> holder(
         mem_sgmt, ZoneTableTree::create(mem_sgmt),
         boost::bind(deleteZoneData, &mem_sgmt, _1, zone_class));
     void* p = mem_sgmt.allocate(sizeof(ZoneTable));
-    ZoneTable* zone_table = new(p) ZoneTable(holder.get());
+    ZoneTable* zone_table = new(p) ZoneTable(zone_class, holder.get());
     holder.release();
     return (zone_table);
 }
 
 void
-ZoneTable::destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable,
-                   RRClass zone_class)
+ZoneTable::destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable)
 {
     ZoneTableTree::destroy(mem_sgmt, ztable->zones_.get(),
                            boost::bind(deleteZoneData, &mem_sgmt, _1,
-                                       zone_class));
+                                       ztable->rrclass_));
     mem_sgmt.deallocate(ztable, sizeof(ZoneTable));
 }
 

+ 6 - 4
src/lib/datasrc/memory/zone_table.h

@@ -102,7 +102,9 @@ private:
     /// This constructor internally involves resource allocation, and if
     /// it fails, a corresponding standard exception will be thrown.
     /// It never throws an exception otherwise.
-    ZoneTable(ZoneTableTree* zones) : zones_(zones)
+    ZoneTable(const dns::RRClass& rrclass, ZoneTableTree* zones) :
+        rrclass_(rrclass),
+        zones_(zones)
     {}
 
 public:
@@ -119,7 +121,7 @@ public:
     /// \param zone_class The RR class of the zone.  It must be the RR class
     /// that is supposed to be associated to the zone table.
     static ZoneTable* create(util::MemorySegment& mem_sgmt,
-                             dns::RRClass zone_class);
+                             const dns::RRClass& zone_class);
 
     /// \brief Destruct and deallocate \c ZoneTable
     ///
@@ -135,8 +137,7 @@ public:
     /// \param ztable A non NULL pointer to a valid \c ZoneTable object
     /// that was originally created by the \c create() method (the behavior
     /// is undefined if this condition isn't met).
-    static void destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable,
-                        dns::RRClass zone_class);
+    static void destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable);
 
     /// Add a new zone to the \c ZoneTable.
     ///
@@ -185,6 +186,7 @@ public:
     FindResult findZone(const isc::dns::Name& name) const;
 
 private:
+    const dns::RRClass rrclass_;
     boost::interprocess::offset_ptr<ZoneTableTree> zones_;
 };
 }

+ 4 - 6
src/lib/datasrc/memory/zone_table_segment.cc

@@ -15,22 +15,20 @@
 #include <datasrc/memory/zone_table_segment.h>
 #include <datasrc/memory/zone_table_segment_local.h>
 
+using namespace isc::dns;
+
 namespace isc {
 namespace datasrc {
 namespace memory {
 
 ZoneTableSegment*
-ZoneTableSegment::create(const isc::data::Element&) {
+ZoneTableSegment::create(const isc::data::Element&, const RRClass& rrclass) {
     /// FIXME: For now, we always return ZoneTableSegmentLocal. This
     /// should be updated eventually to parse the passed Element
     /// argument and construct a corresponding ZoneTableSegment
     /// implementation.
-    return (new ZoneTableSegmentLocal);
-}
 
-ZoneTableSegment*
-ZoneTableSegment::create(isc::util::MemorySegment& segment) {
-    return (new ZoneTableSegmentLocal(segment));
+    return (new ZoneTableSegmentLocal(rrclass));
 }
 
 void

+ 11 - 26
src/lib/datasrc/memory/zone_table_segment.h

@@ -15,6 +15,7 @@
 #ifndef __ZONE_TABLE_SEGMENT_H__
 #define __ZONE_TABLE_SEGMENT_H__
 
+#include <dns/rrclass.h>
 #include <datasrc/memory/zone_table.h>
 #include "load_action.h"
 #include <cc/data.h>
@@ -42,38 +43,21 @@ class ZoneWriter;
 /// map from domain names to zone locators) in memory.
 struct ZoneTableHeader {
 public:
+    ZoneTableHeader(ZoneTable* zone_table) :
+        table_(zone_table)
+    {}
+
     /// \brief Returns a pointer to the underlying zone table.
     ZoneTable* getTable() {
-        return (table.get());
+        return (table_.get());
     }
 
     /// \brief const version of \c getTable().
     const ZoneTable* getTable() const {
-        return (table.get());
-    }
-
-    /// \brief Method to set the internal table
-    ///
-    /// The interface is tentative, we don't know if this is the correct place
-    /// and way to set the data. But for now, we need something to be there
-    /// at least for the tests. So we have this. For this reason, there are
-    /// no tests for this method directly. Do not use in actual
-    /// implementation.
-    ///
-    /// It can be used only once, to initially set it. It can't replace the
-    /// one already there.
-    ///
-    /// \param table Pointer to the table to use.
-    /// \throw isc::Unexpected if called the second time.
-    void setTable(ZoneTable* table) {
-        if (this->table.get() != NULL) {
-            isc_throw(isc::Unexpected, "Replacing table");
-        }
-        this->table = table;
+        return (table_.get());
     }
-
 private:
-    boost::interprocess::offset_ptr<ZoneTable> table;
+    boost::interprocess::offset_ptr<ZoneTable> table_;
 };
 
 /// \brief Manages a ZoneTableHeader, an entry point into a table of
@@ -91,7 +75,7 @@ protected:
     /// An instance implementing this interface is expected to be
     /// created by the factory method (\c create()), so this constructor
     /// is protected.
-    ZoneTableSegment()
+    ZoneTableSegment(isc::dns::RRClass)
     {}
 public:
     /// \brief Destructor
@@ -119,7 +103,8 @@ public:
     /// \param config The configuration based on which a derived object
     ///               is returned.
     /// \return Returns a ZoneTableSegment object
-    static ZoneTableSegment* create(const isc::data::Element& config);
+    static ZoneTableSegment* create(const isc::data::Element& config,
+                                    const isc::dns::RRClass& rrclass);
 
     /// \brief Temporary/Testing version of create.
     ///

+ 11 - 0
src/lib/datasrc/memory/zone_table_segment_local.cc

@@ -15,12 +15,23 @@
 #include <datasrc/memory/zone_table_segment_local.h>
 #include "zone_writer_local.h"
 
+using namespace isc::dns;
 using namespace isc::util;
 
 namespace isc {
 namespace datasrc {
 namespace memory {
 
+ZoneTableSegmentLocal::ZoneTableSegmentLocal(const RRClass& rrclass) :
+    ZoneTableSegment(rrclass),
+    header_(ZoneTable::create(mem_sgmt_, rrclass))
+{
+}
+
+ZoneTableSegmentLocal::~ZoneTableSegmentLocal() {
+    ZoneTable::destroy(mem_sgmt_, header_.getTable());
+}
+
 // After more methods' definitions are added here, it would be a good
 // idea to move getHeader() and getMemorySegment() definitions to the
 // header file.

+ 3 - 11
src/lib/datasrc/memory/zone_table_segment_local.h

@@ -37,17 +37,10 @@ protected:
     /// Instances are expected to be created by the factory method
     /// (\c ZoneTableSegment::create()), so this constructor is
     /// protected.
-    ZoneTableSegmentLocal() :
-        mem_sgmt_(mem_sgmt_local_)
-    {}
-    // TODO: A temporary constructor, for tests for now. Needs to
-    // be removed.
-    ZoneTableSegmentLocal(isc::util::MemorySegment& segment) :
-        mem_sgmt_(segment)
-    {}
+    ZoneTableSegmentLocal(const isc::dns::RRClass& rrclass);
 public:
     /// \brief Destructor
-    virtual ~ZoneTableSegmentLocal() {}
+    virtual ~ZoneTableSegmentLocal();
 
     /// \brief Return the ZoneTableHeader for the local zone table
     /// segment implementation.
@@ -65,9 +58,8 @@ public:
                                       const dns::Name& origin,
                                       const dns::RRClass& rrclass);
 private:
+    isc::util::MemorySegmentLocal mem_sgmt_;
     ZoneTableHeader header_;
-    isc::util::MemorySegmentLocal mem_sgmt_local_;
-    isc::util::MemorySegment& mem_sgmt_;
 };
 
 } // namespace memory

+ 10 - 8
src/lib/datasrc/tests/client_list_unittest.cc

@@ -12,13 +12,12 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#include <util/memory_segment_local.h>
-
 #include <datasrc/client_list.h>
 #include <datasrc/client.h>
 #include <datasrc/iterator.h>
 #include <datasrc/data_source.h>
 #include <datasrc/memory/memory_client.h>
+#include <datasrc/memory/zone_table_segment.h>
 #include <datasrc/memory/zone_finder.h>
 #include <datasrc/memory/zone_writer.h>
 
@@ -33,6 +32,7 @@
 
 using namespace isc::datasrc;
 using isc::datasrc::memory::InMemoryClient;
+using isc::datasrc::memory::ZoneTableSegment;
 using isc::datasrc::memory::InMemoryZoneFinder;
 using namespace isc::data;
 using namespace isc::dns;
@@ -256,7 +256,9 @@ public:
             "   \"type\": \"test_type\","
             "   \"params\": [\"example.org\", \"example.com\", "
             "                \"noiter.org\", \"null.org\"]"
-            "}]"))
+            "}]")),
+        config_(Element::fromJSON("{}")),
+        ztable_segment_(ZoneTableSegment::create(*config_, rrclass_))
     {
         for (size_t i(0); i < ds_count; ++ i) {
             shared_ptr<MockDataSourceClient>
@@ -264,7 +266,7 @@ public:
             ds_.push_back(ds);
             ds_info_.push_back(ConfigurableClientList::DataSourceInfo(
                                    ds.get(), DataSourceClientContainerPtr(),
-                                   false, rrclass_, mem_sgmt_));
+                                   false, rrclass_, ztable_segment_));
         }
     }
 
@@ -284,8 +286,8 @@ public:
 
         // Create cache from the temporary data source, and push it to the
         // client list.
-        const shared_ptr<InMemoryClient> cache(new InMemoryClient(mem_sgmt_,
-                                                                  rrclass_));
+        const shared_ptr<InMemoryClient> cache(
+            new InMemoryClient(ztable_segment_, rrclass_));
         cache->load(zone, *mock_client.getIterator(zone, false));
 
         ConfigurableClientList::DataSourceInfo& dsrc_info =
@@ -363,12 +365,12 @@ public:
                   shared_ptr<InMemoryClient>());
     }
     const RRClass rrclass_;
-    isc::util::MemorySegmentLocal mem_sgmt_;
     shared_ptr<TestedList> list_;
     const ClientList::FindResult negative_result_;
     vector<shared_ptr<MockDataSourceClient> > ds_;
     vector<ConfigurableClientList::DataSourceInfo> ds_info_;
-    const ConstElementPtr config_elem_, config_elem_zones_;
+    const ConstElementPtr config_elem_, config_elem_zones_, config_;
+    shared_ptr<ZoneTableSegment> ztable_segment_;
 };
 
 // Test the test itself

+ 1 - 0
src/lib/datasrc/tests/memory/Makefile.am

@@ -32,6 +32,7 @@ run_unittests_SOURCES += ../../tests/faked_nsec3.h ../../tests/faked_nsec3.cc
 run_unittests_SOURCES += memory_segment_test.h
 run_unittests_SOURCES += segment_object_holder_unittest.cc
 run_unittests_SOURCES += memory_client_unittest.cc
+run_unittests_SOURCES += zone_table_segment_test.h
 run_unittests_SOURCES += zone_table_segment_unittest.cc
 run_unittests_SOURCES += zone_writer_unittest.cc
 

+ 15 - 5
src/lib/datasrc/tests/memory/memory_client_unittest.cc

@@ -36,18 +36,22 @@
 #include <testutils/dnsmessage_test.h>
 
 #include "memory_segment_test.h"
+#include "zone_table_segment_test.h"
 
 #include <gtest/gtest.h>
 
 #include <boost/lexical_cast.hpp>
+#include <boost/shared_ptr.hpp>
 
 #include <new>                  // for bad_alloc
 
+using namespace isc::data;
 using namespace isc::dns;
 using namespace isc::dns::rdata;
 using namespace isc::datasrc;
 using namespace isc::datasrc::memory;
 using namespace isc::testutils;
+using boost::shared_ptr;
 using std::vector;
 
 namespace {
@@ -158,20 +162,22 @@ public:
 class MemoryClientTest : public ::testing::Test {
 protected:
     MemoryClientTest() : zclass_(RRClass::IN()),
-                         client_(new InMemoryClient(mem_sgmt_, zclass_))
+                         ztable_segment_(new test::ZoneTableSegmentTest(
+                             zclass_, mem_sgmt_)),
+                         client_(new InMemoryClient(ztable_segment_, zclass_))
     {}
     ~MemoryClientTest() {
-        if (client_ != NULL) {
-            delete client_;
-        }
+        delete client_;
     }
     void TearDown() {
         delete client_;
         client_ = NULL;
+        ztable_segment_.reset();
         EXPECT_TRUE(mem_sgmt_.allMemoryDeallocated()); // catch any leak here.
     }
     const RRClass zclass_;
     test::MemorySegmentTest mem_sgmt_;
+    shared_ptr<ZoneTableSegment> ztable_segment_;
     InMemoryClient* client_;
 };
 
@@ -295,11 +301,15 @@ TEST_F(MemoryClientTest, loadMemoryAllocationFailures) {
                      boost::lexical_cast<std::string>(i));
         mem_sgmt_.setThrowCount(i);
         EXPECT_THROW({
+            shared_ptr<ZoneTableSegment> ztable_segment(
+                new test::ZoneTableSegmentTest(
+                    zclass_, mem_sgmt_));
+
             // Include the InMemoryClient construction too here. Now,
             // even allocations done from InMemoryClient constructor
             // fail (due to MemorySegmentTest throwing) and we check for
             // leaks when this happens.
-            InMemoryClient client2(mem_sgmt_, zclass_);
+            InMemoryClient client2(ztable_segment, zclass_);
             client2.load(Name("example.org"),
                          TEST_DATA_DIR "/example.org.zone");
         }, std::bad_alloc);

+ 75 - 0
src/lib/datasrc/tests/memory/zone_table_segment_test.h

@@ -0,0 +1,75 @@
+// Copyright (C) 2012  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.
+
+#ifndef DATASRC_MEMORY_ZONE_TABLE_SEGMENT_TEST_H
+#define DATASRC_MEMORY_ZONE_TABLE_SEGMENT_TEST_H 1
+
+#include <datasrc/memory/zone_table_segment.h>
+#include <datasrc/memory/zone_table.h>
+#include <datasrc/memory/zone_writer_local.h>
+
+namespace isc {
+namespace datasrc {
+namespace memory {
+namespace test {
+
+// A special ZoneTableSegment that can be used for tests.  It can be
+// passed a MemorySegment that can be used later to test if all memory
+// was de-allocated on it.
+class ZoneTableSegmentTest : public ZoneTableSegment {
+public:
+    ZoneTableSegmentTest(isc::dns::RRClass rrclass,
+                         isc::util::MemorySegment& mem_sgmt) :
+        ZoneTableSegment(rrclass),
+        mem_sgmt_(mem_sgmt),
+        header_(ZoneTable::create(mem_sgmt_, rrclass))
+    {}
+
+    virtual ~ZoneTableSegmentTest() {
+        ZoneTable::destroy(mem_sgmt_, header_.getTable());
+    }
+
+    virtual ZoneTableHeader& getHeader() {
+        return (header_);
+    }
+
+    virtual const ZoneTableHeader& getHeader() const {
+        return (header_);
+    }
+
+    virtual isc::util::MemorySegment& getMemorySegment() {
+        return (mem_sgmt_);
+    }
+
+    virtual ZoneWriter* getZoneWriter(const LoadAction&, const dns::Name&,
+                                      const dns::RRClass&)
+    {
+        isc_throw(isc::NotImplemented, "Not implemented");
+    }
+
+private:
+    isc::util::MemorySegment& mem_sgmt_;
+    ZoneTableHeader header_;
+};
+
+} // namespace test
+} // namespace memory
+} // namespace datasrc
+} // namespace isc
+
+#endif // DATASRC_MEMORY_ZONE_TABLE_SEGMENT_TEST_H
+
+// Local Variables:
+// mode: c++
+// End:

+ 27 - 28
src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc

@@ -12,78 +12,77 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#include <datasrc/memory/zone_table_segment.h>
+#include "zone_table_segment_test.h"
 #include <datasrc/memory/zone_writer_local.h>
-#include <gtest/gtest.h>
+#include <datasrc/memory/zone_table_segment_local.h>
+#include <util/memory_segment_local.h>
 
+#include <gtest/gtest.h>
 #include <boost/scoped_ptr.hpp>
 
-using boost::scoped_ptr;
-using isc::dns::Name;
-using isc::dns::RRClass;
+using namespace isc::dns;
 using namespace isc::datasrc::memory;
 using namespace isc::data;
 using namespace isc::util;
 using namespace std;
+using boost::scoped_ptr;
 
 namespace {
 
 class ZoneTableSegmentTest : public ::testing::Test {
 protected:
     ZoneTableSegmentTest() :
-        config_(Element::fromJSON("{}")),
-        segment_(ZoneTableSegment::create((*config_.get())))
+        ztable_segment_(new test::ZoneTableSegmentTest(RRClass::IN(),
+                                                       mem_sgmt_))
     {}
 
     ~ZoneTableSegmentTest() {
-        if (segment_ != NULL) {
-            ZoneTableSegment::destroy(segment_);
-        }
+        delete ztable_segment_;
     }
 
     void TearDown() {
-        // Catch any future leaks here.
-        const MemorySegment& mem_sgmt = segment_->getMemorySegment();
-        EXPECT_TRUE(mem_sgmt.allMemoryDeallocated());
+        ZoneTableSegment::destroy(ztable_segment_);
+        ztable_segment_ = NULL;
 
-        ZoneTableSegment::destroy(segment_);
-        segment_ = NULL;
+        // Catch any future leaks here.
+        EXPECT_TRUE(mem_sgmt_.allMemoryDeallocated());
     }
 
-    const ElementPtr config_;
-    ZoneTableSegment* segment_;
+    MemorySegmentLocal mem_sgmt_;
+    ZoneTableSegment* ztable_segment_;
 };
 
 
 TEST_F(ZoneTableSegmentTest, create) {
     // By default, a local zone table segment is created.
-    EXPECT_NE(static_cast<void*>(NULL), segment_);
+    EXPECT_NE(static_cast<void*>(NULL), ztable_segment_);
 }
 
 // Helper function to check const and non-const methods.
 template <typename TS, typename TH, typename TT>
 void
-testGetHeader(ZoneTableSegment* segment) {
-    TH& header = static_cast<TS*>(segment)->getHeader();
+testGetHeader(ZoneTableSegment* ztable_segment) {
+    TH& header = static_cast<TS*>(ztable_segment)->getHeader();
 
-    // The zone table is unset.
+    // The zone table must be set.
     TT* table = header.getTable();
-    EXPECT_EQ(static_cast<void*>(NULL), table);
+    EXPECT_NE(static_cast<void*>(NULL), table);
 }
 
 TEST_F(ZoneTableSegmentTest, getHeader) {
     // non-const version.
-    testGetHeader<ZoneTableSegment, ZoneTableHeader, ZoneTable>(segment_);
+    testGetHeader<ZoneTableSegment, ZoneTableHeader, ZoneTable>
+        (ztable_segment_);
 
     // const version.
     testGetHeader<const ZoneTableSegment, const ZoneTableHeader,
-                  const ZoneTable>(segment_);
+                  const ZoneTable>(ztable_segment_);
 }
 
 TEST_F(ZoneTableSegmentTest, getMemorySegment) {
     // This doesn't do anything fun except test the API.
-    MemorySegment& mem_sgmt = segment_->getMemorySegment();
-    EXPECT_TRUE(mem_sgmt.allMemoryDeallocated());
+    MemorySegment& mem_sgmt = ztable_segment_->getMemorySegment();
+    mem_sgmt.allMemoryDeallocated(); // use mem_sgmt
 }
 
 ZoneData*
@@ -95,8 +94,8 @@ loadAction(MemorySegment&) {
 // Test we can get a writer.
 TEST_F(ZoneTableSegmentTest, getZoneWriter) {
     scoped_ptr<ZoneWriter>
-        writer(segment_->getZoneWriter(loadAction, Name("example.org"),
-                                       RRClass::IN()));
+        writer(ztable_segment_->getZoneWriter(loadAction, Name("example.org"),
+                                              RRClass::IN()));
     // We have to get something
     EXPECT_NE(static_cast<void*>(NULL), writer.get());
     // And for now, it should be the local writer

+ 2 - 2
src/lib/datasrc/tests/memory/zone_table_unittest.cc

@@ -46,11 +46,11 @@ protected:
     {}
     ~ZoneTableTest() {
         if (zone_table != NULL) {
-            ZoneTable::destroy(mem_sgmt_, zone_table, zclass_);
+            ZoneTable::destroy(mem_sgmt_, zone_table);
         }
     }
     void TearDown() {
-        ZoneTable::destroy(mem_sgmt_, zone_table, zclass_);
+        ZoneTable::destroy(mem_sgmt_, zone_table);
         zone_table = NULL;
         EXPECT_TRUE(mem_sgmt_.allMemoryDeallocated()); // catch any leak here.
     }

+ 4 - 8
src/lib/datasrc/tests/memory/zone_writer_unittest.cc

@@ -41,7 +41,8 @@ public:
         // FIXME: The NullElement probably isn't the best one, but we don't
         // know how the config will look, so it just fills the argument
         // (which is currently ignored)
-        segment_(ZoneTableSegment::create(isc::data::NullElement())),
+        segment_(ZoneTableSegment::create(isc::data::NullElement(),
+                                          RRClass::IN())),
         writer_(new
             ZoneWriterLocal(dynamic_cast<ZoneTableSegmentLocal*>(segment_.
                                                                  get()),
@@ -51,18 +52,13 @@ public:
         load_throw_(false),
         load_null_(false),
         load_data_(false)
-    {
-        // TODO: The setTable is only a temporary interface
-        segment_->getHeader().
-            setTable(ZoneTable::create(segment_->getMemorySegment(),
-                                       RRClass::IN()));
-    }
+    {}
     void TearDown() {
         // Release the writer
         writer_.reset();
         // Release the table we used
         ZoneTable::destroy(segment_->getMemorySegment(),
-                           segment_->getHeader().getTable(), RRClass::IN());
+                           segment_->getHeader().getTable());
         // And check we freed all memory
         EXPECT_TRUE(segment_->getMemorySegment().allMemoryDeallocated());
     }

+ 12 - 10
src/lib/datasrc/tests/zone_finder_context_unittest.cc

@@ -14,14 +14,13 @@
 
 #include <exceptions/exceptions.h>
 
-#include <util/memory_segment_local.h>
-
 #include <dns/masterload.h>
 #include <dns/name.h>
 #include <dns/rrclass.h>
 
 #include <datasrc/zone.h>
 #include <datasrc/memory/memory_client.h>
+#include <datasrc/memory/zone_table_segment.h>
 #include <datasrc/database.h>
 #include <datasrc/sqlite3_accessor.h>
 
@@ -41,10 +40,12 @@
 using namespace std;
 using boost::shared_ptr;
 
+using namespace isc::data;
 using namespace isc::util;
 using namespace isc::dns;
 using namespace isc::datasrc;
 using isc::datasrc::memory::InMemoryClient;
+using isc::datasrc::memory::ZoneTableSegment;
 using namespace isc::testutils;
 
 namespace {
@@ -58,15 +59,17 @@ typedef shared_ptr<DataSourceClient> DataSourceClientPtr;
 // This is the type used as the test parameter.  Note that this is
 // intentionally a plain old type (i.e. a function pointer), not a class;
 // otherwise it could cause initialization fiasco at the instantiation time.
-typedef DataSourceClientPtr (*ClientCreator)(MemorySegment&, RRClass,
-                                             const Name&);
+typedef DataSourceClientPtr (*ClientCreator)(RRClass, const Name&);
 
 // Creator for the in-memory client to be tested
 DataSourceClientPtr
-createInMemoryClient(MemorySegment& mem_sgmt, RRClass zclass,
-                     const Name& zname)
+createInMemoryClient(RRClass zclass, const Name& zname)
 {
-    shared_ptr<InMemoryClient> client(new InMemoryClient(mem_sgmt, zclass));
+    const ElementPtr config(Element::fromJSON("{}"));
+    shared_ptr<ZoneTableSegment> ztable_segment(
+        ZoneTableSegment::create(*config, zclass));
+    shared_ptr<InMemoryClient> client(new InMemoryClient(ztable_segment,
+                                                         zclass));
     client->load(zname, TEST_ZONE_FILE);
 
     return (client);
@@ -78,7 +81,7 @@ addRRset(ZoneUpdaterPtr updater, ConstRRsetPtr rrset) {
 }
 
 DataSourceClientPtr
-createSQLite3Client(MemorySegment&, RRClass zclass, const Name& zname) {
+createSQLite3Client(RRClass zclass, const Name& zname) {
     // We always begin with an empty template SQLite3 DB file and install
     // the zone data from the zone file to ensure both cases have the
     // same test data.
@@ -105,7 +108,7 @@ class ZoneFinderContextTest :
 {
 protected:
     ZoneFinderContextTest() : qclass_(RRClass::IN()), qzone_("example.org") {
-        client_ = (*GetParam())(mem_sgmt_, qclass_, qzone_);
+        client_ = (*GetParam())(qclass_, qzone_);
         REQUESTED_A.push_back(RRType::A());
         REQUESTED_AAAA.push_back(RRType::AAAA());
         REQUESTED_BOTH.push_back(RRType::A());
@@ -116,7 +119,6 @@ protected:
         ASSERT_TRUE(finder_);
     }
 
-    MemorySegmentLocal mem_sgmt_;
     const RRClass qclass_;
     const Name qzone_;
     DataSourceClientPtr client_;