2018-05-11 11:43:41 +02:00
|
|
|
#include "testutil.hpp"
|
|
|
|
|
|
|
|
#if defined(ZMQ_CPP11) && defined(ZMQ_BUILD_DRAFT_API)
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
#include <memory>
|
|
|
|
|
2019-04-02 16:01:10 +02:00
|
|
|
#if (__cplusplus >= 201703L)
|
|
|
|
static_assert(std::is_nothrow_swappable<zmq::poller_t<>>::value,
|
|
|
|
"poller_t should be nothrow swappable");
|
|
|
|
#endif
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller create destroy", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::poller_t<> poller;
|
|
|
|
}
|
|
|
|
|
2018-05-12 18:28:28 +02:00
|
|
|
static_assert(!std::is_copy_constructible<zmq::poller_t<>>::value,
|
|
|
|
"poller_t should not be copy-constructible");
|
|
|
|
static_assert(!std::is_copy_assignable<zmq::poller_t<>>::value,
|
|
|
|
"poller_t should not be copy-assignable");
|
2018-05-11 11:43:41 +02:00
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller move construct empty", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::poller_t<> a;
|
2018-05-12 18:28:28 +02:00
|
|
|
zmq::poller_t<> b = std::move(a);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller move assign empty", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::poller_t<> a;
|
|
|
|
zmq::poller_t<> b;
|
2018-05-12 18:28:28 +02:00
|
|
|
b = std::move(a);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2019-04-02 16:01:10 +02:00
|
|
|
TEST_CASE("poller swap", "[poller]")
|
|
|
|
{
|
|
|
|
zmq::poller_t<> a;
|
|
|
|
zmq::poller_t<> b;
|
|
|
|
using std::swap;
|
|
|
|
swap(a, b);
|
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller move construct non empty", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
|
|
|
zmq::socket_t socket{context, zmq::socket_type::router};
|
|
|
|
|
|
|
|
zmq::poller_t<> a;
|
2018-05-12 18:28:28 +02:00
|
|
|
a.add(socket, ZMQ_POLLIN, nullptr);
|
|
|
|
zmq::poller_t<> b = std::move(a);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller move assign non empty", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
|
|
|
zmq::socket_t socket{context, zmq::socket_type::router};
|
|
|
|
|
|
|
|
zmq::poller_t<> a;
|
2018-05-12 18:28:28 +02:00
|
|
|
a.add(socket, ZMQ_POLLIN, nullptr);
|
2018-05-11 11:43:41 +02:00
|
|
|
zmq::poller_t<> b;
|
2018-05-12 18:28:28 +02:00
|
|
|
b = std::move(a);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller add nullptr", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
|
|
|
zmq::socket_t socket{context, zmq::socket_type::router};
|
|
|
|
zmq::poller_t<> poller;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(poller.add(socket, ZMQ_POLLIN, nullptr));
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller add non nullptr", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
|
|
|
zmq::socket_t socket{context, zmq::socket_type::router};
|
|
|
|
zmq::poller_t<> poller;
|
|
|
|
int i;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(poller.add(socket, ZMQ_POLLIN, &i));
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2019-02-04 14:53:03 +01:00
|
|
|
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 3, 0)
|
|
|
|
// this behaviour was added by https://github.com/zeromq/libzmq/pull/3100
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller add handler invalid events type", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
|
|
|
zmq::socket_t socket{context, zmq::socket_type::router};
|
|
|
|
zmq::poller_t<> poller;
|
|
|
|
short invalid_events_type = 2 << 10;
|
2019-02-04 14:53:03 +01:00
|
|
|
CHECK_THROWS_AS(poller.add(socket, invalid_events_type, nullptr), zmq::error_t);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
2019-02-04 14:53:03 +01:00
|
|
|
#endif
|
2018-05-11 11:43:41 +02:00
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller add handler twice throws", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
|
|
|
zmq::socket_t socket{context, zmq::socket_type::router};
|
|
|
|
zmq::poller_t<> poller;
|
2018-05-12 18:28:28 +02:00
|
|
|
poller.add(socket, ZMQ_POLLIN, nullptr);
|
2018-05-11 11:43:41 +02:00
|
|
|
/// \todo the actual error code should be checked
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_THROWS_AS(poller.add(socket, ZMQ_POLLIN, nullptr), zmq::error_t);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller wait with no handlers throws", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::poller_t<> poller;
|
|
|
|
std::vector<zmq_poller_event_t> events;
|
|
|
|
/// \todo the actual error code should be checked
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_THROWS_AS(poller.wait_all(events, std::chrono::milliseconds{10}),
|
2018-05-12 18:28:28 +02:00
|
|
|
zmq::error_t);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller remove unregistered throws", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
|
|
|
zmq::socket_t socket{context, zmq::socket_type::router};
|
|
|
|
zmq::poller_t<> poller;
|
|
|
|
/// \todo the actual error code should be checked
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_THROWS_AS(poller.remove(socket), zmq::error_t);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller remove registered empty", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
|
|
|
zmq::socket_t socket{context, zmq::socket_type::router};
|
|
|
|
zmq::poller_t<> poller;
|
2018-05-12 18:28:28 +02:00
|
|
|
poller.add(socket, ZMQ_POLLIN, nullptr);
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(poller.remove(socket));
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller remove registered non empty", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
|
|
|
zmq::socket_t socket{context, zmq::socket_type::router};
|
|
|
|
zmq::poller_t<> poller;
|
2018-09-23 18:14:25 +02:00
|
|
|
int empty{};
|
|
|
|
poller.add(socket, ZMQ_POLLIN, &empty);
|
|
|
|
CHECK_NOTHROW(poller.remove(socket));
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller poll basic", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
common_server_client_setup s;
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}));
|
2018-05-11 11:43:41 +02:00
|
|
|
|
|
|
|
zmq::poller_t<int> poller;
|
|
|
|
std::vector<zmq_poller_event_t> events{1};
|
|
|
|
int i = 0;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(poller.add(s.server, ZMQ_POLLIN, &i));
|
|
|
|
CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{-1}));
|
|
|
|
CHECK(s.server == events[0].socket);
|
|
|
|
CHECK(&i == events[0].user_data);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller add invalid socket throws", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
|
|
|
zmq::poller_t<> poller;
|
2018-05-11 21:29:15 +02:00
|
|
|
zmq::socket_t a{context, zmq::socket_type::router};
|
2018-05-12 18:28:28 +02:00
|
|
|
zmq::socket_t b{std::move(a)};
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_THROWS_AS(poller.add(a, ZMQ_POLLIN, nullptr), zmq::error_t);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller remove invalid socket throws", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
2018-05-11 21:29:15 +02:00
|
|
|
zmq::socket_t socket{context, zmq::socket_type::router};
|
2018-05-11 11:43:41 +02:00
|
|
|
zmq::poller_t<> poller;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(poller.add(socket, ZMQ_POLLIN, nullptr));
|
2018-05-11 11:43:41 +02:00
|
|
|
std::vector<zmq::socket_t> sockets;
|
2018-05-12 18:28:28 +02:00
|
|
|
sockets.emplace_back(std::move(socket));
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_THROWS_AS(poller.remove(socket), zmq::error_t);
|
|
|
|
CHECK_NOTHROW(poller.remove(sockets[0]));
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller modify empty throws", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
2018-05-11 21:29:15 +02:00
|
|
|
zmq::socket_t socket{context, zmq::socket_type::push};
|
2018-05-11 11:43:41 +02:00
|
|
|
zmq::poller_t<> poller;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_THROWS_AS(poller.modify(socket, ZMQ_POLLIN), zmq::error_t);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller modify invalid socket throws", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
2018-05-11 21:29:15 +02:00
|
|
|
zmq::socket_t a{context, zmq::socket_type::push};
|
2018-05-12 18:28:28 +02:00
|
|
|
zmq::socket_t b{std::move(a)};
|
2018-05-11 11:43:41 +02:00
|
|
|
zmq::poller_t<> poller;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_THROWS_AS(poller.modify(a, ZMQ_POLLIN), zmq::error_t);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller modify not added throws", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
2018-05-11 21:29:15 +02:00
|
|
|
zmq::socket_t a{context, zmq::socket_type::push};
|
|
|
|
zmq::socket_t b{context, zmq::socket_type::push};
|
2018-05-11 11:43:41 +02:00
|
|
|
zmq::poller_t<> poller;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(poller.add(a, ZMQ_POLLIN, nullptr));
|
|
|
|
CHECK_THROWS_AS(poller.modify(b, ZMQ_POLLIN), zmq::error_t);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller modify simple", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
zmq::context_t context;
|
2018-05-11 21:29:15 +02:00
|
|
|
zmq::socket_t a{context, zmq::socket_type::push};
|
2018-05-11 11:43:41 +02:00
|
|
|
zmq::poller_t<> poller;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(poller.add(a, ZMQ_POLLIN, nullptr));
|
|
|
|
CHECK_NOTHROW(poller.modify(a, ZMQ_POLLIN | ZMQ_POLLOUT));
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller poll client server", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
// Setup server and client
|
|
|
|
common_server_client_setup s;
|
|
|
|
|
|
|
|
// Setup poller
|
|
|
|
zmq::poller_t<> poller;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(poller.add(s.server, ZMQ_POLLIN, s.server));
|
2018-05-11 11:43:41 +02:00
|
|
|
|
|
|
|
// client sends message
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}));
|
2018-05-11 11:43:41 +02:00
|
|
|
|
|
|
|
// wait for message and verify events
|
2018-05-12 18:28:28 +02:00
|
|
|
std::vector<zmq_poller_event_t> events(1);
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{500}));
|
|
|
|
CHECK(ZMQ_POLLIN == events[0].events);
|
2018-05-11 11:43:41 +02:00
|
|
|
|
|
|
|
// Modify server socket with pollout flag
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(poller.modify(s.server, ZMQ_POLLIN | ZMQ_POLLOUT));
|
|
|
|
CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{500}));
|
|
|
|
CHECK((ZMQ_POLLIN | ZMQ_POLLOUT) == events[0].events);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller wait one return", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
// Setup server and client
|
|
|
|
common_server_client_setup s;
|
|
|
|
|
|
|
|
// Setup poller
|
|
|
|
zmq::poller_t<> poller;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(poller.add(s.server, ZMQ_POLLIN, nullptr));
|
2018-05-11 11:43:41 +02:00
|
|
|
|
|
|
|
// client sends message
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}));
|
2018-05-11 11:43:41 +02:00
|
|
|
|
|
|
|
// wait for message and verify events
|
2018-05-12 18:28:28 +02:00
|
|
|
std::vector<zmq_poller_event_t> events(1);
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK(1 == poller.wait_all(events, std::chrono::milliseconds{500}));
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller wait on move constructed", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
common_server_client_setup s;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}));
|
2018-05-11 11:43:41 +02:00
|
|
|
zmq::poller_t<> a;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(a.add(s.server, ZMQ_POLLIN, nullptr));
|
2018-05-12 18:28:28 +02:00
|
|
|
zmq::poller_t<> b{std::move(a)};
|
|
|
|
std::vector<zmq_poller_event_t> events(1);
|
2018-05-11 11:43:41 +02:00
|
|
|
/// \todo the actual error code should be checked
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_THROWS_AS(a.wait_all(events, std::chrono::milliseconds{10}), zmq::error_t);
|
|
|
|
CHECK(1 == b.wait_all(events, std::chrono::milliseconds{-1}));
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller wait on move assigned", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
common_server_client_setup s;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}));
|
2018-05-11 11:43:41 +02:00
|
|
|
zmq::poller_t<> a;
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(a.add(s.server, ZMQ_POLLIN, nullptr));
|
2018-05-11 11:43:41 +02:00
|
|
|
zmq::poller_t<> b;
|
2018-05-12 18:28:28 +02:00
|
|
|
b = {std::move(a)};
|
2018-09-23 18:14:25 +02:00
|
|
|
/// \todo the TEST_CASE error code should be checked
|
2018-05-12 18:28:28 +02:00
|
|
|
std::vector<zmq_poller_event_t> events(1);
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_THROWS_AS(a.wait_all(events, std::chrono::milliseconds{10}), zmq::error_t);
|
|
|
|
CHECK(1 == b.wait_all(events, std::chrono::milliseconds{-1}));
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
2018-09-23 18:14:25 +02:00
|
|
|
TEST_CASE("poller remove from handler", "[poller]")
|
2018-05-11 11:43:41 +02:00
|
|
|
{
|
|
|
|
constexpr auto ITER_NO = 10;
|
|
|
|
|
|
|
|
// Setup servers and clients
|
|
|
|
std::vector<common_server_client_setup> setup_list;
|
|
|
|
for (auto i = 0; i < ITER_NO; ++i)
|
2018-05-12 18:28:28 +02:00
|
|
|
setup_list.emplace_back(common_server_client_setup{});
|
2018-05-11 11:43:41 +02:00
|
|
|
|
|
|
|
// Setup poller
|
|
|
|
zmq::poller_t<> poller;
|
|
|
|
for (auto i = 0; i < ITER_NO; ++i) {
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(poller.add(setup_list[i].server, ZMQ_POLLIN, nullptr));
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
// Clients send messages
|
2018-05-11 21:29:15 +02:00
|
|
|
for (auto &s : setup_list) {
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK_NOTHROW(s.client.send(zmq::message_t{"Hi"}));
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for all servers to receive a message
|
2018-05-11 21:29:15 +02:00
|
|
|
for (auto &s : setup_list) {
|
|
|
|
zmq::pollitem_t items[] = {{s.server, 0, ZMQ_POLLIN, 0}};
|
2018-05-12 18:28:28 +02:00
|
|
|
zmq::poll(&items[0], 1);
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fire all handlers in one wait
|
2018-05-12 18:28:28 +02:00
|
|
|
std::vector<zmq_poller_event_t> events(ITER_NO);
|
2018-09-23 18:14:25 +02:00
|
|
|
CHECK(ITER_NO == poller.wait_all(events, std::chrono::milliseconds{-1}));
|
2018-05-11 11:43:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|