Commit 273d03db authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

introduced rrsetsCheck() and rrsetsChecks() for neater tests

examining DNS messages/RRsets.
parent 1c6d27d6
......@@ -8,6 +8,7 @@ if HAVE_GTEST
lib_LTLIBRARIES = libtestutils.la
libtestutils_la_SOURCES = srv_test.h srv_test.cc
libtestutils_la_SOURCES += dnsmessage_test.h dnsmessage_test.cc
libtestutils_la_SOURCES += mockups.h
libtestutils_la_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
endif
// 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 <dns/message.h>
#include <dns/opcode.h>
#include <dns/rcode.h>
#include <dns/rrset.h>
#include <dns/rrttl.h>
#include <gtest/gtest.h>
#include <testutils/dnsmessage_test.h>
using namespace isc::dns;
namespace isc {
namespace testutils {
const unsigned int QR_FLAG = 0x1;
const unsigned int AA_FLAG = 0x2;
const unsigned int TC_FLAG = 0x4;
const unsigned int RD_FLAG = 0x8;
const unsigned int RA_FLAG = 0x10;
const unsigned int AD_FLAG = 0x20;
const unsigned int CD_FLAG = 0x40;
void
headerCheck(const Message& message, const qid_t qid, const Rcode& rcode,
const uint16_t opcodeval, const unsigned int flags,
const unsigned int qdcount,
const unsigned int ancount, const unsigned int nscount,
const unsigned int arcount)
{
EXPECT_EQ(qid, message.getQid());
EXPECT_EQ(rcode, message.getRcode());
EXPECT_EQ(opcodeval, message.getOpcode().getCode());
EXPECT_EQ((flags & QR_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_QR));
EXPECT_EQ((flags & AA_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_AA));
EXPECT_EQ((flags & TC_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_TC));
EXPECT_EQ((flags & RA_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_RA));
EXPECT_EQ((flags & RD_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_RD));
EXPECT_EQ((flags & AD_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_AD));
EXPECT_EQ((flags & CD_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_CD));
EXPECT_EQ(qdcount, message.getRRCount(Message::SECTION_QUESTION));
EXPECT_EQ(ancount, message.getRRCount(Message::SECTION_ANSWER));
EXPECT_EQ(nscount, message.getRRCount(Message::SECTION_AUTHORITY));
EXPECT_EQ(arcount, message.getRRCount(Message::SECTION_ADDITIONAL));
}
void
rrsetCheck(isc::dns::ConstRRsetPtr expected_rrset,
isc::dns::ConstRRsetPtr rrset)
{
EXPECT_EQ(expected_rrset->getName(), rrset->getName());
EXPECT_EQ(expected_rrset->getClass(), rrset->getClass());
EXPECT_EQ(expected_rrset->getType(), rrset->getType());
EXPECT_EQ(expected_rrset->getTTL(), rrset->getTTL());
isc::dns::RdataIteratorPtr rdata_it = rrset->getRdataIterator();
isc::dns::RdataIteratorPtr expected_rdata_it =
expected_rrset->getRdataIterator();
while (!expected_rdata_it->isLast()) {
EXPECT_FALSE(rdata_it->isLast());
if (rdata_it->isLast()) {
// buggy case, should stop here
break;
}
// We use text-based comparison so that we can easily identify which
// data causes the error in case of failure. RDATA::compare() is the
// most strict comparison method, but in this case text-based
// comparison should be okay because we generate the text data
// from Rdata objects rather than hand-write the expected text.
EXPECT_EQ(expected_rdata_it->getCurrent().toText(),
rdata_it->getCurrent().toText());
expected_rdata_it->next();
rdata_it->next();
}
// Make sure we have examined all sets of rrset RDATA
EXPECT_TRUE(rdata_it->isLast());
}
} // end of namespace testutils
} // end of namespace 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
// 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 <algorithm>
#include <functional>
#include <vector>
#include <dns/message.h>
#include <dns/name.h>
#include <dns/masterload.h>
#include <dns/rrclass.h>
#include <dns/rrset.h>
#include <gtest/gtest.h>
namespace isc {
namespace testutils {
// These are flags to indicate whether the corresponding flag bit of the
// DNS header is to be set in the test cases. (The flag values
// is irrelevant to their wire-format values)
extern const unsigned int QR_FLAG;
extern const unsigned int AA_FLAG;
extern const unsigned int TC_FLAG;
extern const unsigned int RD_FLAG;
extern const unsigned int RA_FLAG;
extern const unsigned int AD_FLAG;
extern const unsigned int CD_FLAG;
void
headerCheck(const isc::dns::Message& message, const isc::dns::qid_t qid,
const isc::dns::Rcode& rcode,
const uint16_t opcodeval, const unsigned int flags,
const unsigned int qdcount,
const unsigned int ancount, const unsigned int nscount,
const unsigned int arcount);
void rrsetCheck(isc::dns::ConstRRsetPtr expected_rrset,
isc::dns::ConstRRsetPtr rrset);
namespace detail {
// Helper matching class
struct RRsetMatch : public std::unary_function<isc::dns::ConstRRsetPtr, bool> {
RRsetMatch(isc::dns::ConstRRsetPtr target) : target_(target) {}
bool operator()(isc::dns::ConstRRsetPtr rrset) const {
return (rrset->getType() == target_->getType() &&
rrset->getClass() == target_->getClass() &&
rrset->getName() == target_->getName());
}
const isc::dns::ConstRRsetPtr target_;
};
class RRsetInserter {
public:
RRsetInserter(std::vector<isc::dns::ConstRRsetPtr>& rrsets) :
rrsets_(rrsets)
{}
void operator()(isc::dns::ConstRRsetPtr rrset) const {
rrsets_.push_back(rrset);
}
private:
std::vector<isc::dns::ConstRRsetPtr>& rrsets_;
};
}
template<typename EXPECTED_ITERATOR, typename ACTUAL_ITERATOR>
void
rrsetsCheck(EXPECTED_ITERATOR expected_begin, EXPECTED_ITERATOR expected_end,
ACTUAL_ITERATOR actual_begin, ACTUAL_ITERATOR actual_end)
{
unsigned int rrset_matched = 0;
unsigned int rrset_count = 0;
ACTUAL_ITERATOR it;
for (it = actual_begin; it != actual_end; ++it) {
std::vector<isc::dns::ConstRRsetPtr>::const_iterator found_rrset_it =
find_if(expected_begin, expected_end, detail::RRsetMatch(*it));
if (found_rrset_it != expected_end) {
rrsetCheck(*found_rrset_it, *it);
++rrset_matched;
}
++rrset_count;
}
// make sure all expected RRsets are in rrsets
EXPECT_EQ(distance(expected_begin, expected_end), rrset_matched);
// make sure rrsets only contains expected RRsets
EXPECT_EQ(distance(expected_begin, expected_end), rrset_count);
}
template <typename EXPECTED_CONTAINER, typename ACTUAL_CONTAINER>
void
rrsetsCheck(EXPECTED_CONTAINER& expected_rrsets,
ACTUAL_CONTAINER& actual_rrsets)
{
rrsetsCheck(expected_rrsets.begin(), expected_rrsets.end(),
actual_rrsets.begin(), actual_rrsets.end());
}
template<typename ACTUAL_ITERATOR>
void
rrsetsCheck(std::istream& expected_stream,
ACTUAL_ITERATOR actual_begin, ACTUAL_ITERATOR actual_end,
const isc::dns::Name& origin = isc::dns::Name::ROOT_NAME(),
const isc::dns::RRClass& rrclass = isc::dns::RRClass::IN())
{
std::vector<isc::dns::ConstRRsetPtr> expected;
isc::dns::masterLoad(expected_stream, origin, rrclass,
detail::RRsetInserter(expected));
rrsetsCheck(expected.begin(), expected.end(), actual_begin, actual_end);
}
} // end of namespace testutils
} // end of namespace isc
// Local Variables:
// mode: c++
// End:
......@@ -21,6 +21,7 @@
#include <dns/tests/unittest_util.h>
#include <testutils/dnsmessage_test.h>
#include <testutils/srv_test.h>
using namespace isc::dns;
......@@ -30,14 +31,6 @@ namespace isc {
namespace testutils {
const char* const DEFAULT_REMOTE_ADDRESS = "192.0.2.1";
const unsigned int QR_FLAG = 0x1;
const unsigned int AA_FLAG = 0x2;
const unsigned int TC_FLAG = 0x4;
const unsigned int RD_FLAG = 0x8;
const unsigned int RA_FLAG = 0x10;
const unsigned int AD_FLAG = 0x20;
const unsigned int CD_FLAG = 0x40;
SrvTestBase::SrvTestBase() : request_message(Message::RENDER),
parse_message(new Message(Message::PARSE)),
default_qid(0x1035),
......@@ -232,37 +225,6 @@ SrvTestBase::axfrOverUDP() {
headerCheck(*parse_message, default_qid, isc::dns::Rcode::FORMERR(),
opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
}
void
headerCheck(const Message& message, const qid_t qid, const Rcode& rcode,
const uint16_t opcodeval, const unsigned int flags,
const unsigned int qdcount,
const unsigned int ancount, const unsigned int nscount,
const unsigned int arcount)
{
EXPECT_EQ(qid, message.getQid());
EXPECT_EQ(rcode, message.getRcode());
EXPECT_EQ(opcodeval, message.getOpcode().getCode());
EXPECT_EQ((flags & QR_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_QR));
EXPECT_EQ((flags & AA_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_AA));
EXPECT_EQ((flags & TC_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_TC));
EXPECT_EQ((flags & RA_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_RA));
EXPECT_EQ((flags & RD_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_RD));
EXPECT_EQ((flags & AD_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_AD));
EXPECT_EQ((flags & CD_FLAG) != 0,
message.getHeaderFlag(Message::HEADERFLAG_CD));
EXPECT_EQ(qdcount, message.getRRCount(Message::SECTION_QUESTION));
EXPECT_EQ(ancount, message.getRRCount(Message::SECTION_ANSWER));
EXPECT_EQ(nscount, message.getRRCount(Message::SECTION_AUTHORITY));
EXPECT_EQ(arcount, message.getRRCount(Message::SECTION_ADDITIONAL));
}
} // end of namespace testutils
} // end of namespace isc
......
......@@ -12,8 +12,6 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <gtest/gtest.h>
#include <dns/buffer.h>
#include <dns/name.h>
#include <dns/message.h>
......@@ -46,14 +44,6 @@ extern const unsigned int RA_FLAG;
extern const unsigned int AD_FLAG;
extern const unsigned int CD_FLAG;
void
headerCheck(const isc::dns::Message& message, const isc::dns::qid_t qid,
const isc::dns::Rcode& rcode,
const uint16_t opcodeval, const unsigned int flags,
const unsigned int qdcount,
const unsigned int ancount, const unsigned int nscount,
const unsigned int arcount);
// The base class for Auth and Recurse test case
class SrvTestBase : public ::testing::Test {
protected:
......
Markdown is supported
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