Parcourir la source

[2831] added namedAddress interface to local segment, share the test cases.

JINMEI Tatuya il y a 12 ans
Parent
commit
0fccc0c84f

+ 11 - 5
src/lib/util/memory_segment_local.cc

@@ -48,21 +48,27 @@ MemorySegmentLocal::deallocate(void* ptr, size_t size) {
 
 bool
 MemorySegmentLocal::allMemoryDeallocated() const {
-    return (allocated_size_ == 0);
+    return (allocated_size_ == 0 && named_addrs_.empty());
 }
 
 void*
-MemorySegmentLocal::getNamedAddress(const char* /*name*/) {
+MemorySegmentLocal::getNamedAddress(const char* name) {
+    std::map<std::string, void*>::iterator found = named_addrs_.find(name);
+    if (found != named_addrs_.end()) {
+        return (found->second);
+    }
     return (0);
 }
 
 void
-MemorySegmentLocal::setNamedAddress(const char* /*name*/, void* /*addr*/) {
+MemorySegmentLocal::setNamedAddress(const char* name, void* addr) {
+    named_addrs_[name] = addr;
 }
 
 bool
-MemorySegmentLocal::clearNamedAddress(const char* /*name*/) {
-    return (false);
+MemorySegmentLocal::clearNamedAddress(const char* name) {
+    const size_t n_erase = named_addrs_.erase(name);
+    return (n_erase == 1);
 }
 
 } // namespace util

+ 5 - 0
src/lib/util/memory_segment_local.h

@@ -17,6 +17,9 @@
 
 #include <util/memory_segment.h>
 
+#include <string>
+#include <map>
+
 namespace isc {
 namespace util {
 
@@ -75,6 +78,8 @@ private:
     // is unsigned). But because we only do a check against 0 and not a
     // relation comparison, this is okay.
     size_t allocated_size_;
+
+    std::map<std::string, void*> named_addrs_;
 };
 
 } // namespace util

+ 2 - 0
src/lib/util/tests/Makefile.am

@@ -35,6 +35,8 @@ run_unittests_SOURCES += interprocess_sync_file_unittest.cc
 run_unittests_SOURCES += interprocess_sync_null_unittest.cc
 run_unittests_SOURCES += memory_segment_local_unittest.cc
 run_unittests_SOURCES += memory_segment_mapped_unittest.cc
+run_unittests_SOURCES += memory_segment_common_unittest.h
+run_unittests_SOURCES += memory_segment_common_unittest.cc
 run_unittests_SOURCES += qid_gen_unittest.cc
 run_unittests_SOURCES += random_number_generator_unittest.cc
 run_unittests_SOURCES += sha1_unittest.cc

+ 79 - 0
src/lib/util/tests/memory_segment_common_unittest.cc

@@ -0,0 +1,79 @@
+// Copyright (C) 2013  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 <util/memory_segment.h>
+
+#include <gtest/gtest.h>
+
+#include <cstring>
+#include <stdint.h>
+
+namespace isc {
+namespace util {
+namespace test {
+
+void
+checkSegmentNamedAddress(MemorySegment& segment, bool out_of_segment_ok) {
+    // If not exist, null pointer will be returned.
+    EXPECT_EQ(static_cast<void*>(0), segment.getNamedAddress("test address"));
+
+    // Now set it
+    void* ptr32 = segment.allocate(sizeof(uint32_t));
+    const uint32_t test_val = 42;
+    std::memcpy(ptr32, &test_val, sizeof(test_val));
+    segment.setNamedAddress("test address", ptr32);
+
+    // we can now get it; the stored value should be intact.
+    EXPECT_EQ(ptr32, segment.getNamedAddress("test address"));
+    EXPECT_EQ(test_val, *static_cast<const uint32_t*>(ptr32));
+
+    // Override it.
+    void* ptr16 = segment.allocate(sizeof(uint16_t));
+    const uint16_t test_val16 = 4200;
+    std::memcpy(ptr16, &test_val16, sizeof(test_val16));
+    segment.setNamedAddress("test address", ptr16);
+    EXPECT_EQ(ptr16, segment.getNamedAddress("test address"));
+    EXPECT_EQ(test_val16, *static_cast<const uint16_t*>(ptr16));
+
+    // Clear it.  Then we won't be able to find it any more.
+    EXPECT_TRUE(segment.clearNamedAddress("test address"));
+    EXPECT_EQ(static_cast<void*>(0), segment.getNamedAddress("test address"));
+
+    // duplicate attempt of clear will result in false as it doesn't exist.
+    EXPECT_FALSE(segment.clearNamedAddress("test address"));
+
+    // Setting NULL is okay.
+    segment.setNamedAddress("null address", 0);
+    EXPECT_EQ(static_cast<void*>(0), segment.getNamedAddress("null address"));
+
+    // If the underlying implementation performs explicit check against
+    // out-of-segment address, confirm the behavior.
+    if (!out_of_segment_ok) {
+        uint8_t ch = 'A';
+        EXPECT_THROW(segment.setNamedAddress("local address", &ch),
+                     MemorySegmentError);
+    }
+
+    // clean them up all
+    segment.deallocate(ptr32, sizeof(uint32_t));
+    EXPECT_FALSE(segment.allMemoryDeallocated()); // not fully deallocated
+    segment.deallocate(ptr16, sizeof(uint16_t));  // not yet
+    EXPECT_FALSE(segment.allMemoryDeallocated());
+    EXPECT_TRUE(segment.clearNamedAddress("null address"));
+    EXPECT_TRUE(segment.allMemoryDeallocated()); // now everything is gone
+}
+
+}
+}
+}

+ 36 - 0
src/lib/util/tests/memory_segment_common_unittest.h

@@ -0,0 +1,36 @@
+// Copyright (C) 2013  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 <util/memory_segment.h>
+
+namespace isc {
+namespace util {
+namespace test {
+
+/// \brief Implementation dependent checks on memory segment named addresses.
+///
+/// This function contains a set of test cases for given memory segment
+/// regarding "named address" methods.  The test cases basically only depend
+/// on the base class interfaces, but if the underlying implementation does
+/// not check if the given address to setNamedAddress() belongs to the segment,
+/// out_of_segment_ok should be set to true.
+void checkSegmentNamedAddress(MemorySegment& segment, bool out_of_segment_ok);
+
+}
+}
+}
+
+// Local Variables:
+// mode: c++
+// End:

+ 8 - 1
src/lib/util/tests/memory_segment_local_unittest.cc

@@ -12,7 +12,9 @@
 // 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 <util/tests/memory_segment_common_unittest.h>
+
+#include <util/memory_segment_local.h>
 #include <exceptions/exceptions.h>
 #include <gtest/gtest.h>
 #include <memory>
@@ -106,4 +108,9 @@ TEST(MemorySegmentLocal, TestNullDeallocate) {
     EXPECT_TRUE(segment->allMemoryDeallocated());
 }
 
+TEST(MemorySegmentLocal, namedAddress) {
+    MemorySegmentLocal segment;
+    isc::util::test::checkSegmentNamedAddress(segment, true);
+}
+
 } // anonymous namespace

+ 6 - 45
src/lib/util/tests/memory_segment_mapped_unittest.cc

@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <util/tests/memory_segment_common_unittest.h>
+
 #include <util/memory_segment_mapped.h>
 #include <exceptions/exceptions.h>
 
@@ -20,6 +22,7 @@
 #include <boost/interprocess/file_mapping.hpp>
 #include <boost/scoped_ptr.hpp>
 
+#include <stdint.h>
 #include <cstdlib>
 #include <cstring>
 #include <limits>
@@ -181,59 +184,17 @@ TEST_F(MemorySegmentMappedTest, badDeallocate) {
 }
 
 TEST_F(MemorySegmentMappedTest, namedAddress) {
-    // If not exist, null pointer will be returned.
-    EXPECT_EQ(static_cast<void*>(0), segment_->getNamedAddress("test address"));
-
-    // Now set it
-    void* ptr32 = segment_->allocate(sizeof(uint32_t));
-    const uint32_t test_val = 42;
-    std::memcpy(ptr32, &test_val, sizeof(test_val));
-    segment_->setNamedAddress("test address", ptr32);
-
-    // we can now get it; the stored value should be intact.
-    EXPECT_EQ(ptr32, segment_->getNamedAddress("test address"));
-    EXPECT_EQ(test_val, *static_cast<const uint32_t*>(ptr32));
+    isc::util::test::checkSegmentNamedAddress(*segment_, false);
 
-    // Override it.
+    // Set it again and read it in the read-only mode.
     void* ptr16 = segment_->allocate(sizeof(uint16_t));
-    const uint16_t test_val16 = 4200;
+    const uint16_t test_val16 = 42000;
     std::memcpy(ptr16, &test_val16, sizeof(test_val16));
     segment_->setNamedAddress("test address", ptr16);
-    EXPECT_EQ(ptr16, segment_->getNamedAddress("test address"));
-    EXPECT_EQ(test_val16, *static_cast<const uint16_t*>(ptr16));
-
-    // Clear it.  Then we won't be able to find it any more.
-    EXPECT_TRUE(segment_->clearNamedAddress("test address"));
-    EXPECT_EQ(static_cast<void*>(0), segment_->getNamedAddress("test address"));
-
-    // duplicate attempt of clear will result in false as it doesn't exist.
-    EXPECT_FALSE(segment_->clearNamedAddress("test address"));
-
-    // Setting NULL is okay.
-    segment_->setNamedAddress("null address", 0);
-    EXPECT_EQ(static_cast<void*>(0), segment_->getNamedAddress("null address"));
-
-    // Setting or out-of-segment address is prohibited, and this implementation
-    // detects and rejects it.
-    uint8_t ch = 'A';
-    EXPECT_THROW(segment_->setNamedAddress("local address", &ch),
-                 MemorySegmentError);
-
-    // Set it again and read it in the read-only mode.
-    segment_->setNamedAddress("test address", ptr16);
     MemorySegmentMapped segment_ro(mapped_file);
     EXPECT_TRUE(segment_ro.getNamedAddress("test address"));
     EXPECT_EQ(test_val16, *static_cast<const uint16_t*>(
                   segment_ro.getNamedAddress("test address")));
-    EXPECT_EQ(static_cast<void*>(0),
-              segment_ro.getNamedAddress("null address"));
-
-    // clean them up all
-    segment_->deallocate(ptr32, sizeof(uint32_t));
-    segment_->deallocate(ptr16, sizeof(uint32_t));
-    EXPECT_TRUE(segment_->clearNamedAddress("test address"));
-    EXPECT_TRUE(segment_->clearNamedAddress("null address"));
-    EXPECT_TRUE(segment_->allMemoryDeallocated());
 }
 
 TEST_F(MemorySegmentMappedTest, nullDeallocate) {