monitor.cpp
Go to the documentation of this file.
1 #include "testutil.hpp"
2 
3 #ifdef ZMQ_CPP11
4 #include <thread>
5 #include <mutex>
6 #include <condition_variable>
7 #include <functional>
8 
9 class mock_monitor_t : public zmq::monitor_t
10 {
11  public:
12 
13  void on_event_connected(const zmq_event_t &, const char *) ZMQ_OVERRIDE
14  {
15  ++connected;
16  ++total;
17  }
18 
19  int total{0};
20  int connected{0};
21 };
22 
23 #endif
24 
25 TEST_CASE("monitor create destroy", "[monitor]")
26 {
27  zmq::monitor_t monitor;
28 }
29 
30 #if defined(ZMQ_CPP11)
31 TEST_CASE("monitor move construct", "[monitor]")
32 {
33  zmq::context_t ctx;
35  SECTION("move ctor empty") {
36  zmq::monitor_t monitor1;
37  zmq::monitor_t monitor2 = std::move(monitor1);
38  }
39  SECTION("move ctor init") {
40  zmq::monitor_t monitor1;
41  monitor1.init(sock, "inproc://monitor-client");
42  zmq::monitor_t monitor2 = std::move(monitor1);
43  }
44 }
45 
46 TEST_CASE("monitor move assign", "[monitor]")
47 {
48  zmq::context_t ctx;
50  SECTION("move assign empty") {
51  zmq::monitor_t monitor1;
52  zmq::monitor_t monitor2;
53  monitor1 = std::move(monitor2);
54  }
55  SECTION("move assign init") {
56  zmq::monitor_t monitor1;
57  monitor1.init(sock, "inproc://monitor-client");
58  zmq::monitor_t monitor2;
59  monitor2 = std::move(monitor1);
60  }
61  SECTION("move assign init both") {
62  zmq::monitor_t monitor1;
63  monitor1.init(sock, "inproc://monitor-client");
64  zmq::monitor_t monitor2;
65  zmq::socket_t sock2(ctx, ZMQ_DEALER);
66  monitor2.init(sock2, "inproc://monitor-client2");
67  monitor2 = std::move(monitor1);
68  }
69 }
70 
71 TEST_CASE("monitor init event count", "[monitor]")
72 {
73  common_server_client_setup s{false};
74  mock_monitor_t monitor;
75 
76  const int expected_event_count = 1;
77  monitor.init(s.client, "inproc://foo");
78 
79  CHECK_FALSE(monitor.check_event(0));
80  s.init();
81 
82  while (monitor.check_event(1000) && monitor.total < expected_event_count) {
83  }
84  CHECK(monitor.connected == 1);
85  CHECK(monitor.total == expected_event_count);
86 }
87 
88 TEST_CASE("monitor init abort", "[monitor]")
89 {
90  class mock_monitor : public mock_monitor_t
91  {
92  public:
93  mock_monitor(std::function<void(void)> handle_connected) :
94  handle_connected{std::move(handle_connected)}
95  {
96  }
97 
98  void on_event_connected(const zmq_event_t &e, const char *m) ZMQ_OVERRIDE
99  {
100  mock_monitor_t::on_event_connected(e, m);
101  handle_connected();
102  }
103 
104  std::function<void(void)> handle_connected;
105  };
106 
107  common_server_client_setup s(false);
108 
109  std::mutex mutex;
110  std::condition_variable cond_var;
111  bool done{false};
112 
113  mock_monitor monitor([&]()
114  {
115  std::lock_guard<std::mutex> lock(mutex);
116  done = true;
117  cond_var.notify_one();
118  });
119  monitor.init(s.client, "inproc://foo");
120 
121  auto thread = std::thread([&monitor]
122  {
123  while (monitor.check_event(-1)) {
124  }
125  });
126 
127  s.init();
128  {
129  std::unique_lock<std::mutex> lock(mutex);
130  CHECK(cond_var.wait_for(lock, std::chrono::seconds(1),
131  [&done] { return done; }));
132  }
133  CHECK(monitor.connected == 1);
134  monitor.abort();
135  thread.join();
136 }
137 
138 
139 TEST_CASE("monitor from move assigned socket", "[monitor]")
140 {
141  zmq::context_t ctx;
143  sock = std::move([&ctx] {
145  return sock;
146  }());
147  zmq::monitor_t monitor1;
148  monitor1.init(sock, "inproc://monitor-client");
149  // On failure, this test might hang indefinitely instead of immediately
150  // failing
151 }
152 #endif
153 
154 #if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) \
155  && !defined(ZMQ_CPP11_PARTIAL) && defined(ZMQ_HAVE_POLLER)
156 #include "zmq_addon.hpp"
157 
158 TEST_CASE("poll monitor events using active poller", "[monitor]")
159 {
160  // define necessary class for test
161  class test_monitor : public zmq::monitor_t
162  {
163  public:
164  void init(zmq::socket_t &socket,
165  const char *const addr_,
166  int events = ZMQ_EVENT_ALL)
167  {
168  zmq::monitor_t::init(socket, addr_, events);
169  }
170 
171  void addToPoller(zmq::active_poller_t &inActivePoller)
172  {
173  inActivePoller.add(
174  monitor_socket(), zmq::event_flags::pollin,
175  [&](zmq::event_flags ef) { process_event(static_cast<short>(ef)); });
176  }
177 
178  void on_event_accepted(const zmq_event_t &event_, const char *addr_) override
179  {
180  clientAccepted++;
181  }
183  const char *const addr) override
184  {
185  clientDisconnected++;
186  }
187 
188  int clientAccepted = 0;
189  int clientDisconnected = 0;
190  };
191 
192  //Arrange
193  int messageCounter = 0;
194  const char monitorAddress[] = "inproc://monitor-server";
195 
196  auto addToPoller = [&](zmq::socket_t &socket, zmq::active_poller_t &poller) {
197  poller.add(socket, zmq::event_flags::pollin, [&](zmq::event_flags ef) {
198  zmq::message_t msg;
199  auto result = socket.recv(msg, zmq::recv_flags::dontwait);
200  messageCounter++;
201  });
202  };
203 
204  common_server_client_setup sockets(false);
205 
206  test_monitor monitor;
207  monitor.init(sockets.server, monitorAddress,
209 
210  zmq::active_poller_t poller;
211  monitor.addToPoller(poller);
212  addToPoller(sockets.server, poller);
213 
214  sockets.init();
215  sockets.client.send(zmq::message_t(0), zmq::send_flags::dontwait);
216  CHECK(monitor.clientAccepted == 0);
217  CHECK(monitor.clientDisconnected == 0);
218 
219  //Act
220  for (int i = 0; i < 100; i++) {
221  poller.wait(std::chrono::milliseconds(50));
222  if (monitor.clientAccepted > 0) {
223  break;
224  }
225  }
226  CHECK(monitor.clientAccepted == 1);
227  CHECK(monitor.clientDisconnected == 0);
228 
229  sockets.client.close();
230 
231  for (int i = 0; i < 100; i++) {
232  poller.wait(std::chrono::milliseconds(50));
233  if (monitor.clientDisconnected > 0) {
234  break;
235  }
236  }
237  sockets.server.close();
238 
239  // Assert
240  CHECK(messageCounter == 1);
241  CHECK(monitor.clientAccepted == 1);
242  CHECK(monitor.clientDisconnected == 1);
243 }
244 #endif
zmq_event_t
Definition: zmq.hpp:208
zmq::message_t
Definition: zmq.hpp:409
sock
void * sock
Definition: test_connect_resolve.cpp:9
s
XmlRpcServer s
zmq::socket_t
Definition: zmq.hpp:2188
zmq::monitor_t::on_event_disconnected
virtual void on_event_disconnected(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2444
testutil.hpp
TEST_CASE
TEST_CASE("monitor create destroy", "[monitor]")
Definition: monitor.cpp:25
zmq::monitor_t::init
void init(socket_t &socket, std::string const &addr, int events=ZMQ_EVENT_ALL)
Definition: zmq.hpp:2350
zmq::context_t
Definition: zmq.hpp:799
ZMQ_OVERRIDE
#define ZMQ_OVERRIDE
Definition: zmq.hpp:91
ZMQ_DEALER
#define ZMQ_DEALER
Definition: zmq.h:263
event
struct _cl_event * event
Definition: glcorearb.h:4163
zmq::monitor_t::process_event
bool process_event(short events)
Definition: zmq.hpp:2495
CHECK
#define CHECK(x)
Definition: php/ext/google/protobuf/upb.c:8393
zmq::monitor_t
Definition: zmq.hpp:2311
void
typedef void(APIENTRY *GLDEBUGPROCARB)(GLenum source
i
int i
Definition: gmock-matchers_test.cc:764
zmq::monitor_t::monitor_socket
socket_ref monitor_socket()
Definition: zmq.hpp:2602
ZMQ_EVENT_ACCEPTED
#define ZMQ_EVENT_ACCEPTED
Definition: zmq.h:406
ZMQ_EVENT_ALL
#define ZMQ_EVENT_ALL
Definition: zmq.h:412
ZMQ_EVENT_DISCONNECTED
#define ZMQ_EVENT_DISCONNECTED
Definition: zmq.h:410
zmq::monitor_t::on_event_connected
virtual void on_event_connected(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2397
m
const upb_json_parsermethod * m
Definition: ruby/ext/google/protobuf_c/upb.h:10501
zmq::monitor_t::on_event_accepted
virtual void on_event_accepted(const zmq_event_t &event_, const char *addr_)
Definition: zmq.hpp:2424
zmq_addon.hpp


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