From: JINMEI Tatuya Date: Wed, 18 Jul 2012 23:23:22 +0000 (-0700) Subject: [2094] complete test cases. added a couple of RR types. X-Git-Tag: trac2351_base~158^2~16^2~13 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=73d54f8cb72bbefe66ec44ed3d5d4a6417e25332;p=thirdparty%2Fkea.git [2094] complete test cases. added a couple of RR types. --- diff --git a/src/lib/datasrc/memory/rdata_encoder.cc b/src/lib/datasrc/memory/rdata_encoder.cc index 8996c48d28..28a2e44531 100644 --- a/src/lib/datasrc/memory/rdata_encoder.cc +++ b/src/lib/datasrc/memory/rdata_encoder.cc @@ -12,14 +12,22 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +#include +#include +#include #include #include +#include // for test functions + #include "rdata_encoder.h" +#include + #include using namespace isc::dns; +using std::vector; namespace isc { namespace datasrc { @@ -63,22 +71,34 @@ const uint16_t NAMEATTR_ADDITIONAL_INITIALIZER = const uint16_t NAMEATTR_COMPADDITIONAL_INITIALIZER = static_cast(NAMEATTR_COMPRESSIBLE | NAMEATTR_ADDITIONAL); +// TBD const RdataFieldSpec generic_data_fields[] = { {RdataFieldSpec::VARLEN_DATA, {0}} }; const uint16_t generic_data_fields_count = sizeof(generic_data_fields) / sizeof(RdataFieldSpec); +// TBD +const RdataFieldSpec single_ipv4_fields[] = { + {RdataFieldSpec::FIXEDLEN_DATA, {sizeof(uint32_t)}} +}; +const uint16_t single_ipv4_fields_count = + sizeof(single_ipv4_fields) / sizeof(RdataFieldSpec); + +// TBD const RdataFieldSpec generic_single_name_fields[] = { - {RdataFieldSpec::VARLEN_DATA, {NAMEATTR_COMPADDITIONAL_INITIALIZER}} + {RdataFieldSpec::DOMAIN_NAME, {NAMEATTR_COMPADDITIONAL_INITIALIZER}} }; +const uint16_t generic_single_name_fields_count = + sizeof(generic_single_name_fields) / sizeof(RdataFieldSpec); // Class IN encode specs const RdataEncodeSpec encode_spec_list_in[] = { - {generic_data_fields_count, 0, 0, generic_data_fields} // type #0 + {generic_data_fields_count, 0, 0, generic_data_fields}, // #0 + {single_ipv4_fields_count, 0, 0, single_ipv4_fields}, // #1: A + {generic_single_name_fields_count, 0, 0, generic_single_name_fields} // NS }; -#ifdef notyet inline const RdataEncodeSpec& getRdataEncodeSpec(RRClass rrclass, RRType rrtype) { @@ -87,23 +107,84 @@ getRdataEncodeSpec(RRClass rrclass, RRType rrtype) { } return (encode_spec_list_in[0]); } -#endif } // end of unnamed namespace -#ifdef notyet void -testRdataEncoder(const Rdata& rdata, RRClass rrclass, RRType rrtype, - vector& result) +encodeRdata(const rdata::Rdata& rdata, RRClass rrclass, RRType rrtype, + vector& data_result, vector& /*len_result*/) { + util::OutputBuffer buffer(0); + rdata.toWire(buffer); + util::InputBuffer ibuffer(buffer.getData(), buffer.getLength()); + vector tmp; // used as temporary placeholder below + const RdataEncodeSpec& encode_spec = getRdataEncodeSpec(rrclass, rrtype); for (size_t i = 0; i < encode_spec.field_count; ++i) { - const RdataFieldSpec& field_spec = *encode_spec.fields[i]; - if (field_spec.type == RdataFieldSpec::FIXEDLEN_DATA) - assert(encode_spec.fields[i] != NULL); - + const RdataFieldSpec& field_spec = encode_spec.fields[i]; + switch (field_spec.type) { + case RdataFieldSpec::FIXEDLEN_DATA: + tmp.resize(field_spec.fixeddata_len); + ibuffer.readData(&tmp[0], tmp.size()); + data_result.insert(data_result.end(), tmp.begin(), tmp.end()); + break; + case RdataFieldSpec::DOMAIN_NAME: + { + const Name name(ibuffer); + const LabelSequence labels(name); + size_t nlen; + const uint8_t* ndata = labels.getData(&nlen); + size_t olen; + uint8_t offset_holder[Name::MAX_LABELS]; + labels.getOffsetData(&olen, offset_holder); + data_result.push_back(nlen); + data_result.push_back(olen); + data_result.insert(data_result.end(), ndata, ndata + nlen); + data_result.insert(data_result.end(), offset_holder, + offset_holder + olen); + break; + } + default: + assert(false); + } + } +} + +void +foreachRdataField(RRClass rrclass, RRType rrtype, + const vector& encoded_data, + const vector& /*varlen_list*/, + NameCallback name_callback, DataCallback data_callback) +{ + const RdataEncodeSpec& encode_spec = getRdataEncodeSpec(rrclass, rrtype); + + size_t off = 0; + for (size_t i = 0; i < encode_spec.field_count; ++i) { + const RdataFieldSpec& field_spec = encode_spec.fields[i]; + switch (field_spec.type) { + case RdataFieldSpec::FIXEDLEN_DATA: + if (data_callback) { + data_callback(&encoded_data[off], field_spec.fixeddata_len); + } + off += field_spec.fixeddata_len; + break; + case RdataFieldSpec::DOMAIN_NAME: + { + const uint8_t nlen = encoded_data.at(off); + const uint8_t olen = encoded_data.at(off + 1); + if (name_callback) { + const uint8_t* ndata = &encoded_data.at(off + 2); + const uint8_t* odata = &encoded_data.at(off + 2 + nlen); + name_callback(LabelSequence(ndata, odata, olen), + field_spec.name_attributes); + } + off += (2 + nlen + olen); + break; + } + default: + assert(false); + } } } -#endif } // namespace memory } // namespace datasrc diff --git a/src/lib/datasrc/memory/rdata_encoder.h b/src/lib/datasrc/memory/rdata_encoder.h index e4dc729d72..5ffce4b96f 100644 --- a/src/lib/datasrc/memory/rdata_encoder.h +++ b/src/lib/datasrc/memory/rdata_encoder.h @@ -15,6 +15,15 @@ #ifndef DATASRC_MEMORY_RDATA_ENCODER_H #define DATASRC_MEMORY_RDATA_ENCODER_H 1 +#include +#include +#include +#include + +#include + +#include + namespace isc { namespace datasrc { namespace memory { @@ -24,6 +33,19 @@ enum RdataNameAttributes { NAMEATTR_ADDITIONAL = (NAMEATTR_COMPRESSIBLE << 1) }; +void encodeRdata(const dns::rdata::Rdata& rdata, dns::RRClass rrclass, + dns::RRType rrtype, std::vector& data_result, + std::vector& len_result); + +typedef boost::function NameCallback; +typedef boost::function DataCallback; + +void foreachRdataField(dns::RRClass rrclass, dns::RRType rrtype, + const std::vector& encoded_data, + const std::vector& varlen_list, + NameCallback name_callback, DataCallback data_callback); + } // namespace memory } // namespace datasrc } // namespace isc diff --git a/src/lib/datasrc/memory/tests/rdata_encoder_unittest.cc b/src/lib/datasrc/memory/tests/rdata_encoder_unittest.cc index 88ef551a43..4d454d3e1f 100644 --- a/src/lib/datasrc/memory/tests/rdata_encoder_unittest.cc +++ b/src/lib/datasrc/memory/tests/rdata_encoder_unittest.cc @@ -12,20 +12,102 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +#include +#include +#include +#include +#include +#include + #include +#include + #include +#include + +#include +#include +#include + +using namespace isc::dns; +using namespace isc::dns::rdata; using namespace isc::datasrc::memory; +using isc::util::unittests::matchWireData; +using std::string; +using std::vector; + namespace { -class RdataEncoderTest : public ::testing::Test { -protected: - RdataEncoderTest() {} +struct TestRdata { + const char* const rrclass; + const char* const rrtype; + const char* const rdata; }; +const TestRdata test_rdata_list[] = { + {"IN", "A", "192.0.2.1"}, + {"IN", "NS", "ns.example.com"}, + {NULL, NULL, NULL} +}; + +void +renderNameField(MessageRenderer* renderer, bool additional_required, + const LabelSequence& labels, RdataNameAttributes attributes) +{ + EXPECT_EQ(additional_required, + (attributes & NAMEATTR_ADDITIONAL) != 0); + renderer->writeName(labels, (attributes & NAMEATTR_COMPRESSIBLE) != 0); +} + +void +renderDataField(MessageRenderer* renderer, const uint8_t* data, + size_t data_len) +{ + renderer->writeData(data, data_len); +} + +TEST(RdataFieldSpec, checkData) { + const Name dummy_name("example.com"); + MessageRenderer expected_renderer, actual_renderer; + vector encoded_data; + vector varlen_list; + + std::set need_additionals; + need_additionals.insert(RRType::NS()); + need_additionals.insert(RRType::MX()); + need_additionals.insert(RRType::SRV()); + + for (size_t i = 1; test_rdata_list[i].rrclass != NULL; ++i) { + SCOPED_TRACE(string(test_rdata_list->rrclass) + "/" + + test_rdata_list->rrtype); + + expected_renderer.clear(); + actual_renderer.clear(); + expected_renderer.writeName(dummy_name); + actual_renderer.writeName(dummy_name); + + const RRClass rrclass(test_rdata_list[i].rrclass); + const RRType rrtype(test_rdata_list[i].rrtype); + const ConstRdataPtr rdata = createRdata(rrtype, rrclass, + test_rdata_list[i].rdata); + rdata->toWire(expected_renderer); + + const bool additional_required = + (need_additionals.find(rrtype) != need_additionals.end()); + + encodeRdata(*rdata, rrclass, rrtype, encoded_data, varlen_list); + foreachRdataField(rrclass, rrtype, encoded_data, varlen_list, + boost::bind(renderNameField, &actual_renderer, + additional_required, _1, _2), + boost::bind(renderDataField, &actual_renderer, + _1, _2)); -TEST_F(RdataEncoderTest, test1) { - EXPECT_NE(NAMEATTR_COMPRESSIBLE, NAMEATTR_ADDITIONAL); + matchWireData(expected_renderer.getData(), + expected_renderer.getLength(), + actual_renderer.getData(), + actual_renderer.getLength()); + } } }