Commit 4cf1bd8a authored by Evan Hunt's avatar Evan Hunt
Browse files

Added some asiolink tests, fixed BoB tests

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac327@3125 e5f2f494-b856-4b98-b285-d166d9295462
parent 9bc9618f
...@@ -99,7 +99,7 @@ class TestBoB(unittest.TestCase): ...@@ -99,7 +99,7 @@ class TestBoB(unittest.TestCase):
bob = BoB() bob = BoB()
self.assertEqual(bob.verbose, False) self.assertEqual(bob.verbose, False)
self.assertEqual(bob.msgq_socket_file, None) self.assertEqual(bob.msgq_socket_file, None)
self.assertEqual(bob.auth_port, 5300) self.assertEqual(bob.dns_port, 5300)
self.assertEqual(bob.cc_session, None) self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.address, None) self.assertEqual(bob.address, None)
self.assertEqual(bob.processes, {}) self.assertEqual(bob.processes, {})
...@@ -115,11 +115,11 @@ class TestBoB(unittest.TestCase): ...@@ -115,11 +115,11 @@ class TestBoB(unittest.TestCase):
self.assertEqual(bob.dead_processes, {}) self.assertEqual(bob.dead_processes, {})
self.assertEqual(bob.runnable, False) self.assertEqual(bob.runnable, False)
def test_init_alternate_auth_port(self): def test_init_alternate_dns_port(self):
bob = BoB(None, 9999) bob = BoB(None, 9999)
self.assertEqual(bob.verbose, False) self.assertEqual(bob.verbose, False)
self.assertEqual(bob.msgq_socket_file, None) self.assertEqual(bob.msgq_socket_file, None)
self.assertEqual(bob.auth_port, 9999) self.assertEqual(bob.dns_port, 9999)
self.assertEqual(bob.cc_session, None) self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.address, None) self.assertEqual(bob.address, None)
self.assertEqual(bob.processes, {}) self.assertEqual(bob.processes, {})
...@@ -129,7 +129,7 @@ class TestBoB(unittest.TestCase): ...@@ -129,7 +129,7 @@ class TestBoB(unittest.TestCase):
def test_init_alternate_address(self): def test_init_alternate_address(self):
bob = BoB(None, 5300, '127.127.127.127') bob = BoB(None, 5300, '127.127.127.127')
self.assertEqual(bob.verbose, False) self.assertEqual(bob.verbose, False)
self.assertEqual(bob.auth_port, 5300) self.assertEqual(bob.dns_port, 5300)
self.assertEqual(bob.msgq_socket_file, None) self.assertEqual(bob.msgq_socket_file, None)
self.assertEqual(bob.cc_session, None) self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.address.addr, socket.inet_aton('127.127.127.127')) self.assertEqual(bob.address.addr, socket.inet_aton('127.127.127.127'))
......
...@@ -81,8 +81,7 @@ public: ...@@ -81,8 +81,7 @@ public:
} }
} }
void processNormalQuery(const IOMessage& io_message, void processNormalQuery(const Question& question, MessagePtr message,
const Question& question, MessagePtr message,
OutputBufferPtr buffer, OutputBufferPtr buffer,
DNSServer* server); DNSServer* server);
ModuleCCSession* config_session_; ModuleCCSession* config_session_;
...@@ -406,8 +405,7 @@ Recursor::processMessage(const IOMessage& io_message, MessagePtr message, ...@@ -406,8 +405,7 @@ Recursor::processMessage(const IOMessage& io_message, MessagePtr message,
// The RecursiveQuery object will post the "resume" event to the // The RecursiveQuery object will post the "resume" event to the
// DNSServer when an answer arrives, so we don't have to do it now. // DNSServer when an answer arrives, so we don't have to do it now.
sendAnswer = false; sendAnswer = false;
impl_->processNormalQuery(io_message, *question, message, impl_->processNormalQuery(*question, message, buffer, server);
buffer, server);
} }
} }
...@@ -417,8 +415,7 @@ Recursor::processMessage(const IOMessage& io_message, MessagePtr message, ...@@ -417,8 +415,7 @@ Recursor::processMessage(const IOMessage& io_message, MessagePtr message,
} }
void void
RecursorImpl::processNormalQuery(const IOMessage& io_message, RecursorImpl::processNormalQuery(const Question& question, MessagePtr message,
const Question& question, MessagePtr message,
OutputBufferPtr buffer, DNSServer* server) OutputBufferPtr buffer, DNSServer* server)
{ {
const bool dnssec_ok = message->isDNSSECSupported(); const bool dnssec_ok = message->isDNSSECSupported();
...@@ -428,7 +425,7 @@ RecursorImpl::processNormalQuery(const IOMessage& io_message, ...@@ -428,7 +425,7 @@ RecursorImpl::processNormalQuery(const IOMessage& io_message,
message->setRcode(Rcode::NOERROR()); message->setRcode(Rcode::NOERROR());
message->setDNSSECSupported(dnssec_ok); message->setDNSSECSupported(dnssec_ok);
message->setUDPSize(RecursorImpl::DEFAULT_LOCAL_UDPSIZE); message->setUDPSize(RecursorImpl::DEFAULT_LOCAL_UDPSIZE);
rec_query_->sendQuery(io_message, question, buffer, server); rec_query_->sendQuery(question, buffer, server);
} }
ConstElementPtr ConstElementPtr
......
...@@ -93,8 +93,9 @@ IOMessage::IOMessage(const void* data, const size_t data_size, ...@@ -93,8 +93,9 @@ IOMessage::IOMessage(const void* data, const size_t data_size,
remote_endpoint_(remote_endpoint) remote_endpoint_(remote_endpoint)
{} {}
RecursiveQuery::RecursiveQuery(IOService& io_service, const char& forward) : RecursiveQuery::RecursiveQuery(IOService& io_service, const char& forward,
io_service_(io_service) uint16_t port) :
io_service_(io_service), port_(port)
{ {
error_code err; error_code err;
ns_addr_ = ip::address::from_string(&forward, err); ns_addr_ = ip::address::from_string(&forward, err);
...@@ -105,8 +106,7 @@ RecursiveQuery::RecursiveQuery(IOService& io_service, const char& forward) : ...@@ -105,8 +106,7 @@ RecursiveQuery::RecursiveQuery(IOService& io_service, const char& forward) :
} }
void void
RecursiveQuery::sendQuery(const IOMessage& io_message, RecursiveQuery::sendQuery(const Question& question, OutputBufferPtr buffer,
const Question& question, OutputBufferPtr buffer,
DNSServer* server) DNSServer* server)
{ {
...@@ -115,7 +115,7 @@ RecursiveQuery::sendQuery(const IOMessage& io_message, ...@@ -115,7 +115,7 @@ RecursiveQuery::sendQuery(const IOMessage& io_message,
// UDP and then fall back to TCP on failure, but for the moment // UDP and then fall back to TCP on failure, but for the moment
// we're only going to handle UDP. // we're only going to handle UDP.
asio::io_service& io = io_service_.get_io_service(); asio::io_service& io = io_service_.get_io_service();
UDPQuery q(io, io_message, question, ns_addr_, buffer, server); UDPQuery q(io, question, ns_addr_, port_, buffer, server);
io.post(q); io.post(q);
} }
...@@ -232,6 +232,11 @@ IOService::run() { ...@@ -232,6 +232,11 @@ IOService::run() {
impl_->io_service_.run(); impl_->io_service_.run();
} }
void
IOService::run_one() {
impl_->io_service_.run_one();
}
void void
IOService::stop() { IOService::stop() {
impl_->io_service_.stop(); impl_->io_service_.stop();
......
...@@ -446,6 +446,13 @@ public: ...@@ -446,6 +446,13 @@ public:
/// the \c stop() method is called via some handler. /// the \c stop() method is called via some handler.
void run(); void run();
/// \brief Run the underlying event loop for a single event.
///
/// This method return control to the caller as soon as the
/// first handler has completed. (If no handlers are ready when
/// it is run, it will block until one is.)
void run_one();
/// \brief Stop the underlying event loop. /// \brief Stop the underlying event loop.
/// ///
/// This will return the control to the caller of the \c run() method. /// This will return the control to the caller of the \c run() method.
...@@ -727,12 +734,12 @@ public: ...@@ -727,12 +734,12 @@ public:
/// This is currently the only way to construct \c RecursiveQuery /// This is currently the only way to construct \c RecursiveQuery
/// object. The address of the forward nameserver is specified, /// object. The address of the forward nameserver is specified,
/// and all upstream queries will be sent to that one address. /// and all upstream queries will be sent to that one address.
RecursiveQuery(IOService& io_service, const char& forward); RecursiveQuery(IOService& io_service, const char& forward,
uint16_t port = 53);
//@} //@}
/// \brief Initiates an upstream query in the \c RecursiveQuery object. /// \brief Initiates an upstream query in the \c RecursiveQuery object.
/// ///
/// \param io_message The message from the original client
/// \param question The question being answered <qname/qclass/qtype> /// \param question The question being answered <qname/qclass/qtype>
/// \param buffer An output buffer into which the response can be copied /// \param buffer An output buffer into which the response can be copied
/// \param server A pointer to the \c DNSServer object handling the client /// \param server A pointer to the \c DNSServer object handling the client
...@@ -741,13 +748,13 @@ public: ...@@ -741,13 +748,13 @@ public:
/// the upstream name server. When a reply arrives, 'server' /// the upstream name server. When a reply arrives, 'server'
/// is placed on the ASIO service queue via io_service::post(), so /// is placed on the ASIO service queue via io_service::post(), so
/// that the original \c DNSServer objct can resume processing. /// that the original \c DNSServer objct can resume processing.
void sendQuery(const IOMessage& io_message, void sendQuery(const isc::dns::Question& question,
const isc::dns::Question& question,
isc::dns::OutputBufferPtr buffer, isc::dns::OutputBufferPtr buffer,
DNSServer* server); DNSServer* server);
private: private:
IOService& io_service_; IOService& io_service_;
asio::ip::address ns_addr_; asio::ip::address ns_addr_;
uint16_t port_;
}; };
} // asiolink } // asiolink
......
...@@ -166,9 +166,9 @@ private: ...@@ -166,9 +166,9 @@ private:
class UDPQuery : public coroutine { class UDPQuery : public coroutine {
public: public:
explicit UDPQuery(asio::io_service& io_service, explicit UDPQuery(asio::io_service& io_service,
const IOMessage& io_message,
const isc::dns::Question& q, const isc::dns::Question& q,
const asio::ip::address& addr, const asio::ip::address& addr,
uint16_t port,
isc::dns::OutputBufferPtr buffer, isc::dns::OutputBufferPtr buffer,
DNSServer* server); DNSServer* server);
void operator()(asio::error_code ec = asio::error_code(), void operator()(asio::error_code ec = asio::error_code(),
......
...@@ -17,12 +17,19 @@ ...@@ -17,12 +17,19 @@
#include <config.h> #include <config.h>
#include <string.h>
#include <boost/lexical_cast.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <exceptions/exceptions.h> #include <exceptions/exceptions.h>
#include <dns/tests/unittest_util.h> #include <dns/tests/unittest_util.h>
#include <dns/buffer.h>
#include <dns/message.h>
#include <asiolink/asiolink.h> #include <asiolink/asiolink.h>
#include <asiolink/internal/tcpdns.h> #include <asiolink/internal/tcpdns.h>
#include <asiolink/internal/udpdns.h> #include <asiolink/internal/udpdns.h>
...@@ -30,9 +37,11 @@ ...@@ -30,9 +37,11 @@
using isc::UnitTestUtil; using isc::UnitTestUtil;
using namespace std; using namespace std;
using namespace asiolink; using namespace asiolink;
using namespace isc::dns;
namespace { namespace {
const char* const TEST_PORT = "53535"; const char* const TEST_SERVER_PORT = "53535";
const char* const TEST_CLIENT_PORT = "53535";
const char* const TEST_IPV6_ADDR = "::1"; const char* const TEST_IPV6_ADDR = "::1";
const char* const TEST_IPV4_ADDR = "127.0.0.1"; const char* const TEST_IPV4_ADDR = "127.0.0.1";
// This data is intended to be valid as a DNS/TCP-like message: the first // This data is intended to be valid as a DNS/TCP-like message: the first
...@@ -127,52 +136,54 @@ TEST(IOServiceTest, badPort) { ...@@ -127,52 +136,54 @@ TEST(IOServiceTest, badPort) {
} }
TEST(IOServiceTest, badAddress) { TEST(IOServiceTest, badAddress) {
EXPECT_THROW(IOService(*TEST_PORT, *"192.0.2.1.1", NULL, NULL, NULL), IOError); EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"192.0.2.1.1", NULL, NULL, NULL), IOError);
EXPECT_THROW(IOService(*TEST_PORT, *"2001:db8:::1", NULL, NULL, NULL), IOError); EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"2001:db8:::1", NULL, NULL, NULL), IOError);
EXPECT_THROW(IOService(*TEST_PORT, *"localhost", NULL, NULL, NULL), IOError); EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"localhost", NULL, NULL, NULL), IOError);
} }
TEST(IOServiceTest, unavailableAddress) { TEST(IOServiceTest, unavailableAddress) {
// These addresses should generally be unavailable as a valid local // These addresses should generally be unavailable as a valid local
// address, although there's no guarantee in theory. // address, although there's no guarantee in theory.
EXPECT_THROW(IOService(*TEST_PORT, *"255.255.0.0", NULL, NULL, NULL), IOError); EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"255.255.0.0", NULL, NULL, NULL), IOError);
// Some OSes would simply reject binding attempt for an AF_INET6 socket // Some OSes would simply reject binding attempt for an AF_INET6 socket
// to an IPv4-mapped IPv6 address. Even if those that allow it, since // to an IPv4-mapped IPv6 address. Even if those that allow it, since
// the corresponding IPv4 address is the same as the one used in the // the corresponding IPv4 address is the same as the one used in the
// AF_INET socket case above, it should at least show the same result // AF_INET socket case above, it should at least show the same result
// as the previous one. // as the previous one.
EXPECT_THROW(IOService(*TEST_PORT, *"::ffff:255.255.0.0", NULL, NULL, NULL), IOError); EXPECT_THROW(IOService(*TEST_SERVER_PORT, *"::ffff:255.255.0.0", NULL, NULL, NULL), IOError);
} }
TEST(IOServiceTest, duplicateBind) { TEST(IOServiceTest, duplicateBind) {
// In each sub test case, second attempt should fail due to duplicate bind // In each sub test case, second attempt should fail due to duplicate bind
// IPv6, "any" address // IPv6, "any" address
IOService* io_service = new IOService(*TEST_PORT, false, true, NULL, NULL, NULL); IOService* io_service = new IOService(*TEST_SERVER_PORT, false, true, NULL, NULL, NULL);
EXPECT_THROW(IOService(*TEST_PORT, false, true, NULL, NULL, NULL), IOError); EXPECT_THROW(IOService(*TEST_SERVER_PORT, false, true, NULL, NULL, NULL), IOError);
delete io_service; delete io_service;
// IPv6, specific address // IPv6, specific address
io_service = new IOService(*TEST_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL); io_service = new IOService(*TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL);
EXPECT_THROW(IOService(*TEST_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL), IOError); EXPECT_THROW(IOService(*TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL), IOError);
delete io_service; delete io_service;
// IPv4, "any" address // IPv4, "any" address
io_service = new IOService(*TEST_PORT, true, false, NULL, NULL, NULL); io_service = new IOService(*TEST_SERVER_PORT, true, false, NULL, NULL, NULL);
EXPECT_THROW(IOService(*TEST_PORT, true, false, NULL, NULL, NULL), IOError); EXPECT_THROW(IOService(*TEST_SERVER_PORT, true, false, NULL, NULL, NULL), IOError);
delete io_service; delete io_service;
// IPv4, specific address // IPv4, specific address
io_service = new IOService(*TEST_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL); io_service = new IOService(*TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL);
EXPECT_THROW(IOService(*TEST_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL), IOError); EXPECT_THROW(IOService(*TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL), IOError);
delete io_service; delete io_service;
} }
struct addrinfo* struct addrinfo*
resolveAddress(const int family, const int sock_type, const int protocol) { resolveAddress(const int family, const int sock_type, const int protocol,
const bool client) {
const char* const addr = (family == AF_INET6) ? const char* const addr = (family == AF_INET6) ?
TEST_IPV6_ADDR : TEST_IPV4_ADDR; TEST_IPV6_ADDR : TEST_IPV4_ADDR;
const char* const port = client ? TEST_CLIENT_PORT : TEST_SERVER_PORT;
struct addrinfo hints; struct addrinfo hints;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
...@@ -181,7 +192,7 @@ resolveAddress(const int family, const int sock_type, const int protocol) { ...@@ -181,7 +192,7 @@ resolveAddress(const int family, const int sock_type, const int protocol) {
hints.ai_protocol = protocol; hints.ai_protocol = protocol;
struct addrinfo* res; struct addrinfo* res;
const int error = getaddrinfo(addr, TEST_PORT, &hints, &res); const int error = getaddrinfo(addr, port, &hints, &res);
if (error != 0) { if (error != 0) {
isc_throw(IOError, "getaddrinfo failed: " << gai_strerror(error)); isc_throw(IOError, "getaddrinfo failed: " << gai_strerror(error));
} }
...@@ -219,7 +230,7 @@ protected: ...@@ -219,7 +230,7 @@ protected:
} }
} }
void sendUDP(const int family) { void sendUDP(const int family) {
res_ = resolveAddress(family, SOCK_DGRAM, IPPROTO_UDP); res_ = resolveAddress(family, SOCK_DGRAM, IPPROTO_UDP, false);
sock_ = socket(res_->ai_family, res_->ai_socktype, res_->ai_protocol); sock_ = socket(res_->ai_family, res_->ai_socktype, res_->ai_protocol);
if (sock_ < 0) { if (sock_ < 0) {
...@@ -233,7 +244,7 @@ protected: ...@@ -233,7 +244,7 @@ protected:
io_service_->run(); io_service_->run();
} }
void sendTCP(const int family) { void sendTCP(const int family) {
res_ = resolveAddress(family, SOCK_STREAM, IPPROTO_TCP); res_ = resolveAddress(family, SOCK_STREAM, IPPROTO_TCP, false);
sock_ = socket(res_->ai_family, res_->ai_socktype, res_->ai_protocol); sock_ = socket(res_->ai_family, res_->ai_socktype, res_->ai_protocol);
if (sock_ < 0) { if (sock_ < 0) {
...@@ -244,21 +255,51 @@ protected: ...@@ -244,21 +255,51 @@ protected:
} }
const int cc = send(sock_, test_data, sizeof(test_data), 0); const int cc = send(sock_, test_data, sizeof(test_data), 0);
if (cc != sizeof(test_data)) { if (cc != sizeof(test_data)) {
isc_throw(IOError, "unexpected sendto result: " << cc); isc_throw(IOError, "unexpected send result: " << cc);
} }
io_service_->run(); io_service_->run();
} }
void recvUDP(const int family, void* buffer, size_t size) {
res_ = resolveAddress(family, SOCK_DGRAM, IPPROTO_UDP, true);
sock_ = socket(res_->ai_family, res_->ai_socktype, res_->ai_protocol);
if (sock_ < 0) {
isc_throw(IOError, "failed to open test socket");
}
if (bind(sock_, res_->ai_addr, res_->ai_addrlen) < 0) {
isc_throw(IOError, "bind failed: " << gai_strerror(errno));
}
// The IO service queue should have a RecursiveQuery object scheduled
// to run at this point. This call will cause it to begin an
// async send, then return.
io_service_->run_one();
// ... and this completes the send().
io_service_->run_one();
// Now we attempt to recv() whatever was sent
struct sockaddr addr;
socklen_t addrlen;
fcntl(sock_, F_SETFD, O_NONBLOCK);
const int cc = recvfrom(sock_, buffer, size, MSG_DONTWAIT,
&addr, &addrlen);
if (cc < 0) {
isc_throw(IOError, "recvfrom failed");
}
}
void setIOService(const char& address) { void setIOService(const char& address) {
delete io_service_; delete io_service_;
io_service_ = NULL; io_service_ = NULL;
callback_ = new ASIOCallBack(this); callback_ = new ASIOCallBack(this);
io_service_ = new IOService(*TEST_PORT, address, callback_, NULL, NULL); io_service_ = new IOService(*TEST_SERVER_PORT, address, callback_, NULL, NULL);
} }
void setIOService(const bool use_ipv4, const bool use_ipv6) { void setIOService(const bool use_ipv4, const bool use_ipv6) {
delete io_service_; delete io_service_;
io_service_ = NULL; io_service_ = NULL;
callback_ = new ASIOCallBack(this); callback_ = new ASIOCallBack(this);
io_service_ = new IOService(*TEST_PORT, use_ipv4, use_ipv6, callback_, io_service_ = new IOService(*TEST_SERVER_PORT, use_ipv4, use_ipv6, callback_,
NULL, NULL); NULL, NULL);
} }
void doTest(const int family, const int protocol) { void doTest(const int family, const int protocol) {
...@@ -285,6 +326,51 @@ protected: ...@@ -285,6 +326,51 @@ protected:
callback_data_.size(), callback_data_.size(),
expected_data, expected_datasize); expected_data, expected_datasize);
} }
protected:
class MockServer : public DNSServer {
public:
explicit MockServer(asio::io_service& io_service,
const asio::ip::address& addr, const uint16_t port,
SimpleCallback* checkin = NULL,
DNSLookup* lookup = NULL,
DNSAnswer* answer = NULL) :
io_(io_service),
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;
io_.post(*this);
}
DNSServer* clone() {
MockServer* s = new MockServer(*this);
return (s);
}
inline void asyncLookup() {
// (*lookup_)(*io_message_, message_, respbuf_, this);
}
private:
asio::io_service& io_;
bool done_;
// Callback functions provided by the caller
const SimpleCallback* checkin_;
const DNSLookup* lookup_;
const DNSAnswer* answer_;
};
private: private:
class ASIOCallBack : public SimpleCallback { class ASIOCallBack : public SimpleCallback {
public: public:
...@@ -388,4 +474,37 @@ TEST_F(ASIOLinkTest, v4TCPOnly) { ...@@ -388,4 +474,37 @@ TEST_F(ASIOLinkTest, v4TCPOnly) {
EXPECT_THROW(sendTCP(AF_INET6), IOError); EXPECT_THROW(sendTCP(AF_INET6), IOError);
} }
TEST_F(ASIOLinkTest, recursiveSetupV4) {
setIOService(true, false);
uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
EXPECT_NO_THROW(RecursiveQuery(*io_service_, *TEST_IPV4_ADDR, port));
}
TEST_F(ASIOLinkTest, recursiveSetupV6) {
setIOService(false, true);
uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
EXPECT_NO_THROW(RecursiveQuery(*io_service_, *TEST_IPV6_ADDR, port));
}
// Test disabled because recvUDP() isn't working yet
TEST_F(ASIOLinkTest, DISABLED_recursiveSend) {
setIOService(true, false);
asio::io_service& io = io_service_->get_io_service();
// Note: We use the test prot plus one to ensure we aren't binding
// to the same port as the actual server
uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
asio::ip::address addr = asio::ip::address::from_string(TEST_IPV4_ADDR);
MockServer server(io, addr, port, NULL, NULL, NULL);
RecursiveQuery rq(*io_service_, *TEST_IPV4_ADDR, port);
Question q(Name("example.com"), RRClass::IN(), RRType::TXT());
OutputBufferPtr buffer(new OutputBuffer(0));
rq.sendQuery(q, buffer, &server);
char data[4096];
EXPECT_NO_THROW(recvUDP(AF_INET, data, sizeof(data)));
}
} }