Browse Source

[2850] Add isUsable() and getImplType() methods

It would be better if these were static (to save on space and also to
use them inside ZoneTableSegment::create()), but unfortunately we cannot
make it virtual then. Another option would be to pass a static string
from ZoneTableSegment::create() onto the ZoneTableSegment constructor
and make it a non-virtual base class method.
Mukund Sivaraman 12 years ago
parent
commit
bc3d482930

+ 12 - 1
src/lib/datasrc/memory/zone_table_segment.h

@@ -68,7 +68,7 @@ public:
 class ResetFailedAndSegmentCleared : public isc::Exception {
 class ResetFailedAndSegmentCleared : public isc::Exception {
 public:
 public:
     ResetFailedAndSegmentCleared(const char* file, size_t line,
     ResetFailedAndSegmentCleared(const char* file, size_t line,
-				 const char* what) :
+                                 const char* what) :
         isc::Exception(file, line, what)
         isc::Exception(file, line, what)
     {}
     {}
 };
 };
@@ -119,6 +119,10 @@ public:
     /// \brief Destructor
     /// \brief Destructor
     virtual ~ZoneTableSegment() {}
     virtual ~ZoneTableSegment() {}
 
 
+    /// \brief Return a string name for the ZoneTableSegment
+    /// implementation.
+    virtual const std::string& getImplType() const = 0;
+
     /// \brief Return the ZoneTableHeader for the zone table segment.
     /// \brief Return the ZoneTableHeader for the zone table segment.
     ///
     ///
     /// \throw isc::InvalidOperation may be thrown by some
     /// \throw isc::InvalidOperation may be thrown by some
@@ -263,6 +267,13 @@ public:
     /// \throw none
     /// \throw none
     virtual void clear() = 0;
     virtual void clear() = 0;
 
 
+    /// \brief Return true if the memory segment has been successfully
+    /// \c reset().
+    ///
+    /// Note that after calling \c clear(), this method will return
+    /// false until the segment is reset again.
+    virtual bool isUsable() const = 0;
+
     /// \brief Reset the table header address.
     /// \brief Reset the table header address.
     virtual void resetHeader() = 0;
     virtual void resetHeader() = 0;
 };
 };

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

@@ -23,6 +23,7 @@ namespace memory {
 
 
 ZoneTableSegmentLocal::ZoneTableSegmentLocal(const RRClass& rrclass) :
 ZoneTableSegmentLocal::ZoneTableSegmentLocal(const RRClass& rrclass) :
     ZoneTableSegment(rrclass),
     ZoneTableSegment(rrclass),
+    impl_type_("local"),
     header_(ZoneTable::create(mem_sgmt_, rrclass))
     header_(ZoneTable::create(mem_sgmt_, rrclass))
 {
 {
 }
 }
@@ -37,6 +38,11 @@ ZoneTableSegmentLocal::~ZoneTableSegmentLocal() {
     assert(mem_sgmt_.allMemoryDeallocated());
     assert(mem_sgmt_.allMemoryDeallocated());
 }
 }
 
 
+const std::string&
+ZoneTableSegmentLocal::getImplType() const {
+    return (impl_type_);
+}
+
 void
 void
 ZoneTableSegmentLocal::reset(MemorySegmentOpenMode,
 ZoneTableSegmentLocal::reset(MemorySegmentOpenMode,
                              isc::data::ConstElementPtr)
                              isc::data::ConstElementPtr)

+ 14 - 0
src/lib/datasrc/memory/zone_table_segment_local.h

@@ -18,6 +18,8 @@
 #include <datasrc/memory/zone_table_segment.h>
 #include <datasrc/memory/zone_table_segment.h>
 #include <util/memory_segment_local.h>
 #include <util/memory_segment_local.h>
 
 
+#include <string>
+
 namespace isc {
 namespace isc {
 namespace datasrc {
 namespace datasrc {
 namespace memory {
 namespace memory {
@@ -42,6 +44,9 @@ public:
     /// \brief Destructor
     /// \brief Destructor
     virtual ~ZoneTableSegmentLocal();
     virtual ~ZoneTableSegmentLocal();
 
 
+    /// \brief Returns "local" as the implementation type.
+    virtual const std::string& getImplType() const;
+
     /// \brief This method has an empty definition.
     /// \brief This method has an empty definition.
     virtual void resetHeader();
     virtual void resetHeader();
 
 
@@ -75,7 +80,16 @@ public:
     /// \throw isc::NotImplemented
     /// \throw isc::NotImplemented
     virtual void clear();
     virtual void clear();
 
 
+    /// \brief Return true if the segment is usable.
+    ///
+    /// Local segments are always usable. This implementation always
+    /// returns true.
+    virtual bool isUsable() const {
+        return (true);
+    }
+
 private:
 private:
+    std::string impl_type_;
     isc::util::MemorySegmentLocal mem_sgmt_;
     isc::util::MemorySegmentLocal mem_sgmt_;
     ZoneTableHeader header_;
     ZoneTableHeader header_;
 };
 };

+ 16 - 4
src/lib/datasrc/memory/zone_table_segment_mapped.cc

@@ -36,6 +36,7 @@ const char* const ZONE_TABLE_HEADER_NAME = "zone_table_header";
 
 
 ZoneTableSegmentMapped::ZoneTableSegmentMapped(const RRClass& rrclass) :
 ZoneTableSegmentMapped::ZoneTableSegmentMapped(const RRClass& rrclass) :
     ZoneTableSegment(rrclass),
     ZoneTableSegment(rrclass),
+    impl_type_("mapped"),
     rrclass_(rrclass),
     rrclass_(rrclass),
     cached_header_(NULL)
     cached_header_(NULL)
 {
 {
@@ -45,6 +46,11 @@ ZoneTableSegmentMapped::~ZoneTableSegmentMapped() {
     sync();
     sync();
 }
 }
 
 
+const std::string&
+ZoneTableSegmentMapped::getImplType() const {
+    return (impl_type_);
+}
+
 bool
 bool
 ZoneTableSegmentMapped::processChecksum(MemorySegmentMapped& segment,
 ZoneTableSegmentMapped::processChecksum(MemorySegmentMapped& segment,
                                         bool create,
                                         bool create,
@@ -325,7 +331,7 @@ ZoneTableSegmentMapped::resetHeader() {
     // getHeader() has to work on const objects too. So we do it here
     // getHeader() has to work on const objects too. So we do it here
     // now.
     // now.
 
 
-    if (!mem_sgmt_) {
+    if (!isUsable()) {
         isc_throw(isc::InvalidOperation,
         isc_throw(isc::InvalidOperation,
                   "resetHeader() called without calling reset() first");
                   "resetHeader() called without calling reset() first");
     }
     }
@@ -344,7 +350,7 @@ ZoneTableSegmentMapped::resetHeader() {
 template<typename T>
 template<typename T>
 T*
 T*
 ZoneTableSegmentMapped::getHeaderHelper() const {
 ZoneTableSegmentMapped::getHeaderHelper() const {
-    if (!mem_sgmt_) {
+    if (!isUsable()) {
         isc_throw(isc::InvalidOperation,
         isc_throw(isc::InvalidOperation,
                   "getHeader() called without calling reset() first");
                   "getHeader() called without calling reset() first");
     }
     }
@@ -365,7 +371,7 @@ ZoneTableSegmentMapped::getHeader() const {
 
 
 MemorySegment&
 MemorySegment&
 ZoneTableSegmentMapped::getMemorySegment() {
 ZoneTableSegmentMapped::getMemorySegment() {
-    if (!mem_sgmt_) {
+    if (!isUsable()) {
         isc_throw(isc::InvalidOperation,
         isc_throw(isc::InvalidOperation,
                   "getMemorySegment() called without calling reset() first");
                   "getMemorySegment() called without calling reset() first");
     }
     }
@@ -373,8 +379,14 @@ ZoneTableSegmentMapped::getMemorySegment() {
 }
 }
 
 
 bool
 bool
+ZoneTableSegmentMapped::isUsable() const {
+    // If mem_sgmt_ is not empty, then it is usable.
+    return (mem_sgmt_);
+}
+
+bool
 ZoneTableSegmentMapped::isWritable() const {
 ZoneTableSegmentMapped::isWritable() const {
-    if (!mem_sgmt_) {
+    if (!isUsable()) {
         // If reset() was never performed for this segment, or if the
         // If reset() was never performed for this segment, or if the
         // most recent reset() had failed, then the segment is not
         // most recent reset() had failed, then the segment is not
         // writable.
         // writable.

+ 10 - 0
src/lib/datasrc/memory/zone_table_segment_mapped.h

@@ -19,6 +19,7 @@
 #include <util/memory_segment_mapped.h>
 #include <util/memory_segment_mapped.h>
 
 
 #include <boost/scoped_ptr.hpp>
 #include <boost/scoped_ptr.hpp>
+#include <string>
 
 
 namespace isc {
 namespace isc {
 namespace datasrc {
 namespace datasrc {
@@ -46,6 +47,9 @@ public:
     /// \brief Destructor
     /// \brief Destructor
     virtual ~ZoneTableSegmentMapped();
     virtual ~ZoneTableSegmentMapped();
 
 
+    /// \brief Returns "mapped" as the implementation type.
+    virtual const std::string& getImplType() const;
+
     /// \brief Reset the table header address from the named address in
     /// \brief Reset the table header address from the named address in
     /// the mapped file.
     /// the mapped file.
     virtual void resetHeader();
     virtual void resetHeader();
@@ -111,6 +115,11 @@ public:
     /// \brief Unmap the current file (if mapped).
     /// \brief Unmap the current file (if mapped).
     virtual void clear();
     virtual void clear();
 
 
+    /// \brief Return true if the segment is usable.
+    ///
+    /// See the base class for the description.
+    virtual bool isUsable() const;
+
 private:
 private:
     void sync();
     void sync();
 
 
@@ -126,6 +135,7 @@ private:
     template<typename T> T* getHeaderHelper() const;
     template<typename T> T* getHeaderHelper() const;
 
 
 private:
 private:
+    std::string impl_type_;
     isc::dns::RRClass rrclass_;
     isc::dns::RRClass rrclass_;
     MemorySegmentOpenMode current_mode_;
     MemorySegmentOpenMode current_mode_;
     std::string current_filename_;
     std::string current_filename_;

+ 39 - 7
src/lib/datasrc/tests/memory/zone_table_segment_mapped_unittest.cc

@@ -172,6 +172,10 @@ ZoneTableSegmentMappedTest::setupMappedFiles() {
     ztable_segment_->clear();
     ztable_segment_->clear();
 }
 }
 
 
+TEST_F(ZoneTableSegmentMappedTest, getImplType) {
+    EXPECT_EQ("mapped", ztable_segment_->getImplType());
+}
+
 TEST_F(ZoneTableSegmentMappedTest, getHeaderUninitialized) {
 TEST_F(ZoneTableSegmentMappedTest, getHeaderUninitialized) {
     // This should throw as we haven't called reset() yet.
     // This should throw as we haven't called reset() yet.
     EXPECT_THROW(ztable_segment_->getHeader(), isc::InvalidOperation);
     EXPECT_THROW(ztable_segment_->getHeader(), isc::InvalidOperation);
@@ -182,6 +186,12 @@ TEST_F(ZoneTableSegmentMappedTest, getMemorySegmentUninitialized) {
     EXPECT_THROW(ztable_segment_->getMemorySegment(), isc::InvalidOperation);
     EXPECT_THROW(ztable_segment_->getMemorySegment(), isc::InvalidOperation);
 }
 }
 
 
+TEST_F(ZoneTableSegmentMappedTest, isUsableUninitialized) {
+    // isUsable() must return false by default, when the segment has not
+    // been reset() yet.
+    EXPECT_FALSE(ztable_segment_->isUsable());
+}
+
 TEST_F(ZoneTableSegmentMappedTest, isWritableUninitialized) {
 TEST_F(ZoneTableSegmentMappedTest, isWritableUninitialized) {
     // isWritable() must return false by default, when the segment has
     // isWritable() must return false by default, when the segment has
     // not been reset() yet.
     // not been reset() yet.
@@ -252,13 +262,15 @@ TEST_F(ZoneTableSegmentMappedTest, reset) {
     EXPECT_THROW(ztable_segment_->getHeader(), isc::InvalidOperation);
     EXPECT_THROW(ztable_segment_->getHeader(), isc::InvalidOperation);
     EXPECT_THROW(ztable_segment_->getMemorySegment(), isc::InvalidOperation);
     EXPECT_THROW(ztable_segment_->getMemorySegment(), isc::InvalidOperation);
 
 
-    // isWritable() must still return false, because the segment has not
-    // been successfully reset() yet.
+    // isUsable() and isWritable() must still return false, because the
+    // segment has not been successfully reset() yet.
+    EXPECT_FALSE(ztable_segment_->isUsable());
     EXPECT_FALSE(ztable_segment_->isWritable());
     EXPECT_FALSE(ztable_segment_->isWritable());
 
 
     // READ_WRITE mode must create the mapped file if it doesn't exist
     // READ_WRITE mode must create the mapped file if it doesn't exist
     // (and must not result in an exception).
     // (and must not result in an exception).
     ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params_);
     ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params_);
+    EXPECT_TRUE(ztable_segment_->isUsable());
     EXPECT_TRUE(ztable_segment_->isWritable());
     EXPECT_TRUE(ztable_segment_->isWritable());
 
 
     // The following method calls should no longer throw:
     // The following method calls should no longer throw:
@@ -268,12 +280,14 @@ TEST_F(ZoneTableSegmentMappedTest, reset) {
     // Let's try to re-open the mapped file in READ_ONLY mode. It should
     // Let's try to re-open the mapped file in READ_ONLY mode. It should
     // not fail now.
     // not fail now.
     ztable_segment_->reset(ZoneTableSegment::READ_ONLY, config_params_);
     ztable_segment_->reset(ZoneTableSegment::READ_ONLY, config_params_);
+    EXPECT_TRUE(ztable_segment_->isUsable());
     EXPECT_FALSE(ztable_segment_->isWritable());
     EXPECT_FALSE(ztable_segment_->isWritable());
 
 
     // Re-creating the mapped file should erase old data and should not
     // Re-creating the mapped file should erase old data and should not
     // trigger any exceptions inside reset() due to old data (such as
     // trigger any exceptions inside reset() due to old data (such as
     // named addresses).
     // named addresses).
     ztable_segment_->reset(ZoneTableSegment::CREATE, config_params_);
     ztable_segment_->reset(ZoneTableSegment::CREATE, config_params_);
+    EXPECT_TRUE(ztable_segment_->isUsable());
     EXPECT_TRUE(ztable_segment_->isWritable());
     EXPECT_TRUE(ztable_segment_->isWritable());
 
 
     // When we reset() with an invalid paramter and it fails, then the
     // When we reset() with an invalid paramter and it fails, then the
@@ -282,6 +296,7 @@ TEST_F(ZoneTableSegmentMappedTest, reset) {
         ztable_segment_->reset(ZoneTableSegment::CREATE,
         ztable_segment_->reset(ZoneTableSegment::CREATE,
                                Element::fromJSON("{}"));
                                Element::fromJSON("{}"));
     }, isc::InvalidParameter);
     }, isc::InvalidParameter);
+    EXPECT_TRUE(ztable_segment_->isUsable());
     EXPECT_TRUE(ztable_segment_->isWritable());
     EXPECT_TRUE(ztable_segment_->isWritable());
     // The following should not throw.
     // The following should not throw.
     EXPECT_NO_THROW(ztable_segment_->getHeader());
     EXPECT_NO_THROW(ztable_segment_->getHeader());
@@ -291,6 +306,7 @@ TEST_F(ZoneTableSegmentMappedTest, reset) {
     // would use existing named addresses. This actually re-opens the
     // would use existing named addresses. This actually re-opens the
     // currently open map.
     // currently open map.
     ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params_);
     ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params_);
+    EXPECT_TRUE(ztable_segment_->isUsable());
     EXPECT_TRUE(ztable_segment_->isWritable());
     EXPECT_TRUE(ztable_segment_->isWritable());
 }
 }
 
 
@@ -301,6 +317,7 @@ TEST_F(ZoneTableSegmentMappedTest, resetCreate) {
     // Open the underlying mapped file in create mode.
     // Open the underlying mapped file in create mode.
     ztable_segment_->reset(ZoneTableSegment::CREATE, config_params_);
     ztable_segment_->reset(ZoneTableSegment::CREATE, config_params_);
 
 
+    ASSERT_TRUE(ztable_segment_->isUsable());
     ASSERT_TRUE(ztable_segment_->isWritable());
     ASSERT_TRUE(ztable_segment_->isWritable());
 
 
     // Add the data.
     // Add the data.
@@ -327,6 +344,7 @@ TEST_F(ZoneTableSegmentMappedTest, resetReadWrite) {
     // Open the underlying mapped file in read+write mode.
     // Open the underlying mapped file in read+write mode.
     ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params_);
     ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params_);
 
 
+    ASSERT_TRUE(ztable_segment_->isUsable());
     ASSERT_TRUE(ztable_segment_->isWritable());
     ASSERT_TRUE(ztable_segment_->isWritable());
 
 
     // Add the data.
     // Add the data.
@@ -353,6 +371,7 @@ TEST_F(ZoneTableSegmentMappedTest, resetReadOnly) {
     // Open the underlying mapped file in read+write mode.
     // Open the underlying mapped file in read+write mode.
     ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params_);
     ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params_);
 
 
+    ASSERT_TRUE(ztable_segment_->isUsable());
     ASSERT_TRUE(ztable_segment_->isWritable());
     ASSERT_TRUE(ztable_segment_->isWritable());
 
 
     // Add the data.
     // Add the data.
@@ -389,6 +408,7 @@ TEST_F(ZoneTableSegmentMappedTest, clearUninitialized) {
 
 
     // isWritable() must still return false, because the segment has not
     // isWritable() must still return false, because the segment has not
     // been successfully reset() yet.
     // been successfully reset() yet.
+    EXPECT_FALSE(ztable_segment_->isUsable());
     EXPECT_FALSE(ztable_segment_->isWritable());
     EXPECT_FALSE(ztable_segment_->isWritable());
 }
 }
 
 
@@ -397,6 +417,7 @@ TEST_F(ZoneTableSegmentMappedTest, clear) {
     // exist yet)
     // exist yet)
     ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params_);
     ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params_);
 
 
+    EXPECT_TRUE(ztable_segment_->isUsable());
     EXPECT_TRUE(ztable_segment_->isWritable());
     EXPECT_TRUE(ztable_segment_->isWritable());
     // The following method calls should no longer throw:
     // The following method calls should no longer throw:
     EXPECT_NO_THROW(ztable_segment_->getHeader());
     EXPECT_NO_THROW(ztable_segment_->getHeader());
@@ -405,6 +426,7 @@ TEST_F(ZoneTableSegmentMappedTest, clear) {
     // Now, clear the segment.
     // Now, clear the segment.
     ztable_segment_->clear();
     ztable_segment_->clear();
 
 
+    EXPECT_FALSE(ztable_segment_->isUsable());
     EXPECT_FALSE(ztable_segment_->isWritable());
     EXPECT_FALSE(ztable_segment_->isWritable());
     // The following method calls should now throw.
     // The following method calls should now throw.
     EXPECT_THROW(ztable_segment_->getHeader(), isc::InvalidOperation);
     EXPECT_THROW(ztable_segment_->getHeader(), isc::InvalidOperation);
@@ -425,11 +447,13 @@ TEST_F(ZoneTableSegmentMappedTest, resetFailedCorruptedChecksum) {
     corruptChecksum(*segment);
     corruptChecksum(*segment);
     segment.reset();
     segment.reset();
 
 
-    // Opening mapped file 2 in read-write mode should fail
+    // Resetting to mapped file 2 in read-write mode should fail
     EXPECT_THROW({
     EXPECT_THROW({
         ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params2_);
         ztable_segment_->reset(ZoneTableSegment::READ_WRITE, config_params2_);
     }, ResetFailed);
     }, ResetFailed);
 
 
+    EXPECT_TRUE(ztable_segment_->isUsable());
+    EXPECT_TRUE(ztable_segment_->isWritable());
     // Check for the old data in the segment to make sure it is still
     // Check for the old data in the segment to make sure it is still
     // available and correct.
     // available and correct.
     EXPECT_TRUE(verifyData(ztable_segment_->getMemorySegment()));
     EXPECT_TRUE(verifyData(ztable_segment_->getMemorySegment()));
@@ -449,11 +473,13 @@ TEST_F(ZoneTableSegmentMappedTest, resetFailedMissingChecksum) {
     deleteChecksum(*segment);
     deleteChecksum(*segment);
     segment.reset();
     segment.reset();
 
 
-    // Opening mapped file 2 in read-only mode should fail
+    // Resetting to mapped file 2 in read-only mode should fail
     EXPECT_THROW({
     EXPECT_THROW({
         ztable_segment_->reset(ZoneTableSegment::READ_ONLY, config_params2_);
         ztable_segment_->reset(ZoneTableSegment::READ_ONLY, config_params2_);
     }, ResetFailed);
     }, ResetFailed);
 
 
+    EXPECT_TRUE(ztable_segment_->isUsable());
+    EXPECT_TRUE(ztable_segment_->isWritable());
     // Check for the old data in the segment to make sure it is still
     // Check for the old data in the segment to make sure it is still
     // available and correct.
     // available and correct.
     EXPECT_TRUE(verifyData(ztable_segment_->getMemorySegment()));
     EXPECT_TRUE(verifyData(ztable_segment_->getMemorySegment()));
@@ -473,11 +499,13 @@ TEST_F(ZoneTableSegmentMappedTest, resetFailedMissingHeader) {
     deleteHeader(*segment);
     deleteHeader(*segment);
     segment.reset();
     segment.reset();
 
 
-    // Opening mapped file 2 in read-only mode should fail
+    // Resetting to mapped file 2 in read-only mode should fail
     EXPECT_THROW({
     EXPECT_THROW({
         ztable_segment_->reset(ZoneTableSegment::READ_ONLY, config_params2_);
         ztable_segment_->reset(ZoneTableSegment::READ_ONLY, config_params2_);
     }, ResetFailed);
     }, ResetFailed);
 
 
+    EXPECT_TRUE(ztable_segment_->isUsable());
+    EXPECT_TRUE(ztable_segment_->isWritable());
     // Check for the old data in the segment to make sure it is still
     // Check for the old data in the segment to make sure it is still
     // available and correct.
     // available and correct.
     EXPECT_TRUE(verifyData(ztable_segment_->getMemorySegment()));
     EXPECT_TRUE(verifyData(ztable_segment_->getMemorySegment()));
@@ -494,11 +522,13 @@ TEST_F(ZoneTableSegmentMappedTest, resetCreateOverCorruptedFile) {
     corruptChecksum(*segment);
     corruptChecksum(*segment);
     segment.reset();
     segment.reset();
 
 
-    // Resetting mapped file 1 in CREATE mode over a corrupted file
+    // Resetting to mapped file 1 in CREATE mode over a corrupted file
     // should pass.
     // should pass.
     EXPECT_NO_THROW(ztable_segment_->reset(ZoneTableSegment::CREATE,
     EXPECT_NO_THROW(ztable_segment_->reset(ZoneTableSegment::CREATE,
                                            config_params_));
                                            config_params_));
 
 
+    EXPECT_TRUE(ztable_segment_->isUsable());
+    EXPECT_TRUE(ztable_segment_->isWritable());
     // Check for the old data in the segment. It should not be present
     // Check for the old data in the segment. It should not be present
     // (as we opened the segment in CREATE mode).
     // (as we opened the segment in CREATE mode).
     EXPECT_FALSE(verifyData(ztable_segment_->getMemorySegment()));
     EXPECT_FALSE(verifyData(ztable_segment_->getMemorySegment()));
@@ -513,11 +543,13 @@ TEST_F(ZoneTableSegmentMappedTest, resetCreateOverCorruptedFile) {
     deleteChecksum(*segment);
     deleteChecksum(*segment);
     segment.reset();
     segment.reset();
 
 
-    // Resetting mapped file 1 in CREATE mode over a file missing
+    // Resetting to mapped file 1 in CREATE mode over a file missing
     // checksum should pass.
     // checksum should pass.
     EXPECT_NO_THROW(ztable_segment_->reset(ZoneTableSegment::CREATE,
     EXPECT_NO_THROW(ztable_segment_->reset(ZoneTableSegment::CREATE,
                                            config_params_));
                                            config_params_));
 
 
+    EXPECT_TRUE(ztable_segment_->isUsable());
+    EXPECT_TRUE(ztable_segment_->isWritable());
     // Check for the old data in the segment. It should not be present
     // Check for the old data in the segment. It should not be present
     // (as we opened the segment in CREATE mode).
     // (as we opened the segment in CREATE mode).
     EXPECT_FALSE(verifyData(ztable_segment_->getMemorySegment()));
     EXPECT_FALSE(verifyData(ztable_segment_->getMemorySegment()));

+ 12 - 0
src/lib/datasrc/tests/memory/zone_table_segment_mock.h

@@ -20,6 +20,8 @@
 #include <datasrc/memory/zone_data.h>
 #include <datasrc/memory/zone_data.h>
 #include <datasrc/memory/zone_writer.h>
 #include <datasrc/memory/zone_writer.h>
 
 
+#include <string>
+
 namespace isc {
 namespace isc {
 namespace datasrc {
 namespace datasrc {
 namespace memory {
 namespace memory {
@@ -33,6 +35,7 @@ public:
     ZoneTableSegmentMock(const isc::dns::RRClass& rrclass,
     ZoneTableSegmentMock(const isc::dns::RRClass& rrclass,
                          isc::util::MemorySegment& mem_sgmt) :
                          isc::util::MemorySegment& mem_sgmt) :
         ZoneTableSegment(rrclass),
         ZoneTableSegment(rrclass),
+        impl_type_("mock"),
         mem_sgmt_(mem_sgmt),
         mem_sgmt_(mem_sgmt),
         header_(ZoneTable::create(mem_sgmt_, rrclass))
         header_(ZoneTable::create(mem_sgmt_, rrclass))
     {}
     {}
@@ -41,6 +44,10 @@ public:
         ZoneTable::destroy(mem_sgmt_, header_.getTable());
         ZoneTable::destroy(mem_sgmt_, header_.getTable());
     }
     }
 
 
+    const std::string& getImplType() const {
+        return (impl_type_);
+    }
+
     virtual void reset(MemorySegmentOpenMode, isc::data::ConstElementPtr) {
     virtual void reset(MemorySegmentOpenMode, isc::data::ConstElementPtr) {
         isc_throw(isc::NotImplemented, "reset() is not implemented");
         isc_throw(isc::NotImplemented, "reset() is not implemented");
     }
     }
@@ -66,11 +73,16 @@ public:
         return (mem_sgmt_);
         return (mem_sgmt_);
     }
     }
 
 
+    virtual bool isUsable() const {
+        return (true);
+    }
+
     virtual bool isWritable() const {
     virtual bool isWritable() const {
         return (true);
         return (true);
     }
     }
 
 
 private:
 private:
+    std::string impl_type_;
     isc::util::MemorySegment& mem_sgmt_;
     isc::util::MemorySegment& mem_sgmt_;
     ZoneTableHeader header_;
     ZoneTableHeader header_;
 };
 };

+ 8 - 0
src/lib/datasrc/tests/memory/zone_table_segment_unittest.cc

@@ -41,6 +41,9 @@ protected:
     ZoneTableSegment* ztable_segment_;
     ZoneTableSegment* ztable_segment_;
 };
 };
 
 
+TEST_F(ZoneTableSegmentTest, getImplType) {
+    EXPECT_EQ("local", ztable_segment_->getImplType());
+}
 
 
 TEST_F(ZoneTableSegmentTest, create) {
 TEST_F(ZoneTableSegmentTest, create) {
     // By default, a local zone table segment is created.
     // By default, a local zone table segment is created.
@@ -106,6 +109,11 @@ TEST_F(ZoneTableSegmentTest, getMemorySegment) {
     mem_sgmt.allMemoryDeallocated(); // use mem_sgmt
     mem_sgmt.allMemoryDeallocated(); // use mem_sgmt
 }
 }
 
 
+TEST_F(ZoneTableSegmentTest, isUsable) {
+    // Local segments are always usable.
+    EXPECT_TRUE(ztable_segment_->isUsable());
+}
+
 TEST_F(ZoneTableSegmentTest, isWritable) {
 TEST_F(ZoneTableSegmentTest, isWritable) {
     // Local segments are always writable.
     // Local segments are always writable.
     EXPECT_TRUE(ztable_segment_->isWritable());
     EXPECT_TRUE(ztable_segment_->isWritable());

+ 7 - 0
src/lib/datasrc/tests/memory/zone_writer_unittest.cc

@@ -95,6 +95,13 @@ public:
         ZoneTableSegmentMock(rrclass, mem_sgmt)
         ZoneTableSegmentMock(rrclass, mem_sgmt)
     {}
     {}
 
 
+    // Returns false indicating that the segment is not usable. We
+    // override this too as ZoneTableSegment implementations may use it
+    // internally.
+    virtual bool isUsable() const {
+        return (false);
+    }
+
     // Returns false indicating it is a read-only segment. It is used in
     // Returns false indicating it is a read-only segment. It is used in
     // the ZoneWriter tests.
     // the ZoneWriter tests.
     virtual bool isWritable() const {
     virtual bool isWritable() const {