3
3
4
4
#if defined(ZMQ_CPP11) && defined(ZMQ_BUILD_DRAFT_API)
5
5
6
+ #include < array>
7
+
6
8
TEST (poller, create_destroy)
7
9
{
8
10
zmq::poller_t poller;
@@ -26,7 +28,7 @@ TEST(poller, add_handler)
26
28
zmq::context_t context;
27
29
zmq::socket_t socket{context, zmq::socket_type::router};
28
30
zmq::poller_t poller;
29
- std::function< void ()> handler = [](){} ;
31
+ zmq:: poller_t :: handler_t handler;
30
32
ASSERT_NO_THROW (poller.add (socket, ZMQ_POLLIN, handler));
31
33
}
32
34
@@ -35,7 +37,7 @@ TEST(poller, add_handler_invalid_events_type)
35
37
zmq::context_t context;
36
38
zmq::socket_t socket{context, zmq::socket_type::router};
37
39
zmq::poller_t poller;
38
- std::function< void ()> handler = [](){} ;
40
+ zmq:: poller_t :: handler_t handler;
39
41
short invalid_events_type = 2 << 10 ;
40
42
ASSERT_NO_THROW (poller.add (socket, invalid_events_type, handler));
41
43
}
@@ -45,7 +47,7 @@ TEST(poller, add_handler_twice_throws)
45
47
zmq::context_t context;
46
48
zmq::socket_t socket{context, zmq::socket_type::router};
47
49
zmq::poller_t poller;
48
- std::function< void ()> handler = [](){} ;
50
+ zmq:: poller_t :: handler_t handler;
49
51
poller.add (socket, ZMQ_POLLIN, handler);
50
52
ASSERT_THROW (poller.add (socket, ZMQ_POLLIN, handler), zmq::error_t );
51
53
}
@@ -69,26 +71,46 @@ TEST(poller, remove_registered)
69
71
zmq::context_t context;
70
72
zmq::socket_t socket{context, zmq::socket_type::router};
71
73
zmq::poller_t poller;
72
- std::function< void ()> handler = [](){} ;
74
+ zmq:: poller_t :: handler_t handler;
73
75
poller.add (socket, ZMQ_POLLIN, handler);
74
76
ASSERT_NO_THROW (poller.remove (socket));
75
77
}
76
78
79
+ namespace {
80
+
81
+ class loopback_ip4_binder
82
+ {
83
+ public:
84
+ loopback_ip4_binder (zmq::socket_t &socket) { bind (socket); }
85
+ std::string endpoint () { return endpoint_; }
86
+ private:
87
+ // Helper function used in constructor
88
+ // as Gtest allows only void returning functions
89
+ // and constructor/destructor are not.
90
+ void bind (zmq::socket_t &socket)
91
+ {
92
+ ASSERT_NO_THROW (socket.bind (" tcp://127.0.0.1:*" ));
93
+ std::array<char , 100 > endpoint{};
94
+ size_t endpoint_size = endpoint.size ();
95
+ ASSERT_NO_THROW (socket.getsockopt (ZMQ_LAST_ENDPOINT, endpoint.data (),
96
+ &endpoint_size));
97
+ ASSERT_TRUE (endpoint_size < endpoint.size ());
98
+ endpoint_ = std::string{endpoint.data ()};
99
+ }
100
+ std::string endpoint_;
101
+ };
102
+
103
+ } // namespace
104
+
77
105
TEST (poller, poll_basic)
78
106
{
79
107
zmq::context_t context;
80
108
81
109
zmq::socket_t vent{context, zmq::socket_type::push};
82
- ASSERT_NO_THROW (vent. bind ( " tcp://127.0.0.1:* " ) );
110
+ auto endpoint = loopback_ip4_binder (vent). endpoint ( );
83
111
84
112
zmq::socket_t sink{context, zmq::socket_type::pull};
85
- // TODO: this should be simpler...
86
- std::array<char , 100 > endpoint{};
87
- size_t endpoint_size = endpoint.size ();
88
- ASSERT_NO_THROW (vent.getsockopt (ZMQ_LAST_ENDPOINT, endpoint.data (),
89
- &endpoint_size));
90
- ASSERT_TRUE (endpoint_size < endpoint.size ());
91
- ASSERT_NO_THROW (sink.connect (endpoint.data ()));
113
+ ASSERT_NO_THROW (sink.connect (endpoint));
92
114
93
115
std::string message = " H" ;
94
116
@@ -97,12 +119,59 @@ TEST(poller, poll_basic)
97
119
98
120
zmq::poller_t poller;
99
121
bool message_received = false ;
100
- std::function<void ()> handler = [&message_received]() {
122
+ zmq::poller_t ::handler_t handler = [&message_received](short events) {
123
+ ASSERT_TRUE (0 != (events & ZMQ_POLLIN));
101
124
message_received = true ;
102
125
};
103
126
ASSERT_NO_THROW (poller.add (sink, ZMQ_POLLIN, handler));
104
127
ASSERT_NO_THROW (poller.wait (std::chrono::milliseconds{-1 }));
105
128
ASSERT_TRUE (message_received);
106
129
}
107
130
131
+ TEST (poller, client_server)
132
+ {
133
+ zmq::context_t context;
134
+ std::string send_msg = " Hi" ;
135
+
136
+ // Setup server
137
+ zmq::socket_t server{context, zmq::socket_type::router};
138
+ auto endpoint = loopback_ip4_binder (server).endpoint ();
139
+
140
+ // Setup poller
141
+ zmq::poller_t poller;
142
+ bool got_pollin = false ;
143
+ bool got_pollout = false ;
144
+ zmq::poller_t ::handler_t handler = [&](short events) {
145
+ if (0 != (events & ZMQ_POLLIN)) {
146
+ zmq::message_t zmq_msg;
147
+ ASSERT_NO_THROW (server.recv (&zmq_msg)); // skip msg id
148
+ ASSERT_NO_THROW (server.recv (&zmq_msg)); // get message
149
+ std::string recv_msg (zmq_msg.data <char >(),
150
+ zmq_msg.size ());
151
+ ASSERT_EQ (send_msg, recv_msg);
152
+ got_pollin = true ;
153
+ } else if (0 != (events & ZMQ_POLLOUT)) {
154
+ got_pollout = true ;
155
+ } else {
156
+ ASSERT_TRUE (false ) << " Unexpected event type " << events;
157
+ }
158
+ };
159
+ ASSERT_NO_THROW (poller.add (server, ZMQ_POLLIN, handler));
160
+
161
+ // Setup client and send message
162
+ zmq::socket_t client{context, zmq::socket_type::dealer};
163
+ ASSERT_NO_THROW (client.connect (endpoint));
164
+ ASSERT_NO_THROW (client.send (std::begin (send_msg), std::end (send_msg)));
165
+
166
+ ASSERT_NO_THROW (poller.wait (std::chrono::milliseconds{-1 }));
167
+ ASSERT_TRUE (got_pollin);
168
+ ASSERT_FALSE (got_pollout);
169
+
170
+ // Re-add server socket with pollout flag
171
+ ASSERT_NO_THROW (poller.remove (server));
172
+ ASSERT_NO_THROW (poller.add (server, ZMQ_POLLIN | ZMQ_POLLOUT, handler));
173
+ ASSERT_NO_THROW (poller.wait (std::chrono::milliseconds{-1 }));
174
+ ASSERT_TRUE (got_pollout);
175
+ }
176
+
108
177
#endif
0 commit comments