Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions contrib/jenkins_tests/gtest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,38 @@ function do_get_addrs()
echo $gtest_ip_list
}

gtest_opt="--addr=$(do_get_addrs 'eth' ${opt2})"
gtest_opt_ipv6="--addr=$(do_get_addrs 'inet6' ${opt2}) -r fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" # Remote - Dummy Address
# Retrieve default gateway address
# $1 - family type: 'inet' for IPv4, 'inet6' for IPv6
# Returns: gateway IP address or empty string if not found
function do_get_gateway()
{
local family=$1
local gateway=""

if [ "$family" = "inet6" ]; then
# IPv6: route -6 -n | grep 'UG[ \t]' | awk '{print $2}' | head -1
gateway=$(route -6 -n 2>/dev/null | grep 'UG[ \t]' | awk '{print $2}' | head -1)
else
# IPv4: route -n | grep 'UG[ \t]' | awk '{print $2}' | head -1
gateway=$(route -n 2>/dev/null | grep 'UG[ \t]' | awk '{print $2}' | head -1)
fi

echo "$gateway"
}

# Detect gateway for IPv4
gateway_ipv4=$(do_get_gateway 'inet')
if [ -z "$gateway_ipv4" ]; then
echo "[FAIL] No IPv4 gateway found. Tests requiring routable address cannot run." >&2
exit 1
fi
gtest_opt="--addr=$(do_get_addrs 'eth' ${opt2}) -r 192.0.2.1 -g $gateway_ipv4" # -r is TEST-NET-1 (RFC 5737) non-routable test address

# Detect gateway for IPv6
gateway_ipv6=$(do_get_gateway 'inet6')

# IpV6 tests don't need a gateway address, so we don't enforce it unlike IPv4.
gtest_opt_ipv6="--addr=$(do_get_addrs 'inet6' ${opt2}) -r fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff ${gateway_ipv6:+-g $gateway_ipv6}" # -r is a dummy address

set +eE

Expand Down
52 changes: 18 additions & 34 deletions tests/gtest/common/base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ uint16_t test_base::m_port = 0;
int test_base::m_family = PF_INET;
int test_base::m_break_signal = 0;

static void convert_and_copy_address(const sockaddr_store_t &source, sockaddr_store_t &dest,
sa_family_t target_family)
{
if (((struct sockaddr *)&source)->sa_family != target_family) {
memset(&dest, 0, sizeof(dest));
((struct sockaddr *)&dest)->sa_family = target_family;
sys_ipv4_to_ipv6(&((struct sockaddr_in *)&source)->sin_addr,
&((struct sockaddr_in6 *)&dest)->sin6_addr);
sys_set_port((struct sockaddr *)&dest, sys_get_port((struct sockaddr *)&source));
} else {
memcpy(&dest, &source, sizeof(dest));
}
}

test_base::test_base()
{
m_port = gtest_conf.port;
Expand All @@ -23,38 +37,10 @@ test_base::test_base()
m_family = PF_INET6;
}

if (((struct sockaddr *)&gtest_conf.client_addr)->sa_family != m_family) {
memset(&client_addr, 0, sizeof(client_addr));
((struct sockaddr *)&client_addr)->sa_family = m_family;
sys_ipv4_to_ipv6(&((struct sockaddr_in *)&gtest_conf.client_addr)->sin_addr,
&((struct sockaddr_in6 *)&client_addr)->sin6_addr);
sys_set_port((struct sockaddr *)&client_addr,
sys_get_port((struct sockaddr *)&gtest_conf.client_addr));
} else {
memcpy(&client_addr, &gtest_conf.client_addr, sizeof(client_addr));
}

if (((struct sockaddr *)&gtest_conf.server_addr)->sa_family != m_family) {
memset(&server_addr, 0, sizeof(server_addr));
((struct sockaddr *)&server_addr)->sa_family = m_family;
sys_ipv4_to_ipv6(&((struct sockaddr_in *)&gtest_conf.server_addr)->sin_addr,
&((struct sockaddr_in6 *)&server_addr)->sin6_addr);
sys_set_port((struct sockaddr *)&server_addr,
sys_get_port((struct sockaddr *)&gtest_conf.server_addr));
} else {
memcpy(&server_addr, &gtest_conf.server_addr, sizeof(server_addr));
}

if (((struct sockaddr *)&gtest_conf.remote_addr)->sa_family != m_family) {
memset(&remote_addr, 0, sizeof(remote_addr));
((struct sockaddr *)&remote_addr)->sa_family = m_family;
sys_ipv4_to_ipv6(&((struct sockaddr_in *)&gtest_conf.remote_addr)->sin_addr,
&((struct sockaddr_in6 *)&remote_addr)->sin6_addr);
sys_set_port((struct sockaddr *)&remote_addr,
sys_get_port((struct sockaddr *)&gtest_conf.remote_addr));
} else {
memcpy(&remote_addr, &gtest_conf.remote_addr, sizeof(remote_addr));
}
convert_and_copy_address(gtest_conf.client_addr, client_addr, m_family);
convert_and_copy_address(gtest_conf.server_addr, server_addr, m_family);
convert_and_copy_address(gtest_conf.remote_addr, remote_addr, m_family);
convert_and_copy_address(gtest_conf.remote_routable_addr, remote_routable_addr, m_family);

memset(&bogus_addr, 0, sizeof(bogus_addr));
((struct sockaddr *)&bogus_addr)->sa_family = m_family;
Expand All @@ -67,8 +53,6 @@ test_base::test_base()
&(((struct sockaddr_in6 *)&bogus_addr)->sin6_addr));
}

def_gw_exists = gtest_conf.def_gw_exists;

m_efd_signal = 0;
m_efd = eventfd(m_efd_signal, 0);

Expand Down
2 changes: 1 addition & 1 deletion tests/gtest/common/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ class test_base {
sockaddr_store_t client_addr;
sockaddr_store_t server_addr;
sockaddr_store_t remote_addr;
sockaddr_store_t remote_routable_addr;
sockaddr_store_t bogus_addr;
bool def_gw_exists;
static uint16_t m_port;
static int m_family;

Expand Down
2 changes: 1 addition & 1 deletion tests/gtest/common/def.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ struct gtest_configure_t {
sockaddr_store_t client_addr;
sockaddr_store_t server_addr;
sockaddr_store_t remote_addr;
sockaddr_store_t remote_routable_addr;
uint16_t port;
bool def_gw_exists;
};

#endif /* TESTS_GTEST_COMMON_DEF_H_ */
33 changes: 0 additions & 33 deletions tests/gtest/common/sys.cc
Original file line number Diff line number Diff line change
Expand Up @@ -157,39 +157,6 @@ int sys_dev2addr(const char *dev, struct sockaddr *addr)
return rc;
}

bool sys_gateway(struct sockaddr *addr, sa_family_t family)
{
sockaddr_store_t temp_addr;
bool found = false;
char line[256];
const char cmd4[] = "route -n | grep 'UG[ \t]' | awk '{print $2}'";
const char cmd6[] = "route -6 -n | grep 'UG[ \t]' | awk '{print $2}'";
const char *cmd_ptr = (family == AF_INET ? cmd4 : cmd6);

FILE *file = popen(cmd_ptr, "r");
if (!file) {
log_warn("Unable to execute '%s'.\n", cmd_ptr);
return false;
}

while (fgets(line, sizeof(line), file) != NULL && !found) {
size_t len = strlen(line);
if (line[len - 1] == '\n' || line[len - 1] == '\r') {
line[len - 1] = 0;
}
sys_str2addr(line, &temp_addr.addr, false);
found = (temp_addr.addr.sa_family == family);
if (found) {
sys_str2addr(line, addr, false);
log_trace("%s found gateway ip: %s\n", line, sys_addr2str(addr));
}
}

pclose(file);

return found;
}

// Converts address to sockaddr structure. On an error, addr->sa_family is AF_UNSPEC.
void sys_str2addr(const char *buf, struct sockaddr *addr, bool port)
{
Expand Down
2 changes: 0 additions & 2 deletions tests/gtest/common/sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,6 @@ char *sys_addr2dev(const struct sockaddr *addr, char *buf, size_t size);

int sys_dev2addr(const char *dev, struct sockaddr *addr);

bool sys_gateway(struct sockaddr *addr, sa_family_t family);

void sys_str2addr(const char *buf, struct sockaddr *addr, bool port = true);

static INLINE char *sys_addr2str(const struct sockaddr *addr, bool port = true)
Expand Down
67 changes: 47 additions & 20 deletions tests/gtest/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,40 +52,57 @@ static int _def_config(void)

sys_str2addr("0.0.0.0[0]", (struct sockaddr *)&gtest_conf.client_addr, true);
sys_str2addr("0.0.0.0[0]", (struct sockaddr *)&gtest_conf.server_addr, true);
sys_str2addr("0.0.0.0[8888]", (struct sockaddr *)&gtest_conf.remote_addr, true);
sys_str2addr("192.0.2.1[8888]", (struct sockaddr *)&gtest_conf.remote_addr, true);
sys_str2addr("127.0.0.1[8888]", (struct sockaddr *)&gtest_conf.remote_routable_addr, true);

gtest_conf.port = 55555;

return rc;
}

static void set_def_remote_address()
static void set_def_remote_address(bool user_defined_routable, bool user_defined_remote)
{
gtest_conf.def_gw_exists = sys_gateway((struct sockaddr *)&gtest_conf.remote_addr,
gtest_conf.server_addr.addr.sa_family);
if (gtest_conf.server_addr.addr.sa_family == AF_INET6) {
if (!gtest_conf.def_gw_exists) {
sys_str2addr("::[8888]", (struct sockaddr *)&gtest_conf.remote_addr, true);
if (!user_defined_remote) {
// Replace IPv4 non-routable default with IPv6 non-routable address
sys_str2addr("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff[8888]",
(struct sockaddr *)&gtest_conf.remote_addr, true);
} else {
// User provided -r, just ensure port is set
gtest_conf.remote_addr.addr6.sin6_port = htons(8888);
}
if (!user_defined_routable) {
// User didn't provide -g, use IPv6 localhost as default
sys_str2addr("::1[8888]", (struct sockaddr *)&gtest_conf.remote_routable_addr, true);
} else {
// User provided -g, just ensure port is set
gtest_conf.remote_routable_addr.addr6.sin6_port = htons(8888);
}
} else if (gtest_conf.server_addr.addr.sa_family == AF_INET) {
gtest_conf.remote_addr.addr4.sin_port = htons(8888);
gtest_conf.remote_routable_addr.addr4.sin_port = htons(8888);
}
}

static int _set_config(int argc, char **argv)
{
int rc = 0;
static struct option long_options[] = {
{"addr", required_argument, 0, 'a'}, {"if", required_argument, 0, 'i'},
{"remote", required_argument, 0, 'r'}, {"port", required_argument, 0, 'p'},
{"random", required_argument, 0, 's'}, {"debug", required_argument, 0, 'd'},
{"addr", required_argument, 0, 'a'},
{"if", required_argument, 0, 'i'},
{"remote-non-routable", required_argument, 0, 'r'},
{"remote-routable", required_argument, 0, 'g'},
{"port", required_argument, 0, 'p'},
{"random", required_argument, 0, 's'},
{"debug", required_argument, 0, 'd'},
{"help", no_argument, 0, 'h'},
};
int op;
int option_index;
bool user_defined_remote = false;
bool user_defined_routable = false;

while ((op = getopt_long(argc, argv, "a:i:r:p:d:h", long_options, &option_index)) != -1) {
while ((op = getopt_long(argc, argv, "a:i:r:g:p:d:h", long_options, &option_index)) != -1) {
switch (op) {
case 'a': {
char *token1 = NULL;
Expand Down Expand Up @@ -155,6 +172,15 @@ static int _set_config(int argc, char **argv)
user_defined_remote = true;
}
} break;
case 'g': {
rc = sys_get_addr(optarg, (struct sockaddr *)&gtest_conf.remote_routable_addr);
if (rc < 0) {
rc = -EINVAL;
log_fatal("Failed to resolve ip address %s\n", optarg);
} else {
user_defined_routable = true;
}
} break;
case 'p':
errno = 0;
gtest_conf.port = strtol(optarg, NULL, 0);
Expand Down Expand Up @@ -195,16 +221,16 @@ static int _set_config(int argc, char **argv)
srand(gtest_conf.random_seed);
sys_set_port((struct sockaddr *)&gtest_conf.server_addr, gtest_conf.port);

if (!user_defined_remote) {
set_def_remote_address();
}
set_def_remote_address(user_defined_routable, user_defined_remote);

log_info("CONFIGURATION:\n");
log_info("log level: %d\n", gtest_conf.log_level);
log_info("seed: %d\n", gtest_conf.random_seed);
log_info("client ip: %s\n", sys_addr2str((struct sockaddr *)&gtest_conf.client_addr));
log_info("server ip: %s\n", sys_addr2str((struct sockaddr *)&gtest_conf.server_addr));
log_info("remote ip: %s\n", sys_addr2str((struct sockaddr *)&gtest_conf.remote_addr));
log_info("remote routable ip: %s\n",
sys_addr2str((struct sockaddr *)&gtest_conf.remote_routable_addr));
log_info("port: %d\n", gtest_conf.port);
}

Expand All @@ -214,13 +240,14 @@ static int _set_config(int argc, char **argv)
static void _usage(void)
{
printf("Usage: gtest [options]\n"
"\t--addr,-a <ip,ip> IP address client,server\n"
"\t--if,-i <ip,ip> Interface client,server\n"
"\t--remote,-r <ip> IP address remote\n"
"\t--port,-p <num> Listen/connect to port <num> (default %d).\n"
"\t--random,-s <count> Seed (default %d).\n"
"\t--debug,-d <level> Output verbose level (default: %d).\n"
"\t--help,-h Print help and exit\n",
"\t--addr,-a <ip,ip> IP address client,server\n"
"\t--if,-i <ip,ip> Interface client,server\n"
"\t--remote-non-routable,-r <ip> IP address not reachable\n"
"\t--remote-routable,-g <ip> IP address reachable\n"
"\t--port,-p <num> Listen/connect to port <num> (default %d).\n"
"\t--random,-s <count> Seed (default %d).\n"
"\t--debug,-d <level> Output verbose level (default: %d).\n"
"\t--help,-h Print help and exit\n",

gtest_conf.port, gtest_conf.random_seed, gtest_conf.log_level);
exit(0);
Expand Down
2 changes: 0 additions & 2 deletions tests/gtest/tcp/tcp_bind.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@ TEST_F(tcp_bind, ti_2)
int rc = EOK;
int fd;

SKIP_TRUE(def_gw_exists, "No Default Gateway");

fd = tcp_base::sock_create();
ASSERT_LE(0, fd);

Expand Down
17 changes: 13 additions & 4 deletions tests/gtest/tcp/tcp_event.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,25 @@ TEST_F(tcp_event, DISABLED_ti_1)

TEST_F(tcp_event, ti_2)
{
// Skip if running with default localhost address - test requires real gateway via -g
if (remote_routable_addr.addr.sa_family == AF_INET) {
if (remote_routable_addr.addr4.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
GTEST_SKIP() << "Test requires real gateway address via -g flag (not localhost)";
}
} else if (remote_routable_addr.addr.sa_family == AF_INET6) {
if (IN6_IS_ADDR_LOOPBACK(&remote_routable_addr.addr6.sin6_addr)) {
GTEST_SKIP() << "Test requires real gateway address via -g flag (not localhost)";
}
}

int rc = EOK;
int fd;
struct epoll_event event;

SKIP_TRUE(def_gw_exists, "No Default Gateway");

fd = tcp_base::sock_create_nb();
ASSERT_LE(0, fd);

rc = connect(fd, (struct sockaddr *)&remote_addr, sizeof(remote_addr));
rc = connect(fd, (struct sockaddr *)&remote_routable_addr, sizeof(remote_routable_addr));
ASSERT_EQ(EINPROGRESS, errno);
ASSERT_EQ((-1), rc);

Expand Down Expand Up @@ -92,7 +101,7 @@ TEST_F(tcp_event, DISABLED_ti_4)
fd = tcp_base::sock_create_nb();
ASSERT_LE(0, fd);

rc = connect(fd, (struct sockaddr *)&remote_addr, sizeof(remote_addr));
rc = connect(fd, (struct sockaddr *)&remote_routable_addr, sizeof(remote_routable_addr));
ASSERT_EQ(EINPROGRESS, errno);
ASSERT_EQ((-1), rc);

Expand Down
2 changes: 0 additions & 2 deletions tests/gtest/udp/udp_bind.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,6 @@ TEST_F(udp_bind, ti_2)
int rc = EOK;
int fd;

SKIP_TRUE(def_gw_exists, "No Default Gateway");

fd = udp_base::sock_create();
ASSERT_LE(0, fd);

Expand Down
6 changes: 1 addition & 5 deletions tests/gtest/udp/udp_connect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ TEST_F(udp_connect, ti_2)
int fd;
int i;

SKIP_TRUE(def_gw_exists, "No Default Gateway");

fd = udp_base::sock_create();
ASSERT_LE(0, fd);

Expand All @@ -72,7 +70,7 @@ TEST_F(udp_connect, ti_2)
EXPECT_EQ(0, rc);

for (i = 0; i < 10; i++) {
rc = connect(fd, (struct sockaddr *)&remote_addr, sizeof(remote_addr));
rc = connect(fd, (struct sockaddr *)&remote_routable_addr, sizeof(remote_routable_addr));
ASSERT_TRUE(EOK == errno) << "connect() attempt = " << i << "\n" << close(fd);
ASSERT_EQ(0, rc) << "connect() attempt = " << i << "\n" << close(fd);
usleep(500);
Expand All @@ -93,8 +91,6 @@ TEST_F(udp_connect, ti_3)
int fd;
int i;

SKIP_TRUE(def_gw_exists, "No Default Gateway");

fd = udp_base::sock_create();
ASSERT_LE(0, fd);

Expand Down