testutil_unity.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MPL-2.0 */
2 #include "testutil_unity.hpp"
3 
4 #include <stdlib.h>
5 #include <string.h>
6 
7 #ifdef _WIN32
8 #include <direct.h>
9 #else
10 #include <unistd.h>
11 #endif
12 
14  const char *msg_,
15  const char *expr_,
16  int line_)
17 {
18  if (rc_ == -1) {
19  char buffer[512];
20  buffer[sizeof (buffer) - 1] =
21  0; // to ensure defined behavior with VC++ <= 2013
22  snprintf (buffer, sizeof (buffer) - 1,
23  "%s failed%s%s%s, errno = %i (%s)", expr_,
24  msg_ ? " (additional info: " : "", msg_ ? msg_ : "",
25  msg_ ? ")" : "", zmq_errno (), zmq_strerror (zmq_errno ()));
27  }
28  return rc_;
29 }
30 
32  int rc_, const char *msg_, const char *expr_, int line_, bool zero)
33 {
34  if (rc_ == -1 || (zero && rc_ != 0)) {
35 #if defined ZMQ_HAVE_WINDOWS
36  int current_errno = WSAGetLastError ();
37 #else
38  int current_errno = errno;
39 #endif
40 
41  char buffer[512];
42  buffer[sizeof (buffer) - 1] =
43  0; // to ensure defined behavior with VC++ <= 2013
44  snprintf (
45  buffer, sizeof (buffer) - 1, "%s failed%s%s%s with %d, errno = %i/%s",
46  expr_, msg_ ? " (additional info: " : "", msg_ ? msg_ : "",
47  msg_ ? ")" : "", rc_, current_errno, strerror (current_errno));
49  }
50  return rc_;
51 }
52 
54  const char *msg_,
55  const char *expr_,
56  int line_)
57 {
58  return test_assert_success_message_raw_errno_helper (rc_, msg_, expr_,
59  line_, true);
60 }
61 
63  int rc_, int expected_errno_, const char *msg_, const char *expr_, int line_)
64 {
65  char buffer[512];
66  buffer[sizeof (buffer) - 1] =
67  0; // to ensure defined behavior with VC++ <= 2013
68  if (rc_ != -1) {
69  snprintf (buffer, sizeof (buffer) - 1,
70  "%s was unexpectedly successful%s%s%s, expected "
71  "errno = %i, actual return value = %i",
72  expr_, msg_ ? " (additional info: " : "", msg_ ? msg_ : "",
73  msg_ ? ")" : "", expected_errno_, rc_);
75  } else {
76 #if defined ZMQ_HAVE_WINDOWS
77  int current_errno = WSAGetLastError ();
78 #else
79  int current_errno = errno;
80 #endif
81  if (current_errno != expected_errno_) {
82  snprintf (buffer, sizeof (buffer) - 1,
83  "%s failed with an unexpected error%s%s%s, expected "
84  "errno = %i, actual errno = %i",
85  expr_, msg_ ? " (additional info: " : "",
86  msg_ ? msg_ : "", msg_ ? ")" : "", expected_errno_,
87  current_errno);
89  }
90  }
91  return rc_;
92 }
93 
94 void send_string_expect_success (void *socket_, const char *str_, int flags_)
95 {
96  const size_t len = str_ ? strlen (str_) : 0;
97  const int rc = zmq_send (socket_, str_, len, flags_);
98  TEST_ASSERT_EQUAL_INT ((int) len, rc);
99 }
100 
101 void recv_string_expect_success (void *socket_, const char *str_, int flags_)
102 {
103  const size_t len = str_ ? strlen (str_) : 0;
104  char buffer[255];
106  "recv_string_expect_success cannot be "
107  "used for strings longer than 255 "
108  "characters");
109 
110  const int rc = TEST_ASSERT_SUCCESS_ERRNO (
111  zmq_recv (socket_, buffer, sizeof (buffer), flags_));
112  TEST_ASSERT_EQUAL_INT ((int) len, rc);
113  if (str_)
115 }
116 
117 static void *internal_manage_test_context (bool init_, bool clear_)
118 {
119  static void *test_context = NULL;
120  if (clear_) {
121  TEST_ASSERT_NOT_NULL (test_context);
122  TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_term (test_context));
123  test_context = NULL;
124  } else {
125  if (init_) {
126  TEST_ASSERT_NULL (test_context);
127  test_context = zmq_ctx_new ();
128  TEST_ASSERT_NOT_NULL (test_context);
129  }
130  }
131  return test_context;
132 }
133 
134 static void internal_manage_test_sockets (void *socket_, bool add_)
135 {
136  static void *test_sockets[MAX_TEST_SOCKETS];
137  static size_t test_socket_count = 0;
138  if (!socket_) {
139  TEST_ASSERT_FALSE (add_);
140 
141  // force-close all sockets
142  if (test_socket_count) {
143  for (size_t i = 0; i < test_socket_count; ++i) {
144  close_zero_linger (test_sockets[i]);
145  }
146  fprintf (stderr,
147  "WARNING: Forced closure of %i sockets, this is an "
148  "implementation error unless the test case failed\n",
149  static_cast<int> (test_socket_count));
150  test_socket_count = 0;
151  }
152  } else {
153  if (add_) {
154  ++test_socket_count;
156  "MAX_TEST_SOCKETS must be "
157  "increased, or you cannot use the "
158  "test context");
159  test_sockets[test_socket_count - 1] = socket_;
160  } else {
161  bool found = false;
162  for (size_t i = 0; i < test_socket_count; ++i) {
163  if (test_sockets[i] == socket_) {
164  found = true;
165  }
166  if (found) {
167  if (i < test_socket_count)
168  test_sockets[i] = test_sockets[i + 1];
169  }
170  }
172  "Attempted to close a socket that was "
173  "not created by test_context_socket");
174  --test_socket_count;
175  }
176  }
177 }
178 
180 {
181  internal_manage_test_context (true, false);
182 }
183 
185 {
186  return internal_manage_test_context (false, false);
187 }
188 
190 {
191  // this condition allows an explicit call to teardown_test_context from a
192  // test. if this is never used, it should probably be removed, to detect
193  // misuses
194  if (get_test_context ()) {
196  internal_manage_test_context (false, true);
197  }
198 }
199 
200 void *test_context_socket (int type_)
201 {
202  void *const socket = zmq_socket (get_test_context (), type_);
203  TEST_ASSERT_NOT_NULL (socket);
204  internal_manage_test_sockets (socket, true);
205  return socket;
206 }
207 
208 void *test_context_socket_close (void *socket_)
209 {
211  internal_manage_test_sockets (socket_, false);
212  return socket_;
213 }
214 
216 {
217  const int linger = 0;
218  int rc = zmq_setsockopt (socket_, ZMQ_LINGER, &linger, sizeof (linger));
219  TEST_ASSERT_TRUE (rc == 0 || zmq_errno () == ETERM);
220  return test_context_socket_close (socket_);
221 }
222 
223 void test_bind (void *socket_,
224  const char *bind_address_,
225  char *my_endpoint_,
226  size_t len_)
227 {
228  TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (socket_, bind_address_));
230  zmq_getsockopt (socket_, ZMQ_LAST_ENDPOINT, my_endpoint_, &len_));
231 }
232 
233 void bind_loopback (void *socket_, int ipv6_, char *my_endpoint_, size_t len_)
234 {
235  if (ipv6_ && !is_ipv6_available ()) {
236  TEST_IGNORE_MESSAGE ("ipv6 is not available");
237  }
238 
240  zmq_setsockopt (socket_, ZMQ_IPV6, &ipv6_, sizeof (int)));
241 
242  test_bind (socket_, ipv6_ ? "tcp://[::1]:*" : "tcp://127.0.0.1:*",
243  my_endpoint_, len_);
244 }
245 
246 void bind_loopback_ipv4 (void *socket_, char *my_endpoint_, size_t len_)
247 {
248  bind_loopback (socket_, false, my_endpoint_, len_);
249 }
250 
251 void bind_loopback_ipv6 (void *socket_, char *my_endpoint_, size_t len_)
252 {
253  bind_loopback (socket_, true, my_endpoint_, len_);
254 }
255 
256 void bind_loopback_ipc (void *socket_, char *my_endpoint_, size_t len_)
257 {
258  if (!zmq_has ("ipc")) {
259  TEST_IGNORE_MESSAGE ("ipc is not available");
260  }
261 
262  test_bind (socket_, "ipc://*", my_endpoint_, len_);
263 }
264 
265 void bind_loopback_tipc (void *socket_, char *my_endpoint_, size_t len_)
266 {
267  if (!is_tipc_available ()) {
268  TEST_IGNORE_MESSAGE ("tipc is not available");
269  }
270 
271  test_bind (socket_, "tipc://<*>", my_endpoint_, len_);
272 }
273 
274 #if defined(ZMQ_HAVE_IPC)
275 void make_random_ipc_endpoint (char *out_endpoint_)
276 {
277 #ifdef ZMQ_HAVE_WINDOWS
278  char random_file[MAX_PATH];
279 
280  {
281  const errno_t rc = tmpnam_s (random_file);
282  TEST_ASSERT_EQUAL (0, rc);
283  }
284 
285  // TODO or use CreateDirectoryA and specify permissions?
286  const int rc = _mkdir (random_file);
287  TEST_ASSERT_EQUAL (0, rc);
288 
289  strcat (random_file, "/ipc");
290 
291 #else
292  char random_file[16];
293  strcpy (random_file, "tmpXXXXXX");
294 
295 #ifdef HAVE_MKDTEMP
296  TEST_ASSERT_TRUE (mkdtemp (random_file));
297  strcat (random_file, "/ipc");
298 #else
299  int fd = mkstemp (random_file);
300  TEST_ASSERT_TRUE (fd != -1);
301  close (fd);
302 #endif
303 #endif
304 
305  strcpy (out_endpoint_, "ipc://");
306  strcat (out_endpoint_, random_file);
307 }
308 #endif
zmq_strerror
const ZMQ_EXPORT char * zmq_strerror(int errnum_)
Definition: zmq.cpp:96
bind_loopback_tipc
void bind_loopback_tipc(void *socket_, char *my_endpoint_, size_t len_)
Definition: testutil_unity.cpp:265
TEST_ASSERT_TRUE_MESSAGE
#define TEST_ASSERT_TRUE_MESSAGE(condition, message)
Definition: unity.h:313
TEST_ASSERT_EQUAL_STRING_LEN
#define TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len)
Definition: unity.h:236
NULL
NULL
Definition: test_security_zap.cpp:405
UNITY_TEST_FAIL
#define UNITY_TEST_FAIL(line, message)
Definition: unity_internals.h:647
zmq_errno
ZMQ_EXPORT int zmq_errno(void)
Definition: zmq.cpp:101
test_assert_failure_message_raw_errno_helper
int test_assert_failure_message_raw_errno_helper(int rc_, int expected_errno_, const char *msg_, const char *expr_, int line_)
Definition: testutil_unity.cpp:62
MAX_TEST_SOCKETS
#define MAX_TEST_SOCKETS
Definition: testutil_unity.hpp:183
TEST_ASSERT_TRUE
#define TEST_ASSERT_TRUE(condition)
Definition: unity.h:121
is_ipv6_available
int is_ipv6_available()
Definition: testutil.cpp:236
zmq_ctx_new
ZMQ_EXPORT void * zmq_ctx_new(void)
Definition: zmq.cpp:109
zmq_has
ZMQ_EXPORT int zmq_has(const char *capability_)
Definition: zmq.cpp:1763
ZMQ_LAST_ENDPOINT
#define ZMQ_LAST_ENDPOINT
Definition: zmq.h:298
setup_test_context
void setup_test_context()
Definition: testutil_unity.cpp:179
errno
int errno
bind_loopback_ipv4
void bind_loopback_ipv4(void *socket_, char *my_endpoint_, size_t len_)
Definition: testutil_unity.cpp:246
teardown_test_context
void teardown_test_context()
Definition: testutil_unity.cpp:189
get_test_context
void * get_test_context()
Definition: testutil_unity.cpp:184
found
return found
Definition: socket_poller.cpp:456
TEST_ASSERT_FALSE
#define TEST_ASSERT_FALSE(condition)
Definition: unity.h:123
test_context_socket_close_zero_linger
void * test_context_socket_close_zero_linger(void *socket_)
Definition: testutil_unity.cpp:215
close_zero_linger
void close_zero_linger(void *socket_)
Definition: testutil.cpp:193
testutil_unity.hpp
snprintf
int snprintf(char *str, size_t size, const char *format,...)
Definition: port.cc:64
TEST_ASSERT_LESS_OR_EQUAL_MESSAGE
#define TEST_ASSERT_LESS_OR_EQUAL_MESSAGE(threshold, actual, message)
Definition: unity.h:392
bind_loopback_ipc
void bind_loopback_ipc(void *socket_, char *my_endpoint_, size_t len_)
Definition: testutil_unity.cpp:256
zmq_setsockopt
ZMQ_EXPORT int zmq_setsockopt(void *s_, int option_, const void *optval_, size_t optvallen_)
Definition: zmq.cpp:250
line_
int line_
Definition: objectivec_helpers.cc:1468
buffer
GLuint buffer
Definition: glcorearb.h:2939
test_assert_success_message_errno_helper
int test_assert_success_message_errno_helper(int rc_, const char *msg_, const char *expr_, int line_)
Definition: testutil_unity.cpp:13
ETERM
#define ETERM
Definition: zmq.h:161
zmq_bind
ZMQ_EXPORT int zmq_bind(void *s_, const char *addr_)
Definition: zmq.cpp:299
bind_loopback
void bind_loopback(void *socket_, int ipv6_, char *my_endpoint_, size_t len_)
Definition: testutil_unity.cpp:233
zmq_socket
ZMQ_EXPORT void * zmq_socket(void *, int type_)
Definition: zmq.cpp:230
is_tipc_available
int is_tipc_available()
Definition: testutil.cpp:283
buffer
Definition: buffer_processor.h:43
test_context_socket
void * test_context_socket(int type_)
Definition: testutil_unity.cpp:200
TEST_ASSERT_EQUAL
#define TEST_ASSERT_EQUAL(expected, actual)
Definition: unity.h:133
bind_loopback_ipv6
void bind_loopback_ipv6(void *socket_, char *my_endpoint_, size_t len_)
Definition: testutil_unity.cpp:251
TEST_ASSERT_EQUAL_INT
#define TEST_ASSERT_EQUAL_INT(expected, actual)
Definition: unity.h:128
TEST_ASSERT_LESS_THAN_MESSAGE
#define TEST_ASSERT_LESS_THAN_MESSAGE(threshold, actual, message)
Definition: unity.h:360
zmq_close
ZMQ_EXPORT int zmq_close(void *s_)
Definition: zmq.cpp:241
i
int i
Definition: gmock-matchers_test.cc:764
TEST_IGNORE_MESSAGE
#define TEST_IGNORE_MESSAGE(message)
Definition: unity.h:103
ZMQ_LINGER
#define ZMQ_LINGER
Definition: zmq.h:288
send_string_expect_success
void send_string_expect_success(void *socket_, const char *str_, int flags_)
Definition: testutil_unity.cpp:94
len
int len
Definition: php/ext/google/protobuf/map.c:206
zmq_recv
ZMQ_EXPORT int zmq_recv(void *s_, void *buf_, size_t len_, int flags_)
Definition: zmq.cpp:487
internal_manage_test_sockets
static void internal_manage_test_sockets(void *socket_, bool add_)
Definition: testutil_unity.cpp:134
recv_string_expect_success
void recv_string_expect_success(void *socket_, const char *str_, int flags_)
Definition: testutil_unity.cpp:101
ZMQ_IPV6
#define ZMQ_IPV6
Definition: zmq.h:307
test_assert_success_message_raw_zero_errno_helper
int test_assert_success_message_raw_zero_errno_helper(int rc_, const char *msg_, const char *expr_, int line_)
Definition: testutil_unity.cpp:53
strerror
char * strerror(int errno)
test_assert_success_message_raw_errno_helper
int test_assert_success_message_raw_errno_helper(int rc_, const char *msg_, const char *expr_, int line_, bool zero)
Definition: testutil_unity.cpp:31
internal_manage_test_context
static void * internal_manage_test_context(bool init_, bool clear_)
Definition: testutil_unity.cpp:117
zmq_ctx_term
ZMQ_EXPORT int zmq_ctx_term(void *context_)
Definition: zmq.cpp:128
zmq_send
ZMQ_EXPORT int zmq_send(void *s_, const void *buf_, size_t len_, int flags_)
Definition: zmq.cpp:377
test_context_socket_close
void * test_context_socket_close(void *socket_)
Definition: testutil_unity.cpp:208
TEST_ASSERT_NOT_NULL
#define TEST_ASSERT_NOT_NULL(pointer)
Definition: unity.h:125
TEST_ASSERT_SUCCESS_ERRNO
#define TEST_ASSERT_SUCCESS_ERRNO(expr)
Definition: proxy_thr.cpp:47
zmq_getsockopt
ZMQ_EXPORT int zmq_getsockopt(void *s_, int option_, void *optval_, size_t *optvallen_)
Definition: zmq.cpp:261
test_bind
void test_bind(void *socket_, const char *bind_address_, char *my_endpoint_, size_t len_)
Definition: testutil_unity.cpp:223
TEST_ASSERT_NULL
#define TEST_ASSERT_NULL(pointer)
Definition: unity.h:124


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:59