diff options
| -rw-r--r-- | src/protocol/reqrep0/reqrep_test.c | 104 | ||||
| -rw-r--r-- | tests/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tests/reqpoll.c | 148 |
3 files changed, 101 insertions, 152 deletions
diff --git a/src/protocol/reqrep0/reqrep_test.c b/src/protocol/reqrep0/reqrep_test.c index 564cf158..09ba9ba3 100644 --- a/src/protocol/reqrep0/reqrep_test.c +++ b/src/protocol/reqrep0/reqrep_test.c @@ -100,9 +100,9 @@ test_rep_send_bad_state(void) void test_req_rep_exchange(void) { - nng_socket req; - nng_socket rep; - nng_msg * msg = NULL; + nng_socket req; + nng_socket rep; + nng_msg * msg = NULL; TEST_CHECK(nng_req0_open(&req) == 0); TEST_CHECK(nng_rep0_open(&rep) == 0); @@ -288,6 +288,101 @@ test_req_cancel_abort_recv(void) TEST_CHECK(nng_close(rep) == 0); } +void +test_req_poll_writeable(void) +{ + int fd; + nng_socket req; + nng_socket rep; + + TEST_NNG_PASS(nng_req0_open(&req)); + TEST_NNG_PASS(nng_rep0_open(&rep)); + TEST_NNG_PASS(nng_getopt_int(req, NNG_OPT_SENDFD, &fd)); + TEST_CHECK(fd >= 0); + + // Not writable before connect. + TEST_CHECK(testutil_pollfd(fd) == false); + + TEST_NNG_PASS(testutil_marry(req, rep)); + + // It should be writable now. + TEST_CHECK(testutil_pollfd(fd) == true); + + // Submit a bunch of jobs. Note that we have to stall a bit + // between each message to let it queue up. + for (int i = 0; i < 10; i++) { + int rv = nng_send(req, "", 0, NNG_FLAG_NONBLOCK); + if (rv == NNG_EAGAIN) { + break; + } + TEST_NNG_PASS(rv); + testutil_sleep(50); + } + TEST_CHECK(testutil_pollfd(fd) == 0); + TEST_NNG_PASS(nng_close(req)); + TEST_NNG_PASS(nng_close(rep)); +} + +void +test_req_poll_readable(void) +{ + int fd; + nng_socket req; + nng_socket rep; + nng_msg * msg; + + TEST_NNG_PASS(nng_req0_open(&req)); + TEST_NNG_PASS(nng_rep0_open(&rep)); + TEST_NNG_PASS(nng_getopt_int(req, NNG_OPT_RECVFD, &fd)); + TEST_CHECK(fd >= 0); + + // Not readable if not connected! + TEST_CHECK(testutil_pollfd(fd) == false); + + // Even after connect (no message yet) + TEST_NNG_PASS(testutil_marry(req, rep)); + TEST_CHECK(testutil_pollfd(fd) == false); + + // But once we send messages, it is. + // We have to send a request, in order to send a reply. + + TEST_NNG_PASS(nng_msg_alloc(&msg, 0)); + TEST_NNG_PASS(nng_msg_append(msg, "xyz", 3)); + TEST_NNG_PASS(nng_sendmsg(req, msg, 0)); + TEST_NNG_PASS(nng_recvmsg(rep, &msg, 0)); // recv on rep + TEST_NNG_PASS(nng_sendmsg(rep, msg, 0)); // echo it back + testutil_sleep(200); // give time for message to arrive + + TEST_CHECK(testutil_pollfd(fd) == true); + + // and receiving makes it no longer pollable + TEST_NNG_PASS(nng_recvmsg(req, &msg, 0)); + nng_msg_free(msg); + TEST_CHECK(testutil_pollfd(fd) == false); + + // TODO verify unsolicited response + + TEST_NNG_PASS(nng_close(req)); + TEST_NNG_PASS(nng_close(rep)); +} + +void +test_req_context_not_pollable(void) +{ + int fd; + nng_socket req; + nng_ctx ctx; + + TEST_NNG_PASS(nng_req0_open(&req)); + TEST_NNG_PASS(nng_ctx_open(&ctx, req)); + TEST_NNG_FAIL( + nng_ctx_getopt_int(ctx, NNG_OPT_SENDFD, &fd), NNG_ENOTSUP); + TEST_NNG_FAIL( + nng_ctx_getopt_int(ctx, NNG_OPT_RECVFD, &fd), NNG_ENOTSUP); + TEST_NNG_PASS(nng_ctx_close(ctx)); + TEST_NNG_PASS(nng_close(req)); +} + TEST_LIST = { { "req rep identity", test_req_rep_identity }, { "resend option", test_resend_option }, @@ -296,5 +391,8 @@ TEST_LIST = { { "req rep exchange", test_req_rep_exchange }, { "req cancel", test_req_cancel }, { "req cancel abort recv", test_req_cancel_abort_recv }, + { "req poll writable", test_req_poll_writeable }, + { "req poll readable", test_req_poll_readable }, + { "req context not pollable", test_req_context_not_pollable }, { NULL, NULL }, }; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d4cdf2e8..bab00692 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -170,7 +170,6 @@ add_nng_test(bus 5) add_nng_test(pipeline 5) add_nng_test(pubsub 5) add_nng_test(reqctx 5) -add_nng_test(reqpoll 5) add_nng_test(reqstress 60) add_nng_test(respondpoll 5) add_nng_test(survey 5) diff --git a/tests/reqpoll.c b/tests/reqpoll.c deleted file mode 100644 index 672c2f05..00000000 --- a/tests/reqpoll.c +++ /dev/null @@ -1,148 +0,0 @@ -// -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.com> -// -// This software is supplied under the terms of the MIT License, a -// copy of which should be located in the distribution where this -// file was obtained (LICENSE.txt). A copy of the license may also be -// found online at https://opensource.org/licenses/MIT. -// - -#ifndef _WIN32 -#include <poll.h> -#include <unistd.h> -#define SOCKET int -#else - -#define poll WSAPoll -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#include <windows.h> -#include <winsock2.h> - -#include <mswsock.h> -#endif - -#include <nng/nng.h> -#include <nng/protocol/reqrep0/rep.h> -#include <nng/protocol/reqrep0/req.h> -#include <nng/supplemental/util/platform.h> - -#include "convey.h" -#include "stubs.h" - -bool -isready(SOCKET fd) -{ - struct pollfd pfd; - pfd.fd = fd; - pfd.events = POLLRDNORM; - pfd.revents = 0; - - switch (poll(&pfd, 1, 0)) { - case 0: - return (false); - case 1: - return (true); - default: - printf("BAD POLL RETURN!\n"); - abort(); - } -} - -TestMain("REQ pollable", { - atexit(nng_fini); - - Convey("Given a REQ/REP pair", { - nng_socket req; - nng_socket rep; - nng_ctx ctx; - - So(nng_req0_open(&req) == 0); - So(nng_rep0_open(&rep) == 0); - So(nng_ctx_open(&ctx, req) == 0); - - Reset({ - nng_ctx_close(ctx); - nng_close(req); - nng_close(rep); - }); - So(nng_listen(rep, "inproc://ctx1", NULL, 0) == 0); - - Convey("REQ ctx not pollable", { - int fd; - So(nng_ctx_open(&ctx, req) == 0); - Reset({ nng_ctx_close(ctx); }); - So(nng_ctx_getopt_int(ctx, NNG_OPT_SENDFD, &fd) == - NNG_ENOTSUP); - So(nng_ctx_getopt_int(ctx, NNG_OPT_RECVFD, &fd) == - NNG_ENOTSUP); - }); - - Convey("REQ starts not writable", { - int fd; - - So(nng_getopt_int(req, NNG_OPT_SENDFD, &fd) == 0); - So(isready(fd) == false); - - Convey("And becomes writable on connect", { - So(nng_dial(req, "inproc://ctx1", NULL, 0) == - 0); - nng_msleep(100); - So(isready(fd) == true); - - Convey("Not writable with message pending", { - for (int i = 0; i < 10; i++) { - nng_msg *m; - So(nng_msg_alloc(&m, 0) == 0); - // Fill intermediate queues. - if (nng_sendmsg(req, m, - NNG_FLAG_NONBLOCK) != - 0) { - nng_msg_free(m); - } - } - So(isready(fd) == false); - }); - }); - }); - - Convey("REQ starts not readable", { - int fd; - - So(nng_getopt_int(req, NNG_OPT_RECVFD, &fd) == 0); - So(isready(fd) == false); - - Convey("And doesn't become readable on connect", { - So(nng_dial(req, "inproc://ctx1", NULL, 0) == - 0); - nng_msleep(100); - So(isready(fd) == false); - }); - }); - - Convey("REQ becomes readable", { - int fd; - nng_msg *msg; - - So(nng_dial(req, "inproc://ctx1", NULL, 0) == 0); - - So(nng_msg_alloc(&msg, 0) == 0); - So(nng_getopt_int(req, NNG_OPT_RECVFD, &fd) == 0); - So(isready(fd) == false); - So(nng_msg_append(msg, "xyz", 3) == 0); - So(nng_sendmsg(req, msg, 0) == 0); - So(nng_recvmsg(rep, &msg, 0) == 0); // recv on rep - So(nng_sendmsg(rep, msg, 0) == 0); // echo it back - nng_msleep(200); // give time for message to arrive - So(isready(fd) == true); - Convey("And is no longer readable after receive", { - So(nng_recvmsg(req, &msg, 0) == 0); - nng_msg_free(msg); - So(isready(fd) == false); - }); - }); - }); -}) |
