Browse Source

[1638] pre-work refactoring: extracted some NSEC3 tests into TYPED_TESTs
so that they will be shared with NSEC3PARAM.

JINMEI Tatuya 13 years ago
parent
commit
a2bc586234

+ 1 - 0
src/lib/dns/tests/Makefile.am

@@ -43,6 +43,7 @@ run_unittests_SOURCES += rdata_nsec_unittest.cc
 run_unittests_SOURCES += rdata_nsec3_unittest.cc
 run_unittests_SOURCES += rdata_nsecbitmap_unittest.cc
 run_unittests_SOURCES += rdata_nsec3param_unittest.cc
+run_unittests_SOURCES += rdata_nsec3param_like_unittest.cc
 run_unittests_SOURCES += rdata_rrsig_unittest.cc
 run_unittests_SOURCES += rdata_rp_unittest.cc
 run_unittests_SOURCES += rdata_srv_unittest.cc

+ 5 - 106
src/lib/dns/tests/rdata_nsec3_unittest.cc

@@ -39,19 +39,19 @@ using namespace isc::util::encode;
 using namespace isc::dns::rdata;
 
 namespace {
+
+// Note: some tests can be shared with NSEC3PARAM.  They are unified as
+// typed tests defined in nsec3param_like_unittest.
 class Rdata_NSEC3_Test : public RdataTest {
     // there's nothing to specialize
 public:
     Rdata_NSEC3_Test() :
         nsec3_txt("1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6 "
                   "NS SOA RRSIG DNSKEY NSEC3PARAM"),
-        nsec3_nosalt_txt("1 1 1 - H9RSFB7FPF2L8HG35CMPC765TDK23RP6 A" ),
-        obuffer(0), renderer(obuffer)
+        nsec3_nosalt_txt("1 1 1 - H9RSFB7FPF2L8HG35CMPC765TDK23RP6 A" )
     {}
     const string nsec3_txt;
     const string nsec3_nosalt_txt;
-    OutputBuffer obuffer;
-    MessageRenderer renderer;
 };
 
 TEST_F(Rdata_NSEC3_Test, fromText) {
@@ -59,20 +59,6 @@ TEST_F(Rdata_NSEC3_Test, fromText) {
     // text and construct nsec3_txt.  It will be tested against the wire format
     // representation in the createFromWire test.
 
-    // Numeric parameters have possible maximum values.  Unusual, but must
-    // be accepted.
-    EXPECT_NO_THROW(generic::NSEC3("255 255 65535 D399EAAB "
-                                   "H9RSFB7FPF2L8HG35CMPC765TDK23RP6 "
-                                   "NS SOA RRSIG DNSKEY NSEC3PARAM"));
-
-    // 0-length salt
-    EXPECT_EQ(0, generic::NSEC3(nsec3_nosalt_txt).getSalt().size());
-
-    // salt that has the possible max length
-    EXPECT_EQ(255, generic::NSEC3("1 1 1 " + string(255 * 2, '0') +
-                                  " H9RSFB7FPF2L8HG35CMPC765TDK23RP6 "
-                                  "NS").getSalt().size());
-
     // hash that has the possible max length (see badText about the magic
     // numbers)
     EXPECT_EQ(255, generic::NSEC3("1 1 1 D399EAAB " +
@@ -84,15 +70,6 @@ TEST_F(Rdata_NSEC3_Test, fromText) {
                         "1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6"));
 }
 
-TEST_F(Rdata_NSEC3_Test, toText) {
-    // normal case
-    const generic::NSEC3 rdata_nsec3(nsec3_txt);
-    EXPECT_EQ(nsec3_txt, rdata_nsec3.toText());
-
-    // empty salt case
-    EXPECT_EQ(nsec3_nosalt_txt, generic::NSEC3(nsec3_nosalt_txt).toText());
-}
-
 TEST_F(Rdata_NSEC3_Test, badText) {
     EXPECT_THROW(generic::NSEC3("1 1 1 ADDAFEEE "
                                 "0123456789ABCDEFGHIJKLMNOPQRSTUV "
@@ -101,32 +78,13 @@ TEST_F(Rdata_NSEC3_Test, badText) {
     EXPECT_THROW(generic::NSEC3("1 1 1 ADDAFEE "
                                 "WXYZWXYZWXYZ=WXYZWXYZ==WXYZWXYZW A NS SOA"),
                  BadValue);     // bad hex
-    EXPECT_THROW(generic::NSEC3("1 1 1 -- H9RSFB7FPF2L8HG35CMPC765TDK23RP6 "
-                                "A"),
-                 BadValue); // this shouldn't be confused a valid empty salt
     EXPECT_THROW(generic::NSEC3("1 1 1 ADDAFEEE "
                                 "WXYZWXYZWXYZ=WXYZWXYZ==WXYZWXYZW A NS SOA"),
                  BadValue);     // bad base32hex
-    EXPECT_THROW(generic::NSEC3("1000000 1 1 ADDAFEEE "
-                                "0123456789ABCDEFGHIJKLMNOPQRSTUV A NS SOA"),
-                 InvalidRdataText);
-    EXPECT_THROW(generic::NSEC3("1 1000000 1 ADDAFEEE "
-                                "0123456789ABCDEFGHIJKLMNOPQRSTUV A NS SOA"),
-                 InvalidRdataText);
     EXPECT_THROW(generic::NSEC3("1 1 1000000 ADDAFEEE "
                                 "0123456789ABCDEFGHIJKLMNOPQRSTUV A NS SOA"),
                  InvalidRdataText);
 
-    // There should be a space between "1" and "D399EAAB" (salt)
-    EXPECT_THROW(generic::NSEC3(
-                     "1 1 1D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6 "
-                     "NS SOA RRSIG DNSKEY NSEC3PARAM"), InvalidRdataText);
-
-    // Salt is too long (possible max + 1 bytes)
-    EXPECT_THROW(generic::NSEC3("1 1 1 " + string(256 * 2, '0') +
-                                " H9RSFB7FPF2L8HG35CMPC765TDK23RP6 NS"),
-                 InvalidRdataText);
-
     // Hash is too long.  Max = 255 bytes, base32-hex converts each 5 bytes
     // of the original to 8 characters, so 260 * 8 / 5 is the smallest length
     // of the encoded string that exceeds the max and doesn't require padding.
@@ -136,34 +94,12 @@ TEST_F(Rdata_NSEC3_Test, badText) {
 }
 
 TEST_F(Rdata_NSEC3_Test, createFromWire) {
-    // Normal case
-    const generic::NSEC3 rdata_nsec3(nsec3_txt);
-    EXPECT_EQ(0, rdata_nsec3.compare(
-                  *rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
-                                        "rdata_nsec3_fromWire1")));
-
     // A valid NSEC3 RR with empty type bitmap.
     EXPECT_NO_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
                                          "rdata_nsec3_fromWire15.wire"));
 
-    // Too short RDLENGTH: it doesn't even contain the first 5 octets.
-    EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
-                                      "rdata_nsec3_fromWire2.wire"),
-                 DNSMessageFORMERR);
-
     // Invalid bitmap cases are tested in Rdata_NSECBITMAP_Test.
 
-    // salt length is too large
-    EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
-                                      "rdata_nsec3_fromWire11.wire"),
-                 DNSMessageFORMERR);
-
-    // empty salt.  unusual, but valid.
-    ConstRdataPtr rdata =
-        rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
-                             "rdata_nsec3_fromWire13.wire");
-    EXPECT_EQ(0, dynamic_cast<const generic::NSEC3&>(*rdata).getSalt().size());
-
     // hash length is too large
     EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
                                       "rdata_nsec3_fromWire12.wire"),
@@ -193,37 +129,6 @@ TEST_F(Rdata_NSEC3_Test, createFromWire) {
     }
 }
 
-template <typename OUTPUT_TYPE>
-void
-toWireCheck(OUTPUT_TYPE& output, const char* const data_file) {
-    vector<uint8_t> data;
-    UnitTestUtil::readWireData(data_file, data);
-    InputBuffer buffer(&data[0], data.size());
-    const uint16_t rdlen = buffer.readUint16();
-    const generic::NSEC3 nsec3 =
-        dynamic_cast<const generic::NSEC3&>(*createRdata(
-                                                RRType::NSEC3(), RRClass::IN(),
-                                                buffer, rdlen));
-
-    output.clear();
-    output.writeUint16(rdlen);
-    nsec3.toWire(output);
-    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, output.getData(),
-                        output.getLength(), &data[0], data.size());
-}
-
-TEST_F(Rdata_NSEC3_Test, toWire) {
-    // normal case
-    toWireCheck(renderer, "rdata_nsec3_fromWire1");
-    toWireCheck(obuffer, "rdata_nsec3_fromWire1");
-
-    // empty salt
-    toWireCheck(renderer, "rdata_nsec3_fromWire13.wire");
-    toWireCheck(obuffer, "rdata_nsec3_fromWire13.wire");
-
-    // empty bitmap case is handled in the bitmap tests
-}
-
 TEST_F(Rdata_NSEC3_Test, assign) {
     generic::NSEC3 rdata_nsec3(nsec3_txt);
     generic::NSEC3 other_nsec3 = rdata_nsec3;
@@ -240,14 +145,8 @@ TEST_F(Rdata_NSEC3_Test, compare) {
 
     // test RDATAs, sorted in the ascendent order.  We only check comparison
     // on NSEC3-specific fields.  Bitmap comparison is tested in the bitmap
-    // tests.
+    // tests.  Common cases for NSEC3 and NSECPARAM3 are in their shared tests.
     vector<generic::NSEC3> compare_set;
-    compare_set.push_back(generic::NSEC3("0 0 0 D399EAAB D1K6GQ38"));
-    compare_set.push_back(generic::NSEC3("1 0 0 D399EAAB D1K6GQ38"));
-    compare_set.push_back(generic::NSEC3("1 1 0 D399EAAB D1K6GQ38"));
-    compare_set.push_back(generic::NSEC3("1 1 1 - D1K6GQ38"));
-    compare_set.push_back(generic::NSEC3("1 1 1 D399EAAB D1K6GQ38"));
-    compare_set.push_back(generic::NSEC3("1 1 1 FF99EAAB D1K6GQ38"));
     compare_set.push_back(generic::NSEC3("1 1 1 FF99EA0000 D1K6GQ38"));
     compare_set.push_back(generic::NSEC3("1 1 1 FF99EA0000 D1K6GQ0000000000"));
     compare_set.push_back(generic::NSEC3("1 1 1 FF99EA0000 D1K6GQ00UUUUUUUU"));

+ 250 - 0
src/lib/dns/tests/rdata_nsec3param_like_unittest.cc

@@ -0,0 +1,250 @@
+// 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.
+
+#include <dns/exceptions.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
+#include <dns/rrclass.h>
+#include <dns/rrtype.h>
+
+#include <gtest/gtest.h>
+
+#include <dns/tests/unittest_util.h>
+#include <dns/tests/rdata_unittest.h>
+
+#include <string>
+#include <vector>
+
+using namespace std;
+using isc::UnitTestUtil;
+using namespace isc::dns;
+using namespace isc::dns::rdata;
+
+namespace {
+
+// Template for shared tests for NSEC3 and NSEC3PARAM
+template <typename RDATA_TYPE>
+class NSEC3PARAMLikeTest : public RdataTest {
+protected:
+    NSEC3PARAMLikeTest() :
+        salt_txt("1 1 1 D399EAAB" + getCommonText()),
+        nosalt_txt("1 1 1 -" + getCommonText()),
+        obuffer(0), renderer(obuffer)
+    {}
+
+    RDATA_TYPE fromText(const string& rdata_text) {
+        return (RDATA_TYPE(rdata_text));
+    }
+
+    void compareCheck() const {
+        typename vector<RDATA_TYPE>::const_iterator it;
+        typename vector<RDATA_TYPE>::const_iterator const it_end =
+            compare_set.end();
+        for (it = compare_set.begin(); it != it_end - 1; ++it) {
+            SCOPED_TRACE("compare " + it->toText() + " to " +
+                         (it + 1)->toText());
+            EXPECT_GT(0, (*it).compare(*(it + 1)));
+            EXPECT_LT(0, (*(it + 1)).compare(*it));
+        }
+    }
+
+    const string salt_txt;      // RDATA text with salt
+    const string nosalt_txt;    // RDATA text without salt
+    OutputBuffer obuffer;       // used in toWire() tests
+    MessageRenderer renderer;   // ditto
+    vector<RDATA_TYPE> compare_set; // used in compare() tests
+
+    // Convert generic Rdata to the corresponding derived Rdata class object.
+    // Defined here because it depends on the template parameter.
+    static const RDATA_TYPE& convert(const Rdata& rdata) {
+        return (dynamic_cast<const RDATA_TYPE&>(rdata));
+    }
+
+    // These depend on the specific RR type.  We use specialized methods
+    // for them.
+    static RRType getType(); // return either RRType::NSEC3() or NSEC3PARAM()
+    static string getWireFilePrefix();
+    static string getCommonText(); // commonly used part of textual form
+};
+
+// Instantiate specific typed tests
+typedef ::testing::Types<generic::NSEC3, generic::NSEC3PARAM> TestRdataTypes;
+//typedef ::testing::Types<generic::NSEC3> TestRdataTypes;
+TYPED_TEST_CASE(NSEC3PARAMLikeTest, TestRdataTypes);
+
+template <>
+RRType
+NSEC3PARAMLikeTest<generic::NSEC3>::getType() {
+    return (RRType::NSEC3());
+}
+
+template <>
+RRType
+NSEC3PARAMLikeTest<generic::NSEC3PARAM>::getType() {
+    return (RRType::NSEC3PARAM());
+}
+
+template <>
+string
+NSEC3PARAMLikeTest<generic::NSEC3>::getWireFilePrefix() {
+    return ("rdata_nsec3_");
+}
+
+template <>
+string
+NSEC3PARAMLikeTest<generic::NSEC3PARAM>::getWireFilePrefix() {
+    return ("rdata_nsec3param_");
+}
+
+template <>
+string
+NSEC3PARAMLikeTest<generic::NSEC3>::getCommonText() {
+    // next hash + RR type bitmap
+    return (" H9RSFB7FPF2L8HG35CMPC765TDK23RP6 "
+            "NS SOA RRSIG DNSKEY NSEC3PARAM");
+}
+
+template <>
+string
+NSEC3PARAMLikeTest<generic::NSEC3PARAM>::getCommonText() {
+    // there's no more text for NSEC3PARAM
+    return ("");
+}
+
+TYPED_TEST(NSEC3PARAMLikeTest, fromText) {
+    // Numeric parameters have possible maximum values.  Unusual, but must
+    // be accepted.
+    EXPECT_NO_THROW(this->fromText("255 255 65535 D399EAAB" +
+                                   this->getCommonText()));
+
+    // 0-length salt
+    EXPECT_EQ(0, this->fromText(this->nosalt_txt).getSalt().size());
+
+    // salt that has the possible max length
+    EXPECT_EQ(255, this->fromText("1 1 1 " + string(255 * 2, '0') +
+                                  this->getCommonText()).getSalt().size());
+}
+
+TYPED_TEST(NSEC3PARAMLikeTest, toText) {
+    // normal case
+    EXPECT_EQ(this->salt_txt, this->fromText(this->salt_txt).toText());
+
+    // empty salt case
+    EXPECT_EQ(this->nosalt_txt, this->fromText(this->nosalt_txt).toText());
+}
+
+TYPED_TEST(NSEC3PARAMLikeTest, badText) {
+    // Similar to empty salt, but not really.  This shouldn't cause confusion.
+    EXPECT_THROW(this->fromText("1 1 1 --" + this->getCommonText()),
+                 isc::BadValue);
+
+    // Too large algorithm
+    EXPECT_THROW(this->fromText("1000000 1 1 ADDAFEEE" + this->getCommonText()),
+                 InvalidRdataText);
+
+    // Too large flags
+    EXPECT_THROW(this->fromText("1 1000000 1 ADDAFEEE" + this->getCommonText()),
+                 InvalidRdataText);
+
+    // Too large iterations
+    EXPECT_THROW(this->fromText("1 1 65536 ADDAFEEE" + this->getCommonText()),
+                 InvalidRdataText);
+
+    // There should be a space between "1" and "D399EAAB" (salt)
+    EXPECT_THROW(this->fromText("1 1 1D399EAAB" + this->getCommonText()),
+                 InvalidRdataText);
+
+    // Salt is too long (possible max + 1 bytes)
+    EXPECT_THROW(this->fromText("1 1 1 " + string(256 * 2, '0') +
+                                this->getCommonText()),
+                 InvalidRdataText);
+}
+
+TYPED_TEST(NSEC3PARAMLikeTest, createFromWire) {
+    // Normal case
+    EXPECT_EQ(0, this->fromText(this->salt_txt).compare(
+                  *this->rdataFactoryFromFile(this->getType(), RRClass::IN(),
+                                              (this->getWireFilePrefix() +
+                                               "fromWire1").c_str())));
+
+    // Too short RDLENGTH: it doesn't even contain the first 5 octets.
+    EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(),
+                                            (this->getWireFilePrefix() +
+                                             "fromWire2.wire").c_str()),
+                 DNSMessageFORMERR);
+
+    // salt length is too large
+    EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(),
+                                            (this->getWireFilePrefix() +
+                                             "fromWire11.wire").c_str()),
+                 DNSMessageFORMERR);
+
+    // empty salt.  not so usual, but valid.
+    ConstRdataPtr rdata =
+        this->rdataFactoryFromFile(this->getType(), RRClass::IN(),
+                                   (this->getWireFilePrefix() +
+                                    "fromWire13.wire").c_str());
+    EXPECT_EQ(0, this->convert(*rdata).getSalt().size());
+}
+
+template <typename OUTPUT_TYPE>
+void
+toWireCheck(RRType rrtype, OUTPUT_TYPE& output, const string& data_file) {
+    vector<uint8_t> data;
+    UnitTestUtil::readWireData(data_file.c_str(), data);
+    InputBuffer buffer(&data[0], data.size());
+    const uint16_t rdlen = buffer.readUint16();
+
+    output.clear();
+    output.writeUint16(rdlen);
+    createRdata(rrtype, RRClass::IN(), buffer, rdlen)->toWire(output);
+    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, output.getData(),
+                        output.getLength(), &data[0], data.size());
+}
+
+TYPED_TEST(NSEC3PARAMLikeTest, toWire) {
+    // normal case
+    toWireCheck(this->getType(), this->renderer,
+                this->getWireFilePrefix() + "fromWire1");
+    toWireCheck(this->getType(), this->obuffer,
+                this->getWireFilePrefix() + "fromWire1");
+
+    // empty salt
+    toWireCheck(this->getType(), this->renderer,
+                this->getWireFilePrefix() + "fromWire13.wire");
+    toWireCheck(this->getType(), this->obuffer,
+                this->getWireFilePrefix() + "fromWire13.wire");
+}
+
+TYPED_TEST(NSEC3PARAMLikeTest, compare) {
+    // test RDATAs, sorted in the ascendent order.
+    this->compare_set.push_back(this->fromText("0 0 0 D399EAAB" +
+                                               this->getCommonText()));
+    this->compare_set.push_back(this->fromText("1 0 0 D399EAAB" +
+                                               this->getCommonText()));
+    this->compare_set.push_back(this->fromText("1 1 0 D399EAAB" +
+                                               this->getCommonText()));
+    this->compare_set.push_back(this->fromText("1 1 1 -" +
+                                               this->getCommonText()));
+    this->compare_set.push_back(this->fromText("1 1 1 D399EAAB" +
+                                               this->getCommonText()));
+    this->compare_set.push_back(this->fromText("1 1 1 FF99EAAB" +
+                                               this->getCommonText()));
+    this->compare_set.push_back(this->fromText("1 1 1 FF99EA0000" +
+                                               this->getCommonText()));
+
+    this->compareCheck();
+}
+
+}