aboutsummaryrefslogtreecommitdiff
path: root/src/platform
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2024-12-30 15:39:50 -0800
committerGarrett D'Amore <garrett@damore.org>2024-12-30 15:47:04 -0800
commit7f7a8194a60e9f5883866dd8b8c22d4576fc1abc (patch)
treecbd7af87601a5f68e84ca9dcaad890881dec62db /src/platform
parenta74d853241fa21ef4b6352fd39c25b4d4c6a4ab3 (diff)
downloadnng-7f7a8194a60e9f5883866dd8b8c22d4576fc1abc.tar.gz
nng-7f7a8194a60e9f5883866dd8b8c22d4576fc1abc.tar.bz2
nng-7f7a8194a60e9f5883866dd8b8c22d4576fc1abc.zip
ipc test: add a case for IPC that never connects
This involved test-specific hacks, since connect() for UNIX domain sockets always completes synchronously one way or the other, even though it is documented that it might not. This found a bug, with an uninitialized poll FD as well!
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/ipc_stream_test.c32
-rw-r--r--src/platform/posix/posix_ipc.h3
-rw-r--r--src/platform/posix/posix_ipcdial.c42
3 files changed, 72 insertions, 5 deletions
diff --git a/src/platform/ipc_stream_test.c b/src/platform/ipc_stream_test.c
index 7e5e7701..fb3bc493 100644
--- a/src/platform/ipc_stream_test.c
+++ b/src/platform/ipc_stream_test.c
@@ -108,6 +108,37 @@ test_ipc_stream(void)
}
void
+test_ipc_no_connect(void)
+{
+#ifdef NNG_PLATFORM_POSIX
+ nng_stream_dialer *d = NULL;
+ nng_stream_listener *l = NULL;
+ char *url;
+ nng_aio *daio = NULL;
+
+ NUTS_ADDR(url, "ipc");
+ NUTS_PASS(nng_aio_alloc(&daio, NULL, NULL));
+
+ NUTS_PASS(nng_stream_listener_alloc(&l, url));
+ NUTS_PASS(nng_stream_listener_listen(l));
+ nng_aio_set_timeout(daio, 100);
+
+ NUTS_PASS(nng_stream_dialer_alloc(&d, url));
+ NUTS_PASS(nng_stream_dialer_set_bool(d, "test-no-connect", true));
+ nng_stream_dialer_dial(d, daio);
+
+ nng_aio_wait(daio);
+ NUTS_FAIL(nng_aio_result(daio), NNG_ETIMEDOUT);
+
+ nng_aio_free(daio);
+ nng_stream_dialer_free(d);
+ nng_stream_listener_free(l);
+#else
+ NUTS_SKIP("Not POSIX");
+#endif
+}
+
+void
test_ipc_listen_activation(void)
{
#if defined(NNG_PLATFORM_POSIX)
@@ -290,6 +321,7 @@ test_ipc_listen_activation_bad_arg(void)
NUTS_TESTS = {
{ "ipc stream", test_ipc_stream },
+ { "ipc no connect", test_ipc_no_connect },
{ "ipc socket activation", test_ipc_listen_activation },
{ "ipc socket activation busy", test_ipc_listen_activation_busy },
{ "ipc socket activation closed", test_ipc_listen_activation_closed },
diff --git a/src/platform/posix/posix_ipc.h b/src/platform/posix/posix_ipc.h
index e4bdfd97..09cae865 100644
--- a/src/platform/posix/posix_ipc.h
+++ b/src/platform/posix/posix_ipc.h
@@ -40,6 +40,9 @@ struct nni_ipc_dialer {
nni_mtx mtx;
nng_sockaddr sa;
nni_refcnt ref;
+#ifdef NNG_TEST_LIB
+ bool no_connect; // don't actually connect, for testing cancellation,
+#endif
};
extern int nni_posix_ipc_alloc(
diff --git a/src/platform/posix/posix_ipcdial.c b/src/platform/posix/posix_ipcdial.c
index 2b6d547a..e106cfc9 100644
--- a/src/platform/posix/posix_ipcdial.c
+++ b/src/platform/posix/posix_ipcdial.c
@@ -161,7 +161,6 @@ ipc_dialer_dial(void *arg, nni_aio *aio)
{
ipc_dialer *d = arg;
nni_ipc_conn *c;
- nni_posix_pfd *pfd = NULL;
struct sockaddr_storage ss;
size_t len;
int fd;
@@ -201,7 +200,19 @@ ipc_dialer_dial(void *arg, nni_aio *aio)
goto error;
}
c->dial_aio = aio;
- if (connect(fd, (void *) &ss, len) != 0) {
+#ifdef NNG_TEST_LIB
+ // this stanza exists for testing, because IPC doesn't normally
+ // exhibit a delayed connection. But it could, and we need to try
+ // to test it as much as possible.
+ if (d->no_connect) {
+ errno = EINPROGRESS;
+ }
+ if (d->no_connect || (connect(fd, (void *) &ss, len) != 0))
+#else
+ if (connect(fd, (void *) &ss, len) != 0)
+#endif
+
+ {
if (errno != EINPROGRESS && errno != EAGAIN) {
if (errno == ENOENT) {
// No socket present means nobody listening.
@@ -212,7 +223,7 @@ ipc_dialer_dial(void *arg, nni_aio *aio)
goto error;
}
// Asynchronous connect.
- if ((rv = nni_posix_pfd_arm(pfd, NNI_POLL_OUT)) != 0) {
+ if ((rv = nni_posix_pfd_arm(&c->pfd, NNI_POLL_OUT)) != 0) {
goto error;
}
c->dial_aio = NULL;
@@ -221,8 +232,7 @@ ipc_dialer_dial(void *arg, nni_aio *aio)
nni_mtx_unlock(&d->mtx);
return;
}
- // Immediate connect, cool! This probably only happens
- // on loop back, and probably not on every platform.
+ // Immediate connect, cool! For IPC this is typical.
c->dial_aio = NULL;
nni_aio_set_prov_data(aio, NULL);
nni_mtx_unlock(&d->mtx);
@@ -247,11 +257,33 @@ ipc_dialer_get_remaddr(void *arg, void *buf, size_t *szp, nni_type t)
return (nni_copyout_sockaddr(&d->sa, buf, szp, t));
}
+#ifdef NNG_TEST_LIB
+static int
+ipc_dialer_set_test_no_connect(
+ void *arg, const void *buf, size_t sz, nni_type t)
+{
+ ipc_dialer *d = arg;
+ bool no_connect = false;
+
+ (void) nni_copyin_bool(&no_connect, buf, sz, t);
+ nni_mtx_lock(&d->mtx);
+ d->no_connect = no_connect;
+ nni_mtx_unlock(&d->mtx);
+ return (0);
+}
+#endif
+
static const nni_option ipc_dialer_options[] = {
{
.o_name = NNG_OPT_REMADDR,
.o_get = ipc_dialer_get_remaddr,
},
+#ifdef NNG_TEST_LIB
+ {
+ .o_name = "test-no-connect",
+ .o_set = ipc_dialer_set_test_no_connect,
+ },
+#endif
{
.o_name = NULL,
},