From 597cc5edd624525563e6549dc0057eca2a51c81d Mon Sep 17 00:00:00 2001 From: Micah Anderson Date: Tue, 11 Nov 2014 13:30:46 -0500 Subject: upgrade to new version --- tests/testutil.hpp | 294 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 tests/testutil.hpp (limited to 'tests/testutil.hpp') diff --git a/tests/testutil.hpp b/tests/testutil.hpp new file mode 100644 index 0000000..7a42379 --- /dev/null +++ b/tests/testutil.hpp @@ -0,0 +1,294 @@ +/* + Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file + + This file is part of 0MQ. + + 0MQ is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 0MQ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef __TESTUTIL_HPP_INCLUDED__ +#define __TESTUTIL_HPP_INCLUDED__ + +#include "../include/zmq.h" +#include "../include/zmq_utils.h" +#include "platform.hpp" + +// This defines the settle time used in tests; raise this if we +// get test failures on slower systems due to binds/connects not +// settled. Tested to work reliably at 1 msec on a fast PC. +#define SETTLE_TIME 10 // In msec + +#undef NDEBUG +#include +#include +#include +#include + +#if defined _WIN32 +# if defined _MSC_VER +# include +# pragma warning(disable:4996) +# endif +#else +# include +# include +# include +# include +#endif + +// Bounce a message from client to server and back +// For REQ/REP or DEALER/DEALER pairs only + +void +bounce (void *server, void *client) +{ + const char *content = "12345678ABCDEFGH12345678abcdefgh"; + + // Send message from client to server + int rc = zmq_send (client, content, 32, ZMQ_SNDMORE); + assert (rc == 32); + rc = zmq_send (client, content, 32, 0); + assert (rc == 32); + + // Receive message at server side + char buffer [32]; + rc = zmq_recv (server, buffer, 32, 0); + assert (rc == 32); + // Check that message is still the same + assert (memcmp (buffer, content, 32) == 0); + int rcvmore; + size_t sz = sizeof (rcvmore); + rc = zmq_getsockopt (server, ZMQ_RCVMORE, &rcvmore, &sz); + assert (rc == 0); + assert (rcvmore); + rc = zmq_recv (server, buffer, 32, 0); + assert (rc == 32); + // Check that message is still the same + assert (memcmp (buffer, content, 32) == 0); + rc = zmq_getsockopt (server, ZMQ_RCVMORE, &rcvmore, &sz); + assert (rc == 0); + assert (!rcvmore); + + // Send two parts back to client + rc = zmq_send (server, buffer, 32, ZMQ_SNDMORE); + assert (rc == 32); + rc = zmq_send (server, buffer, 32, 0); + assert (rc == 32); + + // Receive the two parts at the client side + rc = zmq_recv (client, buffer, 32, 0); + assert (rc == 32); + // Check that message is still the same + assert (memcmp (buffer, content, 32) == 0); + rc = zmq_getsockopt (client, ZMQ_RCVMORE, &rcvmore, &sz); + assert (rc == 0); + assert (rcvmore); + rc = zmq_recv (client, buffer, 32, 0); + assert (rc == 32); + // Check that message is still the same + assert (memcmp (buffer, content, 32) == 0); + rc = zmq_getsockopt (client, ZMQ_RCVMORE, &rcvmore, &sz); + assert (rc == 0); + assert (!rcvmore); +} + +// Same as bounce, but expect messages to never arrive +// for security or subscriber reasons. + +void +expect_bounce_fail (void *server, void *client) +{ + const char *content = "12345678ABCDEFGH12345678abcdefgh"; + char buffer [32]; + + int timeout = 150; + int rc; + rc = zmq_setsockopt (client, ZMQ_SNDTIMEO, &timeout, sizeof (int)); + assert (rc == 0); + rc = zmq_setsockopt (client, ZMQ_RCVTIMEO, &timeout, sizeof (int)); + assert (rc == 0); + rc = zmq_setsockopt (server, ZMQ_SNDTIMEO, &timeout, sizeof (int)); + assert (rc == 0); + rc = zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (int)); + assert (rc == 0); + + // Send message from client to server (may fail) + rc = zmq_send (client, content, 32, ZMQ_SNDMORE); + if (rc == -1 && zmq_errno () == EAGAIN) + return; + assert (rc == 32); + rc = zmq_send (client, content, 32, 0); + if (rc == -1 && zmq_errno () == EAGAIN) + return; + assert (rc == 32); + + // Receive message at server side (should not succeed) + rc = zmq_recv (server, buffer, 32, 0); + assert (rc == -1); + assert (zmq_errno () == EAGAIN); + + // Send message from server to client to test other direction + rc = zmq_send (server, content, 32, ZMQ_SNDMORE); + assert (rc == 32); + rc = zmq_send (server, content, 32, 0); + assert (rc == 32); + + // Receive message at client side (should not succeed) + rc = zmq_recv (client, buffer, 32, 0); + assert (rc == -1); + assert (zmq_errno () == EAGAIN); +} + +// Receive 0MQ string from socket and convert into C string +// Caller must free returned string. Returns NULL if the context +// is being terminated. +char * +s_recv (void *socket) { + char buffer [256]; + int size = zmq_recv (socket, buffer, 255, 0); + if (size == -1) + return NULL; + if (size > 255) + size = 255; + buffer [size] = 0; + return strdup (buffer); +} + +// Convert C string to 0MQ string and send to socket +int +s_send (void *socket, const char *string) { + int size = zmq_send (socket, string, strlen (string), 0); + return size; +} + +// Sends string as 0MQ string, as multipart non-terminal +int +s_sendmore (void *socket, const char *string) { + int size = zmq_send (socket, string, strlen (string), ZMQ_SNDMORE); + return size; +} + +#define streq(s1,s2) (!strcmp ((s1), (s2))) +#define strneq(s1,s2) (strcmp ((s1), (s2))) + +const char *SEQ_END = (const char *) 1; + +// Sends a message composed of frames that are C strings or null frames. +// The list must be terminated by SEQ_END. +// Example: s_send_seq (req, "ABC", 0, "DEF", SEQ_END); +void s_send_seq (void *socket, ...) +{ + va_list ap; + va_start (ap, socket); + const char * data = va_arg (ap, const char *); + while (true) + { + const char * prev = data; + data = va_arg (ap, const char *); + bool end = data == SEQ_END; + + if (!prev) { + int rc = zmq_send (socket, 0, 0, end ? 0 : ZMQ_SNDMORE); + assert (rc != -1); + } + else { + int rc = zmq_send (socket, prev, strlen (prev)+1, end ? 0 : ZMQ_SNDMORE); + assert (rc != -1); + } + if (end) + break; + } + va_end (ap); +} + +// Receives message a number of frames long and checks that the frames have +// the given data which can be either C strings or 0 for a null frame. +// The list must be terminated by SEQ_END. +// Example: s_recv_seq (rep, "ABC", 0, "DEF", SEQ_END); +void s_recv_seq (void *socket, ...) +{ + zmq_msg_t msg; + zmq_msg_init (&msg); + + int more; + size_t more_size = sizeof(more); + + va_list ap; + va_start (ap, socket); + const char * data = va_arg (ap, const char *); + + while (true) { + int rc = zmq_msg_recv (&msg, socket, 0); + assert (rc != -1); + + if (!data) + assert (zmq_msg_size (&msg) == 0); + else + assert (strcmp (data, (const char *)zmq_msg_data (&msg)) == 0); + + data = va_arg (ap, const char *); + bool end = data == SEQ_END; + + rc = zmq_getsockopt (socket, ZMQ_RCVMORE, &more, &more_size); + assert (rc == 0); + + assert (!more == end); + if (end) + break; + } + va_end (ap); + + zmq_msg_close (&msg); +} + + +// Sets a zero linger period on a socket and closes it. +void close_zero_linger (void *socket) +{ + int linger = 0; + int rc = zmq_setsockopt (socket, ZMQ_LINGER, &linger, sizeof(linger)); + assert (rc == 0 || errno == ETERM); + rc = zmq_close (socket); + assert (rc == 0); +} + +void setup_test_environment() +{ +#if defined _WIN32 +# if defined _MSC_VER + _set_abort_behavior( 0, _WRITE_ABORT_MSG); + _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE ); + _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR ); +# endif +#endif +#if defined __MVS__ + // z/OS UNIX System Services: Ignore SIGPIPE during test runs, as a + // workaround for no SO_NOGSIGPIPE socket option. + signal(SIGPIPE, SIG_IGN); +#endif +} + +// Provide portable millisecond sleep +// http://www.cplusplus.com/forum/unices/60161/ http://en.cppreference.com/w/cpp/thread/sleep_for +void msleep (int milliseconds) +{ +#ifdef ZMQ_HAVE_WINDOWS + Sleep (milliseconds); +#else + usleep (static_cast (milliseconds) * 1000); +#endif +} + + +#endif -- cgit v1.2.3