testutil_monitoring.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MPL-2.0 */
3 #include "testutil_unity.hpp"
4 
5 #include <stdlib.h>
6 #include <string.h>
7 
8 static int
9 receive_monitor_address (void *monitor_, char **address_, bool expect_more_)
10 {
11  zmq_msg_t msg;
12 
13  zmq_msg_init (&msg);
14  if (zmq_msg_recv (&msg, monitor_, 0) == -1)
15  return -1; // Interrupted, presumably
16  TEST_ASSERT_EQUAL (expect_more_, zmq_msg_more (&msg));
17 
18  if (address_) {
19  const uint8_t *const data =
20  static_cast<const uint8_t *> (zmq_msg_data (&msg));
21  const size_t size = zmq_msg_size (&msg);
22  *address_ = static_cast<char *> (malloc (size + 1));
23  memcpy (*address_, data, size);
24  (*address_)[size] = 0;
25  }
26  zmq_msg_close (&msg);
27 
28  return 0;
29 }
30 
31 // Read one event off the monitor socket; return value and address
32 // by reference, if not null, and event number by value. Returns -1
33 // in case of error.
34 static int get_monitor_event_internal (void *monitor_,
35  int *value_,
36  char **address_,
37  int recv_flag_)
38 {
39  // First frame in message contains event number and value
40  zmq_msg_t msg;
41  zmq_msg_init (&msg);
42  if (zmq_msg_recv (&msg, monitor_, recv_flag_) == -1) {
44  return -1; // timed out or no message available
45  }
47 
48  uint8_t *data = static_cast<uint8_t *> (zmq_msg_data (&msg));
49  uint16_t event = *reinterpret_cast<uint16_t *> (data);
50  if (value_)
51  memcpy (value_, data + 2, sizeof (uint32_t));
52 
53  // Second frame in message contains event address
55  receive_monitor_address (monitor_, address_, false));
56 
57  return event;
58 }
59 
60 int get_monitor_event_with_timeout (void *monitor_,
61  int *value_,
62  char **address_,
63  int timeout_)
64 {
65  int res;
66  if (timeout_ == -1) {
67  // process infinite timeout in small steps to allow the user
68  // to see some information on the console
69 
70  int timeout_step = 250;
71  int wait_time = 0;
72  zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_step,
73  sizeof (timeout_step));
74  while (
75  (res = get_monitor_event_internal (monitor_, value_, address_, 0))
76  == -1) {
77  wait_time += timeout_step;
78  fprintf (stderr, "Still waiting for monitor event after %i ms\n",
79  wait_time);
80  }
81  } else {
82  zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_, sizeof (timeout_));
83  res = get_monitor_event_internal (monitor_, value_, address_, 0);
84  }
85  int timeout_infinite = -1;
86  zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_infinite,
87  sizeof (timeout_infinite));
88  return res;
89 }
90 
91 int get_monitor_event (void *monitor_, int *value_, char **address_)
92 {
93  return get_monitor_event_with_timeout (monitor_, value_, address_, -1);
94 }
95 
96 void expect_monitor_event (void *monitor_, int expected_event_)
97 {
98  TEST_ASSERT_EQUAL_HEX (expected_event_,
99  get_monitor_event (monitor_, NULL, NULL));
100 }
101 
102 static void print_unexpected_event (char *buf_,
103  size_t buf_size_,
104  int event_,
105  int err_,
106  int expected_event_,
107  int expected_err_)
108 {
109  snprintf (buf_, buf_size_,
110  "Unexpected event: 0x%x, value = %i/0x%x (expected: 0x%x, value "
111  "= %i/0x%x)\n",
112  event_, err_, err_, expected_event_, expected_err_,
113  expected_err_);
114 }
115 
117  int err_,
118  int expected_event_,
119  int expected_err_)
120 {
121  char buf[256];
122  print_unexpected_event (buf, sizeof buf, event_, err_, expected_event_,
123  expected_err_);
124  fputs (buf, stderr);
125 }
126 
127 int expect_monitor_event_multiple (void *server_mon_,
128  int expected_event_,
129  int expected_err_,
130  bool optional_)
131 {
132  int count_of_expected_events = 0;
133  int client_closed_connection = 0;
134  int timeout = 250;
135  int wait_time = 0;
136 
137  int event;
138  int err;
139  while ((event =
141  != -1
142  || !count_of_expected_events) {
143  if (event == -1) {
144  if (optional_)
145  break;
146  wait_time += timeout;
147  fprintf (stderr,
148  "Still waiting for first event after %ims (expected event "
149  "%x (value %i/0x%x))\n",
150  wait_time, expected_event_, expected_err_, expected_err_);
151  continue;
152  }
153  // ignore errors with EPIPE/ECONNRESET/ECONNABORTED, which can happen
154  // ECONNRESET can happen on very slow machines, when the engine writes
155  // to the peer and then tries to read the socket before the peer reads
156  // ECONNABORTED happens when a client aborts a connection via RST/timeout
158  && ((err == EPIPE && expected_err_ != EPIPE) || err == ECONNRESET
159  || err == ECONNABORTED)) {
160  fprintf (stderr,
161  "Ignored event (skipping any further events): %x (err = "
162  "%i == %s)\n",
163  event, err, zmq_strerror (err));
164  client_closed_connection = 1;
165  break;
166  }
167  if (event != expected_event_
168  || (-1 != expected_err_ && err != expected_err_)) {
169  char buf[256];
171  expected_event_, expected_err_);
173  }
174  ++count_of_expected_events;
175  }
176  TEST_ASSERT_TRUE (optional_ || count_of_expected_events > 0
177  || client_closed_connection);
178 
179  return count_of_expected_events;
180 }
181 
182 static int64_t get_monitor_event_internal_v2 (void *monitor_,
183  uint64_t **value_,
184  char **local_address_,
185  char **remote_address_,
186  int recv_flag_)
187 {
188  // First frame in message contains event number
189  zmq_msg_t msg;
190  zmq_msg_init (&msg);
191  if (zmq_msg_recv (&msg, monitor_, recv_flag_) == -1) {
193  return -1; // timed out or no message available
194  }
196  TEST_ASSERT_EQUAL_UINT (sizeof (uint64_t), zmq_msg_size (&msg));
197 
198  uint64_t event;
199  memcpy (&event, zmq_msg_data (&msg), sizeof (event));
200  zmq_msg_close (&msg);
201 
202  // Second frame in message contains the number of values
203  zmq_msg_init (&msg);
204  if (zmq_msg_recv (&msg, monitor_, recv_flag_) == -1) {
206  return -1; // timed out or no message available
207  }
209  TEST_ASSERT_EQUAL_UINT (sizeof (uint64_t), zmq_msg_size (&msg));
210 
211  uint64_t value_count;
212  memcpy (&value_count, zmq_msg_data (&msg), sizeof (value_count));
213  zmq_msg_close (&msg);
214 
215  if (value_) {
216  *value_ =
217  (uint64_t *) malloc ((size_t) value_count * sizeof (uint64_t));
219  }
220 
221  for (uint64_t i = 0; i < value_count; ++i) {
222  // Subsequent frames in message contain event values
223  zmq_msg_init (&msg);
224  if (zmq_msg_recv (&msg, monitor_, recv_flag_) == -1) {
226  return -1; // timed out or no message available
227  }
229  TEST_ASSERT_EQUAL_UINT (sizeof (uint64_t), zmq_msg_size (&msg));
230 
231  if (value_ && *value_)
232  memcpy (&(*value_)[i], zmq_msg_data (&msg), sizeof (uint64_t));
233  zmq_msg_close (&msg);
234  }
235 
236  // Second-to-last frame in message contains local address
238  receive_monitor_address (monitor_, local_address_, true));
239 
240  // Last frame in message contains remote address
242  receive_monitor_address (monitor_, remote_address_, false));
243 
244  return event;
245 }
246 
247 static int64_t get_monitor_event_with_timeout_v2 (void *monitor_,
248  uint64_t **value_,
249  char **local_address_,
250  char **remote_address_,
251  int timeout_)
252 {
253  int64_t res;
254  if (timeout_ == -1) {
255  // process infinite timeout in small steps to allow the user
256  // to see some information on the console
257 
258  int timeout_step = 250;
259  int wait_time = 0;
260  zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_step,
261  sizeof (timeout_step));
262  while ((res = get_monitor_event_internal_v2 (
263  monitor_, value_, local_address_, remote_address_, 0))
264  == -1) {
265  wait_time += timeout_step;
266  fprintf (stderr, "Still waiting for monitor event after %i ms\n",
267  wait_time);
268  }
269  } else {
270  zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_, sizeof (timeout_));
271  res = get_monitor_event_internal_v2 (monitor_, value_, local_address_,
272  remote_address_, 0);
273  }
274  int timeout_infinite = -1;
275  zmq_setsockopt (monitor_, ZMQ_RCVTIMEO, &timeout_infinite,
276  sizeof (timeout_infinite));
277  return res;
278 }
279 
280 int64_t get_monitor_event_v2 (void *monitor_,
281  uint64_t **value_,
282  char **local_address_,
283  char **remote_address_)
284 {
285  return get_monitor_event_with_timeout_v2 (monitor_, value_, local_address_,
286  remote_address_, -1);
287 }
288 
289 void expect_monitor_event_v2 (void *monitor_,
290  int64_t expected_event_,
291  const char *expected_local_address_,
292  const char *expected_remote_address_)
293 {
294  char *local_address = NULL;
295  char *remote_address = NULL;
296  int64_t event = get_monitor_event_v2 (
297  monitor_, NULL, expected_local_address_ ? &local_address : NULL,
298  expected_remote_address_ ? &remote_address : NULL);
299  bool failed = false;
300  char buf[256];
301  char *pos = buf;
302  if (event != expected_event_) {
303  pos += snprintf (pos, sizeof buf - (pos - buf),
304  "Expected monitor event %llx, but received %llx\n",
305  static_cast<long long> (expected_event_),
306  static_cast<long long> (event));
307  failed = true;
308  }
309  if (expected_local_address_
310  && 0 != strcmp (local_address, expected_local_address_)) {
311  pos += snprintf (pos, sizeof buf - (pos - buf),
312  "Expected local address %s, but received %s\n",
313  expected_local_address_, local_address);
314  }
315  if (expected_remote_address_
316  && 0 != strcmp (remote_address, expected_remote_address_)) {
317  snprintf (pos, sizeof buf - (pos - buf),
318  "Expected remote address %s, but received %s\n",
319  expected_remote_address_, remote_address);
320  }
321  free (local_address);
322  free (remote_address);
323  TEST_ASSERT_FALSE_MESSAGE (failed, buf);
324 }
325 
326 
327 const char *get_zmqEventName (uint64_t event)
328 {
329  switch (event) {
330  case ZMQ_EVENT_CONNECTED:
331  return "CONNECTED";
333  return "CONNECT_DELAYED";
335  return "CONNECT_RETRIED";
336  case ZMQ_EVENT_LISTENING:
337  return "LISTENING";
339  return "BIND_FAILED";
340  case ZMQ_EVENT_ACCEPTED:
341  return "ACCEPTED";
343  return "ACCEPT_FAILED";
344  case ZMQ_EVENT_CLOSED:
345  return "CLOSED";
347  return "CLOSE_FAILED";
349  return "DISCONNECTED";
351  return "MONITOR_STOPPED";
353  return "HANDSHAKE_FAILED_NO_DETAIL";
355  return "HANDSHAKE_SUCCEEDED";
357  return "HANDSHAKE_FAILED_PROTOCOL";
359  return "HANDSHAKE_FAILED_AUTH";
360  default:
361  return "UNKNOWN";
362  }
363 }
364 
365 void print_events (void *socket, int timeout, int limit)
366 {
367  // print events received
368  int value;
369  char *event_address;
370  int event =
371  get_monitor_event_with_timeout (socket, &value, &event_address, timeout);
372  int i = 0;
373  ;
374  while ((event != -1) && (++i < limit)) {
375  const char *eventName = get_zmqEventName (event);
376  printf ("Got event: %s\n", eventName);
377  event = get_monitor_event_with_timeout (socket, &value, &event_address,
378  timeout);
379  }
380 }
zmq_strerror
const ZMQ_EXPORT char * zmq_strerror(int errnum_)
Definition: zmq.cpp:96
print_unexpected_event_stderr
void print_unexpected_event_stderr(int event_, int err_, int expected_event_, int expected_err_)
Definition: testutil_monitoring.cpp:116
ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
#define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
Definition: zmq.h:414
ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
#define ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
Definition: zmq.h:423
NULL
NULL
Definition: test_security_zap.cpp:405
TEST_ASSERT_TRUE
#define TEST_ASSERT_TRUE(condition)
Definition: unity.h:121
EAGAIN
#define EAGAIN
Definition: errno.hpp:14
ZMQ_EVENT_CLOSED
#define ZMQ_EVENT_CLOSED
Definition: zmq.h:408
TEST_ASSERT_EQUAL_UINT
#define TEST_ASSERT_EQUAL_UINT(expected, actual)
Definition: unity.h:135
get_monitor_event_with_timeout
int get_monitor_event_with_timeout(void *monitor_, int *value_, char **address_, int timeout_)
Definition: testutil_monitoring.cpp:60
ZMQ_EVENT_BIND_FAILED
#define ZMQ_EVENT_BIND_FAILED
Definition: zmq.h:405
ZMQ_EVENT_CLOSE_FAILED
#define ZMQ_EVENT_CLOSE_FAILED
Definition: zmq.h:409
get_zmqEventName
const char * get_zmqEventName(uint64_t event)
Definition: testutil_monitoring.cpp:327
get_monitor_event_with_timeout_v2
static int64_t get_monitor_event_with_timeout_v2(void *monitor_, uint64_t **value_, char **local_address_, char **remote_address_, int timeout_)
Definition: testutil_monitoring.cpp:247
TEST_FAIL_MESSAGE
#define TEST_FAIL_MESSAGE(message)
Definition: unity.h:101
zmq_msg_data
ZMQ_EXPORT void * zmq_msg_data(zmq_msg_t *msg_)
Definition: zmq.cpp:642
ZMQ_EVENT_LISTENING
#define ZMQ_EVENT_LISTENING
Definition: zmq.h:404
get_monitor_event_internal_v2
static int64_t get_monitor_event_internal_v2(void *monitor_, uint64_t **value_, char **local_address_, char **remote_address_, int recv_flag_)
Definition: testutil_monitoring.cpp:182
zmq_msg_size
ZMQ_EXPORT size_t zmq_msg_size(const zmq_msg_t *msg_)
Definition: zmq.cpp:647
get_monitor_event
int get_monitor_event(void *monitor_, int *value_, char **address_)
Definition: testutil_monitoring.cpp:91
testutil_unity.hpp
ZMQ_EVENT_HANDSHAKE_SUCCEEDED
#define ZMQ_EVENT_HANDSHAKE_SUCCEEDED
Definition: zmq.h:417
snprintf
int snprintf(char *str, size_t size, const char *format,...)
Definition: port.cc:64
TEST_ASSERT_EQUAL_HEX
#define TEST_ASSERT_EQUAL_HEX(expected, actual)
Definition: unity.h:140
ECONNABORTED
#define ECONNABORTED
Definition: zmq.h:140
zmq_setsockopt
ZMQ_EXPORT int zmq_setsockopt(void *s_, int option_, const void *optval_, size_t optvallen_)
Definition: zmq.cpp:250
ZMQ_EVENT_CONNECTED
#define ZMQ_EVENT_CONNECTED
Definition: zmq.h:401
event
struct _cl_event * event
Definition: glcorearb.h:4163
get_monitor_event_v2
int64_t get_monitor_event_v2(void *monitor_, uint64_t **value_, char **local_address_, char **remote_address_)
Definition: testutil_monitoring.cpp:280
zmq_msg_t
Definition: zmq.h:218
err
static UPB_NORETURN void err(tarjan *t)
Definition: ruby/ext/google/protobuf_c/upb.c:5856
size
#define size
Definition: glcorearb.h:2944
expect_monitor_event_v2
void expect_monitor_event_v2(void *monitor_, int64_t expected_event_, const char *expected_local_address_, const char *expected_remote_address_)
Definition: testutil_monitoring.cpp:289
zmq_msg_recv
ZMQ_EXPORT int zmq_msg_recv(zmq_msg_t *msg_, void *s_, int flags_)
Definition: zmq.cpp:617
timeout
GLbitfield GLuint64 timeout
Definition: glcorearb.h:3588
get_monitor_event_internal
static int get_monitor_event_internal(void *monitor_, int *value_, char **address_, int recv_flag_)
Definition: testutil_monitoring.cpp:34
TEST_ASSERT_EQUAL
#define TEST_ASSERT_EQUAL(expected, actual)
Definition: unity.h:133
buf
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:4175
ZMQ_EVENT_ACCEPT_FAILED
#define ZMQ_EVENT_ACCEPT_FAILED
Definition: zmq.h:407
zmq_msg_init
ZMQ_EXPORT int zmq_msg_init(zmq_msg_t *msg_)
Definition: zmq.cpp:587
receive_monitor_address
static int receive_monitor_address(void *monitor_, char **address_, bool expect_more_)
Definition: testutil_monitoring.cpp:9
i
int i
Definition: gmock-matchers_test.cc:764
value_
int value_
Definition: gmock-matchers_test.cc:571
expect_monitor_event
void expect_monitor_event(void *monitor_, int expected_event_)
Definition: testutil_monitoring.cpp:96
ZMQ_EVENT_CONNECT_DELAYED
#define ZMQ_EVENT_CONNECT_DELAYED
Definition: zmq.h:402
ZMQ_RCVTIMEO
#define ZMQ_RCVTIMEO
Definition: zmq.h:296
ZMQ_EVENT_ACCEPTED
#define ZMQ_EVENT_ACCEPTED
Definition: zmq.h:406
ZMQ_EVENT_CONNECT_RETRIED
#define ZMQ_EVENT_CONNECT_RETRIED
Definition: zmq.h:403
expect_monitor_event_multiple
int expect_monitor_event_multiple(void *server_mon_, int expected_event_, int expected_err_, bool optional_)
Definition: testutil_monitoring.cpp:127
ZMQ_EVENT_DISCONNECTED
#define ZMQ_EVENT_DISCONNECTED
Definition: zmq.h:410
size
GLsizeiptr size
Definition: glcorearb.h:2943
testutil_monitoring.hpp
print_unexpected_event
static void print_unexpected_event(char *buf_, size_t buf_size_, int event_, int err_, int expected_event_, int expected_err_)
Definition: testutil_monitoring.cpp:102
TEST_ASSERT_FALSE_MESSAGE
#define TEST_ASSERT_FALSE_MESSAGE(condition, message)
Definition: unity.h:315
ECONNRESET
#define ECONNRESET
Definition: zmq.h:143
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL
#define ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL
Definition: zmq.h:420
TEST_ASSERT_FAILURE_ERRNO
#define TEST_ASSERT_FAILURE_ERRNO(error_code, expr)
Definition: testutil_unity.hpp:95
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
print_events
void print_events(void *socket, int timeout, int limit)
Definition: testutil_monitoring.cpp:365
zmq_msg_more
ZMQ_EXPORT int zmq_msg_more(const zmq_msg_t *msg_)
Definition: zmq.cpp:652
TEST_ASSERT_NOT_NULL
#define TEST_ASSERT_NOT_NULL(pointer)
Definition: unity.h:125
zmq_msg_close
ZMQ_EXPORT int zmq_msg_close(zmq_msg_t *msg_)
Definition: zmq.cpp:625
TEST_ASSERT_SUCCESS_ERRNO
#define TEST_ASSERT_SUCCESS_ERRNO(expr)
Definition: proxy_thr.cpp:47
ZMQ_EVENT_MONITOR_STOPPED
#define ZMQ_EVENT_MONITOR_STOPPED
Definition: zmq.h:411


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