Browse Source

[2208] Make ZoneTableSegmentLocal manage a real ZoneTable object

* Change ZoneTableSegment accordingly
* Make ZoneTable hold its RRClass to use during its destruction
* Use a mock ZoneTableSegmentTest that takes a mem_segment so that
  tests can check that all memory is deallocated at teardown.
Mukund Sivaraman 12 years ago
parent
commit
667ecc41e7

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

@@ -52,18 +52,17 @@ ZoneTable::create(util::MemorySegment& mem_sgmt, RRClass zone_class) {
         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));
 }
 

+ 5 - 3
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(dns::RRClass rrclass, ZoneTableTree* zones) :
+        rrclass_(rrclass),
+        zones_(zones)
     {}
 
 public:
@@ -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:
+    dns::RRClass rrclass_;
     boost::interprocess::offset_ptr<ZoneTableTree> zones_;
 };
 }

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

@@ -25,7 +25,12 @@ ZoneTableSegment::create(const isc::data::Element&) {
     /// should be updated eventually to parse the passed Element
     /// argument and construct a corresponding ZoneTableSegment
     /// implementation.
-    return (new ZoneTableSegmentLocal);
+
+    /// FIXME: For now, we always use RRClass::IN(). This
+    /// should be updated eventually to parse the passed Element
+    /// argument and pick the appropriate RRClass.
+
+    return (new ZoneTableSegmentLocal(isc::dns::RRClass::IN()));
 }
 
 void

+ 9 - 4
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 <cc/data.h>
 #include <util/memory_segment.h>
@@ -35,18 +36,22 @@ namespace memory {
 /// 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());
+        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
@@ -64,7 +69,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

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

@@ -14,12 +14,23 @@
 
 #include <datasrc/memory/zone_table_segment_local.h>
 
+using namespace isc::dns;
 using namespace isc::util;
 
 namespace isc {
 namespace datasrc {
 namespace memory {
 
+ZoneTableSegmentLocal::ZoneTableSegmentLocal(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 - 4
src/lib/datasrc/memory/zone_table_segment_local.h

@@ -37,11 +37,10 @@ protected:
     /// Instances are expected to be created by the factory method
     /// (\c ZoneTableSegment::create()), so this constructor is
     /// protected.
-    ZoneTableSegmentLocal()
-    {}
+    ZoneTableSegmentLocal(isc::dns::RRClass rrclass);
 public:
     /// \brief Destructor
-    virtual ~ZoneTableSegmentLocal() {}
+    virtual ~ZoneTableSegmentLocal();
 
     /// \brief Return the ZoneTableHeader for the local zone table
     /// segment implementation.
@@ -55,8 +54,8 @@ public:
     virtual isc::util::MemorySegment& getMemorySegment();
 
 private:
-    ZoneTableHeader header_;
     isc::util::MemorySegmentLocal mem_sgmt_;
+    ZoneTableHeader header_;
 };
 
 } // namespace memory

+ 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_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)

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

@@ -0,0 +1,68 @@
+// 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>
+
+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_);
+    }
+
+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:

+ 15 - 14
src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc

@@ -12,9 +12,14 @@
 // 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_table_segment_local.h>
+#include <util/memory_segment_local.h>
+
 #include <gtest/gtest.h>
 
+using namespace isc::dns;
 using namespace isc::datasrc::memory;
 using namespace isc::data;
 using namespace isc::util;
@@ -25,26 +30,22 @@ namespace {
 class ZoneTableSegmentTest : public ::testing::Test {
 protected:
     ZoneTableSegmentTest() :
-        config_(Element::fromJSON("{}")),
-        segment_(ZoneTableSegment::create((*config_.get())))
+        segment_(new test::ZoneTableSegmentTest(RRClass::IN(), mem_sgmt_))
     {}
 
     ~ZoneTableSegmentTest() {
-        if (segment_ != NULL) {
-            ZoneTableSegment::destroy(segment_);
-        }
+        delete segment_;
     }
 
     void TearDown() {
-        // Catch any future leaks here.
-        const MemorySegment& mem_sgmt = segment_->getMemorySegment();
-        EXPECT_TRUE(mem_sgmt.allMemoryDeallocated());
-
         ZoneTableSegment::destroy(segment_);
         segment_ = NULL;
+
+        // Catch any future leaks here.
+        EXPECT_TRUE(mem_sgmt_.allMemoryDeallocated());
     }
 
-    const ElementPtr config_;
+    MemorySegmentLocal mem_sgmt_;
     ZoneTableSegment* segment_;
 };
 
@@ -60,9 +61,9 @@ void
 testGetHeader(ZoneTableSegment* segment) {
     TH& header = static_cast<TS*>(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) {
@@ -77,7 +78,7 @@ TEST_F(ZoneTableSegmentTest, getHeader) {
 TEST_F(ZoneTableSegmentTest, getMemorySegment) {
     // This doesn't do anything fun except test the API.
     MemorySegment& mem_sgmt = segment_->getMemorySegment();
-    EXPECT_TRUE(mem_sgmt.allMemoryDeallocated());
+    mem_sgmt.allMemoryDeallocated(); // use mem_sgmt
 }
 
 } // anonymous namespace

+ 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.
     }