BIND 10 trac1286, updated. c38fc5257ebbd0cd444e6b9cedb466b31df66cea Merge branch 'master' into trac1286
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Oct 12 14:08:42 UTC 2011
The branch, trac1286 has been updated
via c38fc5257ebbd0cd444e6b9cedb466b31df66cea (commit)
via 625e9b719947e894ad7369d8ca61df23ea31b243 (commit)
via 8a40bdd1108f37caacd6bc5f367ecc1587ee53cc (commit)
via ad1161678c25ee35b1cb7d657d1aba411939efdd (commit)
via b0e43dae72cf709cb01627eb9e3095cc48989f4e (commit)
via 0c88eb0d723fa43865e185b201aba2685173f378 (commit)
via 9ec6d23aa2ca58dd13a45821c92a926a0780591c (commit)
via 46230c83bb8d70e170fe77e9e936765014b762d2 (commit)
via 594dc98507783efcec6781077467885990094ec6 (commit)
via 656f891efdbb6cda87d10a06f7c2ac883e17fb7b (commit)
via 691a23f33ccde30a0d741b98bf0439228336af01 (commit)
via 1c16d6d7fe6253041362ff994e7594805c297b89 (commit)
via 8eb6232b0094778b4c195a870fa2c06cd1b7d0ab (commit)
via f6445b024942629726daeb591f99af090aa43c28 (commit)
via 146934075349f94ee27f23bf9ff01711b94e369e (commit)
via f00e85fff2018483303ccc3dbf7d85b4052cae1c (commit)
via ab1f7bea793d2435080e5cc018f115169ddf07f0 (commit)
via c5753d1c96374bfdf2c8e9fc0773ac036082cfa5 (commit)
via ff329082790af7572016f64a90f62c7be87f593c (commit)
via 5d1dc735923493b057014df7fefa8c8d7b04349e (commit)
via 5fb87e69f26c800823be33e81f99e1cb2143e067 (commit)
via 5220fc55e92504899d102b5704382382a4e450c1 (commit)
via d76b95edce86919636ee0e458f0b9def08a9d2ea (commit)
via d4405856fd2e088fbc7cd4caa9b2e9a6c66e8e83 (commit)
via 99fbf7cc5eacc8c0ec65a19a1eb83b4e0a329cd1 (commit)
via ff4a86af49e629a83e40f35c78c7616a208659c4 (commit)
via 47ea557d9d8a9782e4d576c45c545913bbaac4ea (commit)
via 006133b49eb5d44eeacb1d79593b97ae2212bbca (commit)
via 261656de6d4fbe2f6979162c978023f8859d2289 (commit)
via 419768f653e098ab566c9f94771552e2bfe3cc99 (commit)
via affa93f31bbc9719ac4e2ccc0e44d9a09c2b6a3b (commit)
via 71488ea628a1d791eeba41cb2eed3025c6311565 (commit)
via efe8aa23b59448214ef826a5910e52bdf0ce0015 (commit)
via a4ff990c9b0136c97b101f42dd5498a453fbdf25 (commit)
via 749e1c9c0627c0a20dc824ecc8c475ecee613d8a (commit)
via 8d8d6bd981771edb3011afedc5e62a59d78d7826 (commit)
via eefc291d240bc1fe15d131df9d463343b0333d3a (commit)
via 7e857cbcbd5dfa64552d15dee5ed01ca39bf8937 (commit)
via fa4c8fa8acbff7f4defc768e50a453bc376c56de (commit)
via 9b0785b11da612abf0e60f39950ebed9977b2e65 (commit)
via 8e5b40643255bd93c6edda9cabed39f46b074b0d (commit)
from 0b6ac7ed34c708e6e92c41dc28bc8589864cecd3 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit c38fc5257ebbd0cd444e6b9cedb466b31df66cea
Merge: 0b6ac7ed34c708e6e92c41dc28bc8589864cecd3 625e9b719947e894ad7369d8ca61df23ea31b243
Author: Jeremy C. Reed <jreed at ISC.org>
Date: Wed Oct 12 09:08:37 2011 -0500
Merge branch 'master' into trac1286
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 4 +
src/cppcheck-suppress.lst | 1 +
src/lib/datasrc/memory_datasrc.cc | 2 +-
src/lib/dns/rdata/generic/detail/txt_like.h | 56 +++++-
src/lib/dns/rdata/generic/spf_99.cc | 44 ++++
src/lib/dns/rdata/generic/spf_99.h | 26 +++
src/lib/dns/rdata/in_1/dhcid_49.cc | 8 +-
src/lib/dns/rdata/in_1/dhcid_49.h | 2 +-
src/lib/dns/tests/Makefile.am | 4 +-
src/lib/dns/tests/rdata_dhcid_unittest.cc | 111 +++++++++
src/lib/dns/tests/rdata_txt_like_unittest.cc | 261 ++++++++++++++++++++++
src/lib/dns/tests/rdata_txt_unittest.cc | 166 --------------
src/lib/dns/tests/testdata/Makefile.am | 1 +
src/lib/dns/tests/testdata/rdata_dhcid_fromWire | 12 +
src/lib/dns/tests/testdata/rdata_dhcid_toWire | 7 +
src/lib/python/isc/datasrc/__init__.py | 14 ++
src/lib/python/isc/datasrc/tests/datasrc_test.py | 33 +++
17 files changed, 577 insertions(+), 175 deletions(-)
create mode 100644 src/lib/dns/tests/rdata_dhcid_unittest.cc
create mode 100644 src/lib/dns/tests/rdata_txt_like_unittest.cc
delete mode 100644 src/lib/dns/tests/rdata_txt_unittest.cc
create mode 100644 src/lib/dns/tests/testdata/rdata_dhcid_fromWire
create mode 100644 src/lib/dns/tests/testdata/rdata_dhcid_toWire
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 307bfca..2db865e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+297. [func] dvv
+ Implement the SPF rrtype according to RFC4408.
+ (Trac #1140, git 146934075349f94ee27f23bf9ff01711b94e369e)
+
296. [build] jreed
Do not install the unittest libraries. At this time, they
are not useful without source tree (and they may or may
diff --git a/src/cppcheck-suppress.lst b/src/cppcheck-suppress.lst
index 8a4c7c1..1020ffe 100644
--- a/src/cppcheck-suppress.lst
+++ b/src/cppcheck-suppress.lst
@@ -8,3 +8,4 @@ unreadVariable:src/lib/dns/rdata/template.cc:61
selfAssignment:src/lib/dns/tests/name_unittest.cc:293
selfAssignment:src/lib/dns/tests/rdata_unittest.cc:228
selfAssignment:src/lib/dns/tests/tsigkey_unittest.cc:137
+selfAssignment:src/lib/dns/tests/rdata_txt_like_unittest.cc:222
diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc
index 3f84437..2b556ab 100644
--- a/src/lib/datasrc/memory_datasrc.cc
+++ b/src/lib/datasrc/memory_datasrc.cc
@@ -830,7 +830,7 @@ checkConfigElementString(ConstElementPtr config, const std::string& name,
if (!config->contains(name)) {
addError(errors,
"Config for memory backend does not contain a '"
- "type"
+ +name+
"' value");
return false;
} else if (!config->get(name) ||
diff --git a/src/lib/dns/rdata/generic/detail/txt_like.h b/src/lib/dns/rdata/generic/detail/txt_like.h
index 392a8ce..a0ab7ac 100644
--- a/src/lib/dns/rdata/generic/detail/txt_like.h
+++ b/src/lib/dns/rdata/generic/detail/txt_like.h
@@ -23,8 +23,24 @@
using namespace std;
using namespace isc::util;
+/// \brief \c rdata::TXTLikeImpl class represents the TXT-like RDATA for TXT
+/// and SPF types.
+///
+/// This class implements the basic interfaces inherited by the TXT and SPF
+/// classes from the abstract \c rdata::Rdata class, and provides trivial
+/// accessors to TXT-like RDATA.
template<class Type, uint16_t typeCode>class TXTLikeImpl {
public:
+ /// \brief Constructor from wire-format data.
+ ///
+ /// \param buffer A buffer storing the wire format data.
+ /// \param rdata_len The length of the RDATA in bytes, normally expected
+ /// to be the value of the RDLENGTH field of the corresponding RR.
+ ///
+ /// <b>Exceptions</b>
+ ///
+ /// \c InvalidRdataLength is thrown if rdata_len exceeds the maximum.
+ /// \c DNSMessageFORMERR is thrown if the RR is misformed.
TXTLikeImpl(InputBuffer& buffer, size_t rdata_len) {
if (rdata_len > MAX_RDLENGTH) {
isc_throw(InvalidRdataLength, "RDLENGTH too large: " << rdata_len);
@@ -52,6 +68,14 @@ public:
} while (rdata_len > 0);
}
+ /// \brief Constructor from string.
+ ///
+ /// <b>Exceptions</b>
+ ///
+ /// \c CharStringTooLong is thrown if the parameter string length exceeds
+ /// maximum.
+ /// \c InvalidRdataText is thrown if the method cannot process the
+ /// parameter data.
explicit TXTLikeImpl(const std::string& txtstr) {
// TBD: this is a simple, incomplete implementation that only supports
// a single character-string.
@@ -86,10 +110,17 @@ public:
string_list_.push_back(data);
}
+ /// \brief The copy constructor.
+ ///
+ /// Trivial for now, we could've used the default one.
TXTLikeImpl(const TXTLikeImpl& other) :
string_list_(other.string_list_)
{}
+ /// \brief Render the TXT-like data in the wire format to an OutputBuffer
+ /// object.
+ ///
+ /// \param buffer An output buffer to store the wire data.
void
toWire(OutputBuffer& buffer) const {
for (vector<vector<uint8_t> >::const_iterator it =
@@ -101,6 +132,11 @@ public:
}
}
+ /// \brief Render the TXT-like data in the wire format to an
+ /// AbstractMessageRenderer object.
+ ///
+ /// \param buffer An output AbstractMessageRenderer to send the wire data
+ /// to.
void
toWire(AbstractMessageRenderer& renderer) const {
for (vector<vector<uint8_t> >::const_iterator it =
@@ -112,6 +148,9 @@ public:
}
}
+ /// \brief Convert the TXT-like data to a string.
+ ///
+ /// \return A \c string object that represents the TXT-like data.
string
toText() const {
string s;
@@ -134,20 +173,33 @@ public:
return (s);
}
+ /// \brief Compare two instances of TXT-like RDATA.
+ ///
+ /// It is up to the caller to make sure that \c other is an object of the
+ /// same \c TXTLikeImpl class.
+ ///
+ /// \param other the right-hand operand to compare against.
+ /// \return < 0 if \c this would be sorted before \c other.
+ /// \return 0 if \c this is identical to \c other in terms of sorting
+ /// order.
+ /// \return > 0 if \c this would be sorted after \c other.
int
compare(const TXTLikeImpl& other) const {
// This implementation is not efficient. Revisit this (TBD).
OutputBuffer this_buffer(0);
toWire(this_buffer);
+ uint8_t const* const this_data = (uint8_t const*)this_buffer.getData();
size_t this_len = this_buffer.getLength();
OutputBuffer other_buffer(0);
other.toWire(other_buffer);
+ uint8_t const* const other_data
+ = (uint8_t const*)other_buffer.getData();
const size_t other_len = other_buffer.getLength();
const size_t cmplen = min(this_len, other_len);
- const int cmp = memcmp(this_buffer.getData(), other_buffer.getData(),
- cmplen);
+ const int cmp = memcmp(this_data, other_data, cmplen);
+
if (cmp != 0) {
return (cmp);
} else {
diff --git a/src/lib/dns/rdata/generic/spf_99.cc b/src/lib/dns/rdata/generic/spf_99.cc
index 492de98..aa3e4a1 100644
--- a/src/lib/dns/rdata/generic/spf_99.cc
+++ b/src/lib/dns/rdata/generic/spf_99.cc
@@ -30,8 +30,17 @@ using namespace isc::util;
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
+/// This class implements the basic interfaces inherited from the abstract
+/// \c rdata::Rdata class. The semantics of the class is provided by
+/// a copy of instantiated TXTLikeImpl class common to both TXT and SPF.
+
#include <dns/rdata/generic/detail/txt_like.h>
+/// \brief The assignment operator
+///
+/// It internally allocates a resource, and if it fails a corresponding
+/// standard exception will be thrown.
+/// This method never throws an exception otherwise.
SPF&
SPF::operator=(const SPF& source) {
if (impl_ == source.impl_) {
@@ -45,37 +54,72 @@ SPF::operator=(const SPF& source) {
return (*this);
}
+/// \brief The destructor
SPF::~SPF() {
delete impl_;
}
+/// \brief Constructor from wire-format data.
+///
+/// It internally allocates a resource, and if it fails a corresponding
+/// standard exception will be thrown.
SPF::SPF(InputBuffer& buffer, size_t rdata_len) :
impl_(new SPFImpl(buffer, rdata_len))
{}
+/// \brief Constructor from string.
+///
+/// It internally allocates a resource, and if it fails a corresponding
+/// standard exception will be thrown.
SPF::SPF(const std::string& txtstr) :
impl_(new SPFImpl(txtstr))
{}
+/// \brief Copy constructor
+///
+/// It internally allocates a resource, and if it fails a corresponding
+/// standard exception will be thrown.
SPF::SPF(const SPF& other) :
Rdata(), impl_(new SPFImpl(*other.impl_))
{}
+/// \brief Render the \c SPF in the wire format to a OutputBuffer object
+///
+/// \return is the return of the corresponding implementation method.
void
SPF::toWire(OutputBuffer& buffer) const {
impl_->toWire(buffer);
}
+/// \brief Render the \c SPF in the wire format to an AbstractMessageRenderer
+/// object
+///
+/// \return is the return of the corresponding implementation method.
void
SPF::toWire(AbstractMessageRenderer& renderer) const {
impl_->toWire(renderer);
}
+/// \brief Convert the \c SPF to a string.
+///
+/// \return is the return of the corresponding implementation method.
string
SPF::toText() const {
return (impl_->toText());
}
+/// \brief Compare two instances of \c SPF RDATA.
+///
+/// This method compares \c this and the \c other \c SPF objects.
+///
+/// This method is expected to be used in a polymorphic way, and the
+/// parameter to compare against is therefore of the abstract \c Rdata class.
+/// However, comparing two \c Rdata objects of different RR types
+/// is meaningless, and \c other must point to a \c SPF object;
+/// otherwise, the standard \c bad_cast exception will be thrown.
+///
+/// \param other the right-hand operand to compare against.
+/// \return is the return of the corresponding implementation method.
int
SPF::compare(const Rdata& other) const {
const SPF& other_txt = dynamic_cast<const SPF&>(other);
diff --git a/src/lib/dns/rdata/generic/spf_99.h b/src/lib/dns/rdata/generic/spf_99.h
index 956adb9..04ac99b 100644
--- a/src/lib/dns/rdata/generic/spf_99.h
+++ b/src/lib/dns/rdata/generic/spf_99.h
@@ -30,14 +30,40 @@
template<class Type, uint16_t typeCode> class TXTLikeImpl;
+/// \brief \c rdata::SPF class represents the SPF RDATA as defined %in
+/// RFC4408.
+///
+/// This class implements the basic interfaces inherited from the abstract
+/// \c rdata::Rdata class. The semantics of the class is provided by
+/// a copy of instantiated TXTLikeImpl class common to both TXT and SPF.
class SPF : public Rdata {
public:
// BEGIN_COMMON_MEMBERS
// END_COMMON_MEMBERS
+ /// \brief Assignment operator.
+ ///
+ /// It internally allocates a resource, and if it fails a corresponding
+ /// standard exception will be thrown.
+ /// This operator never throws an exception otherwise.
+ ///
+ /// This operator provides the strong exception guarantee: When an
+ /// exception is thrown the content of the assignment target will be
+ /// intact.
SPF& operator=(const SPF& source);
+
+ /// \brief The destructor.
~SPF();
+ ///
+ /// Specialized methods
+ ///
+
+ /// \brief Return a reference to the data strings
+ ///
+ /// This method never throws an exception.
+ const std::vector<std::vector<uint8_t> >& getString() const;
+
private:
typedef TXTLikeImpl<SPF, 99> SPFImpl;
SPFImpl* impl_;
diff --git a/src/lib/dns/rdata/in_1/dhcid_49.cc b/src/lib/dns/rdata/in_1/dhcid_49.cc
index 0a9a23c..f0c4aca 100644
--- a/src/lib/dns/rdata/in_1/dhcid_49.cc
+++ b/src/lib/dns/rdata/in_1/dhcid_49.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011 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
@@ -20,7 +20,7 @@
#include <exceptions/exceptions.h>
#include <util/buffer.h>
-#include <util/encode/hex.h>
+#include <util/encode/base64.h>
#include <dns/exceptions.h>
#include <dns/messagerenderer.h>
#include <dns/rdata.h>
@@ -52,7 +52,7 @@ DHCID::DHCID(const string& dhcid_str) {
stringbuf digestbuf;
iss >> &digestbuf;
- isc::util::encode::decodeHex(digestbuf.str(), digest_);
+ isc::util::encode::decodeBase64(digestbuf.str(), digest_);
// RFC4701 states DNS software should consider the RDATA section to
// be opaque, but there must be at least three bytes in the data:
@@ -112,7 +112,7 @@ DHCID::toWire(AbstractMessageRenderer& renderer) const {
/// \return A string representation of \c DHCID.
string
DHCID::toText() const {
- return (isc::util::encode::encodeHex(digest_));
+ return (isc::util::encode::encodeBase64(digest_));
}
/// \brief Compare two instances of \c DHCID RDATA.
diff --git a/src/lib/dns/rdata/in_1/dhcid_49.h b/src/lib/dns/rdata/in_1/dhcid_49.h
index 919395f..90f5fab 100644
--- a/src/lib/dns/rdata/in_1/dhcid_49.h
+++ b/src/lib/dns/rdata/in_1/dhcid_49.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011 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
diff --git a/src/lib/dns/tests/Makefile.am b/src/lib/dns/tests/Makefile.am
index 3794678..ceeb3b8 100644
--- a/src/lib/dns/tests/Makefile.am
+++ b/src/lib/dns/tests/Makefile.am
@@ -29,11 +29,13 @@ run_unittests_SOURCES += rdata_unittest.h rdata_unittest.cc
run_unittests_SOURCES += rdatafields_unittest.cc
run_unittests_SOURCES += rdata_in_a_unittest.cc rdata_in_aaaa_unittest.cc
run_unittests_SOURCES += rdata_ns_unittest.cc rdata_soa_unittest.cc
-run_unittests_SOURCES += rdata_txt_unittest.cc rdata_mx_unittest.cc
+run_unittests_SOURCES += rdata_txt_like_unittest.cc
+run_unittests_SOURCES += rdata_mx_unittest.cc
run_unittests_SOURCES += rdata_ptr_unittest.cc rdata_cname_unittest.cc
run_unittests_SOURCES += rdata_dname_unittest.cc
run_unittests_SOURCES += rdata_afsdb_unittest.cc
run_unittests_SOURCES += rdata_opt_unittest.cc
+run_unittests_SOURCES += rdata_dhcid_unittest.cc
run_unittests_SOURCES += rdata_dnskey_unittest.cc
run_unittests_SOURCES += rdata_ds_like_unittest.cc
run_unittests_SOURCES += rdata_nsec_unittest.cc
diff --git a/src/lib/dns/tests/rdata_dhcid_unittest.cc b/src/lib/dns/tests/rdata_dhcid_unittest.cc
new file mode 100644
index 0000000..9df7043
--- /dev/null
+++ b/src/lib/dns/tests/rdata_dhcid_unittest.cc
@@ -0,0 +1,111 @@
+// Copyright (C) 2011 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/buffer.h>
+#include <dns/rdataclass.h>
+#include <util/encode/base64.h>
+
+#include <gtest/gtest.h>
+
+#include <dns/tests/unittest_util.h>
+#include <dns/tests/rdata_unittest.h>
+
+using isc::UnitTestUtil;
+using namespace std;
+using namespace isc::dns;
+using namespace isc::util;
+using namespace isc::util::encode;
+using namespace isc::dns::rdata;
+
+namespace {
+
+const string string_dhcid(
+ "0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw0YHRjCDRkdC70L7Rh9C60LA=");
+
+const in::DHCID rdata_dhcid(string_dhcid);
+
+class Rdata_DHCID_Test : public RdataTest {
+};
+
+TEST_F(Rdata_DHCID_Test, createFromString) {
+ const in::DHCID rdata_dhcid2(string_dhcid);
+ EXPECT_EQ(0, rdata_dhcid2.compare(rdata_dhcid));
+}
+
+TEST_F(Rdata_DHCID_Test, badBase64) {
+ EXPECT_THROW(const in::DHCID rdata_dhcid_bad("00"), isc::BadValue);
+}
+
+TEST_F(Rdata_DHCID_Test, badLength) {
+ EXPECT_THROW(const in::DHCID rdata_dhcid_bad("MDA="), InvalidRdataLength);
+}
+
+TEST_F(Rdata_DHCID_Test, copy) {
+ const in::DHCID rdata_dhcid2(rdata_dhcid);
+ EXPECT_EQ(0, rdata_dhcid.compare(rdata_dhcid2));
+}
+
+TEST_F(Rdata_DHCID_Test, createFromWire) {
+ EXPECT_EQ(0, rdata_dhcid.compare(
+ *rdataFactoryFromFile(RRType("DHCID"), RRClass("IN"),
+ "rdata_dhcid_fromWire")));
+ // TBD: more tests
+}
+
+TEST_F(Rdata_DHCID_Test, toWireRenderer) {
+ rdata_dhcid.toWire(renderer);
+
+ vector<unsigned char> data;
+ UnitTestUtil::readWireData("rdata_dhcid_toWire", data);
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, renderer.getData(),
+ renderer.getLength(), &data[0], data.size());
+}
+
+TEST_F(Rdata_DHCID_Test, toWireBuffer) {
+ rdata_dhcid.toWire(obuffer);
+
+ vector<unsigned char> data;
+ UnitTestUtil::readWireData("rdata_dhcid_toWire", data);
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
+ obuffer.getLength(), &data[0], data.size());
+}
+
+TEST_F(Rdata_DHCID_Test, toText) {
+ EXPECT_EQ(string_dhcid, rdata_dhcid.toText());
+}
+
+TEST_F(Rdata_DHCID_Test, getDHCIDDigest) {
+ const string string_dhcid1(encodeBase64(rdata_dhcid.getDigest()));
+
+ EXPECT_EQ(string_dhcid, string_dhcid1);
+}
+
+TEST_F(Rdata_DHCID_Test, compare) {
+ // trivial case: self equivalence
+ EXPECT_EQ(0, rdata_dhcid.compare(rdata_dhcid));
+
+ in::DHCID rdata_dhcid1("0YLQvtC/0L7Qu9GPINC00LLQsCDRgNGD0LHQu9GP");
+ in::DHCID rdata_dhcid2("0YLQvtC/0L7Qu9GPINGC0YDQuCDRgNGD0LHQu9GP");
+ in::DHCID rdata_dhcid3("0YLQvtC/0L7Qu9GPINGH0LXRgtGL0YDQtSDRgNGD0LHQu9GP");
+
+ EXPECT_LT(rdata_dhcid1.compare(rdata_dhcid2), 0);
+ EXPECT_GT(rdata_dhcid2.compare(rdata_dhcid1), 0);
+
+ EXPECT_LT(rdata_dhcid2.compare(rdata_dhcid3), 0);
+ EXPECT_GT(rdata_dhcid3.compare(rdata_dhcid2), 0);
+
+ // comparison attempt between incompatible RR types should be rejected
+ EXPECT_THROW(rdata_dhcid.compare(*rdata_nomatch), bad_cast);
+}
+}
diff --git a/src/lib/dns/tests/rdata_txt_like_unittest.cc b/src/lib/dns/tests/rdata_txt_like_unittest.cc
new file mode 100644
index 0000000..981265e
--- /dev/null
+++ b/src/lib/dns/tests/rdata_txt_like_unittest.cc
@@ -0,0 +1,261 @@
+// Copyright (C) 2011 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.
+
+// This is the common code for TXT and SPF tests.
+
+#include <util/buffer.h>
+#include <dns/exceptions.h>
+#include <dns/rdataclass.h>
+#include <gtest/gtest.h>
+
+#include <dns/tests/unittest_util.h>
+#include <dns/tests/rdata_unittest.h>
+
+using isc::UnitTestUtil;
+using namespace std;
+using namespace isc::dns;
+using namespace isc::util;
+using namespace isc::dns::rdata;
+
+
+template<class T>
+class RRTYPE : public RRType {
+public:
+ RRTYPE();
+};
+
+template<> RRTYPE<generic::TXT>::RRTYPE() : RRType(RRType::TXT()) {}
+template<> RRTYPE<generic::SPF>::RRTYPE() : RRType(RRType::SPF()) {}
+
+namespace {
+const uint8_t wiredata_txt_like[] = {
+ sizeof("Test String") - 1,
+ 'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g'
+};
+
+const uint8_t wiredata_nulltxt[] = { 0 };
+vector<uint8_t> wiredata_longesttxt(256, 'a');
+
+template<class TXT_LIKE>
+class Rdata_TXT_LIKE_Test : public RdataTest {
+protected:
+ Rdata_TXT_LIKE_Test() {
+ wiredata_longesttxt[0] = 255; // adjust length
+ }
+
+ static const TXT_LIKE rdata_txt_like;
+ static const TXT_LIKE rdata_txt_like_empty;
+ static const TXT_LIKE rdata_txt_like_quoted;
+};
+
+template<class TXT_LIKE>
+const TXT_LIKE Rdata_TXT_LIKE_Test<TXT_LIKE>::rdata_txt_like("Test String");
+
+template<class TXT_LIKE>
+const TXT_LIKE Rdata_TXT_LIKE_Test<TXT_LIKE>::rdata_txt_like_empty("");
+
+template<class TXT_LIKE>
+const TXT_LIKE Rdata_TXT_LIKE_Test<TXT_LIKE>::rdata_txt_like_quoted
+ ("\"Test String\"");
+
+// The list of types we want to test.
+typedef testing::Types<generic::TXT, generic::SPF> Implementations;
+
+TYPED_TEST_CASE(Rdata_TXT_LIKE_Test, Implementations);
+
+TYPED_TEST(Rdata_TXT_LIKE_Test, createFromText) {
+ // normal case is covered in toWireBuffer.
+
+ // surrounding double-quotes shouldn't change the result.
+ EXPECT_EQ(0, this->rdata_txt_like.compare(this->rdata_txt_like_quoted));
+
+ // Null character-string.
+ this->obuffer.clear();
+ TypeParam(string("")).toWire(this->obuffer);
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
+ this->obuffer.getData(),
+ this->obuffer.getLength(),
+ wiredata_nulltxt, sizeof(wiredata_nulltxt));
+
+ // Longest possible character-string.
+ this->obuffer.clear();
+ TypeParam(string(255, 'a')).toWire(this->obuffer);
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
+ this->obuffer.getData(),
+ this->obuffer.getLength(),
+ &wiredata_longesttxt[0], wiredata_longesttxt.size());
+
+ // Too long text for a valid character-string.
+ EXPECT_THROW(TypeParam(string(256, 'a')), CharStringTooLong);
+
+ // The escape character makes the double quote a part of character-string,
+ // so this is invalid input and should be rejected.
+ EXPECT_THROW(TypeParam("\"Test String\\\""), InvalidRdataText);
+
+ // Terminating double-quote is provided, so this is valid, but in this
+ // version of implementation we reject escaped characters.
+ EXPECT_THROW(TypeParam("\"Test String\\\"\""), InvalidRdataText);
+}
+
+void
+makeLargest(vector<uint8_t>& data) {
+ uint8_t ch = 0;
+
+ // create 255 sets of character-strings, each of which has the longest
+ // length (255bytes string + 1-byte length field)
+ for (int i = 0; i < 255; ++i, ++ch) {
+ data.push_back(255);
+ data.insert(data.end(), 255, ch);
+ }
+ // the last character-string should be 255 bytes (including the one-byte
+ // length field) in length so that the total length should be in the range
+ // of 16-bit integers.
+ data.push_back(254);
+ data.insert(data.end(), 254, ch);
+
+ assert(data.size() == 65535);
+}
+
+TYPED_TEST(Rdata_TXT_LIKE_Test, createFromWire) {
+ EXPECT_EQ(0, this->rdata_txt_like.compare(
+ *this->rdataFactoryFromFile(RRTYPE<TypeParam>(), RRClass("IN"),
+ "rdata_txt_fromWire1")));
+
+ // Empty character string
+ EXPECT_EQ(0, this->rdata_txt_like_empty.compare(
+ *this->rdataFactoryFromFile(RRTYPE<TypeParam>(), RRClass("IN"),
+ "rdata_txt_fromWire2.wire")));
+
+ // Multiple character strings
+ this->obuffer.clear();
+ this->rdataFactoryFromFile(RRTYPE<TypeParam>(), RRClass("IN"),
+ "rdata_txt_fromWire3.wire")->toWire(this->obuffer);
+ // the result should be 'wiredata_txt' repeated twice
+ vector<uint8_t> expected_data(wiredata_txt_like, wiredata_txt_like +
+ sizeof(wiredata_txt_like));
+ expected_data.insert(expected_data.end(), wiredata_txt_like,
+ wiredata_txt_like + sizeof(wiredata_txt_like));
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
+ this->obuffer.getData(),
+ this->obuffer.getLength(),
+ &expected_data[0], expected_data.size());
+
+ // Largest length of data. There's nothing special, but should be
+ // constructed safely, and the content should be identical to the original
+ // data.
+ vector<uint8_t> largest_txt_like_data;
+ makeLargest(largest_txt_like_data);
+ InputBuffer ibuffer(&largest_txt_like_data[0],
+ largest_txt_like_data.size());
+ TypeParam largest_txt_like(ibuffer, largest_txt_like_data.size());
+ this->obuffer.clear();
+ largest_txt_like.toWire(this->obuffer);
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
+ this->obuffer.getData(),
+ this->obuffer.getLength(),
+ &largest_txt_like_data[0],
+ largest_txt_like_data.size());
+
+ // rdlen parameter is out of range. This is a rare event because we'd
+ // normally call the constructor via a polymorphic wrapper, where the
+ // length is validated. But this should be checked explicitly.
+ InputBuffer ibuffer2(&largest_txt_like_data[0],
+ largest_txt_like_data.size());
+ EXPECT_THROW(TypeParam(ibuffer2, 65536), InvalidRdataLength);
+
+ // RDATA is empty, which is invalid for TXT_LIKE.
+ EXPECT_THROW(this->rdataFactoryFromFile(RRTYPE<TypeParam>(), RRClass("IN"),
+ "rdata_txt_fromWire4.wire"),
+ DNSMessageFORMERR);
+
+ // character-string length is too large, which could cause overrun.
+ EXPECT_THROW(this->rdataFactoryFromFile(RRTYPE<TypeParam>(), RRClass("IN"),
+ "rdata_txt_fromWire5.wire"),
+ DNSMessageFORMERR);
+}
+
+TYPED_TEST(Rdata_TXT_LIKE_Test, toWireBuffer) {
+ this->rdata_txt_like.toWire(this->obuffer);
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
+ this->obuffer.getData(),
+ this->obuffer.getLength(),
+ wiredata_txt_like, sizeof(wiredata_txt_like));
+}
+
+TYPED_TEST(Rdata_TXT_LIKE_Test, toWireRenderer) {
+ this->rdata_txt_like.toWire(this->renderer);
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
+ this->renderer.getData(),
+ this->renderer.getLength(),
+ wiredata_txt_like, sizeof(wiredata_txt_like));
+}
+
+TYPED_TEST(Rdata_TXT_LIKE_Test, toText) {
+ EXPECT_EQ("\"Test String\"", this->rdata_txt_like.toText());
+}
+
+TYPED_TEST(Rdata_TXT_LIKE_Test, assignment) {
+ TypeParam rdata1("assignment1");
+ TypeParam rdata2("assignment2");
+ rdata1 = rdata2;
+ EXPECT_EQ(0, rdata2.compare(rdata1));
+
+ // Check if the copied data is valid even after the original is deleted
+ TypeParam* rdata3 = new TypeParam(rdata1);
+ TypeParam rdata4("assignment3");
+ rdata4 = *rdata3;
+ delete rdata3;
+ EXPECT_EQ(0, rdata4.compare(rdata1));
+
+ // Self assignment
+ rdata2 = rdata2;
+ EXPECT_EQ(0, rdata2.compare(rdata1));
+}
+
+TYPED_TEST(Rdata_TXT_LIKE_Test, compare) {
+ string const txt1("aaaaaaaa");
+ string const txt2("aaaaaaaaaa");
+ string const txt3("bbbbbbbb");
+ string const txt4(129, 'a');
+ string const txt5(128, 'b');
+
+ EXPECT_EQ(TypeParam(txt1).compare(TypeParam(txt1)), 0);
+
+ EXPECT_LT(TypeParam("").compare(TypeParam(txt1)), 0);
+ EXPECT_GT(TypeParam(txt1).compare(TypeParam("")), 0);
+
+ EXPECT_LT(TypeParam(txt1).compare(TypeParam(txt2)), 0);
+ EXPECT_GT(TypeParam(txt2).compare(TypeParam(txt1)), 0);
+
+ EXPECT_LT(TypeParam(txt1).compare(TypeParam(txt3)), 0);
+ EXPECT_GT(TypeParam(txt3).compare(TypeParam(txt1)), 0);
+
+ // we're comparing the data raw, starting at the length octet, so a shorter
+ // string sorts before a longer one no matter the lexicopraphical order
+ EXPECT_LT(TypeParam(txt3).compare(TypeParam(txt2)), 0);
+ EXPECT_GT(TypeParam(txt2).compare(TypeParam(txt3)), 0);
+
+ // to make sure the length octet compares unsigned
+ EXPECT_LT(TypeParam(txt1).compare(TypeParam(txt4)), 0);
+ EXPECT_GT(TypeParam(txt4).compare(TypeParam(txt1)), 0);
+
+ EXPECT_LT(TypeParam(txt5).compare(TypeParam(txt4)), 0);
+ EXPECT_GT(TypeParam(txt4).compare(TypeParam(txt5)), 0);
+
+ // comparison attempt between incompatible RR types should be rejected
+ EXPECT_THROW(TypeParam(txt1).compare(*this->rdata_nomatch),
+ bad_cast);
+}
+
+}
diff --git a/src/lib/dns/tests/rdata_txt_unittest.cc b/src/lib/dns/tests/rdata_txt_unittest.cc
deleted file mode 100644
index e5f8ac9..0000000
--- a/src/lib/dns/tests/rdata_txt_unittest.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright (C) 2010 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/buffer.h>
-#include <dns/exceptions.h>
-#include <dns/messagerenderer.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>
-
-using isc::UnitTestUtil;
-using namespace std;
-using namespace isc::dns;
-using namespace isc::util;
-using namespace isc::dns::rdata;
-
-namespace {
-const generic::TXT rdata_txt("Test String");
-const generic::TXT rdata_txt_empty("");
-const generic::TXT rdata_txt_quoated("\"Test String\"");
-const uint8_t wiredata_txt[] = {
- sizeof("Test String") - 1,
- 'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g'
-};
-const uint8_t wiredata_nulltxt[] = { 0 };
-vector<uint8_t> wiredata_longesttxt(256, 'a');
-
-class Rdata_TXT_Test : public RdataTest {
-protected:
- Rdata_TXT_Test() {
- wiredata_longesttxt[0] = 255; // adjust length
- }
-};
-
-TEST_F(Rdata_TXT_Test, createFromText) {
- // normal case is covered in toWireBuffer.
-
- // surrounding double-quotes shouldn't change the result.
- EXPECT_EQ(0, rdata_txt.compare(rdata_txt_quoated));
-
- // Null character-string.
- obuffer.clear();
- generic::TXT(string("")).toWire(obuffer);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
- wiredata_nulltxt, sizeof(wiredata_nulltxt));
-
- // Longest possible character-string.
- obuffer.clear();
- generic::TXT(string(255, 'a')).toWire(obuffer);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
- &wiredata_longesttxt[0], wiredata_longesttxt.size());
-
- // Too long text for a valid character-string.
- EXPECT_THROW(generic::TXT(string(256, 'a')), CharStringTooLong);
-
- // The escape character makes the double quote a part of character-string,
- // so this is invalid input and should be rejected.
- EXPECT_THROW(generic::TXT("\"Test String\\\""), InvalidRdataText);
-
- // Terminating double-quote is provided, so this is valid, but in this
- // version of implementation we reject escaped characters.
- EXPECT_THROW(generic::TXT("\"Test String\\\"\""), InvalidRdataText);
-}
-
-void
-makeLargest(vector<uint8_t>& data) {
- uint8_t ch = 0;
-
- // create 255 sets of character-strings, each of which has the longest
- // length (255bytes string + 1-byte length field)
- for (int i = 0; i < 255; ++i, ++ch) {
- data.push_back(255);
- data.insert(data.end(), 255, ch);
- }
- // the last character-string should be 255 bytes (including the one-byte
- // length field) in length so that the total length should be in the range
- // of 16-bit integers.
- data.push_back(254);
- data.insert(data.end(), 254, ch);
-
- assert(data.size() == 65535);
-}
-
-TEST_F(Rdata_TXT_Test, createFromWire) {
- EXPECT_EQ(0, rdata_txt.compare(
- *rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire1")));
-
- // Empty character string
- EXPECT_EQ(0, rdata_txt_empty.compare(
- *rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire2.wire")));
-
- // Multiple character strings
- obuffer.clear();
- rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire3.wire")->toWire(obuffer);
- // the result should be 'wiredata_txt' repeated twice
- vector<uint8_t> expected_data(wiredata_txt, wiredata_txt +
- sizeof(wiredata_txt));
- expected_data.insert(expected_data.end(), wiredata_txt,
- wiredata_txt + sizeof(wiredata_txt));
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
- &expected_data[0], expected_data.size());
-
- // Largest length of data. There's nothing special, but should be
- // constructed safely, and the content should be identical to the original
- // data.
- vector<uint8_t> largest_txt_data;
- makeLargest(largest_txt_data);
- InputBuffer ibuffer(&largest_txt_data[0], largest_txt_data.size());
- generic::TXT largest_txt(ibuffer, largest_txt_data.size());
- obuffer.clear();
- largest_txt.toWire(obuffer);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
- &largest_txt_data[0], largest_txt_data.size());
-
- // rdlen parameter is out of range. This is a rare event because we'd
- // normally call the constructor via a polymorphic wrapper, where the
- // length is validated. But this should be checked explicitly.
- InputBuffer ibuffer2(&largest_txt_data[0], largest_txt_data.size());
- EXPECT_THROW(generic::TXT(ibuffer2, 65536), InvalidRdataLength);
-
- // RDATA is empty, which is invalid for TXT.
- EXPECT_THROW(rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire4.wire"),
- DNSMessageFORMERR);
-
- // character-string length is too large, which could cause overrun.
- EXPECT_THROW(rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire5.wire"),
- DNSMessageFORMERR);
-}
-
-TEST_F(Rdata_TXT_Test, toWireBuffer) {
- rdata_txt.toWire(obuffer);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
- wiredata_txt, sizeof(wiredata_txt));
-}
-
-TEST_F(Rdata_TXT_Test, toText) {
- EXPECT_EQ("\"Test String\"", rdata_txt.toText());
-}
-}
diff --git a/src/lib/dns/tests/testdata/Makefile.am b/src/lib/dns/tests/testdata/Makefile.am
index d8f0d1c..27edf5f 100644
--- a/src/lib/dns/tests/testdata/Makefile.am
+++ b/src/lib/dns/tests/testdata/Makefile.am
@@ -90,6 +90,7 @@ EXTRA_DIST += question_fromWire question_toWire1 question_toWire2
EXTRA_DIST += rdatafields1.spec rdatafields2.spec rdatafields3.spec
EXTRA_DIST += rdatafields4.spec rdatafields5.spec rdatafields6.spec
EXTRA_DIST += rdata_cname_fromWire rdata_dname_fromWire rdata_dnskey_fromWire
+EXTRA_DIST += rdata_dhcid_fromWire rdata_dhcid_toWire
EXTRA_DIST += rdata_ds_fromWire rdata_in_a_fromWire rdata_in_aaaa_fromWire
EXTRA_DIST += rdata_mx_fromWire rdata_mx_toWire1 rdata_mx_toWire2
EXTRA_DIST += rdata_ns_fromWire
diff --git a/src/lib/dns/tests/testdata/rdata_dhcid_fromWire b/src/lib/dns/tests/testdata/rdata_dhcid_fromWire
new file mode 100644
index 0000000..0c8d56a
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_dhcid_fromWire
@@ -0,0 +1,12 @@
+#
+# DHCID RDATA stored in an input buffer
+#
+# Valid RDATA for 0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw0YHRjCDRkdC70L7Rh9C60LA=
+#
+# RDLENGHT=41 bytes
+# 0 1
+ 00 29
+# 0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw0YHRjCDRkdC70L7Rh9C60LA=
+d0 b2 20 d0 bb d0 b5 d1 81 d1 83 20 d1 80 d0 be
+d0 b4 d0 b8 d0 bb d0 b0 d1 81 d1 8c 20 d1 91 d0
+bb d0 be d1 87 d0 ba d0 b0
diff --git a/src/lib/dns/tests/testdata/rdata_dhcid_toWire b/src/lib/dns/tests/testdata/rdata_dhcid_toWire
new file mode 100644
index 0000000..99ec229
--- /dev/null
+++ b/src/lib/dns/tests/testdata/rdata_dhcid_toWire
@@ -0,0 +1,7 @@
+#
+# DHCID RDATA stored in an output buffer
+#
+# 0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw0YHRjCDRkdC70L7Rh9C60LA=
+d0 b2 20 d0 bb d0 b5 d1 81 d1 83 20 d1 80 d0 be
+d0 b4 d0 b8 d0 bb d0 b0 d1 81 d1 8c 20 d1 91 d0
+bb d0 be d1 87 d0 ba d0 b0
diff --git a/src/lib/python/isc/datasrc/__init__.py b/src/lib/python/isc/datasrc/__init__.py
index 0b4ed98..7ebd918 100644
--- a/src/lib/python/isc/datasrc/__init__.py
+++ b/src/lib/python/isc/datasrc/__init__.py
@@ -1,6 +1,16 @@
import sys
import os
+# The datasource factory loader uses dlopen, as does python
+# for its modules. Some dynamic linkers do not play nice if
+# modules are not loaded with RTLD_GLOBAL, a symptom of which
+# is that exceptions are not recognized by type. So to make
+# sure this doesn't happen, we temporarily set RTLD_GLOBAL
+# during the loading of the datasource wrappers.
+import ctypes
+flags = sys.getdlopenflags()
+sys.setdlopenflags(flags | ctypes.RTLD_GLOBAL)
+
# this setup is a temporary workaround to deal with the problem of
# having both 'normal' python modules and a wrapper module
# Once all programs use the new interface, we should remove the
@@ -16,6 +26,10 @@ if intree:
from datasrc import *
else:
from isc.datasrc.datasrc import *
+
+# revert to the default dlopen flags
+sys.setdlopenflags(flags)
+
from isc.datasrc.sqlite3_ds import *
from isc.datasrc.master import *
diff --git a/src/lib/python/isc/datasrc/tests/datasrc_test.py b/src/lib/python/isc/datasrc/tests/datasrc_test.py
index f65cfa0..75a0cfb 100644
--- a/src/lib/python/isc/datasrc/tests/datasrc_test.py
+++ b/src/lib/python/isc/datasrc/tests/datasrc_test.py
@@ -19,6 +19,7 @@ import isc.dns
import unittest
import os
import shutil
+import json
TESTDATA_PATH = os.environ['TESTDATA_PATH'] + os.sep
TESTDATA_WRITE_PATH = os.environ['TESTDATA_WRITE_PATH'] + os.sep
@@ -381,7 +382,39 @@ class DataSrcUpdater(unittest.TestCase):
self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
rrset.to_text())
+ def test_two_modules(self):
+ # load two modules, and check if they don't interfere
+ mem_cfg = { "type": "memory", "class": "IN", "zones": [] };
+ dsc_mem = isc.datasrc.DataSourceClient("memory", json.dumps(mem_cfg))
+ dsc_sql = isc.datasrc.DataSourceClient("sqlite3", READ_ZONE_DB_CONFIG)
+
+ # check if exceptions are working
+ self.assertRaises(isc.datasrc.Error, isc.datasrc.DataSourceClient,
+ "memory", "{}")
+ self.assertRaises(isc.datasrc.Error, isc.datasrc.DataSourceClient,
+ "sqlite3", "{}")
+
+ # see if a lookup succeeds in sqlite3 ds
+ result, finder = dsc_sql.find_zone(isc.dns.Name("example.com"))
+ self.assertEqual(finder.SUCCESS, result)
+ self.assertEqual(isc.dns.RRClass.IN(), finder.get_class())
+ self.assertEqual("example.com.", finder.get_origin().to_text())
+ result, rrset = finder.find(isc.dns.Name("www.example.com"),
+ isc.dns.RRType.A(),
+ None,
+ finder.FIND_DEFAULT)
+ self.assertEqual(finder.SUCCESS, result)
+ self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
+ rrset.to_text())
+
+ # see if a lookup fails in mem ds
+ result, finder = dsc_mem.find_zone(isc.dns.Name("example.com"))
+ self.assertEqual(finder.NXDOMAIN, result)
+
+
def test_update_delete_abort(self):
+ # we don't do enything with this one, just making sure loading two
+ # datasources
dsc = isc.datasrc.DataSourceClient("sqlite3", WRITE_ZONE_DB_CONFIG)
# first make sure, through a separate finder, that some record exists
More information about the bind10-changes
mailing list