Commit f650e003 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

merged trac #448 (regression fix for clang++ build)


git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@4133 e5f2f494-b856-4b98-b285-d166d9295462
parents 09149599 006c32f4
......@@ -597,6 +597,8 @@ AC_CONFIG_FILES([Makefile
src/lib/Makefile
src/lib/asiolink/Makefile
src/lib/asiolink/tests/Makefile
src/lib/asiolink/internal/Makefile
src/lib/asiolink/internal/tests/Makefile
src/lib/bench/Makefile
src/lib/bench/example/Makefile
src/lib/bench/tests/Makefile
......
......@@ -33,6 +33,7 @@ run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(SQLITE_LIBS)
run_unittests_LDADD += $(top_builddir)/src/lib/testutils/libtestutils.la
run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la
run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
......
......@@ -30,15 +30,19 @@
#include <datasrc/memory_datasrc.h>
#include <auth/auth_srv.h>
#include <testutils/srv_unittest.h>
#include <auth/statistics.h>
#include <dns/tests/unittest_util.h>
#include <testutils/srv_test.h>
using namespace std;
using namespace isc::cc;
using namespace isc::dns;
using namespace isc::dns::rdata;
using namespace isc::data;
using namespace isc::xfr;
using namespace asiolink;
using namespace isc::testutils;
using isc::UnitTestUtil;
namespace {
......@@ -55,6 +59,10 @@ protected:
server.setXfrinSession(&notify_session);
server.setStatisticsSession(&statistics_session);
}
virtual void processMessage() {
server.processMessage(*io_message, parse_message, response_obuffer,
&dnsserv);
}
MockSession statistics_session;
MockXfroutClient xfrout;
AuthSrv server;
......@@ -159,48 +167,52 @@ TEST_F(AuthSrvTest, iqueryViaDNSServer) {
// Unsupported requests. Should result in NOTIMP.
TEST_F(AuthSrvTest, unsupportedRequest) {
UNSUPPORTED_REQUEST_TEST;
unsupportedRequest();
}
// Simple API check
TEST_F(AuthSrvTest, verbose) {
VERBOSE_TEST;
EXPECT_FALSE(server.getVerbose());
server.setVerbose(true);
EXPECT_TRUE(server.getVerbose());
server.setVerbose(false);
EXPECT_FALSE(server.getVerbose());
}
// Multiple questions. Should result in FORMERR.
TEST_F(AuthSrvTest, multiQuestion) {
MULTI_QUESTION_TEST;
multiQuestion();
}
// Incoming data doesn't even contain the complete header. Must be silently
// dropped.
TEST_F(AuthSrvTest, shortMessage) {
SHORT_MESSAGE_TEST;
shortMessage();
}
// Response messages. Must be silently dropped, whether it's a valid response
// or malformed or could otherwise cause a protocol error.
TEST_F(AuthSrvTest, response) {
RESPONSE_TEST;
response();
}
// Query with a broken question
TEST_F(AuthSrvTest, shortQuestion) {
SHORT_QUESTION_TEST;
shortQuestion();
}
// Query with a broken answer section
TEST_F(AuthSrvTest, shortAnswer) {
SHORT_ANSWER_TEST;
shortAnswer();
}
// Query with unsupported version of EDNS.
TEST_F(AuthSrvTest, ednsBadVers) {
EDNS_BADVERS_TEST;
ednsBadVers();
}
TEST_F(AuthSrvTest, AXFROverUDP) {
AXFR_OVER_UDP_TEST;
axfrOverUDP();
}
TEST_F(AuthSrvTest, AXFRSuccess) {
......
......@@ -27,6 +27,7 @@ run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(SQLITE_LIBS)
run_unittests_LDADD += $(top_builddir)/src/lib/testutils/libtestutils.la
run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la
run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
......
......@@ -12,10 +12,24 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#include <string>
#include <gtest/gtest.h>
#include <cc/data.h>
#include <asiolink/asiolink.h>
#include <recurse/recursor.h>
#include <testutils/srv_unittest.h>
#include <dns/tests/unittest_util.h>
#include <testutils/srv_test.h>
using namespace std;
using namespace isc::data;
using namespace isc::testutils;
using namespace asiolink;
using isc::UnitTestUtil;
namespace {
class RecursorConfig : public ::testing::Test {
......
......@@ -12,10 +12,15 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#include <dns/name.h>
#include <recurse/recursor.h>
#include <testutils/srv_unittest.h>
#include <dns/tests/unittest_util.h>
#include <testutils/srv_test.h>
using namespace isc::dns;
using namespace isc::testutils;
using isc::UnitTestUtil;
namespace {
const char* const TEST_PORT = "53535";
......@@ -23,48 +28,52 @@ const char* const TEST_PORT = "53535";
class RecursorTest : public SrvTestBase{
protected:
RecursorTest() : server(){}
virtual void processMessage() {
server.processMessage(*io_message, parse_message, response_obuffer,
&dnsserv);
}
Recursor server;
};
// Unsupported requests. Should result in NOTIMP.
TEST_F(RecursorTest, unsupportedRequest) {
UNSUPPORTED_REQUEST_TEST;
unsupportedRequest();
}
// Multiple questions. Should result in FORMERR.
TEST_F(RecursorTest, multiQuestion) {
MULTI_QUESTION_TEST;
multiQuestion();
}
// Incoming data doesn't even contain the complete header. Must be silently
// dropped.
TEST_F(RecursorTest, shortMessage) {
SHORT_MESSAGE_TEST;
shortMessage();
}
// Response messages. Must be silently dropped, whether it's a valid response
// or malformed or could otherwise cause a protocol error.
TEST_F(RecursorTest, response) {
RESPONSE_TEST;
response();
}
// Query with a broken question
TEST_F(RecursorTest, shortQuestion) {
SHORT_QUESTION_TEST;
shortQuestion();
}
// Query with a broken answer section
TEST_F(RecursorTest, shortAnswer) {
SHORT_ANSWER_TEST;
shortAnswer();
}
// Query with unsupported version of EDNS.
TEST_F(RecursorTest, ednsBadVers) {
EDNS_BADVERS_TEST;
ednsBadVers();
}
TEST_F(RecursorTest, AXFROverUDP) {
AXFR_OVER_UDP_TEST;
axfrOverUDP();
}
TEST_F(RecursorTest, AXFRFail) {
......
SUBDIRS = . tests
SUBDIRS = . tests internal
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
......
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(B10_CXXFLAGS)
if USE_STATIC_LINK
AM_LDFLAGS = -static
endif
CLEANFILES = *.gcno *.gcda
TESTS =
if HAVE_GTEST
TESTS += run_unittests
run_unittests_SOURCES = udpdns_unittest.cc
run_unittests_SOURCES += run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
# B10_CXXFLAGS)
run_unittests_CXXFLAGS = $(AM_CXXFLAGS)
if USE_GXX
run_unittests_CXXFLAGS += -Wno-unused-parameter
endif
if USE_CLANGPP
# We need to disable -Werror for any test that uses internal definitions of
# ASIO when using clang++
run_unittests_CXXFLAGS += -Wno-error
endif
endif
noinst_PROGRAMS = $(TESTS)
// Copyright (C) 2010 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 <gtest/gtest.h>
int
main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
return (RUN_ALL_TESTS());
}
......@@ -18,7 +18,6 @@ TESTS += run_unittests
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 += asiolink_unittest.cc
run_unittests_SOURCES += udpdns_unittest.cc
run_unittests_SOURCES += run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
......
......@@ -17,6 +17,9 @@
#include <config.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <string.h>
#include <boost/lexical_cast.hpp>
......@@ -32,19 +35,21 @@
#include <dns/buffer.h>
#include <dns/message.h>
// IMPORTANT: We shouldn't directly use ASIO definitions in this test.
// In particular, we must not include asio.hpp in this file.
// The asiolink module is primarily intended to be a wrapper that hide the
// details of the underlying implementations. We need to test the wrapper
// level behaviors. In addition, some compilers reject to compile this file
// if we include asio.hpp unless we specify a special compiler option.
// If we need to test something at the level of underlying ASIO and need
// their definition, that test should go to asiolink/internal/tests.
#include <asiolink/asiolink.h>
#include <asiolink/iosocket.h>
#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";
......@@ -330,10 +335,30 @@ protected:
// ... and this one will block until the send has completed
io_service_->run_one();
// Now we attempt to recv() whatever was sent
const int ret = recv(sock_, buffer, size, MSG_DONTWAIT);
// Now we attempt to recv() whatever was sent.
// XXX: there's no guarantee the receiving socket can immediately get
// the packet. Normally we can perform blocking recv to wait for it,
// but in theory it's even possible that the packet is lost.
// In order to prevent the test from hanging in such a worst case
// we add an ad hoc timeout.
const struct timeval timeo = { 10, 0 };
int recv_options = 0;
if (setsockopt(sock_, SOL_SOCKET, SO_RCVTIMEO, &timeo,
sizeof(timeo))) {
if (errno == ENOPROTOOPT) {
// Workaround for Solaris: it doesn't accept SO_RCVTIMEO
// with the error of ENOPROTOOPT. Since this is a workaround
// for rare error cases anyway, we simply switch to the
// "don't wait" mode. If we still find an error in recv()
// can happen often we'll consider a more complete solution.
recv_options = MSG_DONTWAIT;
} else {
isc_throw(IOError, "set RCVTIMEO failed: " << strerror(errno));
}
}
const int ret = recv(sock_, buffer, size, recv_options);
if (ret < 0) {
isc_throw(IOError, "recvfrom failed");
isc_throw(IOError, "recvfrom failed: " << strerror(errno));
}
// Pass the message size back via the size parameter
......@@ -411,8 +436,7 @@ protected:
// has completed.
class MockServer : public DNSServer {
public:
explicit MockServer(asio::io_service& io_service,
const asio::ip::address& addr, const uint16_t port,
explicit MockServer(IOService& io_service,
SimpleCallback* checkin = NULL,
DNSLookup* lookup = NULL,
DNSAnswer* answer = NULL) :
......@@ -426,9 +450,7 @@ protected:
size_t length = 0)
{}
void resume(const bool done) {
done_ = done;
io_.post(*this);
void resume(const bool) { // in our test this shouldn't be called
}
DNSServer* clone() {
......@@ -443,7 +465,7 @@ protected:
}
protected:
asio::io_service& io_;
IOService& io_;
bool done_;
private:
......@@ -462,8 +484,8 @@ protected:
// 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, bool* done) :
MockServer(io_service, asio::ip::address(), 0),
explicit MockServerStop(IOService& io_service, bool* done) :
MockServer(io_service),
done_(done)
{}
......@@ -511,7 +533,6 @@ protected:
string callback_address_;
vector<uint8_t> callback_data_;
int sock_;
private:
struct addrinfo* res_;
};
......@@ -640,14 +661,12 @@ TEST_F(ASIOLinkTest, recursiveSetupV6) {
// full code coverage including error cases.
TEST_F(ASIOLinkTest, recursiveSend) {
setDNSService(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);
MockServer server(*io_service_);
RecursiveQuery rq(*dns_service_, singleAddress(TEST_IPV4_ADDR, port));
Question q(Name("example.com"), RRClass::IN(), RRType::TXT());
......@@ -656,7 +675,7 @@ TEST_F(ASIOLinkTest, recursiveSend) {
char data[4096];
size_t size = sizeof(data);
EXPECT_NO_THROW(recvUDP(AF_INET, data, size));
ASSERT_NO_THROW(recvUDP(AF_INET, data, size));
Message m(Message::PARSE);
InputBuffer ibuf(data, size);
......@@ -672,34 +691,27 @@ 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);
res_ = resolveAddress(AF_INET, 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, "failed to bind test socket");
}
// Prepare the server
bool done(true);
MockServerStop server(service, &done);
MockServerStop server(*io_service_, &done);
// Do the answer
const uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
RecursiveQuery query(*dns_service_, singleAddress(TEST_IPV4_ADDR, port),
10, 2);
Question question(Name("example.net"), RRClass::IN(), RRType::A());
......@@ -707,7 +719,27 @@ TEST_F(ASIOLinkTest, recursiveTimeout) {
query.sendQuery(question, buffer, &server);
// Run the test
service.run();
io_service_->run();
// Read up to 3 packets. Use some ad hoc timeout to prevent an infinite
// block (see also recvUDP()).
const struct timeval timeo = { 10, 0 };
int recv_options = 0;
if (setsockopt(sock_, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo))) {
if (errno == ENOPROTOOPT) { // see ASIOLinkTest::recvUDP()
recv_options = MSG_DONTWAIT;
} else {
isc_throw(IOError, "set RCVTIMEO failed: " << strerror(errno));
}
}
int num = 0;
do {
char inbuff[512];
if (recv(sock_, inbuff, sizeof(inbuff), recv_options) < 0) {
num = -1;
break;
}
} while (++num < 3);
// The query should fail
EXPECT_FALSE(done);
......
SUBDIRS = testdata
SUBDIRS = . testdata
EXTRA_DIST = srv_test.h
EXTRA_DIST += srv_unittest.h
EXTRA_DIST += mockups.h
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS=$(B10_CXXFLAGS)
if HAVE_GTEST
lib_LTLIBRARIES = libtestutils.la
libtestutils_la_SOURCES = srv_test.h srv_test.cc
libtestutils_la_SOURCES += srv_unittest.h
libtestutils_la_SOURCES += mockups.h
libtestutils_la_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
endif
Here is some code used by more than one test. No code is used for bind10
itself, only for testing.
As it contains headers only currently, it does not compile here.
// Copyright (C) 2010 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 <netinet/in.h>
#include <dns/message.h>
#include <dns/rcode.h>
#include <asiolink/asiolink.h>
#include <dns/tests/unittest_util.h>
#include <testutils/srv_test.h>
using namespace isc::dns;
using namespace asiolink;
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),
opcode(Opcode(Opcode::QUERY())),
qname("www.example.com"),
qclass(RRClass::IN()),
qtype(RRType::A()), io_sock(NULL),
io_message(NULL), endpoint(NULL),
request_obuffer(0),
request_renderer(request_obuffer),
response_obuffer(new OutputBuffer(0))
{}
SrvTestBase::~SrvTestBase() {
delete io_message;
delete endpoint;
}
void
SrvTestBase::createDataFromFile(const char* const datafile,
const int protocol)
{
delete io_message;
data.clear();