Commit 73d54f8c authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2094] complete test cases. added a couple of RR types.

parent 220170cd
......@@ -12,14 +12,22 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <dns/name.h>
#include <dns/labelsequence.h>
#include <dns/rdata.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
#include <util/buffer.h> // for test functions
#include "rdata_encoder.h"
#include <vector>
#include <stdint.h>
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<uint16_t>(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<uint8_t>& result)
encodeRdata(const rdata::Rdata& rdata, RRClass rrclass, RRType rrtype,
vector<uint8_t>& data_result, vector<uint16_t>& /*len_result*/)
{
util::OutputBuffer buffer(0);
rdata.toWire(buffer);
util::InputBuffer ibuffer(buffer.getData(), buffer.getLength());
vector<uint8_t> 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<uint8_t>& encoded_data,
const vector<uint16_t>& /*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
......
......@@ -15,6 +15,15 @@
#ifndef DATASRC_MEMORY_RDATA_ENCODER_H
#define DATASRC_MEMORY_RDATA_ENCODER_H 1
#include <dns/labelsequence.h>
#include <dns/rdata.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
#include <boost/function.hpp>
#include <vector>
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<uint8_t>& data_result,
std::vector<uint16_t>& len_result);
typedef boost::function<void(const dns::LabelSequence&,
RdataNameAttributes)> NameCallback;
typedef boost::function<void(const uint8_t*, size_t)> DataCallback;
void foreachRdataField(dns::RRClass rrclass, dns::RRType rrtype,
const std::vector<uint8_t>& encoded_data,
const std::vector<uint16_t>& varlen_list,
NameCallback name_callback, DataCallback data_callback);
} // namespace memory
} // namespace datasrc
} // namespace isc
......
......@@ -12,20 +12,102 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <dns/name.h>
#include <dns/labelsequence.h>
#include <dns/messagerenderer.h>
#include <dns/rdata.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
#include <datasrc/memory/rdata_encoder.h>
#include <util/unittests/wiredata.h>
#include <gtest/gtest.h>
#include <boost/bind.hpp>
#include <set>
#include <string>
#include <vector>
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<uint8_t> encoded_data;
vector<uint16_t> varlen_list;
std::set<RRType> 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());
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment