aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2024-12-07 15:45:15 -0800
committerGarrett D'Amore <garrett@damore.org>2024-12-07 15:45:15 -0800
commit45ad63d265261203155c882ec93b80a604e9ab3b (patch)
treeeb6fda615bb65e888a0bada3ad1730daabb72129 /src/testing
parent32c78f7b7b4fcfacea6b45e8601c82771f1e40b3 (diff)
downloadnng-45ad63d265261203155c882ec93b80a604e9ab3b.tar.gz
nng-45ad63d265261203155c882ec93b80a604e9ab3b.tar.bz2
nng-45ad63d265261203155c882ec93b80a604e9ab3b.zip
nuts: try to avoid address in use for most tests
We get test failures somewhat frequently due to port conflicts. This attempts to make more of the tests use the trick of binding to port 0, and letting us use the random port instead.
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/marry.c56
-rw-r--r--src/testing/nuts.h12
-rw-r--r--src/testing/util.c112
3 files changed, 130 insertions, 50 deletions
diff --git a/src/testing/marry.c b/src/testing/marry.c
index 8cc94473..36b879c7 100644
--- a/src/testing/marry.c
+++ b/src/testing/marry.c
@@ -92,6 +92,62 @@ nuts_scratch_addr(const char *scheme, size_t sz, char *addr)
abort();
}
+void
+nuts_scratch_addr_zero(const char *scheme, size_t sz, char *addr)
+{
+ if ((strcmp(scheme, "inproc") == 0) ||
+ (strcmp(scheme, "abstract") == 0)) {
+ (void) snprintf(addr, sz, "%s://nuts%04x%04x%04x%04x", scheme,
+ nng_random(), nng_random(), nng_random(), nng_random());
+ return;
+ }
+
+ if ((strncmp(scheme, "tcp", 3) == 0) ||
+ (strncmp(scheme, "tls", 3) == 0) ||
+ (strncmp(scheme, "udp", 3) == 0)) {
+ const char *ip =
+ strchr(scheme, '6') != NULL ? "[::1]" : "127.0.0.1";
+ (void) snprintf(addr, sz, "%s://%s:%u", scheme, ip, 0);
+ return;
+ }
+
+ if (strncmp(scheme, "ws", 2) == 0) {
+ const char *ip =
+ strchr(scheme, '6') != NULL ? "[::1]" : "127.0.0.1";
+ (void) snprintf(addr, sz, "%s://%s:%u/nuts%04x%04x%04x%04x",
+ scheme, ip, 0, nng_random(), nng_random(), nng_random(),
+ nng_random());
+ return;
+ }
+
+ if ((strncmp(scheme, "ipc", 3) == 0) ||
+ (strncmp(scheme, "unix", 4) == 0)) {
+#ifdef _WIN32
+ // Windows doesn't place IPC names in the filesystem.
+ (void) snprintf(addr, sz, "%s://nuts%04x%04x%04x%04x", scheme,
+ nng_random(), nng_random(), nng_random(), nng_random());
+ return;
+#else
+ char *tmpdir;
+
+ if (((tmpdir = getenv("TMPDIR")) == NULL) &&
+ ((tmpdir = getenv("TEMP")) == NULL) &&
+ ((tmpdir = getenv("TMP")) == NULL)) {
+ tmpdir = "/tmp";
+ }
+
+ (void) snprintf(addr, sz, "%s://%s/nuts%04x%04x%04x%04x",
+ scheme, tmpdir, nng_random(), nng_random(), nng_random(),
+ nng_random());
+ return;
+#endif
+ }
+
+ // We should not be here.
+ nng_log_err("NUTS", "Unknown scheme");
+ abort();
+}
+
// nuts_next_port returns a "next" allocation port.
// Ports are chosen by starting from a random point within a
// range (normally 38000-40000, but other good places to choose
diff --git a/src/testing/nuts.h b/src/testing/nuts.h
index 5fe193db..f2e50c2c 100644
--- a/src/testing/nuts.h
+++ b/src/testing/nuts.h
@@ -85,6 +85,10 @@ extern uint16_t nuts_next_port(void);
// 64 bytes to ensure no truncation occurs.
extern void nuts_scratch_addr(const char *, size_t, char *);
+// like nuts_scratch_addr, but attempts to use an autobind (0 port)
+// address instead.
+extern void nuts_scratch_addr_zero(const char *, size_t, char *);
+
// nuts_marry connects two sockets using inproc. It uses socket
// pipe hooks to ensure that it does not return before both sockets
// are fully connected.
@@ -264,6 +268,14 @@ extern const char *nuts_ecdsa_client_crt;
(var) = nuts_addr_; \
} while (0)
+#define NUTS_ADDR_ZERO(var, scheme) \
+ do { \
+ static char nuts_addr_[64]; \
+ nuts_scratch_addr_zero( \
+ scheme, sizeof(nuts_addr_), nuts_addr_); \
+ (var) = nuts_addr_; \
+ } while (0)
+
#define NUTS_OPEN(sock) NUTS_PASS(nng_pair1_open(&(sock)))
#define NUTS_CLOSE(sock) NUTS_PASS(nng_close(sock))
diff --git a/src/testing/util.c b/src/testing/util.c
index d569bf5f..2bb882b7 100644
--- a/src/testing/util.c
+++ b/src/testing/util.c
@@ -286,16 +286,18 @@ nuts_tran_dialer_closed(const char *scheme)
void
nuts_tran_duplicate_listen(const char *scheme)
{
- nng_socket s = NNG_SOCKET_INITIALIZER;
- nng_listener l1 = NNG_LISTENER_INITIALIZER;
- nng_listener l2 = NNG_LISTENER_INITIALIZER;
- const char *addr;
+ nng_socket s = NNG_SOCKET_INITIALIZER;
+ nng_listener l1 = NNG_LISTENER_INITIALIZER;
+ nng_listener l2 = NNG_LISTENER_INITIALIZER;
+ const char *addr;
+ const nng_url *url;
NUTS_SKIP_IF_IPV6_NEEDED_AND_ABSENT(scheme);
- NUTS_ADDR(addr, scheme);
+ NUTS_ADDR_ZERO(addr, scheme);
NUTS_OPEN(s);
NUTS_PASS(nng_listen(s, addr, &l1, 0));
- NUTS_FAIL(nng_listen(s, addr, &l2, 0), NNG_EADDRINUSE);
+ NUTS_PASS(nng_listener_get_url(l1, &url));
+ NUTS_FAIL(nng_listen_url(s, url, &l2, 0), NNG_EADDRINUSE);
NUTS_TRUE(nng_listener_id(l1) > 0);
NUTS_TRUE(nng_listener_id(l2) < 0);
NUTS_CLOSE(s);
@@ -309,7 +311,7 @@ nuts_tran_listener_cancel(const char *scheme)
const char *addr;
NUTS_SKIP_IF_IPV6_NEEDED_AND_ABSENT(scheme);
- NUTS_ADDR(addr, scheme);
+ NUTS_ADDR_ZERO(addr, scheme);
NUTS_OPEN(s);
NUTS_PASS(nng_listen(s, addr, &l, 0));
NUTS_TRUE(nng_listener_id(l) > 0);
@@ -325,7 +327,7 @@ nuts_tran_listener_closed(const char *scheme)
const char *addr;
NUTS_SKIP_IF_IPV6_NEEDED_AND_ABSENT(scheme);
- NUTS_ADDR(addr, scheme);
+ NUTS_ADDR_ZERO(addr, scheme);
NUTS_OPEN(s);
NUTS_PASS(nng_listener_create(&l, s, addr));
NUTS_TRUE(nng_listener_id(l) > 0);
@@ -337,15 +339,16 @@ nuts_tran_listener_closed(const char *scheme)
void
nuts_tran_listen_accept(const char *scheme)
{
- nng_socket s1 = NNG_SOCKET_INITIALIZER;
- nng_socket s2 = NNG_SOCKET_INITIALIZER;
- nng_listener l1 = NNG_LISTENER_INITIALIZER;
- nng_dialer d1 = NNG_LISTENER_INITIALIZER;
- nng_dialer d2 = NNG_LISTENER_INITIALIZER;
- const char *addr;
+ nng_socket s1 = NNG_SOCKET_INITIALIZER;
+ nng_socket s2 = NNG_SOCKET_INITIALIZER;
+ nng_listener l1 = NNG_LISTENER_INITIALIZER;
+ nng_dialer d1 = NNG_LISTENER_INITIALIZER;
+ nng_dialer d2 = NNG_LISTENER_INITIALIZER;
+ const char *addr;
+ const nng_url *url;
NUTS_SKIP_IF_IPV6_NEEDED_AND_ABSENT(scheme);
- NUTS_ADDR(addr, scheme);
+ NUTS_ADDR_ZERO(addr, scheme);
NUTS_OPEN(s1);
NUTS_OPEN(s2);
NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_SENDTIMEO, 100));
@@ -353,8 +356,9 @@ nuts_tran_listen_accept(const char *scheme)
NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_RECVTIMEO, 100));
NUTS_PASS(nng_socket_set_ms(s2, NNG_OPT_RECVTIMEO, 100));
NUTS_PASS(nng_listen(s1, addr, &l1, 0));
- NUTS_PASS(nng_dial(s2, addr, &d1, 0));
- NUTS_PASS(nng_dial(s2, addr, &d2, 0));
+ NUTS_PASS(nng_listener_get_url(l1, &url));
+ NUTS_PASS(nng_dial_url(s2, url, &d1, 0));
+ NUTS_PASS(nng_dial_url(s2, url, &d2, 0));
NUTS_TRUE(nng_listener_id(l1) > 0);
NUTS_TRUE(nng_dialer_id(d1) > 0);
NUTS_TRUE(nng_dialer_id(d2) > 0);
@@ -366,14 +370,15 @@ nuts_tran_listen_accept(const char *scheme)
void
nuts_tran_exchange(const char *scheme)
{
- nng_socket s1 = NNG_SOCKET_INITIALIZER;
- nng_socket s2 = NNG_SOCKET_INITIALIZER;
- nng_listener l1 = NNG_LISTENER_INITIALIZER;
- nng_dialer d1 = NNG_LISTENER_INITIALIZER;
- const char *addr;
+ nng_socket s1 = NNG_SOCKET_INITIALIZER;
+ nng_socket s2 = NNG_SOCKET_INITIALIZER;
+ nng_listener l1 = NNG_LISTENER_INITIALIZER;
+ nng_dialer d1 = NNG_LISTENER_INITIALIZER;
+ const char *addr;
+ const nng_url *url;
NUTS_SKIP_IF_IPV6_NEEDED_AND_ABSENT(scheme);
- NUTS_ADDR(addr, scheme);
+ NUTS_ADDR_ZERO(addr, scheme);
NUTS_OPEN(s1);
NUTS_OPEN(s2);
NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_SENDTIMEO, 100));
@@ -381,7 +386,8 @@ nuts_tran_exchange(const char *scheme)
NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_RECVTIMEO, 100));
NUTS_PASS(nng_socket_set_ms(s2, NNG_OPT_RECVTIMEO, 100));
NUTS_PASS(nng_listen(s1, addr, &l1, 0));
- NUTS_PASS(nng_dial(s2, addr, &d1, 0));
+ NUTS_PASS(nng_listener_get_url(l1, &url));
+ NUTS_PASS(nng_dial_url(s2, url, &d1, 0));
NUTS_TRUE(nng_listener_id(l1) > 0);
NUTS_TRUE(nng_dialer_id(d1) > 0);
for (int i = 0; i < 5; i++) {
@@ -397,17 +403,18 @@ nuts_tran_exchange(const char *scheme)
void
nuts_tran_pipe_id(const char *scheme)
{
- nng_socket s1 = NNG_SOCKET_INITIALIZER;
- nng_socket s2 = NNG_SOCKET_INITIALIZER;
- nng_listener l1 = NNG_LISTENER_INITIALIZER;
- nng_dialer d1 = NNG_LISTENER_INITIALIZER;
- const char *addr;
- nng_msg *msg;
- nng_pipe p1;
- nng_pipe p2;
+ nng_socket s1 = NNG_SOCKET_INITIALIZER;
+ nng_socket s2 = NNG_SOCKET_INITIALIZER;
+ nng_listener l1 = NNG_LISTENER_INITIALIZER;
+ nng_dialer d1 = NNG_LISTENER_INITIALIZER;
+ const char *addr;
+ nng_msg *msg;
+ nng_pipe p1;
+ nng_pipe p2;
+ const nng_url *url;
NUTS_SKIP_IF_IPV6_NEEDED_AND_ABSENT(scheme);
- NUTS_ADDR(addr, scheme);
+ NUTS_ADDR_ZERO(addr, scheme);
NUTS_OPEN(s1);
NUTS_OPEN(s2);
NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_SENDTIMEO, 100));
@@ -415,7 +422,8 @@ nuts_tran_pipe_id(const char *scheme)
NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_RECVTIMEO, 100));
NUTS_PASS(nng_socket_set_ms(s2, NNG_OPT_RECVTIMEO, 100));
NUTS_PASS(nng_listen(s1, addr, &l1, 0));
- NUTS_PASS(nng_dial(s2, addr, &d1, 0));
+ NUTS_PASS(nng_listener_get_url(l1, &url));
+ NUTS_PASS(nng_dial_url(s2, url, &d1, 0));
NUTS_TRUE(nng_listener_id(l1) > 0);
NUTS_TRUE(nng_dialer_id(d1) > 0);
NUTS_SEND(s1, "ping");
@@ -438,18 +446,19 @@ nuts_tran_pipe_id(const char *scheme)
void
nuts_tran_huge_msg(const char *scheme, size_t size)
{
- nng_socket s1 = NNG_SOCKET_INITIALIZER;
- nng_socket s2 = NNG_SOCKET_INITIALIZER;
- nng_listener l1 = NNG_LISTENER_INITIALIZER;
- nng_dialer d1 = NNG_LISTENER_INITIALIZER;
- const char *addr;
- char *buf;
- nng_msg *msg;
+ nng_socket s1 = NNG_SOCKET_INITIALIZER;
+ nng_socket s2 = NNG_SOCKET_INITIALIZER;
+ nng_listener l1 = NNG_LISTENER_INITIALIZER;
+ nng_dialer d1 = NNG_LISTENER_INITIALIZER;
+ const char *addr;
+ char *buf;
+ nng_msg *msg;
+ const nng_url *url;
buf = nng_alloc(size);
NUTS_SKIP_IF_IPV6_NEEDED_AND_ABSENT(scheme);
- NUTS_ADDR(addr, scheme);
+ NUTS_ADDR_ZERO(addr, scheme);
NUTS_OPEN(s1);
NUTS_OPEN(s2);
NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_SENDTIMEO, 5000));
@@ -457,7 +466,8 @@ nuts_tran_huge_msg(const char *scheme, size_t size)
NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_RECVTIMEO, 5000));
NUTS_PASS(nng_socket_set_ms(s2, NNG_OPT_RECVTIMEO, 5000));
NUTS_PASS(nng_listen(s1, addr, &l1, 0));
- NUTS_PASS(nng_dial(s2, addr, &d1, 0));
+ NUTS_PASS(nng_listener_get_url(l1, &url));
+ NUTS_PASS(nng_dial_url(s2, url, &d1, 0));
NUTS_TRUE(nng_listener_id(l1) > 0);
NUTS_TRUE(nng_dialer_id(d1) > 0);
for (int i = 0; i < 5; i++) {
@@ -483,12 +493,13 @@ nuts_tran_huge_msg(const char *scheme, size_t size)
void
nuts_tran_msg_props(const char *scheme, void (*check)(nng_msg *))
{
- nng_socket s1 = NNG_SOCKET_INITIALIZER;
- nng_socket s2 = NNG_SOCKET_INITIALIZER;
- nng_listener l1 = NNG_LISTENER_INITIALIZER;
- nng_dialer d1 = NNG_LISTENER_INITIALIZER;
- const char *addr;
- nng_msg *msg;
+ nng_socket s1 = NNG_SOCKET_INITIALIZER;
+ nng_socket s2 = NNG_SOCKET_INITIALIZER;
+ nng_listener l1 = NNG_LISTENER_INITIALIZER;
+ nng_dialer d1 = NNG_LISTENER_INITIALIZER;
+ const char *addr;
+ nng_msg *msg;
+ const nng_url *url;
NUTS_SKIP_IF_IPV6_NEEDED_AND_ABSENT(scheme);
NUTS_ADDR(addr, scheme);
@@ -499,7 +510,8 @@ nuts_tran_msg_props(const char *scheme, void (*check)(nng_msg *))
NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_RECVTIMEO, 100));
NUTS_PASS(nng_socket_set_ms(s2, NNG_OPT_RECVTIMEO, 100));
NUTS_PASS(nng_listen(s1, addr, &l1, 0));
- NUTS_PASS(nng_dial(s2, addr, &d1, 0));
+ NUTS_PASS(nng_listener_get_url(l1, &url));
+ NUTS_PASS(nng_dial_url(s2, url, &d1, 0));
NUTS_TRUE(nng_listener_id(l1) > 0);
NUTS_TRUE(nng_dialer_id(d1) > 0);
NUTS_SEND(s1, "ping");