int XS_TEST_MAIN () { fprintf (stderr, "hwm test running...\n"); void *ctx = xs_init (); assert (ctx); // Create pair of socket, each with high watermark of 2. Thus the total // buffer space should be 4 messages. void *sb = xs_socket (ctx, XS_PULL); assert (sb); int hwm = 2; int rc = xs_setsockopt (sb, XS_RCVHWM, &hwm, sizeof (hwm)); assert (rc == 0); rc = xs_bind (sb, "inproc://a"); assert (rc != -1); void *sc = xs_socket (ctx, XS_PUSH); assert (sc); rc = xs_setsockopt (sc, XS_SNDHWM, &hwm, sizeof (hwm)); assert (rc == 0); rc = xs_connect (sc, "inproc://a"); assert (rc != -1); // Try to send 10 messages. Only 4 should succeed. for (int i = 0; i < 10; i++) { rc = xs_send (sc, NULL, 0, XS_DONTWAIT); if (i < 4) assert (rc == 0); else assert (rc < 0 && errno == EAGAIN); } // There should be now 4 messages pending, consume them. for (int i = 0; i != 4; i++) { rc = xs_recv (sb, NULL, 0, 0); assert (rc == 0); } // Now it should be possible to send one more. rc = xs_send (sc, NULL, 0, 0); assert (rc == 0); // Consume the remaining message. rc = xs_recv (sb, NULL, 0, 0); assert (rc == 0); rc = xs_close (sc); assert (rc == 0); rc = xs_close (sb); assert (rc == 0); rc = xs_term (ctx); assert (rc == 0); return 0; }
int XS_TEST_MAIN () { fprintf (stderr, "linger test running...\n"); // Create socket. void *ctx = xs_init (); assert (ctx); void *s = xs_socket (ctx, XS_PUSH); assert (s); // Set linger to 0.1 second. int linger = 100; int rc = xs_setsockopt (s, XS_LINGER, &linger, sizeof (int)); // Connect to non-existent endpoing. assert (rc == 0); rc = xs_connect (s, "tcp://127.0.0.1:5560"); assert (rc == 0); // Send a message. rc = xs_send (s, "r", 1, 0); assert (rc == 1); // Close the socket. rc = xs_close (s); assert (rc == 0); // Terminate the context. This should take 0.1 second. void *watch = xs_stopwatch_start (); rc = xs_term (ctx); assert (rc == 0); int ms = (int) xs_stopwatch_stop (watch) / 1000; #if !defined _WIN32 || !defined _DEBUG assert (ms > 50 && ms < 150); #endif return 0; }
int zmq_setsockopt (void *s, int option, const void *optval, size_t optvallen) { switch (option) { case ZMQ_AFFINITY: case ZMQ_IDENTITY: case ZMQ_SUBSCRIBE: case ZMQ_UNSUBSCRIBE: case ZMQ_LINGER: case ZMQ_RECONNECT_IVL: case ZMQ_RECONNECT_IVL_MAX: case ZMQ_BACKLOG: return xs_setsockopt (s, option, optval, optvallen); case ZMQ_HWM: { if (optvallen != sizeof (uint64_t)) { errno = EINVAL; return -1; } int val = (int) *(uint64_t*) optval; int rc = xs_setsockopt (s, XS_SNDHWM, &val, sizeof (int)); if (rc < 0) return -1; return xs_setsockopt (s, XS_RCVHWM, &val, sizeof (int)); } case ZMQ_RATE: { if (optvallen != sizeof (int64_t)) { errno = EINVAL; return -1; } int val = (int) *(int64_t*) optval; return xs_setsockopt (s, option, &val, sizeof (int)); } case ZMQ_RECOVERY_IVL: { if (optvallen != sizeof (int64_t)) { errno = EINVAL; return -1; } int val = ((int) *(int64_t*) optval) * 1000; return xs_setsockopt (s, option, &val, sizeof (int)); } case ZMQ_RECOVERY_IVL_MSEC: { if (optvallen != sizeof (int64_t)) { errno = EINVAL; return -1; } int val = (int) *(int64_t*) optval; return xs_setsockopt (s, option, &val, sizeof (int)); } case ZMQ_SNDBUF: case ZMQ_RCVBUF: { if (optvallen != sizeof (uint64_t)) { errno = EINVAL; return -1; } int val = (int) *(uint64_t*) optval; return xs_setsockopt (s, option, &val, sizeof (int)); } default: errno = EINVAL; return -1; } }
int XS_TEST_MAIN () { fprintf (stderr, "sub_forward test running...\n"); void *ctx = xs_init (); assert (ctx); // First, create an intermediate device. void *xpub = xs_socket (ctx, XS_XPUB); assert (xpub); int rc = xs_bind (xpub, "tcp://127.0.0.1:5560"); assert (rc == 0); void *xsub = xs_socket (ctx, XS_XSUB); assert (xsub); rc = xs_bind (xsub, "tcp://127.0.0.1:5561"); assert (rc == 0); // Create a publisher. void *pub = xs_socket (ctx, XS_PUB); assert (pub); rc = xs_connect (pub, "tcp://127.0.0.1:5561"); assert (rc == 0); // Create a subscriber. void *sub = xs_socket (ctx, XS_SUB); assert (sub); rc = xs_connect (sub, "tcp://127.0.0.1:5560"); assert (rc == 0); // Subscribe for all messages. rc = xs_setsockopt (sub, XS_SUBSCRIBE, "", 0); assert (rc == 0); // Pass the subscription upstream through the device. char buff [32]; rc = xs_recv (xpub, buff, sizeof (buff), 0); assert (rc >= 0); rc = xs_send (xsub, buff, rc, 0); assert (rc >= 0); // Wait a bit till the subscription gets to the publisher. sleep (1); // Send an empty message. rc = xs_send (pub, NULL, 0, 0); assert (rc == 0); // Pass the message downstream through the device. rc = xs_recv (xsub, buff, sizeof (buff), 0); assert (rc >= 0); rc = xs_send (xpub, buff, rc, 0); assert (rc >= 0); // Receive the message in the subscriber. rc = xs_recv (sub, buff, sizeof (buff), 0); assert (rc == 0); // Clean up. rc = xs_close (xpub); assert (rc == 0); rc = xs_close (xsub); assert (rc == 0); rc = xs_close (pub); assert (rc == 0); rc = xs_close (sub); assert (rc == 0); rc = xs_term (ctx); assert (rc == 0); return 0 ; }
int XS_TEST_MAIN () { int rc; char buf [32]; fprintf (stderr, "survey test running...\n"); // Create the basic infrastructure. void *ctx = xs_init (); assert (ctx); void *xsurveyor = xs_socket (ctx, XS_XSURVEYOR); assert (xsurveyor); rc = xs_bind (xsurveyor, "inproc://a"); assert (rc != -1); void *xrespondent = xs_socket (ctx, XS_XRESPONDENT); assert (xrespondent); rc = xs_bind (xrespondent, "inproc://b"); assert (rc != -1); void *surveyor = xs_socket (ctx, XS_SURVEYOR); assert (surveyor); rc = xs_connect (surveyor, "inproc://b"); assert (rc != -1); void *respondent1 = xs_socket (ctx, XS_RESPONDENT); assert (respondent1); rc = xs_connect (respondent1, "inproc://a"); assert (rc != -1); void *respondent2 = xs_socket (ctx, XS_RESPONDENT); assert (respondent2); rc = xs_connect (respondent2, "inproc://a"); assert (rc != -1); // Send the survey. rc = xs_send (surveyor, "ABC", 3, 0); assert (rc == 3); // Forward the survey through the intermediate device. // Survey consist of identity (4 bytes), survey ID (4 bytes) and the body. rc = xs_recv (xrespondent, buf, sizeof (buf), 0); assert (rc == 4); rc = xs_send (xsurveyor, buf, 4, XS_SNDMORE); assert (rc == 4); rc = xs_recv (xrespondent, buf, sizeof (buf), 0); assert (rc == 4); rc = xs_send (xsurveyor, buf, 4, XS_SNDMORE); assert (rc == 4); rc = xs_recv (xrespondent, buf, sizeof (buf), 0); assert (rc == 3); rc = xs_send (xsurveyor, buf, 3, 0); assert (rc == 3); // Respondent 1 responds to the survey. rc = xs_recv (respondent1, buf, sizeof (buf), 0); assert (rc == 3); rc = xs_send (respondent1, "DE", 2, 0); assert (rc == 2); // Forward the response through the intermediate device. rc = xs_recv (xsurveyor, buf, sizeof (buf), 0); assert (rc == 4); rc = xs_send (xrespondent, buf, 4, XS_SNDMORE); assert (rc == 4); rc = xs_recv (xsurveyor, buf, sizeof (buf), 0); assert (rc == 4); rc = xs_send (xrespondent, buf, 4, XS_SNDMORE); assert (rc == 4); rc = xs_recv (xsurveyor, buf, sizeof (buf), 0); assert (rc == 2); rc = xs_send (xrespondent, buf, 2, 0); assert (rc == 2); // Surveyor gets the response. rc = xs_recv (surveyor, buf, sizeof (buf), 0); assert (rc == 2); // Respondent 2 responds to the survey. rc = xs_recv (respondent2, buf, sizeof (buf), 0); assert (rc == 3); rc = xs_send (respondent2, "FGHI", 4, 0); assert (rc == 4); // Forward the response through the intermediate device. rc = xs_recv (xsurveyor, buf, sizeof (buf), 0); assert (rc == 4); rc = xs_send (xrespondent, buf, 4, XS_SNDMORE); assert (rc == 4); rc = xs_recv (xsurveyor, buf, sizeof (buf), 0); assert (rc == 4); rc = xs_send (xrespondent, buf, 4, XS_SNDMORE); assert (rc == 4); rc = xs_recv (xsurveyor, buf, sizeof (buf), 0); assert (rc == 4); rc = xs_send (xrespondent, buf, 4, 0); assert (rc == 4); // Surveyor gets the response. rc = xs_recv (surveyor, buf, sizeof (buf), 0); assert (rc == 4); // Now let's test whether survey timeout works as expected. int timeout = 100; rc = xs_setsockopt (surveyor, XS_SURVEY_TIMEOUT, &timeout, sizeof (int)); assert (rc == 0); rc = xs_send (surveyor, "ABC", 3, 0); assert (rc == 3); void *watch = xs_stopwatch_start (); rc = xs_recv (surveyor, buf, sizeof (buf), 0); assert (rc == - 1 && errno == EAGAIN); unsigned long elapsed = xs_stopwatch_stop (watch) / 1000; time_assert (elapsed, (unsigned long) timeout); // Test whether responses for old surveys are discarded. First, // initiate new survey. rc = xs_setsockopt (surveyor, XS_SURVEY_TIMEOUT, &timeout, sizeof (int)); assert (rc == 0); rc = xs_send (surveyor, "DE", 2, 0); assert (rc == 2); // Read, process and reply to the old survey. rc = xs_recv (xrespondent, buf, sizeof (buf), 0); assert (rc == 4); rc = xs_send (xrespondent, buf, 4, XS_SNDMORE); assert (rc == 4); rc = xs_recv (xrespondent, buf, sizeof (buf), 0); assert (rc == 4); rc = xs_send (xrespondent, buf, 4, XS_SNDMORE); assert (rc == 4); rc = xs_recv (xrespondent, buf, sizeof (buf), 0); assert (rc == 3); rc = xs_send (xrespondent, buf, 3, 0); assert (rc == 3); // Read, process and reply to the new survey. rc = xs_recv (xrespondent, buf, sizeof (buf), 0); assert (rc == 4); rc = xs_send (xrespondent, buf, 4, XS_SNDMORE); assert (rc == 4); rc = xs_recv (xrespondent, buf, sizeof (buf), 0); assert (rc == 4); rc = xs_send (xrespondent, buf, 4, XS_SNDMORE); assert (rc == 4); rc = xs_recv (xrespondent, buf, sizeof (buf), 0); assert (rc == 2); rc = xs_send (xrespondent, buf, 2, 0); assert (rc == 2); // Get the response and check it's the response to the new survey and // that response to the old survey was silently discarded. rc = xs_recv (surveyor, buf, sizeof (buf), 0); assert (rc == 2); rc = xs_close (respondent2); assert (rc == 0); rc = xs_close (respondent1); assert (rc == 0); rc = xs_close (surveyor); assert (rc == 0); rc = xs_close (xrespondent); assert (rc == 0); rc = xs_close (xsurveyor); assert (rc == 0); rc = xs_term (ctx); assert (rc == 0); return 0 ; }