Skip to content

Commit 0bd3443

Browse files
committed
issue: HPCINFRA-3949 distinguish remote addresses
Split the remote address configuration into two separate addresses to properly test different network scenarios: 1. remote_addr (-r): Non-routable address for bind failure tests (e.g., 74.190.183.38 or fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) Used in tcp_bind.ti_2 and udp_bind.ti_2 to verify EADDRNOTAVAIL 2. remote_routable_addr (-g): Routable address for connect tests (dynamically detected default gateway or manually specified) Used in tcp_event.ti_2, udp_connect.ti_2 to test actual routing Remove the def_gw_exists flag and sys_gateway() C++ function, moving gateway detection to the shell script layer using do_get_gateway(). This bash function mirrors the original C++ logic using route command to detect default gateway for both IPv4 and IPv6. Update gtest.sh to dynamically detect system default, making tests more portable across different network environments. Gateway detection happens at test invocation time rather than during test execution. Remove SKIP_TRUE(def_gw_exists) checks from tests as gateway detection is now handled by the shell script which passes the appropriate address via command-line arguments. Tests requiring routable addresses will receive the actual gateway IP, while bind failure tests continue using non-routable dummy addresses. Changes: - Add remote_routable_addr to gtest_configure_t structure - Add -g/--remote-routable command-line option to gtest - Implement do_get_gateway() bash function in gtest.sh - Update tcp_event and udp_connect tests to use remote_routable_addr - Remove sys_gateway() function from common/sys.cc - Remove def_gw_exists flag from test_base class - Remove gateway detection skip logic from individual tests Signed-off-by: Tomer Cabouly <[email protected]>
1 parent d9d85e9 commit 0bd3443

File tree

11 files changed

+94
-108
lines changed

11 files changed

+94
-108
lines changed

contrib/jenkins_tests/gtest.sh

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,38 @@ function do_get_addrs()
5858
echo $gtest_ip_list
5959
}
6060

61-
gtest_opt="--addr=$(do_get_addrs 'eth' ${opt2})"
62-
gtest_opt_ipv6="--addr=$(do_get_addrs 'inet6' ${opt2}) -r fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" # Remote - Dummy Address
61+
# Retrieve default gateway address
62+
# $1 - family type: 'inet' for IPv4, 'inet6' for IPv6
63+
# Returns: gateway IP address or empty string if not found
64+
function do_get_gateway()
65+
{
66+
local family=$1
67+
local gateway=""
68+
69+
if [ "$family" = "inet6" ]; then
70+
# IPv6: route -6 -n | grep 'UG[ \t]' | awk '{print $2}' | head -1
71+
gateway=$(route -6 -n 2>/dev/null | grep 'UG[ \t]' | awk '{print $2}' | head -1)
72+
else
73+
# IPv4: route -n | grep 'UG[ \t]' | awk '{print $2}' | head -1
74+
gateway=$(route -n 2>/dev/null | grep 'UG[ \t]' | awk '{print $2}' | head -1)
75+
fi
76+
77+
echo "$gateway"
78+
}
79+
80+
# Detect gateway for IPv4
81+
gateway_ipv4=$(do_get_gateway 'inet')
82+
if [ -z "$gateway_ipv4" ]; then
83+
echo "[FAIL] No IPv4 gateway found. Tests requiring routable address cannot run." >&2
84+
exit 1
85+
fi
86+
gtest_opt="--addr=$(do_get_addrs 'eth' ${opt2}) -r 74.190.183.38 -g $gateway_ipv4" # -r is a dummy address
87+
88+
# Detect gateway for IPv6
89+
gateway_ipv6=$(do_get_gateway 'inet6')
90+
91+
# IpV6 tests don't need a gateway address, so we don't enforce it unlike IPv4.
92+
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
6393

6494
set +eE
6595

tests/gtest/common/base.cc

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@ uint16_t test_base::m_port = 0;
1313
int test_base::m_family = PF_INET;
1414
int test_base::m_break_signal = 0;
1515

16+
static void convert_and_copy_address(const sockaddr_store_t &source, sockaddr_store_t &dest,
17+
sa_family_t target_family)
18+
{
19+
if (((struct sockaddr *)&source)->sa_family != target_family) {
20+
memset(&dest, 0, sizeof(dest));
21+
((struct sockaddr *)&dest)->sa_family = target_family;
22+
sys_ipv4_to_ipv6(&((struct sockaddr_in *)&source)->sin_addr,
23+
&((struct sockaddr_in6 *)&dest)->sin6_addr);
24+
sys_set_port((struct sockaddr *)&dest, sys_get_port((struct sockaddr *)&source));
25+
} else {
26+
memcpy(&dest, &source, sizeof(dest));
27+
}
28+
}
29+
1630
test_base::test_base()
1731
{
1832
m_port = gtest_conf.port;
@@ -23,38 +37,10 @@ test_base::test_base()
2337
m_family = PF_INET6;
2438
}
2539

26-
if (((struct sockaddr *)&gtest_conf.client_addr)->sa_family != m_family) {
27-
memset(&client_addr, 0, sizeof(client_addr));
28-
((struct sockaddr *)&client_addr)->sa_family = m_family;
29-
sys_ipv4_to_ipv6(&((struct sockaddr_in *)&gtest_conf.client_addr)->sin_addr,
30-
&((struct sockaddr_in6 *)&client_addr)->sin6_addr);
31-
sys_set_port((struct sockaddr *)&client_addr,
32-
sys_get_port((struct sockaddr *)&gtest_conf.client_addr));
33-
} else {
34-
memcpy(&client_addr, &gtest_conf.client_addr, sizeof(client_addr));
35-
}
36-
37-
if (((struct sockaddr *)&gtest_conf.server_addr)->sa_family != m_family) {
38-
memset(&server_addr, 0, sizeof(server_addr));
39-
((struct sockaddr *)&server_addr)->sa_family = m_family;
40-
sys_ipv4_to_ipv6(&((struct sockaddr_in *)&gtest_conf.server_addr)->sin_addr,
41-
&((struct sockaddr_in6 *)&server_addr)->sin6_addr);
42-
sys_set_port((struct sockaddr *)&server_addr,
43-
sys_get_port((struct sockaddr *)&gtest_conf.server_addr));
44-
} else {
45-
memcpy(&server_addr, &gtest_conf.server_addr, sizeof(server_addr));
46-
}
47-
48-
if (((struct sockaddr *)&gtest_conf.remote_addr)->sa_family != m_family) {
49-
memset(&remote_addr, 0, sizeof(remote_addr));
50-
((struct sockaddr *)&remote_addr)->sa_family = m_family;
51-
sys_ipv4_to_ipv6(&((struct sockaddr_in *)&gtest_conf.remote_addr)->sin_addr,
52-
&((struct sockaddr_in6 *)&remote_addr)->sin6_addr);
53-
sys_set_port((struct sockaddr *)&remote_addr,
54-
sys_get_port((struct sockaddr *)&gtest_conf.remote_addr));
55-
} else {
56-
memcpy(&remote_addr, &gtest_conf.remote_addr, sizeof(remote_addr));
57-
}
40+
convert_and_copy_address(gtest_conf.client_addr, client_addr, m_family);
41+
convert_and_copy_address(gtest_conf.server_addr, server_addr, m_family);
42+
convert_and_copy_address(gtest_conf.remote_addr, remote_addr, m_family);
43+
convert_and_copy_address(gtest_conf.remote_routable_addr, remote_routable_addr, m_family);
5844

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

70-
def_gw_exists = gtest_conf.def_gw_exists;
71-
7256
m_efd_signal = 0;
7357
m_efd = eventfd(m_efd_signal, 0);
7458

tests/gtest/common/base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ class test_base {
8080
sockaddr_store_t client_addr;
8181
sockaddr_store_t server_addr;
8282
sockaddr_store_t remote_addr;
83+
sockaddr_store_t remote_routable_addr;
8384
sockaddr_store_t bogus_addr;
84-
bool def_gw_exists;
8585
static uint16_t m_port;
8686
static int m_family;
8787

tests/gtest/common/def.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ struct gtest_configure_t {
105105
sockaddr_store_t client_addr;
106106
sockaddr_store_t server_addr;
107107
sockaddr_store_t remote_addr;
108+
sockaddr_store_t remote_routable_addr;
108109
uint16_t port;
109-
bool def_gw_exists;
110110
};
111111

112112
#endif /* TESTS_GTEST_COMMON_DEF_H_ */

tests/gtest/common/sys.cc

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -157,39 +157,6 @@ int sys_dev2addr(const char *dev, struct sockaddr *addr)
157157
return rc;
158158
}
159159

160-
bool sys_gateway(struct sockaddr *addr, sa_family_t family)
161-
{
162-
sockaddr_store_t temp_addr;
163-
bool found = false;
164-
char line[256];
165-
const char cmd4[] = "route -n | grep 'UG[ \t]' | awk '{print $2}'";
166-
const char cmd6[] = "route -6 -n | grep 'UG[ \t]' | awk '{print $2}'";
167-
const char *cmd_ptr = (family == AF_INET ? cmd4 : cmd6);
168-
169-
FILE *file = popen(cmd_ptr, "r");
170-
if (!file) {
171-
log_warn("Unable to execute '%s'.\n", cmd_ptr);
172-
return false;
173-
}
174-
175-
while (fgets(line, sizeof(line), file) != NULL && !found) {
176-
size_t len = strlen(line);
177-
if (line[len - 1] == '\n' || line[len - 1] == '\r') {
178-
line[len - 1] = 0;
179-
}
180-
sys_str2addr(line, &temp_addr.addr, false);
181-
found = (temp_addr.addr.sa_family == family);
182-
if (found) {
183-
sys_str2addr(line, addr, false);
184-
log_trace("%s found gateway ip: %s\n", line, sys_addr2str(addr));
185-
}
186-
}
187-
188-
pclose(file);
189-
190-
return found;
191-
}
192-
193160
// Converts address to sockaddr structure. On an error, addr->sa_family is AF_UNSPEC.
194161
void sys_str2addr(const char *buf, struct sockaddr *addr, bool port)
195162
{

tests/gtest/common/sys.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,6 @@ char *sys_addr2dev(const struct sockaddr *addr, char *buf, size_t size);
111111

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

114-
bool sys_gateway(struct sockaddr *addr, sa_family_t family);
115-
116114
void sys_str2addr(const char *buf, struct sockaddr *addr, bool port = true);
117115

118116
static INLINE char *sys_addr2str(const struct sockaddr *addr, bool port = true)

tests/gtest/main.cc

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,39 +53,48 @@ static int _def_config(void)
5353
sys_str2addr("0.0.0.0[0]", (struct sockaddr *)&gtest_conf.client_addr, true);
5454
sys_str2addr("0.0.0.0[0]", (struct sockaddr *)&gtest_conf.server_addr, true);
5555
sys_str2addr("0.0.0.0[8888]", (struct sockaddr *)&gtest_conf.remote_addr, true);
56+
sys_str2addr("127.0.0.1[8888]", (struct sockaddr *)&gtest_conf.remote_routable_addr, true);
5657

5758
gtest_conf.port = 55555;
5859

5960
return rc;
6061
}
6162

62-
static void set_def_remote_address()
63+
static void set_def_remote_address(bool user_defined_routable)
6364
{
64-
gtest_conf.def_gw_exists = sys_gateway((struct sockaddr *)&gtest_conf.remote_addr,
65-
gtest_conf.server_addr.addr.sa_family);
6665
if (gtest_conf.server_addr.addr.sa_family == AF_INET6) {
67-
if (!gtest_conf.def_gw_exists) {
68-
sys_str2addr("::[8888]", (struct sockaddr *)&gtest_conf.remote_addr, true);
66+
gtest_conf.remote_addr.addr6.sin6_port = htons(8888);
67+
if (!user_defined_routable) {
68+
// User didn't provide -g, use IPv6 localhost as default
69+
sys_str2addr("::1[8888]", (struct sockaddr *)&gtest_conf.remote_routable_addr, true);
6970
} else {
70-
gtest_conf.remote_addr.addr6.sin6_port = htons(8888);
71+
// User provided -g, just ensure port is set
72+
gtest_conf.remote_routable_addr.addr6.sin6_port = htons(8888);
7173
}
74+
} else if (gtest_conf.server_addr.addr.sa_family == AF_INET) {
75+
gtest_conf.remote_addr.addr4.sin_port = htons(8888);
76+
gtest_conf.remote_routable_addr.addr4.sin_port = htons(8888);
7277
}
7378
}
7479

7580
static int _set_config(int argc, char **argv)
7681
{
7782
int rc = 0;
7883
static struct option long_options[] = {
79-
{"addr", required_argument, 0, 'a'}, {"if", required_argument, 0, 'i'},
80-
{"remote", required_argument, 0, 'r'}, {"port", required_argument, 0, 'p'},
81-
{"random", required_argument, 0, 's'}, {"debug", required_argument, 0, 'd'},
84+
{"addr", required_argument, 0, 'a'},
85+
{"if", required_argument, 0, 'i'},
86+
{"remote-non-routable", required_argument, 0, 'r'},
87+
{"remote-routable", required_argument, 0, 'g'},
88+
{"port", required_argument, 0, 'p'},
89+
{"random", required_argument, 0, 's'},
90+
{"debug", required_argument, 0, 'd'},
8291
{"help", no_argument, 0, 'h'},
8392
};
8493
int op;
8594
int option_index;
86-
bool user_defined_remote = false;
95+
bool user_defined_routable = false;
8796

88-
while ((op = getopt_long(argc, argv, "a:i:r:p:d:h", long_options, &option_index)) != -1) {
97+
while ((op = getopt_long(argc, argv, "a:i:r:g:p:d:h", long_options, &option_index)) != -1) {
8998
switch (op) {
9099
case 'a': {
91100
char *token1 = NULL;
@@ -148,11 +157,18 @@ static int _set_config(int argc, char **argv)
148157
} break;
149158
case 'r': {
150159
rc = sys_get_addr(optarg, (struct sockaddr *)&gtest_conf.remote_addr);
160+
if (rc < 0) {
161+
rc = -EINVAL;
162+
log_fatal("Failed to resolve ip address %s\n", optarg);
163+
}
164+
} break;
165+
case 'g': {
166+
rc = sys_get_addr(optarg, (struct sockaddr *)&gtest_conf.remote_routable_addr);
151167
if (rc < 0) {
152168
rc = -EINVAL;
153169
log_fatal("Failed to resolve ip address %s\n", optarg);
154170
} else {
155-
user_defined_remote = true;
171+
user_defined_routable = true;
156172
}
157173
} break;
158174
case 'p':
@@ -195,16 +211,16 @@ static int _set_config(int argc, char **argv)
195211
srand(gtest_conf.random_seed);
196212
sys_set_port((struct sockaddr *)&gtest_conf.server_addr, gtest_conf.port);
197213

198-
if (!user_defined_remote) {
199-
set_def_remote_address();
200-
}
214+
set_def_remote_address(user_defined_routable);
201215

202216
log_info("CONFIGURATION:\n");
203217
log_info("log level: %d\n", gtest_conf.log_level);
204218
log_info("seed: %d\n", gtest_conf.random_seed);
205219
log_info("client ip: %s\n", sys_addr2str((struct sockaddr *)&gtest_conf.client_addr));
206220
log_info("server ip: %s\n", sys_addr2str((struct sockaddr *)&gtest_conf.server_addr));
207221
log_info("remote ip: %s\n", sys_addr2str((struct sockaddr *)&gtest_conf.remote_addr));
222+
log_info("remote routable ip: %s\n",
223+
sys_addr2str((struct sockaddr *)&gtest_conf.remote_routable_addr));
208224
log_info("port: %d\n", gtest_conf.port);
209225
}
210226

@@ -214,13 +230,14 @@ static int _set_config(int argc, char **argv)
214230
static void _usage(void)
215231
{
216232
printf("Usage: gtest [options]\n"
217-
"\t--addr,-a <ip,ip> IP address client,server\n"
218-
"\t--if,-i <ip,ip> Interface client,server\n"
219-
"\t--remote,-r <ip> IP address remote\n"
220-
"\t--port,-p <num> Listen/connect to port <num> (default %d).\n"
221-
"\t--random,-s <count> Seed (default %d).\n"
222-
"\t--debug,-d <level> Output verbose level (default: %d).\n"
223-
"\t--help,-h Print help and exit\n",
233+
"\t--addr,-a <ip,ip> IP address client,server\n"
234+
"\t--if,-i <ip,ip> Interface client,server\n"
235+
"\t--remote-non-routable,-r <ip> IP address not reachable\n"
236+
"\t--remote-routable,-g <ip> IP address reachable\n"
237+
"\t--port,-p <num> Listen/connect to port <num> (default %d).\n"
238+
"\t--random,-s <count> Seed (default %d).\n"
239+
"\t--debug,-d <level> Output verbose level (default: %d).\n"
240+
"\t--help,-h Print help and exit\n",
224241

225242
gtest_conf.port, gtest_conf.random_seed, gtest_conf.log_level);
226243
exit(0);

tests/gtest/tcp/tcp_bind.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ TEST_F(tcp_bind, ti_2)
115115
int rc = EOK;
116116
int fd;
117117

118-
SKIP_TRUE(def_gw_exists, "No Default Gateway");
119-
120118
fd = tcp_base::sock_create();
121119
ASSERT_LE(0, fd);
122120

tests/gtest/tcp/tcp_event.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,10 @@ TEST_F(tcp_event, ti_2)
4242
int fd;
4343
struct epoll_event event;
4444

45-
SKIP_TRUE(def_gw_exists, "No Default Gateway");
46-
4745
fd = tcp_base::sock_create_nb();
4846
ASSERT_LE(0, fd);
4947

50-
rc = connect(fd, (struct sockaddr *)&remote_addr, sizeof(remote_addr));
48+
rc = connect(fd, (struct sockaddr *)&remote_routable_addr, sizeof(remote_routable_addr));
5149
ASSERT_EQ(EINPROGRESS, errno);
5250
ASSERT_EQ((-1), rc);
5351

@@ -92,7 +90,7 @@ TEST_F(tcp_event, DISABLED_ti_4)
9290
fd = tcp_base::sock_create_nb();
9391
ASSERT_LE(0, fd);
9492

95-
rc = connect(fd, (struct sockaddr *)&remote_addr, sizeof(remote_addr));
93+
rc = connect(fd, (struct sockaddr *)&remote_routable_addr, sizeof(remote_routable_addr));
9694
ASSERT_EQ(EINPROGRESS, errno);
9795
ASSERT_EQ((-1), rc);
9896

tests/gtest/udp/udp_bind.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,6 @@ TEST_F(udp_bind, ti_2)
110110
int rc = EOK;
111111
int fd;
112112

113-
SKIP_TRUE(def_gw_exists, "No Default Gateway");
114-
115113
fd = udp_base::sock_create();
116114
ASSERT_LE(0, fd);
117115

0 commit comments

Comments
 (0)