Browse Source

added more tests for rrparamregistry
added removeRdataFactory methods


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/jinmei-dnsrdata2@799 e5f2f494-b856-4b98-b285-d166d9295462

JINMEI Tatuya 15 years ago
parent
commit
bc6d1d5d32

+ 27 - 0
src/lib/dns/cpp/rrparamregistry-placeholder.cc

@@ -286,6 +286,33 @@ RRParamRegistry::add(const string& typecode_string, uint16_t typecode,
     }
 }
 
+bool
+RRParamRegistry::removeRdataFactory(const RRType& rrtype,
+                                    const RRClass& rrclass)
+{
+    RdataFactoryMap::iterator found =
+        impl_->rdata_factories.find(RRTypeClass(rrtype, rrclass));
+    if (found != impl_->rdata_factories.end()) {
+        impl_->rdata_factories.erase(found);
+        return (true);
+    }
+
+    return (false);
+}
+
+bool
+RRParamRegistry::removeRdataFactory(const RRType& rrtype)
+{
+    GenericRdataFactoryMap::iterator found =
+        impl_->genericrdata_factories.find(rrtype);
+    if (found != impl_->genericrdata_factories.end()) {
+        impl_->genericrdata_factories.erase(found);
+        return (true);
+    }
+
+    return (false);
+}
+
 namespace {
 ///
 /// These are helper functions to implement case-insensitive string comparison.

+ 13 - 14
src/lib/dns/cpp/rrparamregistry.h

@@ -52,12 +52,6 @@ public:
         isc::Exception(file, line, what) {}
 };
 
-class InvalidRdataText : public Exception {
-public:
-    InvalidRdataText(const char* file, size_t line, const char* what) :
-        isc::Exception(file, line, what) {}
-};
-
 namespace rdata {
 class AbstractRdataFactory {
 protected:
@@ -158,7 +152,7 @@ public:
     /// representations.
     ///
     /// Regarding the mappings between textual representations and integer
-    /// codes, this methods behaves in the same way as \c addType() and
+    /// codes, this method behaves in the same way as \c addType() and
     /// \c addClass().  That is, it ignores any overriding attempt as
     /// long as the mapping is the same; otherwise the corresponding exception
     /// will be thrown.
@@ -168,9 +162,6 @@ public:
     /// stored in the registry; if this method throws an exception the
     /// registry will remain in the state before this method is called.
     ///
-    /// Note: this method will be extended to support more parameters in a
-    /// near future version.
-    ///
     /// \param type_string The textual representation of the RR type.
     /// \param type_code The integer code of the RR type.
     /// \param class_string The textual representation of the RR class.
@@ -219,7 +210,7 @@ public:
     /// exist in the registry.  If not, this method simply ignores the attempt
     /// and returns \c false.
     ///
-    /// This method never throw an exception.
+    /// This method never throws an exception.
     ///
     /// \param type_code The integer code of the RR type.
     /// \return \c true if mappings for the specified RR type exists and is
@@ -251,7 +242,8 @@ public:
     ///
     /// \param class_string The textual representation of the RR class.
     /// \param class_code The integer code of the RR class.
-    /// \return
+    /// \return \c true if a new mapping is added to the repository; \c false
+    /// if the same mapping is already registered.
     bool addClass(const std::string& class_string, uint16_t class_code);
 
     /// \brief Remove mappings between RR class code and textual representation
@@ -261,11 +253,18 @@ public:
     /// exist in the registry.  If not, this method simply ignores the attempt
     /// and returns \c false.
     ///
-    /// This method never throw an exception.
+    /// This method never throws an exception.
     ///
     /// \param class_code The integer code of the RR class.
-    /// \return
+    /// \return \c true if mappings for the specified RR type exists and is
+    /// removed; \c false if no such mapping is in the registry.
     bool removeClass(uint16_t class_code);
+
+    /// TBD
+    bool removeRdataFactory(const RRType& rrtype, const RRClass& rrclass);
+
+    /// TBD
+    bool removeRdataFactory(const RRType& rrtype);
     //@}
 
     ///

+ 70 - 4
src/lib/dns/cpp/tests/rrparamregistry_unittest.cc

@@ -22,11 +22,14 @@
 #include <gtest/gtest.h>
 
 #include <dns/rrclass.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
 #include <dns/rrparamregistry.h>
 #include <dns/rrtype.h>
 
 using namespace std;
 using namespace isc::dns;
+using namespace isc::dns::rdata;
 
 namespace {
 class RRParamRegistryTest : public ::testing::Test {
@@ -41,6 +44,17 @@ protected:
         oss2 << test_type_code;
         test_type_unknown_str = "TYPE" + oss2.str();
     }
+    ~RRParamRegistryTest()
+    {
+        // cleanup any non well-known parameters that possibly remain
+        // as a side effect.
+        RRParamRegistry::getRegistry().removeType(test_type_code);
+        RRParamRegistry::getRegistry().removeClass(test_class_code);
+        RRParamRegistry::getRegistry().removeRdataFactory(
+            RRType(test_type_code), RRClass(test_class_code));
+        RRParamRegistry::getRegistry().removeRdataFactory(
+            RRType(test_type_code));
+    }
 
     string test_class_unknown_str;
     string test_type_unknown_str;
@@ -64,16 +78,16 @@ TEST_F(RRParamRegistryTest, addRemove)
     EXPECT_EQ(65534, RRType("TESTTYPE").getCode());
 
     // the first removal attempt should succeed
-    EXPECT_TRUE(RRParamRegistry::getRegistry().removeType(65534));
+    EXPECT_TRUE(RRParamRegistry::getRegistry().removeType(test_type_code));
     // then toText() should treat it as an "unknown" 
     EXPECT_EQ(test_type_unknown_str, RRType(test_type_code).toText());
     // attempt of removing non-existent mapping should result in 'false'
-    EXPECT_FALSE(RRParamRegistry::getRegistry().removeType(65534));
+    EXPECT_FALSE(RRParamRegistry::getRegistry().removeType(test_type_code));
 
     // same set of tests for RR class.
-    EXPECT_TRUE(RRParamRegistry::getRegistry().removeClass(65533));
+    EXPECT_TRUE(RRParamRegistry::getRegistry().removeClass(test_class_code));
     EXPECT_EQ(test_class_unknown_str, RRClass(test_class_code).toText());
-    EXPECT_FALSE(RRParamRegistry::getRegistry().removeClass(65533));
+    EXPECT_FALSE(RRParamRegistry::getRegistry().removeClass(test_class_code));
 }
 
 TEST_F(RRParamRegistryTest, addError)
@@ -89,4 +103,56 @@ TEST_F(RRParamRegistryTest, addError)
                  RRTypeExists);
     EXPECT_EQ("A", RRType(1).toText());
 }
+
+class TestRdataFactory : public AbstractRdataFactory {
+public:
+    virtual RdataPtr create(const string& rdata_str) const
+    { return RdataPtr(new in::A(rdata_str)); }
+    virtual RdataPtr create(InputBuffer& buffer, size_t rdata_len) const
+    { return RdataPtr(new in::A(buffer, rdata_len)); }
+    virtual RdataPtr create(const Rdata& source) const
+    { return RdataPtr(new in::A(dynamic_cast<const in::A&>(source))); }
+};
+
+TEST_F(RRParamRegistryTest, addRemoveFactory)
+{
+    // By default, the test type/code pair should be considered "unknown",
+    // so the following should trigger an exception.
+    EXPECT_THROW(createRdata(RRType(test_type_code), RRClass(test_class_code),
+                             "192.0.2.1"),
+                 InvalidRdataText);
+    // Add factories so that we can treat this pair just like in::A.
+    RRParamRegistry::getRegistry().add(test_type_str, test_type_code,
+                                       test_class_str, test_class_code,
+                                       RdataFactoryPtr(new TestRdataFactory));
+    // Now it should be accepted, and should be identical to the same data of
+    // in::A.
+    EXPECT_EQ(0, in::A("192.0.2.1").compare(
+                  *createRdata(RRType(test_type_code), RRClass(test_class_code),
+                              "192.0.2.1")));
+    // It should still fail with other classes as we specified the factories
+    // as class-specific.
+    EXPECT_THROW(createRdata(RRType(test_type_code), RRClass("IN"),
+                             "192.0.2.1"),
+                 InvalidRdataText);
+    // Add the factories also as a class independent RRtype
+    RRParamRegistry::getRegistry().add(test_type_str, test_type_code,
+                                       RdataFactoryPtr(new TestRdataFactory));
+    // Now it should be okay for other classes than the test class.
+    EXPECT_EQ(0, in::A("192.0.2.1").compare(
+                  *createRdata(RRType(test_type_code), RRClass("IN"),
+                              "192.0.2.1")));
+
+    // Remove the added factories: first attempt should succeed; the second
+    // should return false as there's no match
+    EXPECT_TRUE(RRParamRegistry::getRegistry().removeRdataFactory(
+                    RRType(test_type_code), RRClass(test_class_code)));
+    EXPECT_FALSE(RRParamRegistry::getRegistry().removeRdataFactory(
+                     RRType(test_type_code), RRClass(test_class_code)));
+    EXPECT_TRUE(RRParamRegistry::getRegistry().removeRdataFactory(
+                    RRType(test_type_code)));
+    EXPECT_FALSE(RRParamRegistry::getRegistry().removeRdataFactory(
+                     RRType(test_type_code)));
+}
+
 }