poller.cpp
Go to the documentation of this file.
1 #include "testutil.hpp"
2 
3 #if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && !defined(ZMQ_CPP11_PARTIAL) && defined(ZMQ_HAVE_POLLER)
4 
5 #include <array>
6 #include <memory>
7 
8 #ifdef ZMQ_CPP17
9 static_assert(std::is_nothrow_swappable_v<zmq::poller_t<>>);
10 #endif
11 static_assert(sizeof(zmq_poller_event_t) == sizeof(zmq::poller_event<>), "");
12 static_assert(sizeof(zmq_poller_event_t) == sizeof(zmq::poller_event<zmq::
13  no_user_data>), "");
14 static_assert(sizeof(zmq_poller_event_t) == sizeof(zmq::poller_event<int>), "");
15 static_assert(alignof(zmq_poller_event_t) == alignof(zmq::poller_event<>), "");
16 static_assert(alignof(zmq_poller_event_t) == alignof(zmq::poller_event<int>), "");
17 
18 static_assert(!std::is_copy_constructible<zmq::poller_t<>>::value,
19  "poller_t should not be copy-constructible");
20 static_assert(!std::is_copy_assignable<zmq::poller_t<>>::value,
21  "poller_t should not be copy-assignable");
22 
23 TEST_CASE("event flags", "[poller]")
24 {
25  CHECK((zmq::event_flags::pollin | zmq::event_flags::pollout)
26  == static_cast<zmq::event_flags>(ZMQ_POLLIN | ZMQ_POLLOUT));
27  CHECK((zmq::event_flags::pollin & zmq::event_flags::pollout)
28  == static_cast<zmq::event_flags>(ZMQ_POLLIN & ZMQ_POLLOUT));
29  CHECK((zmq::event_flags::pollin ^ zmq::event_flags::pollout)
30  == static_cast<zmq::event_flags>(ZMQ_POLLIN ^ ZMQ_POLLOUT));
31  CHECK(~zmq::event_flags::pollin == static_cast<zmq::event_flags>(~ZMQ_POLLIN));
32 }
33 
34 TEST_CASE("poller create destroy", "[poller]")
35 {
36  zmq::poller_t<> a;
37 #ifdef ZMQ_CPP17 // CTAD
38  zmq::poller_t b;
39  zmq::poller_event e;
40 #endif
41 }
42 
43 TEST_CASE("poller move construct empty", "[poller]")
44 {
45  zmq::poller_t<> a;
46  zmq::poller_t<> b = std::move(a);
47 }
48 
49 TEST_CASE("poller move assign empty", "[poller]")
50 {
51  zmq::poller_t<> a;
52  zmq::poller_t<> b;
53  b = std::move(a);
54 }
55 
56 TEST_CASE("poller swap", "[poller]")
57 {
58  zmq::poller_t<> a;
59  zmq::poller_t<> b;
60  using std::swap;
61  swap(a, b);
62 }
63 
64 TEST_CASE("poller move construct non empty", "[poller]")
65 {
66  zmq::context_t context;
67  zmq::socket_t socket{context, zmq::socket_type::router};
68 
69  zmq::poller_t<> a;
70  a.add(socket, zmq::event_flags::pollin);
71  zmq::poller_t<> b = std::move(a);
72 }
73 
74 TEST_CASE("poller move assign non empty", "[poller]")
75 {
76  zmq::context_t context;
77  zmq::socket_t socket{context, zmq::socket_type::router};
78 
79  zmq::poller_t<> a;
80  a.add(socket, zmq::event_flags::pollin);
81  zmq::poller_t<> b;
82  b = std::move(a);
83 }
84 
85 TEST_CASE("poller add nullptr", "[poller]")
86 {
87  zmq::context_t context;
88  zmq::socket_t socket{context, zmq::socket_type::router};
89  zmq::poller_t<void> poller;
90  CHECK_NOTHROW(poller.add(socket, zmq::event_flags::pollin, nullptr));
91 }
92 
93 TEST_CASE("poller add non nullptr", "[poller]")
94 {
95  zmq::context_t context;
96  zmq::socket_t socket{context, zmq::socket_type::router};
97  zmq::poller_t<int> poller;
98  int i;
99  CHECK_NOTHROW(poller.add(socket, zmq::event_flags::pollin, &i));
100 }
101 
102 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 3, 0)
103 // this behaviour was added by https://github.com/zeromq/libzmq/pull/3100
104 TEST_CASE("poller add handler invalid events type", "[poller]")
105 {
106  zmq::context_t context;
107  zmq::socket_t socket{context, zmq::socket_type::router};
108  zmq::poller_t<> poller;
109  short invalid_events_type = 2 << 10;
110  CHECK_THROWS_AS(
111  poller.add(socket, static_cast<zmq::event_flags>(invalid_events_type)),
112  zmq::error_t);
113 }
114 #endif
115 
116 TEST_CASE("poller add handler twice throws", "[poller]")
117 {
118  zmq::context_t context;
119  zmq::socket_t socket{context, zmq::socket_type::router};
120  zmq::poller_t<> poller;
121  poller.add(socket, zmq::event_flags::pollin);
123  CHECK_THROWS_AS(poller.add(socket, zmq::event_flags::pollin),
124  zmq::error_t);
125 }
126 
127 TEST_CASE("poller wait with no handlers throws", "[poller]")
128 {
129  zmq::poller_t<> poller;
130  std::vector<zmq::poller_event<>> events;
132  CHECK_THROWS_AS(poller.wait_all(events, std::chrono::milliseconds{10}),
133  zmq::error_t);
134 }
135 
136 #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 3, 3)
137 TEST_CASE("poller add/remove size checks", "[poller]")
138 {
139  zmq::context_t context;
140  zmq::socket_t socket{context, zmq::socket_type::router};
141  zmq::poller_t<> poller;
142  CHECK(poller.size() == 0);
143  poller.add(socket, zmq::event_flags::pollin);
144  CHECK(poller.size() == 1);
145  CHECK_NOTHROW(poller.remove(socket));
146  CHECK(poller.size() == 0);
147 }
148 #endif
149 
150 TEST_CASE("poller remove unregistered throws", "[poller]")
151 {
152  zmq::context_t context;
153  zmq::socket_t socket{context, zmq::socket_type::router};
154  zmq::poller_t<> poller;
156  CHECK_THROWS_AS(poller.remove(socket), zmq::error_t);
157 }
158 
159 TEST_CASE("poller remove registered empty", "[poller]")
160 {
161  zmq::context_t context;
162  zmq::socket_t socket{context, zmq::socket_type::router};
163  zmq::poller_t<> poller;
164  poller.add(socket, zmq::event_flags::pollin);
165  CHECK_NOTHROW(poller.remove(socket));
166 }
167 
168 TEST_CASE("poller remove registered non empty", "[poller]")
169 {
170  zmq::context_t context;
171  zmq::socket_t socket{context, zmq::socket_type::router};
172  zmq::poller_t<int> poller;
173  int empty{};
174  poller.add(socket, zmq::event_flags::pollin, &empty);
175  CHECK_NOTHROW(poller.remove(socket));
176 }
177 
178 const std::string hi_str = "Hi";
179 
180 TEST_CASE("poller poll basic", "[poller]")
181 {
182  common_server_client_setup s;
183 
184  CHECK_NOTHROW(s.client.send(zmq::message_t{hi_str}, zmq::send_flags::none));
185 
186  zmq::poller_t<int> poller;
187  std::vector<zmq::poller_event<int>> events{1};
188  int i = 0;
189  CHECK_NOTHROW(poller.add(s.server, zmq::event_flags::pollin, &i));
190  CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{-1}));
191  CHECK(s.server == events[0].socket);
192  CHECK(&i == events[0].user_data);
193 }
194 
195 TEST_CASE("poller poll basic static array", "[poller]")
196 {
197  common_server_client_setup s;
198 
199  CHECK_NOTHROW(s.client.send(zmq::message_t{hi_str}, zmq::send_flags::none));
200 
201  zmq::poller_t<int> poller;
202  std::array<zmq::poller_event<int>, 1> events;
203  int i = 0;
204  CHECK_NOTHROW(poller.add(s.server, zmq::event_flags::pollin, &i));
205  CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{-1}));
206  CHECK(s.server == events[0].socket);
207  CHECK(&i == events[0].user_data);
208 }
209 
210 TEST_CASE("poller add invalid socket throws", "[poller]")
211 {
212  zmq::context_t context;
213  zmq::poller_t<> poller;
214  zmq::socket_t a{context, zmq::socket_type::router};
215  zmq::socket_t b{std::move(a)};
216  CHECK_THROWS_AS(poller.add(a, zmq::event_flags::pollin), zmq::error_t);
217 }
218 
219 TEST_CASE("poller remove invalid socket throws", "[poller]")
220 {
221  zmq::context_t context;
222  zmq::socket_t socket{context, zmq::socket_type::router};
223  zmq::poller_t<> poller;
224  CHECK_NOTHROW(poller.add(socket, zmq::event_flags::pollin));
225  std::vector<zmq::socket_t> sockets;
226  sockets.emplace_back(std::move(socket));
227  CHECK_THROWS_AS(poller.remove(socket), zmq::error_t);
228  CHECK_NOTHROW(poller.remove(sockets[0]));
229 }
230 
231 TEST_CASE("poller modify empty throws", "[poller]")
232 {
233  zmq::context_t context;
234  zmq::socket_t socket{context, zmq::socket_type::push};
235  zmq::poller_t<> poller;
236  CHECK_THROWS_AS(poller.modify(socket, zmq::event_flags::pollin),
237  zmq::error_t);
238 }
239 
240 TEST_CASE("poller modify invalid socket throws", "[poller]")
241 {
242  zmq::context_t context;
244  zmq::socket_t b{std::move(a)};
245  zmq::poller_t<> poller;
246  CHECK_THROWS_AS(poller.modify(a, zmq::event_flags::pollin), zmq::error_t);
247 }
248 
249 TEST_CASE("poller modify not added throws", "[poller]")
250 {
251  zmq::context_t context;
254  zmq::poller_t<> poller;
255  CHECK_NOTHROW(poller.add(a, zmq::event_flags::pollin));
256  CHECK_THROWS_AS(poller.modify(b, zmq::event_flags::pollin), zmq::error_t);
257 }
258 
259 TEST_CASE("poller modify simple", "[poller]")
260 {
261  zmq::context_t context;
263  zmq::poller_t<> poller;
264  CHECK_NOTHROW(poller.add(a, zmq::event_flags::pollin));
265  CHECK_NOTHROW(
266  poller.modify(a, zmq::event_flags::pollin | zmq::event_flags::pollout));
267 }
268 
269 TEST_CASE("poller poll client server", "[poller]")
270 {
271  // Setup server and client
272  common_server_client_setup s;
273 
274  // Setup poller
275  zmq::poller_t<zmq::socket_t> poller;
276  CHECK_NOTHROW(poller.add(s.server, zmq::event_flags::pollin, &s.server));
277 
278  // client sends message
279  CHECK_NOTHROW(s.client.send(zmq::message_t{hi_str}, zmq::send_flags::none));
280 
281  // wait for message and verify events
282  std::vector<zmq::poller_event<zmq::socket_t>> events(1);
283  CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{500}));
284  CHECK(zmq::event_flags::pollin == events[0].events);
285 
286  // Modify server socket with pollout flag
287  CHECK_NOTHROW(
288  poller.modify(s.server, zmq::event_flags::pollin | zmq::event_flags::pollout
289  ));
290  CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{500}));
291  CHECK((zmq::event_flags::pollin | zmq::event_flags::pollout) == events[0].events)
292  ;
293 }
294 
295 TEST_CASE("poller wait one return", "[poller]")
296 {
297  // Setup server and client
298  common_server_client_setup s;
299 
300  // Setup poller
301  zmq::poller_t<> poller;
302  CHECK_NOTHROW(poller.add(s.server, zmq::event_flags::pollin));
303 
304  // client sends message
305  CHECK_NOTHROW(s.client.send(zmq::message_t{hi_str}, zmq::send_flags::none));
306 
307  // wait for message and verify events
308  std::vector<zmq::poller_event<>> events(1);
309  CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{500}));
310 }
311 
312 TEST_CASE("poller wait on move constructed", "[poller]")
313 {
314  common_server_client_setup s;
315  CHECK_NOTHROW(s.client.send(zmq::message_t{hi_str}, zmq::send_flags::none));
316  zmq::poller_t<> a;
317  CHECK_NOTHROW(a.add(s.server, zmq::event_flags::pollin));
318  zmq::poller_t<> b{std::move(a)};
319  std::vector<zmq::poller_event<>> events(1);
321  CHECK_THROWS_AS(a.wait_all(events, std::chrono::milliseconds{10}),
322  zmq::error_t);
323  CHECK(1 == b.wait_all(events, std::chrono::milliseconds{-1}));
324 }
325 
326 TEST_CASE("poller wait on move assigned", "[poller]")
327 {
328  common_server_client_setup s;
329  CHECK_NOTHROW(s.client.send(zmq::message_t{hi_str}, zmq::send_flags::none));
330  zmq::poller_t<> a;
331  CHECK_NOTHROW(a.add(s.server, zmq::event_flags::pollin));
332  zmq::poller_t<> b;
333  b = {std::move(a)};
335  std::vector<zmq::poller_event<>> events(1);
336  CHECK_THROWS_AS(a.wait_all(events, std::chrono::milliseconds{10}),
337  zmq::error_t);
338  CHECK(1 == b.wait_all(events, std::chrono::milliseconds{-1}));
339 }
340 
341 TEST_CASE("poller remove from handler", "[poller]")
342 {
343  constexpr size_t ITER_NO = 10;
344 
345  // Setup servers and clients
346  std::vector<common_server_client_setup> setup_list;
347  for (size_t i = 0; i < ITER_NO; ++i)
348  setup_list.emplace_back(common_server_client_setup{});
349 
350  // Setup poller
351  zmq::poller_t<> poller;
352  for (size_t i = 0; i < ITER_NO; ++i) {
353  CHECK_NOTHROW(poller.add(setup_list[i].server, zmq::event_flags::pollin));
354  }
355  // Clients send messages
356  for (auto &s : setup_list) {
357  CHECK_NOTHROW(s.client.send(zmq::message_t{hi_str}, zmq::send_flags::none));
358  }
359 
360  // Wait for all servers to receive a message
361  for (auto &s : setup_list) {
362  zmq::pollitem_t items[] = {{s.server, 0, ZMQ_POLLIN, 0}};
363  zmq::poll(&items[0], 1);
364  }
365 
366  // Fire all handlers in one wait
367  std::vector<zmq::poller_event<>> events(ITER_NO);
368  CHECK(ITER_NO == poller.wait_all(events, std::chrono::milliseconds{-1}));
369 }
370 
371 #endif
TEST_CASE
TEST_CASE("context construct default and destroy", "[context]")
Definition: context.cpp:9
zmq::swap
void swap(message_t &a, message_t &b) ZMQ_NOTHROW
Definition: zmq.hpp:749
zmq::poll
int poll(zmq_pollitem_t *items_, size_t nitems_, long timeout_=-1)
Definition: zmq.hpp:319
zmq::message_t
Definition: zmq.hpp:409
s
XmlRpcServer s
zmq::socket_t
Definition: zmq.hpp:2188
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
zmq_pollitem_t
Definition: zmq.h:487
testutil.hpp
b
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:3228
ZMQ_POLLIN
#define ZMQ_POLLIN
Definition: zmq.h:482
zmq
Definition: zmq.hpp:229
zmq::context_t
Definition: zmq.hpp:799
ZMQ_POLLOUT
#define ZMQ_POLLOUT
Definition: zmq.h:483
zmq_poller_event_t
Definition: zmq_draft.h:114
std::swap
void swap(Json::Value &a, Json::Value &b)
Specialize std::swap() for Json::Value.
Definition: json.h:1226
CHECK
#define CHECK(x)
Definition: php/ext/google/protobuf/upb.c:8393
i
int i
Definition: gmock-matchers_test.cc:764
push
static void push(tarjan *t, const upb_refcounted *r)
Definition: ruby/ext/google/protobuf_c/upb.c:5890
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
a
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:3228
zmq::error_t
Definition: zmq.hpp:290


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