Browse Source

[trac569] split up unittests as well

Though most of the tests fell into recursive_query_unittest.cc
Jelte Jansen 14 years ago
parent
commit
a9ac4ee373

+ 1 - 1
src/lib/asiolink/Makefile.am

@@ -1,4 +1,4 @@
-SUBDIRS = . tests internal
+SUBDIRS = . tests
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += $(BOOST_INCLUDES)

+ 0 - 1
src/lib/asiolink/internal/Makefile.am

@@ -1 +0,0 @@
-SUBDIRS = tests

+ 0 - 37
src/lib/asiolink/internal/tests/Makefile.am

@@ -1,37 +0,0 @@
-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)

+ 7 - 1
src/lib/asiolink/tests/Makefile.am

@@ -17,7 +17,13 @@ if HAVE_GTEST
 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 += udp_query_unittest.cc
+run_unittests_SOURCES += ioaddress_unittest.cc
+run_unittests_SOURCES += ioendpoint_unittest.cc
+run_unittests_SOURCES += iosocket_unittest.cc
+run_unittests_SOURCES += io_service_unittest.cc
+run_unittests_SOURCES += interval_timer_unittest.cc
+run_unittests_SOURCES += recursive_query_unittest.cc
 run_unittests_SOURCES += run_unittests.cc
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(LOG4CXX_LDFLAGS)

+ 292 - 0
src/lib/asiolink/tests/interval_timer_unittest.cc

@@ -0,0 +1,292 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <gtest/gtest.h>
+
+#include <asiolink/asiolink.h>
+
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
+namespace {
+// TODO: Consider this margin
+const boost::posix_time::time_duration TIMER_MARGIN_MSEC =
+    boost::posix_time::milliseconds(50);
+}
+
+using namespace asiolink;
+
+// This fixture is for testing IntervalTimer. Some callback functors are 
+// registered as callback function of the timer to test if they are called
+// or not.
+class IntervalTimerTest : public ::testing::Test {
+protected:
+    IntervalTimerTest() : io_service_() {}
+    ~IntervalTimerTest() {}
+    class TimerCallBack : public std::unary_function<void, void> {
+    public:
+        TimerCallBack(IntervalTimerTest* test_obj) : test_obj_(test_obj) {}
+        void operator()() const {
+            test_obj_->timer_called_ = true;
+            test_obj_->io_service_.stop();
+            return;
+        }
+    private:
+        IntervalTimerTest* test_obj_;
+    };
+    class TimerCallBackCounter : public std::unary_function<void, void> {
+    public:
+        TimerCallBackCounter(IntervalTimerTest* test_obj) : test_obj_(test_obj) {
+            counter_ = 0;
+        }
+        void operator()() {
+            ++counter_;
+            return;
+        }
+        int counter_;
+    private:
+        IntervalTimerTest* test_obj_;
+    };
+    class TimerCallBackCancelDeleter : public std::unary_function<void, void> {
+    public:
+        TimerCallBackCancelDeleter(IntervalTimerTest* test_obj,
+                                   IntervalTimer* timer,
+                                   TimerCallBackCounter& counter)
+            : test_obj_(test_obj), timer_(timer), counter_(counter), count_(0)
+        {}
+        void operator()() {
+            ++count_;
+            if (count_ == 1) {
+                // First time of call back.
+                // Store the value of counter_.counter_.
+                prev_counter_ = counter_.counter_;
+                delete timer_;
+            } else if (count_ == 2) {
+                // Second time of call back.
+                // Stop io_service to stop all timers.
+                test_obj_->io_service_.stop();
+                // Compare the value of counter_.counter_ with stored one.
+                // If TimerCallBackCounter was not called (expected behavior),
+                // they are same.
+                if (counter_.counter_ == prev_counter_) {
+                    test_obj_->timer_cancel_success_ = true;
+                }
+            }
+            return;
+        }
+    private:
+        IntervalTimerTest* test_obj_;
+        IntervalTimer* timer_;
+        TimerCallBackCounter& counter_;
+        int count_;
+        int prev_counter_;
+    };
+    class TimerCallBackCanceller {
+    public:
+        TimerCallBackCanceller(unsigned int& counter, IntervalTimer& itimer) :
+            counter_(counter), itimer_(itimer)
+        {}
+        void operator()() {
+            ++counter_;
+            itimer_.cancel();
+        }
+    private:
+        unsigned int& counter_;
+        IntervalTimer& itimer_;
+    };
+    class TimerCallBackOverwriter : public std::unary_function<void, void> {
+    public:
+        TimerCallBackOverwriter(IntervalTimerTest* test_obj,
+                                IntervalTimer& timer)
+            : test_obj_(test_obj), timer_(timer), count_(0)
+        {}
+        void operator()() {
+            ++count_;
+            if (count_ == 1) {
+                // First time of call back.
+                // Call setup() to update callback function to TimerCallBack.
+                test_obj_->timer_called_ = false;
+                timer_.setup(TimerCallBack(test_obj_), 100);
+            } else if (count_ == 2) {
+                // Second time of call back.
+                // If it reaches here, re-setup() is failed (unexpected).
+                // We should stop here.
+                test_obj_->io_service_.stop();
+            }
+            return;
+        }
+    private:
+        IntervalTimerTest* test_obj_;
+        IntervalTimer& timer_;
+        int count_;
+    };
+protected:
+    IOService io_service_;
+    bool timer_called_;
+    bool timer_cancel_success_;
+};
+
+TEST_F(IntervalTimerTest, invalidArgumentToIntervalTimer) {
+    // Create asio_link::IntervalTimer and setup.
+    IntervalTimer itimer(io_service_);
+    // expect throw if call back function is empty
+    EXPECT_THROW(itimer.setup(IntervalTimer::Callback(), 1),
+                 isc::InvalidParameter);
+    // expect throw if interval is not greater than 0
+    EXPECT_THROW(itimer.setup(TimerCallBack(this), 0), isc::BadValue);
+    EXPECT_THROW(itimer.setup(TimerCallBack(this), -1), isc::BadValue);
+}
+
+TEST_F(IntervalTimerTest, startIntervalTimer) {
+    // Create asio_link::IntervalTimer and setup.
+    // Then run IOService and test if the callback function is called.
+    IntervalTimer itimer(io_service_);
+    timer_called_ = false;
+    // store start time
+    boost::posix_time::ptime start;
+    start = boost::posix_time::microsec_clock::universal_time();
+    // setup timer
+    itimer.setup(TimerCallBack(this), 100);
+    EXPECT_EQ(100, itimer.getInterval());
+    io_service_.run();
+    // reaches here after timer expired
+    // delta: difference between elapsed time and 100 milliseconds.
+    boost::posix_time::time_duration delta =
+        (boost::posix_time::microsec_clock::universal_time() - start)
+         - boost::posix_time::millisec(100);
+    if (delta.is_negative()) {
+        delta.invert_sign();
+    }
+    // expect TimerCallBack is called; timer_called_ is true
+    EXPECT_TRUE(timer_called_);
+    // expect interval is 100 milliseconds +/- TIMER_MARGIN_MSEC.
+    EXPECT_TRUE(delta < TIMER_MARGIN_MSEC);
+}
+
+TEST_F(IntervalTimerTest, destructIntervalTimer) {
+    // This code isn't exception safe, but we'd rather keep the code
+    // simpler and more readable as this is only for tests and if it throws
+    // the program would immediately terminate anyway.
+
+    // The call back function will not be called after the timer is
+    // destroyed.
+    //
+    // There are two timers:
+    //  itimer_counter (A)
+    //   (Calls TimerCallBackCounter)
+    //     - increments internal counter in callback function
+    //  itimer_canceller (B)
+    //   (Calls TimerCallBackCancelDeleter)
+    //     - first time of callback, it stores the counter value of
+    //       callback_canceller and destroys itimer_counter
+    //     - second time of callback, it compares the counter value of
+    //       callback_canceller with stored value
+    //       if they are same the timer was not called; expected result
+    //       if they are different the timer was called after destroyed
+    //
+    //     0  100  200  300  400  500  600 (ms)
+    // (A) i--------+----x
+    //                   ^
+    //                   |destroy itimer_counter
+    // (B) i-------------+--------------s
+    //                                  ^stop io_service
+    //                                   and check if itimer_counter have been
+    //                                   stopped
+
+    // itimer_counter will be deleted in TimerCallBackCancelDeleter
+    IntervalTimer* itimer_counter = new IntervalTimer(io_service_);
+    IntervalTimer itimer_canceller(io_service_);
+    timer_cancel_success_ = false;
+    TimerCallBackCounter callback_canceller(this);
+    itimer_counter->setup(callback_canceller, 200);
+    itimer_canceller.setup(
+        TimerCallBackCancelDeleter(this, itimer_counter, callback_canceller),
+        300);
+    io_service_.run();
+    EXPECT_TRUE(timer_cancel_success_);
+}
+
+TEST_F(IntervalTimerTest, cancel) {
+    // Similar to destructIntervalTimer test, but the first timer explicitly
+    // cancels itself on first callback.
+    IntervalTimer itimer_counter(io_service_);
+    IntervalTimer itimer_watcher(io_service_);
+    unsigned int counter = 0;
+    itimer_counter.setup(TimerCallBackCanceller(counter, itimer_counter), 100);
+    itimer_watcher.setup(TimerCallBack(this), 200);
+    io_service_.run();
+    EXPECT_EQ(1, counter);
+    EXPECT_EQ(0, itimer_counter.getInterval());
+
+    // canceling an already canceled timer shouldn't cause any surprise.
+    EXPECT_NO_THROW(itimer_counter.cancel());
+}
+
+TEST_F(IntervalTimerTest, overwriteIntervalTimer) {
+    // Calling setup() multiple times updates call back function and interval.
+    //
+    // There are two timers:
+    //  itimer (A)
+    //   (Calls TimerCallBackCounter / TimerCallBack)
+    //     - increments internal counter in callback function
+    //       (TimerCallBackCounter)
+    //       interval: 300 milliseconds
+    //     - io_service_.stop() (TimerCallBack)
+    //       interval: 100 milliseconds
+    //  itimer_overwriter (B)
+    //   (Calls TimerCallBackOverwriter)
+    //     - first time of callback, it calls setup() to change call back
+    //       function to TimerCallBack and interval of itimer to 100
+    //       milliseconds
+    //       after 300 + 100 milliseconds from the beginning of this test,
+    //       TimerCallBack() will be called and io_service_ stops.
+    //     - second time of callback, it means the test fails.
+    //
+    //     0  100  200  300  400  500  600  700  800 (ms)
+    // (A) i-------------+----C----s
+    //                        ^    ^stop io_service
+    //                        |change call back function
+    // (B) i------------------+-------------------S
+    //                                            ^(stop io_service on fail)
+    //
+
+    IntervalTimer itimer(io_service_);
+    IntervalTimer itimer_overwriter(io_service_);
+    // store start time
+    boost::posix_time::ptime start;
+    start = boost::posix_time::microsec_clock::universal_time();
+    itimer.setup(TimerCallBackCounter(this), 300);
+    itimer_overwriter.setup(TimerCallBackOverwriter(this, itimer), 400);
+    io_service_.run();
+    // reaches here after timer expired
+    // if interval is updated, it takes
+    //   400 milliseconds for TimerCallBackOverwriter
+    //   + 100 milliseconds for TimerCallBack (stop)
+    //   = 500 milliseconds.
+    // otherwise (test fails), it takes
+    //   400 milliseconds for TimerCallBackOverwriter
+    //   + 400 milliseconds for TimerCallBackOverwriter (stop)
+    //   = 800 milliseconds.
+    // delta: difference between elapsed time and 400 + 100 milliseconds
+    boost::posix_time::time_duration delta =
+        (boost::posix_time::microsec_clock::universal_time() - start)
+         - boost::posix_time::millisec(400 + 100);
+    if (delta.is_negative()) {
+        delta.invert_sign();
+    }
+    // expect callback function is updated: TimerCallBack is called
+    EXPECT_TRUE(timer_called_);
+    // expect interval is updated
+    EXPECT_TRUE(delta < TIMER_MARGIN_MSEC);
+}

+ 115 - 0
src/lib/asiolink/tests/io_service_unittest.cc

@@ -0,0 +1,115 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <gtest/gtest.h>
+
+#include <asiolink/asiolink.h>
+
+using namespace asiolink;
+
+const char* const TEST_SERVER_PORT = "53535";
+const char* const TEST_CLIENT_PORT = "53536";
+const char* const TEST_IPV6_ADDR = "::1";
+const char* const TEST_IPV4_ADDR = "127.0.0.1";
+
+TEST(IOServiceTest, badPort) {
+    IOService io_service;
+    EXPECT_THROW(DNSService(io_service, *"65536", true, false, NULL, NULL, NULL), IOError);
+    EXPECT_THROW(DNSService(io_service, *"5300.0", true, false, NULL, NULL, NULL), IOError);
+    EXPECT_THROW(DNSService(io_service, *"-1", true, false, NULL, NULL, NULL), IOError);
+    EXPECT_THROW(DNSService(io_service, *"domain", true, false, NULL, NULL, NULL), IOError);
+}
+
+TEST(IOServiceTest, badAddress) {
+    IOService io_service;
+    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"192.0.2.1.1", NULL, NULL, NULL), IOError);
+    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"2001:db8:::1", NULL, NULL, NULL), IOError);
+    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"localhost", NULL, NULL, NULL), IOError);
+}
+
+TEST(IOServiceTest, unavailableAddress) {
+    IOService io_service;
+    // These addresses should generally be unavailable as a valid local
+    // address, although there's no guarantee in theory.
+    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"192.0.2.0", NULL, NULL, NULL), IOError);
+
+    // 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
+    // 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
+    // as the previous one.
+    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:192.0.2.0", NULL, NULL, NULL), IOError);
+}
+
+TEST(IOServiceTest, duplicateBind_v6) {
+    // In each sub test case, second attempt should fail due to duplicate bind
+    IOService io_service;
+
+    // IPv6, "any" address
+    DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, false, true, NULL, NULL, NULL);
+    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, false, true, NULL, NULL, NULL), IOError);
+    delete dns_service;
+
+}
+
+TEST(IOServiceTest, duplicateBind_v6_address) {
+    // In each sub test case, second attempt should fail due to duplicate bind
+    IOService io_service;
+
+    // IPv6, specific address
+    DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL);
+    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL), IOError);
+    delete dns_service;
+
+}
+
+TEST(IOServiceTest, duplicateBind_v4) {
+    // In each sub test case, second attempt should fail due to duplicate bind
+    IOService io_service;
+
+    // IPv4, "any" address
+    DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, true, false, NULL, NULL, NULL);
+    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, true, false, NULL, NULL, NULL), IOError);
+    delete dns_service;
+
+}
+
+TEST(IOServiceTest, duplicateBind_v4_address) {
+    // In each sub test case, second attempt should fail due to duplicate bind
+    IOService io_service;
+
+    // IPv4, specific address
+    DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL);
+    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL), IOError);
+    delete dns_service;
+}
+
+// Disabled because IPv4-mapped addresses don't seem to be working with
+// the IOService constructor
+TEST(IOServiceTest, DISABLED_IPv4MappedDuplicateBind) {
+    IOService io_service;
+    // Duplicate bind on IPv4-mapped IPv6 address
+    DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL);
+    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL), IOError);
+    delete dns_service;
+
+    // XXX:
+    // Currently, this throws an "invalid argument" exception.  I have
+    // not been able to get IPv4-mapped addresses to work.
+    dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL);
+    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL), IOError);
+    delete dns_service;
+}
+

+ 57 - 0
src/lib/asiolink/tests/ioaddress_unittest.cc

@@ -0,0 +1,57 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <gtest/gtest.h>
+
+#include <asiolink/asiolink.h>
+
+using namespace asiolink;
+
+TEST(IOAddressTest, fromText) {
+    IOAddress io_address_v4("192.0.2.1");
+    EXPECT_EQ("192.0.2.1", io_address_v4.toText());
+
+    IOAddress io_address_v6("2001:db8::1234");
+    EXPECT_EQ("2001:db8::1234", io_address_v6.toText());
+
+    // 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(IOAddressTest, Equality) {
+    EXPECT_TRUE(IOAddress("192.0.2.1") == IOAddress("192.0.2.1"));
+    EXPECT_FALSE(IOAddress("192.0.2.1") != IOAddress("192.0.2.1"));
+
+    EXPECT_TRUE(IOAddress("192.0.2.1") != IOAddress("192.0.2.2"));
+    EXPECT_FALSE(IOAddress("192.0.2.1") == IOAddress("192.0.2.2"));
+
+    EXPECT_TRUE(IOAddress("2001:db8::12") == IOAddress("2001:0DB8:0:0::0012"));
+    EXPECT_FALSE(IOAddress("2001:db8::12") != IOAddress("2001:0DB8:0:0::0012"));
+
+    EXPECT_TRUE(IOAddress("2001:db8::1234") != IOAddress("2001:db8::1235"));
+    EXPECT_FALSE(IOAddress("2001:db8::1234") == IOAddress("2001:db8::1235"));
+
+    EXPECT_TRUE(IOAddress("2001:db8::1234") != IOAddress("192.0.2.3"));
+    EXPECT_FALSE(IOAddress("2001:db8::1234") == IOAddress("192.0.2.3"));
+}

+ 67 - 0
src/lib/asiolink/tests/ioendpoint_unittest.cc

@@ -0,0 +1,67 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <gtest/gtest.h>
+
+#include <asiolink/asiolink.h>
+
+using namespace asiolink;
+
+TEST(IOEndpointTest, createUDPv4) {
+    const IOEndpoint* ep;
+    ep = IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.1"), 5300);
+    EXPECT_EQ("192.0.2.1", ep->getAddress().toText());
+    EXPECT_EQ(5300, ep->getPort());
+    EXPECT_EQ(AF_INET, ep->getFamily());
+    EXPECT_EQ(AF_INET, ep->getAddress().getFamily());
+    EXPECT_EQ(IPPROTO_UDP, ep->getProtocol());
+}
+
+TEST(IOEndpointTest, createTCPv4) {
+    const IOEndpoint* ep;
+    ep = IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.1"), 5301);
+    EXPECT_EQ("192.0.2.1", ep->getAddress().toText());
+    EXPECT_EQ(5301, ep->getPort());
+    EXPECT_EQ(AF_INET, ep->getFamily());
+    EXPECT_EQ(AF_INET, ep->getAddress().getFamily());
+    EXPECT_EQ(IPPROTO_TCP, ep->getProtocol());
+}
+
+TEST(IOEndpointTest, createUDPv6) {
+    const IOEndpoint* ep;
+    ep = IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1234"), 5302);
+    EXPECT_EQ("2001:db8::1234", ep->getAddress().toText());
+    EXPECT_EQ(5302, ep->getPort());
+    EXPECT_EQ(AF_INET6, ep->getFamily());
+    EXPECT_EQ(AF_INET6, ep->getAddress().getFamily());
+    EXPECT_EQ(IPPROTO_UDP, ep->getProtocol());
+}
+
+TEST(IOEndpointTest, createTCPv6) {
+    const IOEndpoint* ep;
+    ep = IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1234"), 5303);
+    EXPECT_EQ("2001:db8::1234", ep->getAddress().toText());
+    EXPECT_EQ(5303, ep->getPort());
+    EXPECT_EQ(AF_INET6, ep->getFamily());
+    EXPECT_EQ(AF_INET6, ep->getAddress().getFamily());
+    EXPECT_EQ(IPPROTO_TCP, ep->getProtocol());
+}
+
+TEST(IOEndpointTest, createIPProto) {
+    EXPECT_THROW(IOEndpoint::create(IPPROTO_IP, IOAddress("192.0.2.1"),
+                                    5300)->getAddress().toText(),
+                 IOError);
+}
+

+ 13 - 5
src/lib/asiolink/internal/tests/run_unittests.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -12,10 +12,18 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <config.h>
 #include <gtest/gtest.h>
 
-int
-main(int argc, char* argv[]) {
-    ::testing::InitGoogleTest(&argc, argv);
-    return (RUN_ALL_TESTS());
+#include <asiolink/asiolink.h>
+
+using namespace asiolink;
+
+TEST(IOSocketTest, dummySockets) {
+    EXPECT_EQ(IPPROTO_UDP, IOSocket::getDummyUDPSocket().getProtocol());
+    EXPECT_EQ(IPPROTO_TCP, IOSocket::getDummyTCPSocket().getProtocol());
+    EXPECT_EQ(-1, IOSocket::getDummyUDPSocket().getNative());
+    EXPECT_EQ(-1, IOSocket::getDummyTCPSocket().getNative());
 }
+
+

+ 30 - 478
src/lib/asiolink/tests/asiolink_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -58,188 +58,6 @@ const char* const TEST_IPV4_ADDR = "127.0.0.1";
 // two octets encode the length of the rest of the data.  This is crucial
 // for the tests below.
 const uint8_t test_data[] = {0, 4, 1, 2, 3, 4};
-// TODO: Consider this margin
-const boost::posix_time::time_duration TIMER_MARGIN_MSEC =
-    boost::posix_time::milliseconds(50);
-
-TEST(IOAddressTest, fromText) {
-    IOAddress io_address_v4("192.0.2.1");
-    EXPECT_EQ("192.0.2.1", io_address_v4.toText());
-
-    IOAddress io_address_v6("2001:db8::1234");
-    EXPECT_EQ("2001:db8::1234", io_address_v6.toText());
-
-    // 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(IOAddressTest, Equality) {
-    EXPECT_TRUE(IOAddress("192.0.2.1") == IOAddress("192.0.2.1"));
-    EXPECT_FALSE(IOAddress("192.0.2.1") != IOAddress("192.0.2.1"));
-
-    EXPECT_TRUE(IOAddress("192.0.2.1") != IOAddress("192.0.2.2"));
-    EXPECT_FALSE(IOAddress("192.0.2.1") == IOAddress("192.0.2.2"));
-
-    EXPECT_TRUE(IOAddress("2001:db8::12") == IOAddress("2001:0DB8:0:0::0012"));
-    EXPECT_FALSE(IOAddress("2001:db8::12") != IOAddress("2001:0DB8:0:0::0012"));
-
-    EXPECT_TRUE(IOAddress("2001:db8::1234") != IOAddress("2001:db8::1235"));
-    EXPECT_FALSE(IOAddress("2001:db8::1234") == IOAddress("2001:db8::1235"));
-
-    EXPECT_TRUE(IOAddress("2001:db8::1234") != IOAddress("192.0.2.3"));
-    EXPECT_FALSE(IOAddress("2001:db8::1234") == IOAddress("192.0.2.3"));
-}
-
-TEST(IOEndpointTest, createUDPv4) {
-    const IOEndpoint* ep;
-    ep = IOEndpoint::create(IPPROTO_UDP, IOAddress("192.0.2.1"), 5300);
-    EXPECT_EQ("192.0.2.1", ep->getAddress().toText());
-    EXPECT_EQ(5300, ep->getPort());
-    EXPECT_EQ(AF_INET, ep->getFamily());
-    EXPECT_EQ(AF_INET, ep->getAddress().getFamily());
-    EXPECT_EQ(IPPROTO_UDP, ep->getProtocol());
-}
-
-TEST(IOEndpointTest, createTCPv4) {
-    const IOEndpoint* ep;
-    ep = IOEndpoint::create(IPPROTO_TCP, IOAddress("192.0.2.1"), 5301);
-    EXPECT_EQ("192.0.2.1", ep->getAddress().toText());
-    EXPECT_EQ(5301, ep->getPort());
-    EXPECT_EQ(AF_INET, ep->getFamily());
-    EXPECT_EQ(AF_INET, ep->getAddress().getFamily());
-    EXPECT_EQ(IPPROTO_TCP, ep->getProtocol());
-}
-
-TEST(IOEndpointTest, createUDPv6) {
-    const IOEndpoint* ep;
-    ep = IOEndpoint::create(IPPROTO_UDP, IOAddress("2001:db8::1234"), 5302);
-    EXPECT_EQ("2001:db8::1234", ep->getAddress().toText());
-    EXPECT_EQ(5302, ep->getPort());
-    EXPECT_EQ(AF_INET6, ep->getFamily());
-    EXPECT_EQ(AF_INET6, ep->getAddress().getFamily());
-    EXPECT_EQ(IPPROTO_UDP, ep->getProtocol());
-}
-
-TEST(IOEndpointTest, createTCPv6) {
-    const IOEndpoint* ep;
-    ep = IOEndpoint::create(IPPROTO_TCP, IOAddress("2001:db8::1234"), 5303);
-    EXPECT_EQ("2001:db8::1234", ep->getAddress().toText());
-    EXPECT_EQ(5303, ep->getPort());
-    EXPECT_EQ(AF_INET6, ep->getFamily());
-    EXPECT_EQ(AF_INET6, ep->getAddress().getFamily());
-    EXPECT_EQ(IPPROTO_TCP, ep->getProtocol());
-}
-
-TEST(IOEndpointTest, createIPProto) {
-    EXPECT_THROW(IOEndpoint::create(IPPROTO_IP, IOAddress("192.0.2.1"),
-                                    5300)->getAddress().toText(),
-                 IOError);
-}
-
-TEST(IOSocketTest, dummySockets) {
-    EXPECT_EQ(IPPROTO_UDP, IOSocket::getDummyUDPSocket().getProtocol());
-    EXPECT_EQ(IPPROTO_TCP, IOSocket::getDummyTCPSocket().getProtocol());
-    EXPECT_EQ(-1, IOSocket::getDummyUDPSocket().getNative());
-    EXPECT_EQ(-1, IOSocket::getDummyTCPSocket().getNative());
-}
-
-TEST(IOServiceTest, badPort) {
-    IOService io_service;
-    EXPECT_THROW(DNSService(io_service, *"65536", true, false, NULL, NULL, NULL), IOError);
-    EXPECT_THROW(DNSService(io_service, *"5300.0", true, false, NULL, NULL, NULL), IOError);
-    EXPECT_THROW(DNSService(io_service, *"-1", true, false, NULL, NULL, NULL), IOError);
-    EXPECT_THROW(DNSService(io_service, *"domain", true, false, NULL, NULL, NULL), IOError);
-}
-
-TEST(IOServiceTest, badAddress) {
-    IOService io_service;
-    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"192.0.2.1.1", NULL, NULL, NULL), IOError);
-    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"2001:db8:::1", NULL, NULL, NULL), IOError);
-    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"localhost", NULL, NULL, NULL), IOError);
-}
-
-TEST(IOServiceTest, unavailableAddress) {
-    IOService io_service;
-    // These addresses should generally be unavailable as a valid local
-    // address, although there's no guarantee in theory.
-    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"192.0.2.0", NULL, NULL, NULL), IOError);
-
-    // 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
-    // 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
-    // as the previous one.
-    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:192.0.2.0", NULL, NULL, NULL), IOError);
-}
-
-TEST(IOServiceTest, duplicateBind_v6) {
-    // In each sub test case, second attempt should fail due to duplicate bind
-    IOService io_service;
-
-    // IPv6, "any" address
-    DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, false, true, NULL, NULL, NULL);
-    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, false, true, NULL, NULL, NULL), IOError);
-    delete dns_service;
-
-}
-
-TEST(IOServiceTest, duplicateBind_v6_address) {
-    // In each sub test case, second attempt should fail due to duplicate bind
-    IOService io_service;
-
-    // IPv6, specific address
-    DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL);
-    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV6_ADDR, NULL, NULL, NULL), IOError);
-    delete dns_service;
-
-}
-
-TEST(IOServiceTest, duplicateBind_v4) {
-    // In each sub test case, second attempt should fail due to duplicate bind
-    IOService io_service;
-
-    // IPv4, "any" address
-    DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, true, false, NULL, NULL, NULL);
-    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, true, false, NULL, NULL, NULL), IOError);
-    delete dns_service;
-
-}
-
-TEST(IOServiceTest, duplicateBind_v4_address) {
-    // In each sub test case, second attempt should fail due to duplicate bind
-    IOService io_service;
-
-    // IPv4, specific address
-    DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL);
-    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *TEST_IPV4_ADDR, NULL, NULL, NULL), IOError);
-    delete dns_service;
-}
-
-// Disabled because IPv4-mapped addresses don't seem to be working with
-// the IOService constructor
-TEST(IOServiceTest, DISABLED_IPv4MappedDuplicateBind) {
-    IOService io_service;
-    // Duplicate bind on IPv4-mapped IPv6 address
-    DNSService* dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL);
-    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL), IOError);
-    delete dns_service;
-
-    // XXX:
-    // Currently, this throws an "invalid argument" exception.  I have
-    // not been able to get IPv4-mapped addresses to work.
-    dns_service = new DNSService(io_service, *TEST_SERVER_PORT, *"::ffff:127.0.0.1", NULL, NULL, NULL);
-    EXPECT_THROW(DNSService(io_service, *TEST_SERVER_PORT, *"127.0.0.1", NULL, NULL, NULL), IOError);
-    delete dns_service;
-}
 
 // This function returns an addrinfo structure for use by tests, using
 // different addresses and ports depending on whether we're testing
@@ -276,12 +94,12 @@ resolveAddress(const int family, const int protocol, const bool client) {
 // expected parameters.
 // If initialization parameters of the IOService should be modified, the test
 // case can do it using the setDNSService() method.
-// Note: the set of tests in ASIOLinkTest use actual network services and may
+// Note: the set of tests in RecursiveQueryTest use actual network services and may
 // involve undesirable side effects such as blocking.
-class ASIOLinkTest : public ::testing::Test {
+class RecursiveQueryTest : public ::testing::Test {
 protected:
-    ASIOLinkTest();
-    ~ASIOLinkTest() {
+    RecursiveQueryTest();
+    ~RecursiveQueryTest() {
         if (res_ != NULL) {
             freeaddrinfo(res_);
         }
@@ -556,12 +374,12 @@ protected:
 private:
     class ASIOCallBack : public SimpleCallback {
     public:
-        ASIOCallBack(ASIOLinkTest* test_obj) : test_obj_(test_obj) {}
+        ASIOCallBack(RecursiveQueryTest* test_obj) : test_obj_(test_obj) {}
         void operator()(const IOMessage& io_message) const {
             test_obj_->callBack(io_message);
         }
     private:
-        ASIOLinkTest* test_obj_;
+        RecursiveQueryTest* test_obj_;
     };
     void callBack(const IOMessage& io_message) {
         callback_protocol_ = io_message.getSocket().getProtocol();
@@ -588,30 +406,30 @@ protected:
     struct addrinfo* res_;
 };
 
-ASIOLinkTest::ASIOLinkTest() :
+RecursiveQueryTest::RecursiveQueryTest() :
     dns_service_(NULL), callback_(NULL), sock_(-1), res_(NULL)
 {
     io_service_ = new IOService();
     setDNSService(true, true);
 }
 
-TEST_F(ASIOLinkTest, v6UDPSend) {
+TEST_F(RecursiveQueryTest, v6UDPSend) {
     doTest(AF_INET6, IPPROTO_UDP);
 }
 
-TEST_F(ASIOLinkTest, v6TCPSend) {
+TEST_F(RecursiveQueryTest, v6TCPSend) {
     doTest(AF_INET6, IPPROTO_TCP);
 }
 
-TEST_F(ASIOLinkTest, v4UDPSend) {
+TEST_F(RecursiveQueryTest, v4UDPSend) {
     doTest(AF_INET, IPPROTO_UDP);
 }
 
-TEST_F(ASIOLinkTest, v4TCPSend) {
+TEST_F(RecursiveQueryTest, v4TCPSend) {
     doTest(AF_INET, IPPROTO_TCP);
 }
 
-TEST_F(ASIOLinkTest, v6UDPSendSpecific) {
+TEST_F(RecursiveQueryTest, v6UDPSendSpecific) {
     // Explicitly set a specific address to be bound to the socket.
     // The subsequent test does not directly ensures the underlying socket
     // is bound to the expected address, but the success of the tests should
@@ -627,26 +445,26 @@ TEST_F(ASIOLinkTest, v6UDPSendSpecific) {
     doTest(AF_INET6, IPPROTO_UDP);
 }
 
-TEST_F(ASIOLinkTest, v6TCPSendSpecific) {
+TEST_F(RecursiveQueryTest, v6TCPSendSpecific) {
     setDNSService(*TEST_IPV6_ADDR);
     doTest(AF_INET6, IPPROTO_TCP);
 
     EXPECT_THROW(sendTCP(AF_INET), IOError);
 }
 
-TEST_F(ASIOLinkTest, v4UDPSendSpecific) {
+TEST_F(RecursiveQueryTest, v4UDPSendSpecific) {
     setDNSService(*TEST_IPV4_ADDR);
     doTest(AF_INET, IPPROTO_UDP);
 }
 
-TEST_F(ASIOLinkTest, v4TCPSendSpecific) {
+TEST_F(RecursiveQueryTest, v4TCPSendSpecific) {
     setDNSService(*TEST_IPV4_ADDR);
     doTest(AF_INET, IPPROTO_TCP);
 
     EXPECT_THROW(sendTCP(AF_INET6), IOError);
 }
 
-TEST_F(ASIOLinkTest, v6AddServer) {
+TEST_F(RecursiveQueryTest, v6AddServer) {
     setDNSService();
     dns_service_->addServer(*TEST_SERVER_PORT, TEST_IPV6_ADDR);
     doTest(AF_INET6, IPPROTO_TCP);
@@ -654,7 +472,7 @@ TEST_F(ASIOLinkTest, v6AddServer) {
     EXPECT_THROW(sendTCP(AF_INET), IOError);
 }
 
-TEST_F(ASIOLinkTest, v4AddServer) {
+TEST_F(RecursiveQueryTest, v4AddServer) {
     setDNSService();
     dns_service_->addServer(*TEST_SERVER_PORT, TEST_IPV4_ADDR);
     doTest(AF_INET, IPPROTO_TCP);
@@ -662,7 +480,7 @@ TEST_F(ASIOLinkTest, v4AddServer) {
     EXPECT_THROW(sendTCP(AF_INET6), IOError);
 }
 
-TEST_F(ASIOLinkTest, DISABLED_clearServers) {
+TEST_F(RecursiveQueryTest, DISABLED_clearServers) {
     // FIXME: Enable when clearServers actually close the sockets
     //    See #388
     setDNSService();
@@ -672,7 +490,7 @@ TEST_F(ASIOLinkTest, DISABLED_clearServers) {
     EXPECT_THROW(sendTCP(AF_INET6), IOError);
 }
 
-TEST_F(ASIOLinkTest, v6TCPOnly) {
+TEST_F(RecursiveQueryTest, v6TCPOnly) {
     // Open only IPv6 TCP socket.  A subsequent attempt of establishing an
     // IPv4/TCP connection should fail.  See above for why we only test this
     // for TCP.
@@ -680,7 +498,7 @@ TEST_F(ASIOLinkTest, v6TCPOnly) {
     EXPECT_THROW(sendTCP(AF_INET), IOError);
 }
 
-TEST_F(ASIOLinkTest, v4TCPOnly) {
+TEST_F(RecursiveQueryTest, v4TCPOnly) {
     setDNSService(true, false);
     EXPECT_THROW(sendTCP(AF_INET6), IOError);
 }
@@ -692,7 +510,7 @@ singleAddress(const string &address, uint16_t port) {
     return (result);
 }
 
-TEST_F(ASIOLinkTest, recursiveSetupV4) {
+TEST_F(RecursiveQueryTest, recursiveSetupV4) {
     setDNSService(true, false);
     uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
     EXPECT_NO_THROW(RecursiveQuery(*dns_service_,
@@ -700,7 +518,7 @@ TEST_F(ASIOLinkTest, recursiveSetupV4) {
                                    singleAddress(TEST_IPV4_ADDR, port)));
 }
 
-TEST_F(ASIOLinkTest, recursiveSetupV6) {
+TEST_F(RecursiveQueryTest, recursiveSetupV6) {
     setDNSService(false, true);
     uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
     EXPECT_NO_THROW(RecursiveQuery(*dns_service_,
@@ -713,7 +531,7 @@ TEST_F(ASIOLinkTest, recursiveSetupV6) {
 // a routine that can do this with variable address family, address, and
 // port, and with the various callbacks defined in such a way as to ensure
 // full code coverage including error cases.
-TEST_F(ASIOLinkTest, forwarderSend) {
+TEST_F(RecursiveQueryTest, forwarderSend) {
     setDNSService(true, false);
 
     // Note: We use the test prot plus one to ensure we aren't binding
@@ -767,7 +585,7 @@ setSocketTimeout(int sock_, size_t tv_sec, size_t tv_usec) {
     const struct timeval timeo = { tv_sec, tv_usec };
     int recv_options = 0;
     if (setsockopt(sock_, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo))) {
-        if (errno == ENOPROTOOPT) { // see ASIOLinkTest::recvUDP()
+        if (errno == ENOPROTOOPT) { // see RecursiveQueryTest::recvUDP()
             recv_options = MSG_DONTWAIT;
         } else {
             isc_throw(IOError, "set RCVTIMEO failed: " << strerror(errno));
@@ -795,7 +613,7 @@ bool tryRead(int sock_, int recv_options, size_t max, int* num) {
 
 
 // Test it tries the correct amount of times before giving up
-TEST_F(ASIOLinkTest, forwardQueryTimeout) {
+TEST_F(RecursiveQueryTest, forwardQueryTimeout) {
     // Prepare the service (we do not use the common setup, we do not answer
     setDNSService();
 
@@ -835,7 +653,7 @@ TEST_F(ASIOLinkTest, forwardQueryTimeout) {
 // If we set client timeout to lower than querytimeout, we should
 // get a failure answer, but still see retries
 // (no actual answer is given here yet)
-TEST_F(ASIOLinkTest, forwardClientTimeout) {
+TEST_F(RecursiveQueryTest, forwardClientTimeout) {
     // Prepare the service (we do not use the common setup, we do not answer
     setDNSService();
 
@@ -880,7 +698,7 @@ TEST_F(ASIOLinkTest, forwardClientTimeout) {
 
 // If we set lookup timeout to lower than querytimeout*retries, we should
 // fail before the full amount of retries
-TEST_F(ASIOLinkTest, forwardLookupTimeout) {
+TEST_F(RecursiveQueryTest, forwardLookupTimeout) {
     // Prepare the service (we do not use the common setup, we do not answer
     setDNSService();
 
@@ -926,7 +744,7 @@ TEST_F(ASIOLinkTest, forwardLookupTimeout) {
 // for the skeleton code, it shouldn't be too much of a problem
 // Ok so even we don't all have access to the DNS world right now,
 // so disabling these tests too.
-TEST_F(ASIOLinkTest, DISABLED_recursiveSendOk) {
+TEST_F(RecursiveQueryTest, DISABLED_recursiveSendOk) {
     setDNSService(true, false);
     bool done;
     
@@ -951,7 +769,7 @@ TEST_F(ASIOLinkTest, DISABLED_recursiveSendOk) {
 }
 
 // see comments at previous test
-TEST_F(ASIOLinkTest, DISABLED_recursiveSendNXDOMAIN) {
+TEST_F(RecursiveQueryTest, DISABLED_recursiveSendNXDOMAIN) {
     setDNSService(true, false);
     bool done;
     
@@ -970,270 +788,4 @@ TEST_F(ASIOLinkTest, DISABLED_recursiveSendNXDOMAIN) {
     EXPECT_EQ(0, answer->getRRCount(Message::SECTION_ANSWER));
 }
 
-
-
-// This fixture is for testing IntervalTimer. Some callback functors are 
-// registered as callback function of the timer to test if they are called
-// or not.
-class IntervalTimerTest : public ::testing::Test {
-protected:
-    IntervalTimerTest() : io_service_() {}
-    ~IntervalTimerTest() {}
-    class TimerCallBack : public std::unary_function<void, void> {
-    public:
-        TimerCallBack(IntervalTimerTest* test_obj) : test_obj_(test_obj) {}
-        void operator()() const {
-            test_obj_->timer_called_ = true;
-            test_obj_->io_service_.stop();
-            return;
-        }
-    private:
-        IntervalTimerTest* test_obj_;
-    };
-    class TimerCallBackCounter : public std::unary_function<void, void> {
-    public:
-        TimerCallBackCounter(IntervalTimerTest* test_obj) : test_obj_(test_obj) {
-            counter_ = 0;
-        }
-        void operator()() {
-            ++counter_;
-            return;
-        }
-        int counter_;
-    private:
-        IntervalTimerTest* test_obj_;
-    };
-    class TimerCallBackCancelDeleter : public std::unary_function<void, void> {
-    public:
-        TimerCallBackCancelDeleter(IntervalTimerTest* test_obj,
-                                   IntervalTimer* timer,
-                                   TimerCallBackCounter& counter)
-            : test_obj_(test_obj), timer_(timer), counter_(counter), count_(0)
-        {}
-        void operator()() {
-            ++count_;
-            if (count_ == 1) {
-                // First time of call back.
-                // Store the value of counter_.counter_.
-                prev_counter_ = counter_.counter_;
-                delete timer_;
-            } else if (count_ == 2) {
-                // Second time of call back.
-                // Stop io_service to stop all timers.
-                test_obj_->io_service_.stop();
-                // Compare the value of counter_.counter_ with stored one.
-                // If TimerCallBackCounter was not called (expected behavior),
-                // they are same.
-                if (counter_.counter_ == prev_counter_) {
-                    test_obj_->timer_cancel_success_ = true;
-                }
-            }
-            return;
-        }
-    private:
-        IntervalTimerTest* test_obj_;
-        IntervalTimer* timer_;
-        TimerCallBackCounter& counter_;
-        int count_;
-        int prev_counter_;
-    };
-    class TimerCallBackCanceller {
-    public:
-        TimerCallBackCanceller(unsigned int& counter, IntervalTimer& itimer) :
-            counter_(counter), itimer_(itimer)
-        {}
-        void operator()() {
-            ++counter_;
-            itimer_.cancel();
-        }
-    private:
-        unsigned int& counter_;
-        IntervalTimer& itimer_;
-    };
-    class TimerCallBackOverwriter : public std::unary_function<void, void> {
-    public:
-        TimerCallBackOverwriter(IntervalTimerTest* test_obj,
-                                IntervalTimer& timer)
-            : test_obj_(test_obj), timer_(timer), count_(0)
-        {}
-        void operator()() {
-            ++count_;
-            if (count_ == 1) {
-                // First time of call back.
-                // Call setup() to update callback function to TimerCallBack.
-                test_obj_->timer_called_ = false;
-                timer_.setup(TimerCallBack(test_obj_), 100);
-            } else if (count_ == 2) {
-                // Second time of call back.
-                // If it reaches here, re-setup() is failed (unexpected).
-                // We should stop here.
-                test_obj_->io_service_.stop();
-            }
-            return;
-        }
-    private:
-        IntervalTimerTest* test_obj_;
-        IntervalTimer& timer_;
-        int count_;
-    };
-protected:
-    IOService io_service_;
-    bool timer_called_;
-    bool timer_cancel_success_;
-};
-
-TEST_F(IntervalTimerTest, invalidArgumentToIntervalTimer) {
-    // Create asio_link::IntervalTimer and setup.
-    IntervalTimer itimer(io_service_);
-    // expect throw if call back function is empty
-    EXPECT_THROW(itimer.setup(IntervalTimer::Callback(), 1),
-                 isc::InvalidParameter);
-    // expect throw if interval is not greater than 0
-    EXPECT_THROW(itimer.setup(TimerCallBack(this), 0), isc::BadValue);
-    EXPECT_THROW(itimer.setup(TimerCallBack(this), -1), isc::BadValue);
-}
-
-TEST_F(IntervalTimerTest, startIntervalTimer) {
-    // Create asio_link::IntervalTimer and setup.
-    // Then run IOService and test if the callback function is called.
-    IntervalTimer itimer(io_service_);
-    timer_called_ = false;
-    // store start time
-    boost::posix_time::ptime start;
-    start = boost::posix_time::microsec_clock::universal_time();
-    // setup timer
-    itimer.setup(TimerCallBack(this), 100);
-    EXPECT_EQ(100, itimer.getInterval());
-    io_service_.run();
-    // reaches here after timer expired
-    // delta: difference between elapsed time and 100 milliseconds.
-    boost::posix_time::time_duration delta =
-        (boost::posix_time::microsec_clock::universal_time() - start)
-         - boost::posix_time::millisec(100);
-    if (delta.is_negative()) {
-        delta.invert_sign();
-    }
-    // expect TimerCallBack is called; timer_called_ is true
-    EXPECT_TRUE(timer_called_);
-    // expect interval is 100 milliseconds +/- TIMER_MARGIN_MSEC.
-    EXPECT_TRUE(delta < TIMER_MARGIN_MSEC);
-}
-
-TEST_F(IntervalTimerTest, destructIntervalTimer) {
-    // This code isn't exception safe, but we'd rather keep the code
-    // simpler and more readable as this is only for tests and if it throws
-    // the program would immediately terminate anyway.
-
-    // The call back function will not be called after the timer is
-    // destroyed.
-    //
-    // There are two timers:
-    //  itimer_counter (A)
-    //   (Calls TimerCallBackCounter)
-    //     - increments internal counter in callback function
-    //  itimer_canceller (B)
-    //   (Calls TimerCallBackCancelDeleter)
-    //     - first time of callback, it stores the counter value of
-    //       callback_canceller and destroys itimer_counter
-    //     - second time of callback, it compares the counter value of
-    //       callback_canceller with stored value
-    //       if they are same the timer was not called; expected result
-    //       if they are different the timer was called after destroyed
-    //
-    //     0  100  200  300  400  500  600 (ms)
-    // (A) i--------+----x
-    //                   ^
-    //                   |destroy itimer_counter
-    // (B) i-------------+--------------s
-    //                                  ^stop io_service
-    //                                   and check if itimer_counter have been
-    //                                   stopped
-
-    // itimer_counter will be deleted in TimerCallBackCancelDeleter
-    IntervalTimer* itimer_counter = new IntervalTimer(io_service_);
-    IntervalTimer itimer_canceller(io_service_);
-    timer_cancel_success_ = false;
-    TimerCallBackCounter callback_canceller(this);
-    itimer_counter->setup(callback_canceller, 200);
-    itimer_canceller.setup(
-        TimerCallBackCancelDeleter(this, itimer_counter, callback_canceller),
-        300);
-    io_service_.run();
-    EXPECT_TRUE(timer_cancel_success_);
-}
-
-TEST_F(IntervalTimerTest, cancel) {
-    // Similar to destructIntervalTimer test, but the first timer explicitly
-    // cancels itself on first callback.
-    IntervalTimer itimer_counter(io_service_);
-    IntervalTimer itimer_watcher(io_service_);
-    unsigned int counter = 0;
-    itimer_counter.setup(TimerCallBackCanceller(counter, itimer_counter), 100);
-    itimer_watcher.setup(TimerCallBack(this), 200);
-    io_service_.run();
-    EXPECT_EQ(1, counter);
-    EXPECT_EQ(0, itimer_counter.getInterval());
-
-    // canceling an already canceled timer shouldn't cause any surprise.
-    EXPECT_NO_THROW(itimer_counter.cancel());
-}
-
-TEST_F(IntervalTimerTest, overwriteIntervalTimer) {
-    // Calling setup() multiple times updates call back function and interval.
-    //
-    // There are two timers:
-    //  itimer (A)
-    //   (Calls TimerCallBackCounter / TimerCallBack)
-    //     - increments internal counter in callback function
-    //       (TimerCallBackCounter)
-    //       interval: 300 milliseconds
-    //     - io_service_.stop() (TimerCallBack)
-    //       interval: 100 milliseconds
-    //  itimer_overwriter (B)
-    //   (Calls TimerCallBackOverwriter)
-    //     - first time of callback, it calls setup() to change call back
-    //       function to TimerCallBack and interval of itimer to 100
-    //       milliseconds
-    //       after 300 + 100 milliseconds from the beginning of this test,
-    //       TimerCallBack() will be called and io_service_ stops.
-    //     - second time of callback, it means the test fails.
-    //
-    //     0  100  200  300  400  500  600  700  800 (ms)
-    // (A) i-------------+----C----s
-    //                        ^    ^stop io_service
-    //                        |change call back function
-    // (B) i------------------+-------------------S
-    //                                            ^(stop io_service on fail)
-    //
-
-    IntervalTimer itimer(io_service_);
-    IntervalTimer itimer_overwriter(io_service_);
-    // store start time
-    boost::posix_time::ptime start;
-    start = boost::posix_time::microsec_clock::universal_time();
-    itimer.setup(TimerCallBackCounter(this), 300);
-    itimer_overwriter.setup(TimerCallBackOverwriter(this, itimer), 400);
-    io_service_.run();
-    // reaches here after timer expired
-    // if interval is updated, it takes
-    //   400 milliseconds for TimerCallBackOverwriter
-    //   + 100 milliseconds for TimerCallBack (stop)
-    //   = 500 milliseconds.
-    // otherwise (test fails), it takes
-    //   400 milliseconds for TimerCallBackOverwriter
-    //   + 400 milliseconds for TimerCallBackOverwriter (stop)
-    //   = 800 milliseconds.
-    // delta: difference between elapsed time and 400 + 100 milliseconds
-    boost::posix_time::time_duration delta =
-        (boost::posix_time::microsec_clock::universal_time() - start)
-         - boost::posix_time::millisec(400 + 100);
-    if (delta.is_negative()) {
-        delta.invert_sign();
-    }
-    // expect callback function is updated: TimerCallBack is called
-    EXPECT_TRUE(timer_called_);
-    // expect interval is updated
-    EXPECT_TRUE(delta < TIMER_MARGIN_MSEC);
-}
-
 }

+ 1 - 1
src/lib/asiolink/internal/tests/udpdns_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2010  CZ.NIC
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above