From: Mukund Sivaraman Date: Thu, 18 Oct 2012 05:20:42 +0000 (+0530) Subject: [2208] Make ZoneTableSegmentLocal manage a real ZoneTable object X-Git-Tag: trac2487_base~21^2~8^2~8^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=667ecc41e7f8c0a47a1d701cb5cf16ecc7264205;p=thirdparty%2Fkea.git [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. --- diff --git a/src/lib/datasrc/memory/zone_table.cc b/src/lib/datasrc/memory/zone_table.cc index 836b020088..7fce633f6d 100644 --- a/src/lib/datasrc/memory/zone_table.cc +++ b/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)); } diff --git a/src/lib/datasrc/memory/zone_table.h b/src/lib/datasrc/memory/zone_table.h index 024558eb30..36febe4971 100644 --- a/src/lib/datasrc/memory/zone_table.h +++ b/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 zones_; }; } diff --git a/src/lib/datasrc/memory/zone_table_segment.cc b/src/lib/datasrc/memory/zone_table_segment.cc index 7a80e3c4c1..7e8e480053 100644 --- a/src/lib/datasrc/memory/zone_table_segment.cc +++ b/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 diff --git a/src/lib/datasrc/memory/zone_table_segment.h b/src/lib/datasrc/memory/zone_table_segment.h index 7fd1310229..bd408b09d3 100644 --- a/src/lib/datasrc/memory/zone_table_segment.h +++ b/src/lib/datasrc/memory/zone_table_segment.h @@ -15,6 +15,7 @@ #ifndef __ZONE_TABLE_SEGMENT_H__ #define __ZONE_TABLE_SEGMENT_H__ +#include #include #include #include @@ -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 table; + boost::interprocess::offset_ptr 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 diff --git a/src/lib/datasrc/memory/zone_table_segment_local.cc b/src/lib/datasrc/memory/zone_table_segment_local.cc index 589c9afb30..27a3a44c13 100644 --- a/src/lib/datasrc/memory/zone_table_segment_local.cc +++ b/src/lib/datasrc/memory/zone_table_segment_local.cc @@ -14,12 +14,23 @@ #include +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. diff --git a/src/lib/datasrc/memory/zone_table_segment_local.h b/src/lib/datasrc/memory/zone_table_segment_local.h index de776a9036..d548dac731 100644 --- a/src/lib/datasrc/memory/zone_table_segment_local.h +++ b/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 diff --git a/src/lib/datasrc/tests/memory/Makefile.am b/src/lib/datasrc/tests/memory/Makefile.am index 37e9043523..ad28bf48de 100644 --- a/src/lib/datasrc/tests/memory/Makefile.am +++ b/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) diff --git a/src/lib/datasrc/tests/memory/zone_table_segment_test.h b/src/lib/datasrc/tests/memory/zone_table_segment_test.h new file mode 100644 index 0000000000..0b995aa3c5 --- /dev/null +++ b/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 +#include + +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: diff --git a/src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc b/src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc index 6bdd7379af..1d62c7023c 100644 --- a/src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc +++ b/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 +#include "zone_table_segment_test.h" + +#include +#include + #include +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(segment)->getHeader(); - // The zone table is unset. + // The zone table must be set. TT* table = header.getTable(); - EXPECT_EQ(static_cast(NULL), table); + EXPECT_NE(static_cast(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 diff --git a/src/lib/datasrc/tests/memory/zone_table_unittest.cc b/src/lib/datasrc/tests/memory/zone_table_unittest.cc index 80f2a6e5f2..3c53a59f9c 100644 --- a/src/lib/datasrc/tests/memory/zone_table_unittest.cc +++ b/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. }