[svn] commit: r3264 - in /branches/trac327/src: bin/auth/tests/auth_srv_unittest.cc bin/recurse/tests/Makefile.am bin/recurse/tests/recursor_unittest.cc lib/asiolink/tests/asiolink_unittest.cc lib/dns/tests/unittest_util.cc lib/dns/tests/unittest_util.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Oct 18 23:00:53 UTC 2010
Author: each
Date: Mon Oct 18 23:00:52 2010
New Revision: 3264
Log:
Addressed more review comments:
- moved createRequestMessage() into unittest_utils
- added more bogus-address tests in asiolink unit test
- added tests with IPv4-mapped IPv6 addresses, but disabled because
v4-mapped addresses don't work on my test systems
- added documentation for asiolink test helper functions
- moved MockSession, MockServer, etc from auth/recurse unit tests
into a single external mockups.h to reduce code duplication
Modified:
branches/trac327/src/bin/auth/tests/auth_srv_unittest.cc
branches/trac327/src/bin/recurse/tests/Makefile.am
branches/trac327/src/bin/recurse/tests/recursor_unittest.cc
branches/trac327/src/lib/asiolink/tests/asiolink_unittest.cc
branches/trac327/src/lib/dns/tests/unittest_util.cc
branches/trac327/src/lib/dns/tests/unittest_util.h
Modified: branches/trac327/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac327/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac327/src/bin/auth/tests/auth_srv_unittest.cc Mon Oct 18 23:00:52 2010
@@ -34,14 +34,15 @@
#include <asiolink/asiolink.h>
#include <dns/tests/unittest_util.h>
-
-using isc::UnitTestUtil;
+#include <auth/tests/mockups.h>
+
using namespace std;
using namespace isc::cc;
using namespace isc::dns;
using namespace isc::data;
using namespace isc::xfr;
using namespace asiolink;
+using isc::UnitTestUtil;
namespace {
const char* const CONFIG_TESTDB =
@@ -65,78 +66,6 @@
};
class AuthSrvTest : public ::testing::Test {
-private:
- class MockXfroutClient : public AbstractXfroutClient {
- public:
- MockXfroutClient() :
- is_connected_(false), connect_ok_(true), send_ok_(true),
- disconnect_ok_(true)
- {}
- virtual void connect();
- virtual void disconnect();
- virtual int sendXfroutRequestInfo(int tcp_sock, const void* msg_data,
- uint16_t msg_len);
- bool isConnected() const { return (is_connected_); }
- void disableConnect() { connect_ok_ = false; }
- void disableDisconnect() { disconnect_ok_ = false; }
- void enableDisconnect() { disconnect_ok_ = true; }
- void disableSend() { send_ok_ = false; }
- private:
- bool is_connected_;
- bool connect_ok_;
- bool send_ok_;
- bool disconnect_ok_;
- };
-
- class MockSession : public AbstractSession {
- public:
- MockSession() :
- // by default we return a simple "success" message.
- msg_(Element::fromJSON("{\"result\": [0, \"SUCCESS\"]}")),
- send_ok_(true), receive_ok_(true)
- {}
- virtual void establish(const char* socket_file);
- virtual void disconnect();
- virtual int group_sendmsg(ConstElementPtr msg, string group,
- string instance, string to);
- virtual bool group_recvmsg(ConstElementPtr& envelope,
- ConstElementPtr& msg,
- bool nonblock, int seq);
- virtual void subscribe(string group, string instance);
- virtual void unsubscribe(string group, string instance);
- virtual void startRead(boost::function<void()> read_callback);
- virtual int reply(ConstElementPtr envelope, ConstElementPtr newmsg);
- virtual bool hasQueuedMsgs() const;
- virtual void setTimeout(size_t timeout UNUSED_PARAM) {};
- virtual size_t getTimeout() const { return 0; };
-
- void setMessage(ConstElementPtr msg) { msg_ = msg; }
- void disableSend() { send_ok_ = false; }
- void disableReceive() { receive_ok_ = false; }
-
- ConstElementPtr sent_msg;
- string msg_destination;
- private:
- ConstElementPtr msg_;
- bool send_ok_;
- bool receive_ok_;
- };
-
- // A nonoperative task object to be used in calls to processMessage()
- class MockTask : public DNSServer {
- public:
- MockTask() : done_(false) {}
- void operator()(asio::error_code ec UNUSED_PARAM,
- size_t length UNUSED_PARAM)
- {}
- // virtual void doLookup() { return; }
- virtual void resume(const bool done) { done_ = done; }
- virtual bool hasAnswer() { return (done_); }
- virtual int value() { return (0); }
- private:
- bool done_;
- };
-
protected:
AuthSrvTest() : server(true, xfrout),
request_message(Message::RENDER),
@@ -155,7 +84,7 @@
}
MockSession notify_session;
MockXfroutClient xfrout;
- MockTask task;
+ MockServer dnsserv;
AuthSrv server;
Message request_message;
MessagePtr parse_message;
@@ -173,103 +102,8 @@
vector<uint8_t> data;
void createDataFromFile(const char* const datafile, int protocol);
- void createRequestMessage(const Opcode& opcode, const Name& request_name,
- const RRClass& rrclass, const RRType& rrtype);
- void createRequestPacket(const Opcode& opcode, const Name& request_name,
- const RRClass& rrclass, const RRType& rrtype,
- int protocol);
- void createRequestPacket(int protocol);
+ void createRequestPacket(Message& message, int protocol);
};
-
-void
-AuthSrvTest::MockSession::establish(const char* socket_file UNUSED_PARAM) {}
-
-void
-AuthSrvTest::MockSession::disconnect() {}
-
-void
-AuthSrvTest::MockSession::subscribe(string group UNUSED_PARAM,
- string instance UNUSED_PARAM)
-{}
-
-void
-AuthSrvTest::MockSession::unsubscribe(string group UNUSED_PARAM,
- string instance UNUSED_PARAM)
-{}
-
-void
-AuthSrvTest::MockSession::startRead(
- boost::function<void()> read_callback UNUSED_PARAM)
-{}
-
-int
-AuthSrvTest::MockSession::reply(ConstElementPtr envelope UNUSED_PARAM,
- ConstElementPtr newmsg UNUSED_PARAM)
-{
- return (-1);
-}
-
-bool
-AuthSrvTest::MockSession::hasQueuedMsgs() const {
- return (false);
-}
-
-int
-AuthSrvTest::MockSession::group_sendmsg(ConstElementPtr msg, string group,
- string instance UNUSED_PARAM,
- string to UNUSED_PARAM)
-{
- if (!send_ok_) {
- isc_throw(XfroutError, "mock session send is disabled for test");
- }
-
- sent_msg = msg;
- msg_destination = group;
- return (0);
-}
-
-bool
-AuthSrvTest::MockSession::group_recvmsg(ConstElementPtr& envelope UNUSED_PARAM,
- ConstElementPtr& msg,
- bool nonblock UNUSED_PARAM,
- int seq UNUSED_PARAM)
-{
- if (!receive_ok_) {
- isc_throw(XfroutError, "mock session receive is disabled for test");
- }
-
- msg = msg_;
- return (true);
-}
-
-void
-AuthSrvTest::MockXfroutClient::connect() {
- if (!connect_ok_) {
- isc_throw(XfroutError, "xfrout connection disabled for test");
- }
- is_connected_ = true;
-}
-
-void
-AuthSrvTest::MockXfroutClient::disconnect() {
- if (!disconnect_ok_) {
- isc_throw(XfroutError,
- "closing xfrout connection is disabled for test");
- }
- is_connected_ = false;
-}
-
-int
-AuthSrvTest::MockXfroutClient::sendXfroutRequestInfo(
- const int tcp_sock UNUSED_PARAM,
- const void* msg_data UNUSED_PARAM,
- const uint16_t msg_len UNUSED_PARAM)
-{
- if (!send_ok_) {
- isc_throw(XfroutError, "xfrout connection send is disabled for test");
- }
- return (0);
-}
// These are flags to indicate whether the corresponding flag bit of the
@@ -300,30 +134,10 @@
}
void
-AuthSrvTest::createRequestMessage(const Opcode& opcode,
- const Name& request_name,
- const RRClass& rrclass,
- const RRType& rrtype)
-{
- request_message.clear(Message::RENDER);
- request_message.setOpcode(opcode);
- request_message.setQid(default_qid);
- request_message.addQuestion(Question(request_name, rrclass, rrtype));
-}
-
-void
-AuthSrvTest::createRequestPacket(const Opcode& opcode,
- const Name& request_name,
- const RRClass& rrclass, const RRType& rrtype,
+AuthSrvTest::createRequestPacket(Message& message,
const int protocol = IPPROTO_UDP)
{
- createRequestMessage(opcode, request_name, rrclass, rrtype);
- createRequestPacket(protocol);
-}
-
-void
-AuthSrvTest::createRequestPacket(const int protocol = IPPROTO_UDP) {
- request_message.toWire(request_renderer);
+ message.toWire(request_renderer);
delete io_message;
delete io_sock;
@@ -374,8 +188,8 @@
parse_message->clear(Message::PARSE);
server.processMessage(*io_message, parse_message, response_obuffer,
- &task);
- EXPECT_TRUE(task.hasAnswer());
+ &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::NOTIMP(), i, QR_FLAG,
0, 0, 0, 0);
}
@@ -393,8 +207,8 @@
// Multiple questions. Should result in FORMERR.
TEST_F(AuthSrvTest, multiQuestion) {
createDataFromFile("multiquestion_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
QR_FLAG, 2, 0, 0, 0);
@@ -414,8 +228,8 @@
// dropped.
TEST_F(AuthSrvTest, shortMessage) {
createDataFromFile("shortmessage_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
// Response messages. Must be silently dropped, whether it's a valid response
@@ -423,26 +237,26 @@
TEST_F(AuthSrvTest, response) {
// A valid (although unusual) response
createDataFromFile("simpleresponse_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
// A response with a broken question section. must be dropped rather than
// returning FORMERR.
createDataFromFile("shortresponse_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
// A response to iquery. must be dropped rather than returning NOTIMP.
createDataFromFile("iqueryresponse_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
// Query with a broken question
TEST_F(AuthSrvTest, shortQuestion) {
createDataFromFile("shortquestion_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
// Since the query's question is broken, the question section of the
// response should be empty.
headerCheck(*parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
@@ -452,8 +266,8 @@
// Query with a broken answer section
TEST_F(AuthSrvTest, shortAnswer) {
createDataFromFile("shortanswer_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
// This is a bogus query, but question section is valid. So the response
// should copy the question section.
@@ -471,8 +285,8 @@
// Query with unsupported version of EDNS.
TEST_F(AuthSrvTest, ednsBadVers) {
createDataFromFile("queryBadEDNS_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
// The response must have an EDNS OPT RR in the additional section.
// Note that the DNSSEC DO bit is cleared even if this bit in the query
@@ -485,32 +299,36 @@
TEST_F(AuthSrvTest, AXFROverUDP) {
// AXFR over UDP is invalid and should result in FORMERR.
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_UDP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(),
+ RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
QR_FLAG, 1, 0, 0, 0);
}
TEST_F(AuthSrvTest, AXFRSuccess) {
EXPECT_FALSE(xfrout.isConnected());
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_TCP);
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(), RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_TCP);
// On success, the AXFR query has been passed to a separate process,
// so we shouldn't have to respond.
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
EXPECT_FALSE(xfrout.isConnected());
}
TEST_F(AuthSrvTest, AXFRConnectFail) {
EXPECT_FALSE(xfrout.isConnected()); // check prerequisite
xfrout.disableConnect();
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_TCP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(), RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_TCP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
// For a shot term workaround with xfrout we currently close the connection
@@ -521,18 +339,20 @@
TEST_F(AuthSrvTest, AXFRSendFail) {
// first send a valid query, making the connection with the xfr process
// open.
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_TCP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(), RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_TCP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
EXPECT_FALSE(xfrout.isConnected()); // see above
xfrout.disableSend();
parse_message->clear(Message::PARSE);
response_obuffer->clear();
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_TCP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(), RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_TCP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
@@ -545,10 +365,11 @@
// should it be thrown.
xfrout.disableSend();
xfrout.disableDisconnect();
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_TCP);
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(), RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_TCP);
EXPECT_THROW(server.processMessage(*io_message, parse_message,
- response_obuffer, &task),
+ response_obuffer, &dnsserv),
XfroutError);
EXPECT_TRUE(xfrout.isConnected());
// XXX: we need to re-enable disconnect. otherwise an exception would be
@@ -557,12 +378,12 @@
}
TEST_F(AuthSrvTest, notify) {
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- request_message.setHeaderFlag(MessageFlag::AA());
- createRequestPacket(IPPROTO_UDP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ request_message.setHeaderFlag(MessageFlag::AA());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
// An internal command message should have been created and sent to an
// external module. Check them.
@@ -589,12 +410,12 @@
TEST_F(AuthSrvTest, notifyForCHClass) {
// Same as the previous test, but for the CH RRClass.
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::CH(),
- RRType::SOA());
- request_message.setHeaderFlag(MessageFlag::AA());
- createRequestPacket(IPPROTO_UDP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::CH(), RRType::SOA());
+ request_message.setHeaderFlag(MessageFlag::AA());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
// Other conditions should be the same, so simply confirm the RR class is
// set correctly.
@@ -609,56 +430,57 @@
request_message.setHeaderFlag(MessageFlag::AA());
request_message.setQid(default_qid);
request_message.toWire(request_renderer);
- createRequestPacket(IPPROTO_UDP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
}
TEST_F(AuthSrvTest, notifyMultiQuestions) {
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
// add one more SOA question
request_message.addQuestion(Question(Name("example.com"), RRClass::IN(),
RRType::SOA()));
request_message.setHeaderFlag(MessageFlag::AA());
- createRequestPacket(IPPROTO_UDP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
Opcode::NOTIFY().getCode(), QR_FLAG, 2, 0, 0, 0);
}
TEST_F(AuthSrvTest, notifyNonSOAQuestion) {
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::NS());
- request_message.setHeaderFlag(MessageFlag::AA());
- createRequestPacket(IPPROTO_UDP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::NS());
+ request_message.setHeaderFlag(MessageFlag::AA());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::FORMERR(),
Opcode::NOTIFY().getCode(), QR_FLAG, 1, 0, 0, 0);
}
TEST_F(AuthSrvTest, notifyWithoutAA) {
// implicitly leave the AA bit off. our implementation will accept it.
- createRequestPacket(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
}
TEST_F(AuthSrvTest, notifyWithErrorRcode) {
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
request_message.setHeaderFlag(MessageFlag::AA());
request_message.setRcode(Rcode::SERVFAIL());
- createRequestPacket(IPPROTO_UDP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::NOERROR(),
Opcode::NOTIFY().getCode(), QR_FLAG | AA_FLAG, 1, 0, 0, 0);
}
@@ -666,61 +488,61 @@
TEST_F(AuthSrvTest, notifyWithoutSession) {
server.setXfrinSession(NULL);
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- request_message.setHeaderFlag(MessageFlag::AA());
- createRequestPacket(IPPROTO_UDP);
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ request_message.setHeaderFlag(MessageFlag::AA());
+ createRequestPacket(request_message, IPPROTO_UDP);
// we simply ignore the notify and let it be resent if an internal error
// happens.
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
TEST_F(AuthSrvTest, notifySendFail) {
notify_session.disableSend();
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- request_message.setHeaderFlag(MessageFlag::AA());
- createRequestPacket(IPPROTO_UDP);
-
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ request_message.setHeaderFlag(MessageFlag::AA());
+ createRequestPacket(request_message, IPPROTO_UDP);
+
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
TEST_F(AuthSrvTest, notifyReceiveFail) {
notify_session.disableReceive();
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- request_message.setHeaderFlag(MessageFlag::AA());
- createRequestPacket(IPPROTO_UDP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ request_message.setHeaderFlag(MessageFlag::AA());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
TEST_F(AuthSrvTest, notifyWithBogusSessionMessage) {
notify_session.setMessage(Element::fromJSON("{\"foo\": 1}"));
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- request_message.setHeaderFlag(MessageFlag::AA());
- createRequestPacket(IPPROTO_UDP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ request_message.setHeaderFlag(MessageFlag::AA());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
TEST_F(AuthSrvTest, notifyWithSessionMessageError) {
notify_session.setMessage(
Element::fromJSON("{\"result\": [1, \"FAIL\"]}"));
- createRequestMessage(Opcode::NOTIFY(), Name("example.com"), RRClass::IN(),
- RRType::SOA());
- request_message.setHeaderFlag(MessageFlag::AA());
- createRequestPacket(IPPROTO_UDP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ UnitTestUtil::createRequestMessage(request_message, Opcode::NOTIFY(), default_qid,
+ Name("example.com"), RRClass::IN(), RRType::SOA());
+ request_message.setHeaderFlag(MessageFlag::AA());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
void
@@ -745,8 +567,8 @@
// response should have the AA flag on, and have an RR in each answer
// and authority section.
createDataFromFile("examplequery_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
QR_FLAG | AA_FLAG, 1, 1, 1, 0);
}
@@ -759,8 +581,8 @@
// in a SERVFAIL response, and the answer and authority sections should
// be empty.
createDataFromFile("badExampleQuery_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::SERVFAIL(),
opcode.getCode(), QR_FLAG, 1, 0, 0, 0);
}
@@ -774,8 +596,8 @@
// The original data source should still exist.
createDataFromFile("examplequery_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
QR_FLAG | AA_FLAG, 1, 1, 1, 0);
}
Modified: branches/trac327/src/bin/recurse/tests/Makefile.am
==============================================================================
--- branches/trac327/src/bin/recurse/tests/Makefile.am (original)
+++ branches/trac327/src/bin/recurse/tests/Makefile.am Mon Oct 18 23:00:52 2010
@@ -17,6 +17,7 @@
run_unittests_SOURCES = $(top_srcdir)/src/lib/dns/tests/unittest_util.h
run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
run_unittests_SOURCES += ../recursor.h ../recursor.cc
+run_unittests_SOURCES += ../../auth/tests/mockups.h
run_unittests_SOURCES += recursor_unittest.cc
run_unittests_SOURCES += run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
Modified: branches/trac327/src/bin/recurse/tests/recursor_unittest.cc
==============================================================================
--- branches/trac327/src/bin/recurse/tests/recursor_unittest.cc (original)
+++ branches/trac327/src/bin/recurse/tests/recursor_unittest.cc Mon Oct 18 23:00:52 2010
@@ -35,6 +35,8 @@
#include <dns/tests/unittest_util.h>
+#include <auth/tests/mockups.h>
+
using isc::UnitTestUtil;
using namespace std;
using namespace isc::cc;
@@ -59,56 +61,6 @@
};
class RecursorTest : public ::testing::Test {
-private:
- class MockSession : public AbstractSession {
- public:
- MockSession() :
- // by default we return a simple "success" message.
- msg_(Element::fromJSON("{\"result\": [0, \"SUCCESS\"]}")),
- send_ok_(true), receive_ok_(true)
- {}
- virtual void establish(const char* socket_file);
- virtual void disconnect();
- virtual int group_sendmsg(ConstElementPtr msg, string group,
- string instance, string to);
- virtual bool group_recvmsg(ConstElementPtr& envelope,
- ConstElementPtr& msg,
- bool nonblock, int seq);
- virtual void subscribe(string group, string instance);
- virtual void unsubscribe(string group, string instance);
- virtual void startRead(boost::function<void()> read_callback);
- virtual int reply(ConstElementPtr envelope, ConstElementPtr newmsg);
- virtual bool hasQueuedMsgs() const;
- virtual void setTimeout(size_t timeout UNUSED_PARAM) {};
- virtual size_t getTimeout() const { return 0; };
-
- void setMessage(ConstElementPtr msg) { msg_ = msg; }
- void disableSend() { send_ok_ = false; }
- void disableReceive() { receive_ok_ = false; }
-
- ConstElementPtr sent_msg;
- string msg_destination;
- private:
- ConstElementPtr msg_;
- bool send_ok_;
- bool receive_ok_;
- };
-
- // A nonoperative task object to be used in calls to processMessage()
- class MockTask : public DNSServer {
- public:
- MockTask() : done_(false) {}
- void operator()(asio::error_code ec UNUSED_PARAM,
- size_t length UNUSED_PARAM)
- {}
- // virtual void doLookup() { return; }
- virtual void resume(const bool done) { done_ = done; }
- virtual bool hasAnswer() { return (done_); }
- virtual int value() { return (0); }
- private:
- bool done_;
- };
-
protected:
RecursorTest() : ios(*TEST_PORT, true, false, NULL, NULL, NULL),
server(*DEFAULT_REMOTE_ADDRESS),
@@ -126,7 +78,7 @@
delete endpoint;
}
MockSession notify_session;
- MockTask task;
+ MockServer dnsserv;
IOService ios;
Recursor server;
Message request_message;
@@ -145,73 +97,38 @@
vector<uint8_t> data;
void createDataFromFile(const char* const datafile, int protocol);
- void createRequestMessage(const Opcode& opcode, const Name& request_name,
- const RRClass& rrclass, const RRType& rrtype);
- void createRequestPacket(const Opcode& opcode, const Name& request_name,
- const RRClass& rrclass, const RRType& rrtype,
- int protocol);
- void createRequestPacket(int protocol);
+ void createRequestPacket(Message& message, int protocol);
};
void
-RecursorTest::MockSession::establish(const char* socket_file UNUSED_PARAM) {}
+RecursorTest::createDataFromFile(const char* const datafile,
+ const int protocol = IPPROTO_UDP)
+{
+ delete io_message;
+ data.clear();
+
+ delete endpoint;
+ endpoint = IOEndpoint::create(protocol,
+ IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
+ UnitTestUtil::readWireData(datafile, data);
+ io_sock = new DummySocket(protocol);
+ io_message = new IOMessage(&data[0], data.size(), *io_sock, *endpoint);
+}
void
-RecursorTest::MockSession::disconnect() {}
-
-void
-RecursorTest::MockSession::subscribe(string group UNUSED_PARAM,
- string instance UNUSED_PARAM)
-{}
-
-void
-RecursorTest::MockSession::unsubscribe(string group UNUSED_PARAM,
- string instance UNUSED_PARAM)
-{}
-
-void
-RecursorTest::MockSession::startRead(
- boost::function<void()> read_callback UNUSED_PARAM)
-{}
-
-int
-RecursorTest::MockSession::reply(ConstElementPtr envelope UNUSED_PARAM,
- ConstElementPtr newmsg UNUSED_PARAM)
+RecursorTest::createRequestPacket(Message& message,
+ const int protocol = IPPROTO_UDP)
{
- return (-1);
-}
-
-bool
-RecursorTest::MockSession::hasQueuedMsgs() const {
- return (false);
-}
-
-int
-RecursorTest::MockSession::group_sendmsg(ConstElementPtr msg, string group,
- string instance UNUSED_PARAM,
- string to UNUSED_PARAM)
-{
- if (!send_ok_) {
- isc_throw(FatalError, "mock session send is disabled for test");
- }
-
- sent_msg = msg;
- msg_destination = group;
- return (0);
-}
-
-bool
-RecursorTest::MockSession::group_recvmsg(ConstElementPtr& envelope UNUSED_PARAM,
- ConstElementPtr& msg,
- bool nonblock UNUSED_PARAM,
- int seq UNUSED_PARAM)
-{
- if (!receive_ok_) {
- isc_throw(FatalError, "mock session receive is disabled for test");
- }
-
- msg = msg_;
- return (true);
+ message.toWire(request_renderer);
+
+ delete io_message;
+
+ endpoint = IOEndpoint::create(protocol,
+ IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
+ io_sock = new DummySocket(protocol);
+ io_message = new IOMessage(request_renderer.getData(),
+ request_renderer.getLength(),
+ *io_sock, *endpoint);
}
// These are flags to indicate whether the corresponding flag bit of the
@@ -224,57 +141,6 @@
const unsigned int RA_FLAG = 0x10;
const unsigned int AD_FLAG = 0x20;
const unsigned int CD_FLAG = 0x40;
-
-void
-RecursorTest::createDataFromFile(const char* const datafile,
- const int protocol = IPPROTO_UDP)
-{
- delete io_message;
- data.clear();
-
- delete endpoint;
- endpoint = IOEndpoint::create(protocol,
- IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
- UnitTestUtil::readWireData(datafile, data);
- io_sock = new DummySocket(protocol);
- io_message = new IOMessage(&data[0], data.size(), *io_sock, *endpoint);
-}
-
-void
-RecursorTest::createRequestMessage(const Opcode& opcode,
- const Name& request_name,
- const RRClass& rrclass,
- const RRType& rrtype)
-{
- request_message.clear(Message::RENDER);
- request_message.setOpcode(opcode);
- request_message.setQid(default_qid);
- request_message.addQuestion(Question(request_name, rrclass, rrtype));
-}
-
-void
-RecursorTest::createRequestPacket(const Opcode& opcode,
- const Name& request_name,
- const RRClass& rrclass, const RRType& rrtype,
- const int protocol = IPPROTO_UDP)
-{
- createRequestMessage(opcode, request_name, rrclass, rrtype);
- createRequestPacket(protocol);
-}
-
-void
-RecursorTest::createRequestPacket(const int protocol = IPPROTO_UDP) {
- request_message.toWire(request_renderer);
-
- delete io_message;
-
- endpoint = IOEndpoint::create(protocol,
- IOAddress(DEFAULT_REMOTE_ADDRESS), 5300);
- io_sock = new DummySocket(protocol);
- io_message = new IOMessage(request_renderer.getData(),
- request_renderer.getLength(),
- *io_sock, *endpoint);
-}
void
headerCheck(const Message& message, const qid_t qid, const Rcode& rcode,
@@ -314,8 +180,8 @@
parse_message->clear(Message::PARSE);
server.processMessage(*io_message, parse_message,
- response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::NOTIMP(), i, QR_FLAG,
0, 0, 0, 0);
}
@@ -333,8 +199,8 @@
// Multiple questions. Should result in FORMERR.
TEST_F(RecursorTest, multiQuestion) {
createDataFromFile("multiquestion_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
QR_FLAG, 2, 0, 0, 0);
@@ -354,8 +220,8 @@
// dropped.
TEST_F(RecursorTest, shortMessage) {
createDataFromFile("shortmessage_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
// Response messages. Must be silently dropped, whether it's a valid response
@@ -363,26 +229,26 @@
TEST_F(RecursorTest, response) {
// A valid (although unusual) response
createDataFromFile("simpleresponse_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
// A response with a broken question section. must be dropped rather than
// returning FORMERR.
createDataFromFile("shortresponse_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
// A response to iquery. must be dropped rather than returning NOTIMP.
createDataFromFile("iqueryresponse_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_FALSE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_FALSE(dnsserv.hasAnswer());
}
// Query with a broken question
TEST_F(RecursorTest, shortQuestion) {
createDataFromFile("shortquestion_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
// Since the query's question is broken, the question section of the
// response should be empty.
headerCheck(*parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
@@ -392,8 +258,8 @@
// Query with a broken answer section
TEST_F(RecursorTest, shortAnswer) {
createDataFromFile("shortanswer_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
// This is a bogus query, but question section is valid. So the response
// should copy the question section.
@@ -411,8 +277,8 @@
// Query with unsupported version of EDNS.
TEST_F(RecursorTest, ednsBadVers) {
createDataFromFile("queryBadEDNS_fromWire");
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
// The response must have an EDNS OPT RR in the additional section.
// Note that the DNSSEC DO bit is cleared even if this bit in the query
@@ -425,20 +291,23 @@
TEST_F(RecursorTest, AXFROverUDP) {
// AXFR over UDP is invalid and should result in FORMERR.
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_UDP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(), RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
QR_FLAG, 1, 0, 0, 0);
}
TEST_F(RecursorTest, AXFRFail) {
- createRequestPacket(opcode, Name("example.com"), RRClass::IN(),
- RRType::AXFR(), IPPROTO_TCP);
+ UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
+ Name("example.com"), RRClass::IN(),
+ RRType::AXFR());
+ createRequestPacket(request_message, IPPROTO_TCP);
// AXFR is not implemented and should always send NOTIMP.
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::NOTIMP(), opcode.getCode(),
QR_FLAG, 1, 0, 0, 0);
}
@@ -449,10 +318,10 @@
request_message.setOpcode(Opcode::NOTIFY());
request_message.setHeaderFlag(MessageFlag::AA());
request_message.setQid(default_qid);
- request_message.toWire(request_renderer);
- createRequestPacket(IPPROTO_UDP);
- server.processMessage(*io_message, parse_message, response_obuffer, &task);
- EXPECT_TRUE(task.hasAnswer());
+ request_message.setHeaderFlag(MessageFlag::AA());
+ createRequestPacket(request_message, IPPROTO_UDP);
+ server.processMessage(*io_message, parse_message, response_obuffer, &dnsserv);
+ EXPECT_TRUE(dnsserv.hasAnswer());
headerCheck(*parse_message, default_qid, Rcode::NOTAUTH(),
Opcode::NOTIFY().getCode(), QR_FLAG, 0, 0, 0, 0);
}
Modified: branches/trac327/src/lib/asiolink/tests/asiolink_unittest.cc
==============================================================================
--- branches/trac327/src/lib/asiolink/tests/asiolink_unittest.cc (original)
+++ branches/trac327/src/lib/asiolink/tests/asiolink_unittest.cc Mon Oct 18 23:00:52 2010
@@ -71,8 +71,14 @@
// bogus IPv4 address-like input
EXPECT_THROW(IOAddress("192.0.2.2.1"), IOError);
+ // bogus IPv4 address-like input: out-of-range octet
+ EXPECT_THROW(IOAddress("192.0.2.300"), IOError);
+
// bogus IPv6 address-like input
EXPECT_THROW(IOAddress("2001:db8:::1234"), IOError);
+
+ // bogus IPv6 address-like input
+ EXPECT_THROW(IOAddress("2001:db8::efgh"), IOError);
}
TEST(IOEndpointTest, createUDPv4) {
@@ -178,9 +184,27 @@
delete io_service;
}
+// Disabled because IPv4-mapped addresses don't seem to be working with
+// the IOService constructor
+TEST(IOServiceTest, DISABLED_IPv4MappedDuplicateBind) {
+ // Duplicate bind on IPv4-mapped IPv6 address
+ IOService* io_service = new IOService(*TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL);
+ EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL), IOError);
+ delete io_service;
+
+ // XXX:
+ // Currently, this throws an "invalid argument" exception. I have
+ // not been able to get IPv4-mapped addresses to work.
+ io_service = new IOService(*TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL);
+ EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL), IOError);
+ delete io_service;
+}
+
+// This function returns an addrinfo structure for use by tests, using
+// different addresses and ports depending on whether we're testing
+// IPv4 or v6, TCP or UDP, and client or server operation.
struct addrinfo*
-resolveAddress(const int family, const int sock_type, const int protocol,
- const bool client) {
+resolveAddress(const int family, const int protocol, const bool client) {
const char* const addr = (family == AF_INET6) ?
TEST_IPV6_ADDR : TEST_IPV4_ADDR;
const char* const port = client ? TEST_CLIENT_PORT : TEST_SERVER_PORT;
@@ -188,7 +212,7 @@
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = family;
- hints.ai_socktype = sock_type;
+ hints.ai_socktype = (protocol == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
hints.ai_protocol = protocol;
hints.ai_flags = AI_NUMERICSERV;
@@ -230,8 +254,10 @@
delete callback_;
}
}
+
+ // Send a test UDP packet to a mock server
void sendUDP(const int family) {
- res_ = resolveAddress(family, SOCK_DGRAM, IPPROTO_UDP, false);
+ res_ = resolveAddress(family, IPPROTO_UDP, false);
sock_ = socket(res_->ai_family, res_->ai_socktype, res_->ai_protocol);
if (sock_ < 0) {
@@ -244,8 +270,10 @@
}
io_service_->run();
}
+
+ // Send a test TCP packet to a mock server
void sendTCP(const int family) {
- res_ = resolveAddress(family, SOCK_STREAM, IPPROTO_TCP, false);
+ res_ = resolveAddress(family, IPPROTO_TCP, false);
sock_ = socket(res_->ai_family, res_->ai_socktype, res_->ai_protocol);
if (sock_ < 0) {
@@ -260,8 +288,12 @@
}
io_service_->run();
}
+
+ // Receive a UDP packet from a mock server; used for testing
+ // recursive lookup. The caller must place a RecursiveQuery
+ // on the IO Service queue before running this routine.
void recvUDP(const int family, void* buffer, size_t& size) {
- res_ = resolveAddress(family, SOCK_DGRAM, IPPROTO_UDP, true);
+ res_ = resolveAddress(family, IPPROTO_UDP, true);
sock_ = socket(res_->ai_family, res_->ai_socktype, res_->ai_protocol);
if (sock_ < 0) {
@@ -289,12 +321,18 @@
// Pass the message size back via the size parameter
size = ret;
}
+
+
+ // Set up an IO Service queue using the specified address
void setIOService(const char& address) {
delete io_service_;
io_service_ = NULL;
callback_ = new ASIOCallBack(this);
io_service_ = new IOService(*TEST_SERVER_PORT, address, callback_, NULL, NULL);
}
+
+ // Set up an IO Service queue using the "any" address, on IPv4 if
+ // 'use_ipv4' is true and on IPv6 if 'use_ipv6' is true.
void setIOService(const bool use_ipv4, const bool use_ipv6) {
delete io_service_;
io_service_ = NULL;
@@ -302,6 +340,13 @@
io_service_ = new IOService(*TEST_SERVER_PORT, use_ipv4, use_ipv6, callback_,
NULL, NULL);
}
+
+ // Run a simple server test, on either IPv4 or IPv6, and over either
+ // UDP or TCP. Calls the sendUDP() or sendTCP() methods, which will
+ // start the IO Service queue. The UDPServer or TCPServer that was
+ // created by setIOSerice() will receive the test packet and issue a
+ // callback, which enables us to check that the data it received
+ // matches what we sent.
void doTest(const int family, const int protocol) {
if (protocol == IPPROTO_UDP) {
sendUDP(family);
@@ -328,6 +373,9 @@
}
protected:
+ // This is a nonfunctional mockup of a DNSServer object. Its purpose
+ // is to resume after a recursive query or other asynchronous call
+ // has completed.
class MockServer : public DNSServer {
public:
explicit MockServer(asio::io_service& io_service,
@@ -336,16 +384,14 @@
DNSLookup* lookup = NULL,
DNSAnswer* answer = NULL) :
io_(io_service),
+ message_(new Message(Message::PARSE)),
+ respbuf_(new OutputBuffer(0)),
checkin_(checkin), lookup_(lookup), answer_(answer)
- {
- // HERE set up address
- }
+ {}
void operator()(asio::error_code ec = asio::error_code(),
size_t length = 0)
- {
- // Do some stuff
- }
+ {}
void resume(const bool done) {
done_ = done;
@@ -358,12 +404,20 @@
}
inline void asyncLookup() {
- // (*lookup_)(*io_message_, message_, respbuf_, this);
+ if (lookup_) {
+ (*lookup_)(*io_message_, message_, respbuf_, this);
+ }
}
private:
asio::io_service& io_;
bool done_;
+
+ // Currently unused; these will be used for testing
+ // asynchronous lookup calls via the asyncLookup() method
+ boost::shared_ptr<asiolink::IOMessage> io_message_;
+ isc::dns::MessagePtr message_;
+ isc::dns::OutputBufferPtr respbuf_;
// Callback functions provided by the caller
const SimpleCallback* checkin_;
Modified: branches/trac327/src/lib/dns/tests/unittest_util.cc
==============================================================================
--- branches/trac327/src/lib/dns/tests/unittest_util.cc (original)
+++ branches/trac327/src/lib/dns/tests/unittest_util.cc Mon Oct 18 23:00:52 2010
@@ -26,12 +26,13 @@
#include <gtest/gtest.h>
#include <dns/name.h>
+#include <dns/message.h>
#include <dns/tests/unittest_util.h>
using namespace std;
+using namespace isc::dns;
using isc::UnitTestUtil;
-using isc::dns::NameComparisonResult;
namespace {
class UnitTestUtilConfig {
@@ -179,3 +180,18 @@
}
return (::testing::AssertionSuccess());
}
+
+void
+UnitTestUtil::createRequestMessage(Message& message,
+ const Opcode& opcode,
+ const uint16_t qid,
+ const Name& name,
+ const RRClass& rrclass,
+ const RRType& rrtype)
+{
+ message.clear(Message::RENDER);
+ message.setOpcode(opcode);
+ message.setQid(qid);
+ message.addQuestion(Question(name, rrclass, rrtype));
+}
+
Modified: branches/trac327/src/lib/dns/tests/unittest_util.h
==============================================================================
--- branches/trac327/src/lib/dns/tests/unittest_util.h (original)
+++ branches/trac327/src/lib/dns/tests/unittest_util.h Mon Oct 18 23:00:52 2010
@@ -21,6 +21,7 @@
#include <string>
#include <dns/name.h>
+#include <dns/message.h>
#include <gtest/gtest.h>
@@ -80,6 +81,20 @@
static ::testing::AssertionResult
matchName(const char* nameexp1, const char* nameexp2,
const isc::dns::Name& name1, const isc::dns::Name& name2);
+
+ ///
+ /// Populate a request message
+ ///
+ /// Create a request message in 'request_message' using the
+ /// opcode 'opcode' and the name/class/type query tuple specified in
+ /// 'name', 'rrclass' and 'rrtype.
+ static void
+ createRequestMessage(isc::dns::Message& request_message,
+ const isc::dns::Opcode& opcode,
+ const uint16_t qid,
+ const isc::dns::Name& name,
+ const isc::dns::RRClass& rrclass,
+ const isc::dns::RRType& rrtype);
};
}
#endif // __UNITTEST_UTIL_H
More information about the bind10-changes
mailing list