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

Tests for the get_sock function

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/vorner-sockcreator@3146 e5f2f494-b856-4b98-b285-d166d9295462
parent 3b1fef1e
// Copyright (C) 2010 CZ NIC
//
// 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 "sockcreator.h"
using namespace isc::socket_creator;
int main() {
int
main() {
/*
* TODO Maybe use some OS-specific caps interface and drop everything
* but ability to bind ports? It would be nice.
......
CLEANFILES = *.gcno *.gcda
TESTS =
if HAVE_GTEST
TESTS += run_unittests
run_unittests_SOURCES = ../sockcreator.cc ../sockcreator.h
run_unittests_SOURCES += sockcreator_tests.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)
endif
noinst_PROGRAMS = $(TESTS)
// Copyright (C) 2010 CZ NIC
//
// 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();
}
// Copyright (C) 2010 CZ NIC
//
// 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 "../sockcreator.h"
#include <gtest/gtest.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <cstring>
#include <cerrno>
using namespace isc::socket_creator;
namespace {
/*
* Generic version of the creation of socket test. It just tries to
* create the socket and checks the result is not negative (eg.
* it is valid descriptor) and that it can listen.
*
* This is a macro so ASSERT_* does abort the TEST, not just the
* function inside.
*/
#define TEST_ANY_CREATE(SOCK_TYPE, ADDR_TYPE, ADDR_FAMILY, ADDR_SET, \
CHECK_SOCK) \
do { \
/*
* This should create an address that binds on all interfaces
* and lets the OS choose a free port.
*/ \
struct ADDR_TYPE addr; \
memset(&addr, 0, sizeof addr); \
ADDR_SET(addr); \
struct sockaddr *addr_ptr = static_cast<struct sockaddr *>( \
static_cast<void *>(&addr)); \
addr_ptr->sa_family = ADDR_FAMILY; \
\
int socket = get_sock(SOCK_TYPE, addr_ptr, sizeof addr); \
/* Provide even nice error message. */ \
ASSERT_GE(socket, 0) << "Couldn't create a socket of type " \
#SOCK_TYPE " and family " #ADDR_FAMILY ", failed with " \
<< socket << " and errno " << errno; \
CHECK_SOCK(ADDR_TYPE, socket); \
EXPECT_EQ(0, close(socket)); \
} while(0)
// Just helper macros
#define INADDR_SET(WHAT) do { WHAT.sin_addr.s_addr = INADDR_ANY; } while(0)
#define IN6ADDR_SET(WHAT) do { WHAT.sin6_addr = in6addr_any; } while(0)
// If the get_sock returned something useful, listen must work
#define TCP_CHECK(UNUSED, SOCKET) do { \
EXPECT_EQ(0, listen(SOCKET, 1)); \
} while(0)
// More complicated with UDP, so we send a packet to ourselfs and se if it
// arrives
#define UDP_CHECK(ADDR_TYPE, SOCKET) do { \
struct ADDR_TYPE addr; \
memset(&addr, 0, sizeof addr); \
struct sockaddr *addr_ptr = static_cast<struct sockaddr *>( \
static_cast<void *>(&addr)); \
\
socklen_t len = sizeof addr; \
ASSERT_EQ(0, getsockname(SOCKET, addr_ptr, &len)); \
ASSERT_EQ(5, sendto(SOCKET, "test", 5, 0, addr_ptr, sizeof addr)); \
char buffer[5]; \
ASSERT_EQ(5, recv(SOCKET, buffer, 5, 0)); \
EXPECT_STREQ("test", buffer); \
} while(0)
/*
* Several tests to ensure we can create the sockets.
*/
TEST(get_sock, udp4_create) {
TEST_ANY_CREATE(SOCK_DGRAM, sockaddr_in, AF_INET, INADDR_SET, UDP_CHECK);
}
TEST(get_sock, tcp4_create) {
TEST_ANY_CREATE(SOCK_STREAM, sockaddr_in, AF_INET, INADDR_SET, TCP_CHECK);
}
TEST(get_sock, udp6_create) {
TEST_ANY_CREATE(SOCK_DGRAM, sockaddr_in6, AF_INET6, IN6ADDR_SET,
UDP_CHECK);
}
TEST(get_sock, tcp6_create) {
TEST_ANY_CREATE(SOCK_STREAM, sockaddr_in6, AF_INET6, IN6ADDR_SET,
TCP_CHECK);
}
/*
* Try to ask the get_sock function some nonsense and test if it
* is able to report error.
*/
TEST(get_sock, fail_with_nonsense) {
ASSERT_LT(get_sock(0, NULL, 0), 0);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment