Commit 0e4b8f14 authored by Michal Vaner's avatar Michal Vaner
Browse files

Tests and interface for timeouts in RecursiveQuery

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/vorner-recursor-timeouts@3409 e5f2f494-b856-4b98-b285-d166d9295462
parent 1e3a58c2
......@@ -218,12 +218,21 @@ DNSService::DNSService(IOService& io_service,
impl_ = new DNSServiceImpl(io_service, port, v4addrp, v6addrp, checkin, lookup, answer);
}
// TODO This should be removed upon merge with the configuration
DNSService::DNSService(IOService& io_service, SimpleCallback *checkin,
DNSLookup* lookup, DNSAnswer* answer) :
impl_(NULL), io_service_(io_service)
{
impl_ = new DNSServiceImpl(io_service, *"0", NULL, NULL, checkin, lookup,
answer);
}
DNSService::~DNSService() {
delete impl_;
}
RecursiveQuery::RecursiveQuery(DNSService& dns_service, const char& forward,
uint16_t port) :
uint16_t port, int timeout, unsigned retries) :
dns_service_(dns_service), ns_addr_(&forward), port_(port)
{}
......
......@@ -207,6 +207,9 @@ public:
const bool use_ipv4, const bool use_ipv6,
SimpleCallback* checkin, DNSLookup* lookup,
DNSAnswer* answer);
/// TODO This is temporary, until we merge with the config
DNSService(IOService& io_service, SimpleCallback* checkin,
DNSLookup* lookup, DNSAnswer* answer);
/// \brief The destructor.
~DNSService();
//@}
......@@ -517,8 +520,13 @@ public:
/// query on
/// \param forward The address of the nameserver to forward to
/// \param port The remote port to send the dns query to
/// \param timeout How long to timeout the query, in ms
/// -1 means never timeout (but do not use that).
/// TODO: This should be computed somehow dynamically in future
/// \param retries how many times we try again (0 means just send and
// and return if it returs).
RecursiveQuery(DNSService& dns_service, const char& forward,
uint16_t port = 53);
uint16_t port = 53, int timeout = -1, unsigned retries = 0);
//@}
/// \brief Initiates an upstream query in the \c RecursiveQuery object.
......
......@@ -20,6 +20,7 @@
#include <string.h>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <gtest/gtest.h>
......@@ -34,10 +35,14 @@
#include <asiolink/internal/tcpdns.h>
#include <asiolink/internal/udpdns.h>
#include <asio.hpp>
using isc::UnitTestUtil;
using namespace std;
using namespace asiolink;
using namespace isc::dns;
using namespace asio;
using asio::ip::udp;
namespace {
const char* const TEST_SERVER_PORT = "53535";
......@@ -365,6 +370,16 @@ protected:
NULL, NULL);
}
// Set up empty DNS Service
void setDNSService() {
delete dns_service_;
dns_service_ = NULL;
delete io_service_;
io_service_ = new IOService();
callback_ = new ASIOCallBack(this);
dns_service_ = new DNSService(*io_service_, 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
......@@ -433,10 +448,11 @@ protected:
}
}
private:
protected:
asio::io_service& io_;
bool done_;
private:
// Currently unused; these will be used for testing
// asynchronous lookup calls via the asyncLookup() method
boost::shared_ptr<asiolink::IOMessage> io_message_;
......@@ -449,6 +465,28 @@ protected:
const DNSAnswer* answer_;
};
// This version of mock server just stops the io_service when it is resumed
class MockServerStop : public MockServer {
public:
explicit MockServerStop(asio::io_service& io_service) :
MockServer(io_service, asio::ip::address(), 0)
{}
void operator()(asio::error_code ec = asio::error_code(),
size_t length = 0)
{
io_.stop();
}
DNSServer* clone() {
return (new MockServerStop(*this));
}
bool done() const {
return done_;
}
};
private:
class ASIOCallBack : public SimpleCallback {
public:
......@@ -607,4 +645,43 @@ TEST_F(ASIOLinkTest, recursiveSend) {
EXPECT_EQ(q.getClass(), q2->getClass());
}
void
receive_and_inc(udp::socket* socket, int* num) {
*num ++;
static char inbuff[512];
socket->async_receive(asio::buffer(inbuff, 512),
boost::bind(receive_and_inc, socket, num));
}
// Test it tries the correct amount of times before giving up
TEST_F(ASIOLinkTest, recursiveTimeout) {
// Prepare the service (we do not use the common setup, we do not answer
setDNSService();
asio::io_service& service = io_service_->get_io_service();
// Prepare the socket
uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
udp::socket socket(service, udp::v4());
socket.set_option(socket_base::reuse_address(true));
socket.bind(udp::endpoint(ip::address::from_string(TEST_IPV4_ADDR), port));
// And count the answers
int num = -1; // One is counted before the receipt of the first one
receive_and_inc(&socket, &num);
// Prepare the server
MockServerStop server(service);
// Do the answer
RecursiveQuery query(*dns_service_, *TEST_IPV4_ADDR, port, 10, 2);
Question question(Name("example.net"), RRClass::IN(), RRType::A());
OutputBufferPtr buffer(new OutputBuffer(0));
query.sendQuery(question, buffer, &server);
// Run the test
service.run();
EXPECT_TRUE(server.done());
EXPECT_EQ(3, num);
}
}
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