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) {
// 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 " +
"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 "
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.
}
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"),
}
}
-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;
// 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"));
--- /dev/null
+// 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();
+}
+
+}