diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-01-23 22:49:57 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-01-23 22:49:57 -0800 |
| commit | 7df0822d3ed58ee73918cac576c0b07363e84425 (patch) | |
| tree | 5cae69dc0dc3e609260e0bd99bb8743c1c1a28cc /tests/compat_reqrep.c | |
| parent | 91a0b46b6a63f1c2345279b831a02c972e7b1781 (diff) | |
| download | nng-7df0822d3ed58ee73918cac576c0b07363e84425.tar.gz nng-7df0822d3ed58ee73918cac576c0b07363e84425.tar.bz2 nng-7df0822d3ed58ee73918cac576c0b07363e84425.zip | |
Added a bunch more compatibility stuff.
I implemented the reqrep compatibility test, which uncovered a few
semantic issues I had in the REQ/REP protocol, which I've fixed.
There are still missing things. and at least one portion of the req/rep
test suite cannot be enabled until I add tuning of the reconnect timeout,
which is currently way too long (1 sec) for the test suite to work.
Diffstat (limited to 'tests/compat_reqrep.c')
| -rw-r--r-- | tests/compat_reqrep.c | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/tests/compat_reqrep.c b/tests/compat_reqrep.c new file mode 100644 index 00000000..a418b8d9 --- /dev/null +++ b/tests/compat_reqrep.c @@ -0,0 +1,194 @@ +/* + Copyright (c) 2012 Martin Sustrik All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom + the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#include "nng_compat.h" + +#include "compat_testutil.h" + +#define SOCKET_ADDRESS "inproc://test" + +extern void nng_usleep(uint64_t); + +int main () +{ + int rc; + int rep1; + int rep2; + int req1; + int req2; + int resend_ivl; + char buf [7]; + int timeo; + + /* Test req/rep with full socket types. */ + rep1 = test_socket (AF_SP, NN_REP); + test_bind (rep1, SOCKET_ADDRESS); + req1 = test_socket (AF_SP, NN_REQ); + test_connect (req1, SOCKET_ADDRESS); + req2 = test_socket (AF_SP, NN_REQ); + test_connect (req2, SOCKET_ADDRESS); + + /* Check invalid sequence of sends and recvs. */ + rc = nn_send (rep1, "ABC", 3, 0); + nn_assert (rc == -1 && nn_errno () == EFSM); + rc = nn_recv (req1, buf, sizeof (buf), 0); + nn_assert (rc == -1 && nn_errno () == EFSM); + + /* Check fair queueing the requests. */ + test_send (req2, "ABC"); + test_recv (rep1, "ABC"); + test_send (rep1, "ABC"); + test_recv (req2, "ABC"); + + test_send (req1, "ABC"); + test_recv (rep1, "ABC"); + test_send (rep1, "ABC"); + test_recv (req1, "ABC"); + + test_close (rep1); + test_close (req1); + test_close (req2); + + /* Check load-balancing of requests. */ + req1 = test_socket (AF_SP, NN_REQ); + test_bind (req1, SOCKET_ADDRESS); + + rep1 = test_socket (AF_SP, NN_REP); + test_connect (rep1, SOCKET_ADDRESS); + + nng_usleep(10000); // ensure rep1 binds before rep2 + + rep2 = test_socket (AF_SP, NN_REP); + test_connect (rep2, SOCKET_ADDRESS); + + timeo = 500; + test_setsockopt (req1, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); + test_setsockopt (rep1, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); + test_setsockopt (rep2, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); + + // Give time for connections to settle -- required for LB stuff. + nng_usleep(100000); + + test_send (req1, "ABC"); + test_recv (rep1, "ABC"); + test_send (rep1, "ABC"); + test_recv (req1, "ABC"); + + test_send (req1, "ABC"); + test_recv (rep2, "ABC"); + test_send (rep2, "ABC"); + test_recv (req1, "ABC"); + + test_close (rep2); + test_close (rep1); + test_close (req1); + + /* Test re-sending of the request. */ + rep1 = test_socket (AF_SP, NN_REP); + test_bind (rep1, SOCKET_ADDRESS); + req1 = test_socket (AF_SP, NN_REQ); + test_connect (req1, SOCKET_ADDRESS); + resend_ivl = 100; + rc = nn_setsockopt (req1, NN_REQ, NN_REQ_RESEND_IVL, + &resend_ivl, sizeof (resend_ivl)); + errno_assert (rc == 0); + + test_send (req1, "ABC"); + test_recv (rep1, "ABC"); + /* The following waits for request to be resent */ + test_recv (rep1, "ABC"); + + test_close (req1); + test_close (rep1); + + +#if 0 // The default reconnect interval is waaay to large for this to pass. + /* Check sending a request when the peer is not available. (It should + be sent immediatelly when the peer comes online rather than relying + on the resend algorithm. */ + req1 = test_socket (AF_SP, NN_REQ); + timeo = 10; + rc = nn_setsockopt (req1, NN_SOL_SOCKET, NN_RECONNECT_IVL, + &timeo, sizeof (timeo)); + test_send (req1, "ABC"); + test_connect (req1, SOCKET_ADDRESS); + + rep1 = test_socket (AF_SP, NN_REP); + test_bind (rep1, SOCKET_ADDRESS); + timeo = 500; + rc = nn_setsockopt (rep1, NN_SOL_SOCKET, NN_RCVTIMEO, + &timeo, sizeof (timeo)); + printf("RC = %d errno %d (%s)\n", rc, errno, strerror(errno)); + errno_assert (rc == 0); + test_recv (rep1, "ABC"); + + test_close (req1); + test_close (rep1); +#endif + + /* Check removing socket request sent to (It should + be sent immediatelly to other peer rather than relying + on the resend algorithm). */ + req1 = test_socket (AF_SP, NN_REQ); + test_bind (req1, SOCKET_ADDRESS); + rep1 = test_socket (AF_SP, NN_REP); + test_connect (rep1, SOCKET_ADDRESS); + rep2 = test_socket (AF_SP, NN_REP); + nng_usleep(10000); // give time for rep1 to connect + test_connect (rep2, SOCKET_ADDRESS); + + timeo = 500; // Was 200, but Windows occasionally fails at that rate. + test_setsockopt (rep1, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); + test_setsockopt (rep2, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); + + test_send (req1, "ABC"); + /* We got request through rep1 */ + test_recv (rep1, "ABC"); + /* But instead replying we simulate crash */ + test_close (rep1); + /* The rep2 should get request immediately */ + test_recv (rep2, "ABC"); + /* Let's check it's delivered well */ + test_send (rep2, "REPLY"); + test_recv (req1, "REPLY"); + + test_close (req1); + test_close (rep2); + + /* Test cancelling delayed request */ + + req1 = test_socket (AF_SP, NN_REQ); + test_connect (req1, SOCKET_ADDRESS); + test_send (req1, "ABC"); + test_send (req1, "DEF"); + + rep1 = test_socket (AF_SP, NN_REP); + test_bind (rep1, SOCKET_ADDRESS); + timeo = 100; + test_recv (rep1, "DEF"); + + test_close (req1); + test_close (rep1); + + return 0; +} + |
