Commit 25677115 authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

[2096] Test decoding

Provide three more decoders of the data, using the RdataReader. This
does not link, as the reader has no bodies of the methods.
parent fdb51ca6
......@@ -138,7 +138,11 @@ public:
/// \brief The domain label.
///
/// This holds the domain label. It is only valid if type() == NAME.
const dns::LabelSequence& sequence;
const dns::LabelSequence& label() const;
/// \brief Is the name in label() compressible?
///
/// This is valid only if type() == NAME.
bool compressible() const;
/// \brief If there are data returned.
///
/// This returns if there are any data at all returned. This is
......
......@@ -30,6 +30,7 @@
#include <datasrc/memory/rdata_encoder.h>
#include <datasrc/memory/rdata_field.h>
#include <datasrc/memory/rdata_reader.h>
#include <util/unittests/wiredata.h>
......@@ -102,7 +103,7 @@ const TestRdata test_rdata_list[] = {
// from encoded representation of each RDATA.
void
renderNameField(MessageRenderer* renderer, bool additional_required,
const LabelSequence& labels, RdataNameAttributes attributes)
const LabelSequence& labels, unsigned attributes)
{
EXPECT_EQ(additional_required,
(attributes & NAMEATTR_ADDITIONAL) != 0);
......@@ -169,6 +170,21 @@ public:
// constant.
const Name dummy_name2("example.com");
bool
additionalRequired(const RRType& type) {
// The set of RR types that require additional section processing.
// We'll pass it to renderNameField to check the stored attribute matches
// our expectation.
static std::set<RRType> need_additionals;
if (need_additionals.empty()) {
need_additionals.insert(RRType::NS());
need_additionals.insert(RRType::MX());
need_additionals.insert(RRType::SRV());
}
return (need_additionals.find(type) != need_additionals.end());
}
// A decoder that does not use RdataReader. Not recommended for use,
// but it allows the tests to check the internals of the data.
class ManualDecoderStyle {
......@@ -282,22 +298,11 @@ public:
encoded_data.end());
}
// The set of RR types that require additional section processing.
// We'll pass it to renderNameField to check the stored attribute matches
// our expectation.
std::set<RRType> need_additionals;
need_additionals.insert(RRType::NS());
need_additionals.insert(RRType::MX());
need_additionals.insert(RRType::SRV());
const bool additional_required =
(need_additionals.find(rrtype) != need_additionals.end());
// Create wire-format data from the encoded data
foreachRdataField(rrclass, rrtype, rdata_count, encoded_data,
varlen_list,
boost::bind(renderNameField, &renderer,
additional_required, _1, _2),
additionalRequired(rrtype), _1, _2),
boost::bind(renderDataField, &renderer, _1, _2));
// 2nd dummy name
......@@ -308,7 +313,87 @@ public:
}
};
typedef ::testing::Types<ManualDecoderStyle> DecoderStyles;
// Decode using reader with the return value of next
class NextDecoder {
public:
static void decode(const isc::dns::RRClass& rrclass,
const isc::dns::RRType& rrtype,
size_t, size_t, size_t,
const vector<uint8_t>& encoded_data,
MessageRenderer& renderer)
{
RDataReader reader(rrclass, rrtype, encoded_data.size(),
&encoded_data[0]);
RDataReader::Result field;
while (field = reader.next()) {
switch (field.type()) {
case RDataReader::DATA:
renderer.writeData(field.data(), field.size());
break;
case RDataReader::NAME:
renderer.writeName(field.label(), field.compressible());
break;
default:
FAIL();
}
}
renderer.writeName(dummy_name2);
while (field = reader.nextSig()) {
switch (field.type()) {
case RDataReader::DATA:
renderer.writeData(field.data(), field.size());
break;
default: // There are also no NAME fields in RRSigs
FAIL();
}
}
}
};
// Check using callbacks and calling next until the end.
class CallbackDecoder {
public:
static void decode(const isc::dns::RRClass& rrclass,
const isc::dns::RRType& rrtype,
size_t, size_t, size_t,
const vector<uint8_t>& encoded_data,
MessageRenderer& renderer)
{
RDataReader reader(rrclass, rrtype, encoded_data.size(),
&encoded_data[0],
boost::bind(renderNameField, &renderer,
additionalRequired(rrtype), _1, _2),
boost::bind(renderDataField, &renderer, _1, _2));
while (reader.next()) { }
renderer.writeName(dummy_name2);
while (reader.nextSig()) { }
}
};
// Check using callbacks and calling iterate.
class IterateDecoder {
public:
static void decode(const isc::dns::RRClass& rrclass,
const isc::dns::RRType& rrtype,
size_t, size_t, size_t,
const vector<uint8_t>& encoded_data,
MessageRenderer& renderer)
{
RDataReader reader(rrclass, rrtype, encoded_data.size(),
&encoded_data[0],
boost::bind(renderNameField, &renderer,
additionalRequired(rrtype), _1, _2),
boost::bind(renderDataField, &renderer, _1, _2));
reader.iterate();
renderer.writeName(dummy_name2);
reader.iterateSig();
}
};
typedef ::testing::Types<ManualDecoderStyle, NextDecoder, CallbackDecoder,
IterateDecoder> DecoderStyles;
TYPED_TEST_CASE(RdataEncodeDecodeTest, DecoderStyles);
void
......
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