Commit a9ac4ee3 authored by Jelte Jansen's avatar Jelte Jansen

[trac569] split up unittests as well

Though most of the tests fell into recursive_query_unittest.cc
parent dfb68c22
SUBDIRS = . tests internal
SUBDIRS = . tests
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)
......@@ -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)
......
// 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);
}
// 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;
}
// 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"));
}
// 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);
}