mirror of
https://github.com/zeromq/cppzmq.git
synced 2025-10-16 18:56:56 +02:00
Problem: Socket options lack type-safety (#393)
Solution: Implement a type for each socket option. Each option has an associated type, therefore they can't be simply defined as an enum class. Use new sockopt getter in test util Add socket option get function for strings and tests
This commit is contained in:

committed by
GitHub

parent
10431084bb
commit
a3e5b54c3c
424
tests/socket.cpp
424
tests/socket.cpp
@@ -47,22 +47,424 @@ TEST_CASE("socket swap", "[socket]")
|
||||
swap(socket1, socket2);
|
||||
}
|
||||
|
||||
#ifdef ZMQ_CPP11
|
||||
TEST_CASE("socket options", "[socket]")
|
||||
{
|
||||
zmq::context_t context;
|
||||
zmq::socket_t socket(context, zmq::socket_type::router);
|
||||
|
||||
#ifdef ZMQ_IMMEDIATE
|
||||
socket.set(zmq::sockopt::immediate, 0);
|
||||
socket.set(zmq::sockopt::immediate, false);
|
||||
CHECK(socket.get(zmq::sockopt::immediate) == false);
|
||||
// unit out of range
|
||||
CHECK_THROWS_AS(socket.set(zmq::sockopt::immediate, 80), const zmq::error_t &);
|
||||
#endif
|
||||
#ifdef ZMQ_LINGER
|
||||
socket.set(zmq::sockopt::linger, 55);
|
||||
CHECK(socket.get(zmq::sockopt::linger) == 55);
|
||||
#endif
|
||||
#ifdef ZMQ_ROUTING_ID
|
||||
const std::string id = "foobar";
|
||||
socket.set(zmq::sockopt::routing_id, "foobar");
|
||||
socket.set(zmq::sockopt::routing_id, zmq::buffer(id));
|
||||
socket.set(zmq::sockopt::routing_id, id);
|
||||
#ifdef ZMQ_CPP17
|
||||
socket.set(zmq::sockopt::routing_id, std::string_view{id});
|
||||
#endif
|
||||
|
||||
std::string id_ret(10, ' ');
|
||||
auto size = socket.get(zmq::sockopt::routing_id, zmq::buffer(id_ret));
|
||||
id_ret.resize(size);
|
||||
CHECK(id == id_ret);
|
||||
auto stropt = socket.get(zmq::sockopt::routing_id);
|
||||
CHECK(id == stropt);
|
||||
|
||||
std::string id_ret_small(3, ' ');
|
||||
// truncated
|
||||
CHECK_THROWS_AS(socket.get(zmq::sockopt::routing_id, zmq::buffer(id_ret_small)),
|
||||
const zmq::error_t &);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void check_array_opt(T opt,
|
||||
zmq::socket_t &sock,
|
||||
std::string info,
|
||||
bool set_only = false)
|
||||
{
|
||||
const std::string val = "foobar";
|
||||
INFO("setting " + info);
|
||||
sock.set(opt, val);
|
||||
if (set_only)
|
||||
return;
|
||||
|
||||
INFO("getting " + info);
|
||||
auto s = sock.get(opt);
|
||||
CHECK(s == val);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void check_array_opt_get(T opt, zmq::socket_t &sock, std::string info)
|
||||
{
|
||||
INFO("getting " + info);
|
||||
(void) sock.get(opt);
|
||||
}
|
||||
|
||||
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 0, 0)
|
||||
template<class T> void check_bin_z85(T opt, zmq::socket_t &sock, std::string str_val)
|
||||
{
|
||||
std::vector<uint8_t> bin_val(32);
|
||||
const auto dret = zmq_z85_decode(bin_val.data(), str_val.c_str());
|
||||
CHECK(dret != nullptr);
|
||||
|
||||
sock.set(opt, str_val);
|
||||
sock.set(opt, zmq::buffer(bin_val));
|
||||
auto sv = sock.get(opt);
|
||||
CHECK(sv == str_val);
|
||||
|
||||
auto bv = sock.get(opt, 32);
|
||||
REQUIRE(bv.size() == bin_val.size());
|
||||
CHECK(std::memcmp(bv.data(), bin_val.data(), bin_val.size()) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("socket check array options", "[socket]")
|
||||
{
|
||||
zmq::context_t context;
|
||||
zmq::socket_t router(context, zmq::socket_type::router);
|
||||
zmq::socket_t xpub(context, zmq::socket_type::xpub);
|
||||
zmq::socket_t sub(context, zmq::socket_type::sub);
|
||||
|
||||
#ifdef ZMQ_BINDTODEVICE
|
||||
// requires setting CAP_NET_RAW
|
||||
//check_array_opt(zmq::sockopt::bindtodevice, router, "bindtodevice");
|
||||
#endif
|
||||
#ifdef ZMQ_CONNECT_ROUTING_ID
|
||||
check_array_opt(zmq::sockopt::connect_routing_id, router, "connect_routing_id",
|
||||
true);
|
||||
#endif
|
||||
#ifdef ZMQ_LAST_ENDPOINT
|
||||
check_array_opt_get(zmq::sockopt::last_endpoint, router, "last_endpoint");
|
||||
#endif
|
||||
#ifdef ZMQ_METADATA
|
||||
router.set(zmq::sockopt::metadata, zmq::str_buffer("X-foo:bar"));
|
||||
#endif
|
||||
#ifdef ZMQ_PLAIN_PASSWORD
|
||||
check_array_opt(zmq::sockopt::plain_password, router, "plain_password");
|
||||
#endif
|
||||
#ifdef ZMQ_PLAIN_USERNAME
|
||||
check_array_opt(zmq::sockopt::plain_username, router, "plain_username");
|
||||
#endif
|
||||
#ifdef ZMQ_ROUTING_ID
|
||||
check_array_opt(zmq::sockopt::routing_id, router, "routing_id");
|
||||
#endif
|
||||
#ifdef ZMQ_SOCKS_PROXY
|
||||
check_array_opt(zmq::sockopt::socks_proxy, router, "socks_proxy");
|
||||
#endif
|
||||
#ifdef ZMQ_SUBSCRIBE
|
||||
check_array_opt(zmq::sockopt::subscribe, sub, "subscribe", true);
|
||||
#endif
|
||||
#ifdef ZMQ_UNSUBSCRIBE
|
||||
check_array_opt(zmq::sockopt::unsubscribe, sub, "unsubscribe", true);
|
||||
#endif
|
||||
#ifdef ZMQ_XPUB_WELCOME_MSG
|
||||
check_array_opt(zmq::sockopt::xpub_welcome_msg, xpub, "xpub_welcome_msg", true);
|
||||
#endif
|
||||
#ifdef ZMQ_ZAP_DOMAIN
|
||||
check_array_opt(zmq::sockopt::zap_domain, router, "zap_domain");
|
||||
#endif
|
||||
|
||||
// curve
|
||||
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 0, 0) && defined(ZMQ_HAS_CAPABILITIES)
|
||||
if (zmq_has("curve") == 1) {
|
||||
const std::string spk = "rq:rM>}U?@Lns47E1%kR.o@n%FcmmsL/@{H8]yf7";
|
||||
const std::string ssk = "JTKVSB%%)wK0E.X)V>+}o?pNmC{O&4W4b!Ni{Lh6";
|
||||
const std::string cpk = "Yne@$w-vo<fVvi]a<NY6T1ed:M$fCG*[IaLV{hID";
|
||||
const std::string csk = "D:)Q[IlAW!ahhC2ac:9*A}h:p?([4%wOTJ%JR%cs";
|
||||
|
||||
zmq::socket_t curve_server(context, zmq::socket_type::router);
|
||||
curve_server.set(zmq::sockopt::curve_server, true);
|
||||
CHECK(curve_server.get(zmq::sockopt::curve_server));
|
||||
check_bin_z85(zmq::sockopt::curve_secretkey, curve_server, ssk);
|
||||
|
||||
zmq::socket_t curve_client(context, zmq::socket_type::router);
|
||||
curve_client.set(zmq::sockopt::curve_server, false);
|
||||
CHECK_FALSE(curve_client.get(zmq::sockopt::curve_server));
|
||||
check_bin_z85(zmq::sockopt::curve_serverkey, curve_client, spk);
|
||||
check_bin_z85(zmq::sockopt::curve_publickey, curve_client, cpk);
|
||||
check_bin_z85(zmq::sockopt::curve_secretkey, curve_client, csk);
|
||||
}
|
||||
#endif
|
||||
|
||||
// gssapi
|
||||
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0) && defined(ZMQ_HAS_CAPABILITIES)
|
||||
if (zmq_has("gssapi") == 1 && false) // TODO enable
|
||||
{
|
||||
zmq::socket_t gss_server(context, zmq::socket_type::router);
|
||||
gss_server.set(zmq::sockopt::gssapi_server, true);
|
||||
CHECK(gss_server.get(zmq::sockopt::gssapi_server) == 1);
|
||||
gss_server.set(zmq::sockopt::gssapi_plaintext, false);
|
||||
CHECK(gss_server.get(zmq::sockopt::gssapi_plaintext) == 0);
|
||||
check_array_opt(zmq::sockopt::gssapi_principal, gss_server,
|
||||
"gssapi_principal");
|
||||
|
||||
zmq::socket_t gss_client(context, zmq::socket_type::router);
|
||||
CHECK(gss_client.get(zmq::sockopt::gssapi_server) == 0);
|
||||
check_array_opt(zmq::sockopt::gssapi_principal, gss_client,
|
||||
"gssapi_principal");
|
||||
check_array_opt(zmq::sockopt::gssapi_service_principal, gss_client,
|
||||
"gssapi_service_principal");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T, class Opt>
|
||||
void check_integral_opt(Opt opt,
|
||||
zmq::socket_t &sock,
|
||||
std::string info,
|
||||
bool set_only = false)
|
||||
{
|
||||
const T val = 1;
|
||||
INFO("setting " + info);
|
||||
sock.set(opt, val);
|
||||
if (set_only)
|
||||
return;
|
||||
|
||||
INFO("getting " + info);
|
||||
auto s = sock.get(opt);
|
||||
CHECK(s == val);
|
||||
}
|
||||
|
||||
template<class T, class Opt>
|
||||
void check_integral_opt_get(Opt opt, zmq::socket_t &sock, std::string info)
|
||||
{
|
||||
INFO("getting " + info);
|
||||
(void) sock.get(opt);
|
||||
}
|
||||
|
||||
TEST_CASE("socket check integral options", "[socket]")
|
||||
{
|
||||
zmq::context_t context;
|
||||
zmq::socket_t router(context, zmq::socket_type::router);
|
||||
zmq::socket_t xpub(context, zmq::socket_type::xpub);
|
||||
zmq::socket_t req(context, zmq::socket_type::req);
|
||||
#ifdef ZMQ_STREAM_NOTIFY
|
||||
zmq::socket_t stream(context, zmq::socket_type::stream);
|
||||
#endif
|
||||
|
||||
#ifdef ZMQ_AFFINITY
|
||||
check_integral_opt<uint64_t>(zmq::sockopt::affinity, router, "affinity");
|
||||
#endif
|
||||
#ifdef ZMQ_BACKLOG
|
||||
check_integral_opt<int>(zmq::sockopt::backlog, router, "backlog");
|
||||
#endif
|
||||
#ifdef ZMQ_CONFLATE
|
||||
check_integral_opt<int>(zmq::sockopt::conflate, router, "conflate");
|
||||
#endif
|
||||
#ifdef ZMQ_CONNECT_TIMEOUT
|
||||
check_integral_opt<int>(zmq::sockopt::connect_timeout, router,
|
||||
"connect_timeout");
|
||||
#endif
|
||||
#ifdef ZMQ_EVENTS
|
||||
check_integral_opt_get<int>(zmq::sockopt::events, router, "events");
|
||||
#endif
|
||||
#ifdef ZMQ_FD
|
||||
check_integral_opt_get<zmq::sockopt::cppzmq_fd_t>(zmq::sockopt::fd, router,
|
||||
"fd");
|
||||
#endif
|
||||
#ifdef ZMQ_HANDSHAKE_IVL
|
||||
check_integral_opt<int>(zmq::sockopt::handshake_ivl, router, "handshake_ivl");
|
||||
#endif
|
||||
#ifdef ZMQ_HEARTBEAT_IVL
|
||||
check_integral_opt<int>(zmq::sockopt::heartbeat_ivl, router, "heartbeat_ivl");
|
||||
#endif
|
||||
#ifdef ZMQ_HEARTBEAT_TIMEOUT
|
||||
check_integral_opt<int>(zmq::sockopt::heartbeat_timeout, router,
|
||||
"heartbeat_timeout");
|
||||
#endif
|
||||
#ifdef ZMQ_HEARTBEAT_TTL
|
||||
router.set(zmq::sockopt::heartbeat_ttl, 100);
|
||||
CHECK(router.get(zmq::sockopt::heartbeat_ttl) == 100);
|
||||
#endif
|
||||
#ifdef ZMQ_IMMEDIATE
|
||||
check_integral_opt<int>(zmq::sockopt::immediate, router, "immediate");
|
||||
#endif
|
||||
#ifdef ZMQ_INVERT_MATCHING
|
||||
check_integral_opt<int>(zmq::sockopt::invert_matching, router,
|
||||
"invert_matching");
|
||||
#endif
|
||||
#ifdef ZMQ_IPV6
|
||||
check_integral_opt<int>(zmq::sockopt::ipv6, router, "ipv6");
|
||||
#endif
|
||||
#ifdef ZMQ_LINGER
|
||||
check_integral_opt<int>(zmq::sockopt::linger, router, "linger");
|
||||
#endif
|
||||
#ifdef ZMQ_MAXMSGSIZE
|
||||
check_integral_opt<int64_t>(zmq::sockopt::maxmsgsize, router, "maxmsgsize");
|
||||
#endif
|
||||
#ifdef ZMQ_MECHANISM
|
||||
check_integral_opt_get<int>(zmq::sockopt::mechanism, router, "mechanism");
|
||||
#endif
|
||||
#ifdef ZMQ_MULTICAST_HOPS
|
||||
check_integral_opt<int>(zmq::sockopt::multicast_hops, router, "multicast_hops");
|
||||
#endif
|
||||
#ifdef ZMQ_MULTICAST_LOOP
|
||||
check_integral_opt<int>(zmq::sockopt::multicast_loop, router, "multicast_loop");
|
||||
#endif
|
||||
#ifdef ZMQ_MULTICAST_MAXTPDU
|
||||
check_integral_opt<int>(zmq::sockopt::multicast_maxtpdu, router,
|
||||
"multicast_maxtpdu");
|
||||
#endif
|
||||
#ifdef ZMQ_PLAIN_SERVER
|
||||
check_integral_opt<int>(zmq::sockopt::plain_server, router, "plain_server");
|
||||
#endif
|
||||
#ifdef ZMQ_USE_FD
|
||||
check_integral_opt<int>(zmq::sockopt::use_fd, router, "use_fd");
|
||||
#endif
|
||||
#ifdef ZMQ_PROBE_ROUTER
|
||||
check_integral_opt<int>(zmq::sockopt::probe_router, router, "probe_router",
|
||||
true);
|
||||
#endif
|
||||
#ifdef ZMQ_RATE
|
||||
check_integral_opt<int>(zmq::sockopt::rate, router, "rate");
|
||||
#endif
|
||||
#ifdef ZMQ_RCVBUF
|
||||
check_integral_opt<int>(zmq::sockopt::rcvbuf, router, "rcvbuf");
|
||||
#endif
|
||||
#ifdef ZMQ_RCVHWM
|
||||
check_integral_opt<int>(zmq::sockopt::rcvhwm, router, "rcvhwm");
|
||||
#endif
|
||||
#ifdef ZMQ_RCVMORE
|
||||
check_integral_opt_get<int>(zmq::sockopt::rcvmore, router, "rcvmore");
|
||||
#endif
|
||||
#ifdef ZMQ_RCVTIMEO
|
||||
check_integral_opt<int>(zmq::sockopt::rcvtimeo, router, "rcvtimeo");
|
||||
#endif
|
||||
#ifdef ZMQ_RECONNECT_IVL
|
||||
check_integral_opt<int>(zmq::sockopt::reconnect_ivl, router, "reconnect_ivl");
|
||||
#endif
|
||||
#ifdef ZMQ_RECONNECT_IVL_MAX
|
||||
check_integral_opt<int>(zmq::sockopt::reconnect_ivl_max, router,
|
||||
"reconnect_ivl_max");
|
||||
#endif
|
||||
#ifdef ZMQ_RECOVERY_IVL
|
||||
check_integral_opt<int>(zmq::sockopt::recovery_ivl, router, "recovery_ivl");
|
||||
#endif
|
||||
#ifdef ZMQ_REQ_CORRELATE
|
||||
check_integral_opt<int>(zmq::sockopt::req_correlate, req, "req_correlate", true);
|
||||
#endif
|
||||
#ifdef ZMQ_REQ_RELAXED
|
||||
check_integral_opt<int>(zmq::sockopt::req_relaxed, req, "req_relaxed", true);
|
||||
#endif
|
||||
#ifdef ZMQ_ROUTER_HANDOVER
|
||||
check_integral_opt<int>(zmq::sockopt::router_handover, router, "router_handover",
|
||||
true);
|
||||
#endif
|
||||
#ifdef ZMQ_ROUTER_MANDATORY
|
||||
check_integral_opt<int>(zmq::sockopt::router_mandatory, router,
|
||||
"router_mandatory", true);
|
||||
#endif
|
||||
#ifdef ZMQ_ROUTER_NOTIFY
|
||||
check_integral_opt<int>(zmq::sockopt::router_notify, router, "router_notify");
|
||||
#endif
|
||||
#ifdef ZMQ_SNDBUF
|
||||
check_integral_opt<int>(zmq::sockopt::sndbuf, router, "sndbuf");
|
||||
#endif
|
||||
#ifdef ZMQ_SNDHWM
|
||||
check_integral_opt<int>(zmq::sockopt::sndhwm, router, "sndhwm");
|
||||
#endif
|
||||
#ifdef ZMQ_SNDTIMEO
|
||||
check_integral_opt<int>(zmq::sockopt::sndtimeo, router, "sndtimeo");
|
||||
#endif
|
||||
#ifdef ZMQ_STREAM_NOTIFY
|
||||
check_integral_opt<int>(zmq::sockopt::stream_notify, stream, "stream_notify",
|
||||
true);
|
||||
#endif
|
||||
#ifdef ZMQ_TCP_KEEPALIVE
|
||||
check_integral_opt<int>(zmq::sockopt::tcp_keepalive, router, "tcp_keepalive");
|
||||
#endif
|
||||
#ifdef ZMQ_TCP_KEEPALIVE_CNT
|
||||
check_integral_opt<int>(zmq::sockopt::tcp_keepalive_cnt, router,
|
||||
"tcp_keepalive_cnt");
|
||||
#endif
|
||||
#ifdef ZMQ_TCP_KEEPALIVE_IDLE
|
||||
check_integral_opt<int>(zmq::sockopt::tcp_keepalive_idle, router,
|
||||
"tcp_keepalive_idle");
|
||||
#endif
|
||||
#ifdef ZMQ_TCP_KEEPALIVE_INTVL
|
||||
check_integral_opt<int>(zmq::sockopt::tcp_keepalive_intvl, router,
|
||||
"tcp_keepalive_intvl");
|
||||
#endif
|
||||
#ifdef ZMQ_TCP_MAXRT
|
||||
check_integral_opt<int>(zmq::sockopt::tcp_maxrt, router, "tcp_maxrt");
|
||||
#endif
|
||||
#ifdef ZMQ_THREAD_SAFE
|
||||
check_integral_opt_get<bool>(zmq::sockopt::thread_safe, router, "thread_safe");
|
||||
#endif
|
||||
#ifdef ZMQ_TOS
|
||||
check_integral_opt<int>(zmq::sockopt::tos, router, "tos");
|
||||
#endif
|
||||
#ifdef ZMQ_TYPE
|
||||
check_integral_opt_get<int>(zmq::sockopt::type, router, "type");
|
||||
#endif
|
||||
|
||||
#ifdef ZMQ_HAVE_VMCI
|
||||
#ifdef ZMQ_VMCI_BUFFER_SIZE
|
||||
check_integral_opt<uint64_t>(zmq::sockopt::vmci_buffer_size, router,
|
||||
"vmci_buffer_size");
|
||||
#endif
|
||||
#ifdef ZMQ_VMCI_BUFFER_MIN_SIZE
|
||||
check_integral_opt<uint64_t>(zmq::sockopt::vmci_buffer_min_size, router,
|
||||
"vmci_buffer_min_size");
|
||||
#endif
|
||||
#ifdef ZMQ_VMCI_BUFFER_MAX_SIZE
|
||||
check_integral_opt<uint64_t>(zmq::sockopt::vmci_buffer_max_size, router,
|
||||
"vmci_buffer_max_size");
|
||||
#endif
|
||||
#ifdef ZMQ_VMCI_CONNECT_TIMEOUT
|
||||
check_integral_opt<int>(zmq::sockopt::vmci_connect_timeout, router,
|
||||
"vmci_connect_timeout");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ZMQ_XPUB_VERBOSE
|
||||
check_integral_opt<int>(zmq::sockopt::xpub_verbose, xpub, "xpub_verbose", true);
|
||||
#endif
|
||||
#ifdef ZMQ_XPUB_VERBOSER
|
||||
check_integral_opt<int>(zmq::sockopt::xpub_verboser, xpub, "xpub_verboser",
|
||||
true);
|
||||
#endif
|
||||
#ifdef ZMQ_XPUB_MANUAL
|
||||
check_integral_opt<int>(zmq::sockopt::xpub_manual, xpub, "xpub_manual", true);
|
||||
#endif
|
||||
#ifdef ZMQ_XPUB_NODROP
|
||||
check_integral_opt<int>(zmq::sockopt::xpub_nodrop, xpub, "xpub_nodrop", true);
|
||||
#endif
|
||||
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN
|
||||
check_integral_opt<int>(zmq::sockopt::zap_enforce_domain, router,
|
||||
"zap_enforce_domain");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TEST_CASE("socket flags", "[socket]")
|
||||
{
|
||||
CHECK((zmq::recv_flags::dontwait | zmq::recv_flags::none)
|
||||
== static_cast<zmq::recv_flags>(ZMQ_DONTWAIT | 0));
|
||||
== static_cast<zmq::recv_flags>(ZMQ_DONTWAIT | 0));
|
||||
CHECK((zmq::recv_flags::dontwait & zmq::recv_flags::none)
|
||||
== static_cast<zmq::recv_flags>(ZMQ_DONTWAIT & 0));
|
||||
== static_cast<zmq::recv_flags>(ZMQ_DONTWAIT & 0));
|
||||
CHECK((zmq::recv_flags::dontwait ^ zmq::recv_flags::none)
|
||||
== static_cast<zmq::recv_flags>(ZMQ_DONTWAIT ^ 0));
|
||||
== static_cast<zmq::recv_flags>(ZMQ_DONTWAIT ^ 0));
|
||||
CHECK(~zmq::recv_flags::dontwait == static_cast<zmq::recv_flags>(~ZMQ_DONTWAIT));
|
||||
|
||||
CHECK((zmq::send_flags::dontwait | zmq::send_flags::sndmore)
|
||||
== static_cast<zmq::send_flags>(ZMQ_DONTWAIT | ZMQ_SNDMORE));
|
||||
== static_cast<zmq::send_flags>(ZMQ_DONTWAIT | ZMQ_SNDMORE));
|
||||
CHECK((zmq::send_flags::dontwait & zmq::send_flags::sndmore)
|
||||
== static_cast<zmq::send_flags>(ZMQ_DONTWAIT & ZMQ_SNDMORE));
|
||||
== static_cast<zmq::send_flags>(ZMQ_DONTWAIT & ZMQ_SNDMORE));
|
||||
CHECK((zmq::send_flags::dontwait ^ zmq::send_flags::sndmore)
|
||||
== static_cast<zmq::send_flags>(ZMQ_DONTWAIT ^ ZMQ_SNDMORE));
|
||||
== static_cast<zmq::send_flags>(ZMQ_DONTWAIT ^ ZMQ_SNDMORE));
|
||||
CHECK(~zmq::send_flags::dontwait == static_cast<zmq::send_flags>(~ZMQ_DONTWAIT));
|
||||
}
|
||||
|
||||
@@ -125,8 +527,8 @@ TEST_CASE("socket send dontwait", "[socket]")
|
||||
std::vector<char> buf(4);
|
||||
auto res = s.send(zmq::buffer(buf), zmq::send_flags::dontwait);
|
||||
CHECK(!res);
|
||||
res = s.send(zmq::buffer(buf),
|
||||
zmq::send_flags::dontwait | zmq::send_flags::sndmore);
|
||||
res =
|
||||
s.send(zmq::buffer(buf), zmq::send_flags::dontwait | zmq::send_flags::sndmore);
|
||||
CHECK(!res);
|
||||
|
||||
zmq::message_t msg;
|
||||
@@ -253,8 +655,7 @@ TEST_CASE("socket proxy", "[socket]")
|
||||
front.bind("inproc://test1");
|
||||
back.bind("inproc://test2");
|
||||
capture.bind("inproc://test3");
|
||||
auto f = std::async(std::launch::async, [&]()
|
||||
{
|
||||
auto f = std::async(std::launch::async, [&]() {
|
||||
auto s1 = std::move(front);
|
||||
auto s2 = std::move(back);
|
||||
auto s3 = std::move(capture);
|
||||
@@ -279,8 +680,7 @@ TEST_CASE("socket proxy steerable", "[socket]")
|
||||
front.bind("inproc://test1");
|
||||
back.bind("inproc://test2");
|
||||
control.connect("inproc://test3");
|
||||
auto f = std::async(std::launch::async, [&]()
|
||||
{
|
||||
auto f = std::async(std::launch::async, [&]() {
|
||||
auto s1 = std::move(front);
|
||||
auto s2 = std::move(back);
|
||||
auto s3 = std::move(control);
|
||||
|
@@ -4,30 +4,14 @@
|
||||
#include <zmq.hpp>
|
||||
|
||||
#if defined(ZMQ_CPP11)
|
||||
#include <array>
|
||||
|
||||
class loopback_ip4_binder
|
||||
inline std::string bind_ip4_loopback(zmq::socket_t &socket)
|
||||
{
|
||||
public:
|
||||
loopback_ip4_binder(zmq::socket_t &socket) { bind(socket); }
|
||||
std::string endpoint() { return endpoint_; }
|
||||
|
||||
private:
|
||||
// Helper function used in constructor
|
||||
// as Gtest allows ASSERT_* only in void returning functions
|
||||
// and constructor/destructor are not.
|
||||
void bind(zmq::socket_t &socket)
|
||||
{
|
||||
REQUIRE_NOTHROW(socket.bind("tcp://127.0.0.1:*"));
|
||||
std::array<char, 100> endpoint{};
|
||||
size_t endpoint_size = endpoint.size();
|
||||
REQUIRE_NOTHROW(
|
||||
socket.getsockopt(ZMQ_LAST_ENDPOINT, endpoint.data(), &endpoint_size));
|
||||
REQUIRE(endpoint_size < endpoint.size());
|
||||
endpoint_ = std::string{endpoint.data()};
|
||||
}
|
||||
std::string endpoint_;
|
||||
};
|
||||
socket.bind("tcp://127.0.0.1:*");
|
||||
std::string endpoint(100, ' ');
|
||||
endpoint.resize(socket.get(zmq::sockopt::last_endpoint, zmq::buffer(endpoint)));
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
struct common_server_client_setup
|
||||
{
|
||||
@@ -39,7 +23,7 @@ struct common_server_client_setup
|
||||
|
||||
void init()
|
||||
{
|
||||
endpoint = loopback_ip4_binder{server}.endpoint();
|
||||
endpoint = bind_ip4_loopback(server);
|
||||
REQUIRE_NOTHROW(client.connect(endpoint));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user