1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-06-17 07:37:13 +02:00

Initial ZMQ bindings.

This commit is contained in:
Sandu Liviu Catalin
2021-02-02 19:07:02 +02:00
parent 82b7f75b80
commit fc9419677f
1092 changed files with 147348 additions and 92 deletions

73
vendor/ZMQ/unittests/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,73 @@
# CMake build script for ZeroMQ unit tests
cmake_minimum_required(VERSION "2.8.1")
set(unittests
unittest_ypipe
unittest_poller
unittest_mtrie
unittest_ip_resolver
unittest_udp_address
unittest_radix_tree
unittest_curve_encoding)
# if(ENABLE_DRAFTS) list(APPEND tests ) endif(ENABLE_DRAFTS)
# add location of platform.hpp for Windows builds
if(WIN32)
add_definitions(-DZMQ_CUSTOM_PLATFORM_HPP)
add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS)
# Same name on 64bit systems
link_libraries(ws2_32.lib)
endif()
include_directories("${ZeroMQ_SOURCE_DIR}/include" "${ZeroMQ_SOURCE_DIR}/src" "${ZeroMQ_BINARY_DIR}")
include_directories("${ZeroMQ_SOURCE_DIR}/external/unity")
foreach(test ${unittests})
# target_sources not supported before CMake 3.1
add_executable(${test} ${test}.cpp "unittest_resolver_common.hpp")
# per-test directories not generated on OS X / Darwin
if(NOT ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang.*")
link_directories(${test} PRIVATE "${ZeroMQ_SOURCE_DIR}/../lib")
endif()
target_link_libraries(${test} testutil-static)
if(RT_LIBRARY)
target_link_libraries(${test} ${RT_LIBRARY})
endif()
if(CMAKE_SYSTEM_NAME MATCHES "QNX")
target_link_libraries(${test} socket)
target_link_libraries(${test} m)
endif()
if(WIN32)
add_test(
NAME ${test}
WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
COMMAND ${test})
else()
add_test(NAME ${test} COMMAND ${test})
endif()
set_tests_properties(${test} PROPERTIES TIMEOUT 10)
# TODO prevent libzmq (non-static) being in the list of link libraries at all
get_target_property(LIBS ${test} LINK_LIBRARIES)
list(REMOVE_ITEM LIBS libzmq)
set_target_properties(${test} PROPERTIES LINK_LIBRARIES "${LIBS}")
endforeach()
# Check whether all tests in the current folder are present TODO duplicated with tests/CMakeLists.txt, define as a
# function?
file(READ "${CMAKE_CURRENT_LIST_FILE}" CURRENT_LIST_FILE_CONTENT)
file(GLOB ALL_TEST_SOURCES "test_*.cpp")
foreach(TEST_SOURCE ${ALL_TEST_SOURCES})
get_filename_component(TESTNAME "${TEST_SOURCE}" NAME_WE)
string(REGEX MATCH "${TESTNAME}" MATCH_TESTNAME "${CURRENT_LIST_FILE_CONTENT}")
if(NOT MATCH_TESTNAME)
message(AUTHOR_WARNING "Test '${TESTNAME}' is not known to CTest.")
endif()
endforeach()

View File

@ -0,0 +1,155 @@
/*
Copyright (c) 2018 Contributors as noted in the AUTHORS file
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../tests/testutil_unity.hpp"
// TODO: remove this ugly hack
#ifdef close
#undef close
#endif
#include <curve_mechanism_base.hpp>
#include <msg.hpp>
#include <random.hpp>
#include <unity.h>
#include <vector>
void setUp ()
{
}
void tearDown ()
{
}
void test_roundtrip (zmq::msg_t *msg_)
{
#ifdef ZMQ_HAVE_CURVE
const std::vector<uint8_t> original (static_cast<uint8_t *> (msg_->data ()),
static_cast<uint8_t *> (msg_->data ())
+ msg_->size ());
zmq::curve_encoding_t encoding_client ("CurveZMQMESSAGEC",
"CurveZMQMESSAGES",
false);
zmq::curve_encoding_t encoding_server ("CurveZMQMESSAGES",
"CurveZMQMESSAGEC",
false);
uint8_t client_public[32];
uint8_t client_secret[32];
TEST_ASSERT_SUCCESS_ERRNO (
crypto_box_keypair (client_public, client_secret));
uint8_t server_public[32];
uint8_t server_secret[32];
TEST_ASSERT_SUCCESS_ERRNO (
crypto_box_keypair (server_public, server_secret));
TEST_ASSERT_SUCCESS_ERRNO (
crypto_box_beforenm (encoding_client.get_writable_precom_buffer (),
server_public, client_secret));
TEST_ASSERT_SUCCESS_ERRNO (
crypto_box_beforenm (encoding_server.get_writable_precom_buffer (),
client_public, server_secret));
TEST_ASSERT_SUCCESS_ERRNO (encoding_client.encode (msg_));
// TODO: This is hacky...
encoding_server.set_peer_nonce (0);
int error_event_code;
TEST_ASSERT_SUCCESS_ERRNO (
encoding_server.decode (msg_, &error_event_code));
TEST_ASSERT_EQUAL_INT (original.size (), msg_->size ());
if (!original.empty ()) {
TEST_ASSERT_EQUAL_UINT8_ARRAY (&original[0], msg_->data (),
original.size ());
}
#else
TEST_IGNORE_MESSAGE ("CURVE support is disabled");
#endif
}
void test_roundtrip_empty ()
{
zmq::msg_t msg;
msg.init ();
test_roundtrip (&msg);
msg.close ();
}
void test_roundtrip_small ()
{
zmq::msg_t msg;
msg.init_size (32);
memcpy (msg.data (), "0123456789ABCDEF0123456789ABCDEF", 32);
test_roundtrip (&msg);
msg.close ();
}
void test_roundtrip_large ()
{
zmq::msg_t msg;
msg.init_size (2048);
for (size_t pos = 0; pos < 2048; pos += 32) {
memcpy (static_cast<char *> (msg.data ()) + pos,
"0123456789ABCDEF0123456789ABCDEF", 32);
}
test_roundtrip (&msg);
msg.close ();
}
void test_roundtrip_empty_more ()
{
zmq::msg_t msg;
msg.init ();
msg.set_flags (zmq::msg_t::more);
test_roundtrip (&msg);
TEST_ASSERT_TRUE (msg.flags () & zmq::msg_t::more);
msg.close ();
}
int main ()
{
setup_test_environment ();
zmq::random_open ();
UNITY_BEGIN ();
RUN_TEST (test_roundtrip_empty);
RUN_TEST (test_roundtrip_small);
RUN_TEST (test_roundtrip_large);
RUN_TEST (test_roundtrip_empty_more);
zmq::random_close ();
return UNITY_END ();
}

View File

@ -0,0 +1,969 @@
/*
Copyright (c) 2018 Contributors as noted in the AUTHORS file
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unity.h>
#include "../src/macros.hpp"
#include "../tests/testutil.hpp"
#include "../tests/testutil_unity.hpp"
#include "../unittests/unittest_resolver_common.hpp"
#include <ip_resolver.hpp>
#include <ip.hpp>
#ifndef _WIN32
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#endif
void setUp ()
{
}
void tearDown ()
{
}
class test_ip_resolver_t ZMQ_FINAL : public zmq::ip_resolver_t
{
public:
test_ip_resolver_t (zmq::ip_resolver_options_t opts_) :
ip_resolver_t (opts_)
{
}
protected:
struct dns_lut_t
{
const char *hostname;
const char *ipv4;
const char *ipv6;
};
int do_getaddrinfo (const char *node_,
const char *service_,
const struct addrinfo *hints_,
struct addrinfo **res_) ZMQ_FINAL
{
static const struct dns_lut_t dns_lut[] = {
{"ip.zeromq.org", "10.100.0.1", "fdf5:d058:d656::1"},
{"ipv4only.zeromq.org", "10.100.0.2", "::ffff:10.100.0.2"},
{"ipv6only.zeromq.org", NULL, "fdf5:d058:d656::2"},
};
unsigned lut_len = sizeof (dns_lut) / sizeof (dns_lut[0]);
struct addrinfo ai;
TEST_ASSERT_NULL (service_);
bool ipv6 = (hints_->ai_family == AF_INET6);
bool no_dns = (hints_->ai_flags & AI_NUMERICHOST) != 0;
const char *ip = NULL;
if (!no_dns) {
for (unsigned i = 0; i < lut_len; i++) {
if (strcmp (dns_lut[i].hostname, node_) == 0) {
if (ipv6) {
ip = dns_lut[i].ipv6;
} else {
ip = dns_lut[i].ipv4;
if (ip == NULL) {
// No address associated with NAME
return EAI_NODATA;
}
}
}
}
}
if (ip == NULL) {
// No entry for 'node_' found in the LUT (or DNS is
// forbidden), assume that it's a numeric IP address
ip = node_;
}
// Call the real getaddrinfo implementation, making sure that it won't
// attempt to resolve using DNS
ai = *hints_;
ai.ai_flags |= AI_NUMERICHOST;
return zmq::ip_resolver_t::do_getaddrinfo (ip, NULL, &ai, res_);
}
unsigned int do_if_nametoindex (const char *ifname_) ZMQ_FINAL
{
static const char *dummy_interfaces[] = {
"lo0",
"eth0",
"eth1",
};
unsigned lut_len =
sizeof (dummy_interfaces) / sizeof (dummy_interfaces[0]);
for (unsigned i = 0; i < lut_len; i++) {
if (strcmp (dummy_interfaces[i], ifname_) == 0) {
// The dummy index will be the position in the array + 1 (0 is
// invalid)
return i + 1;
}
}
// Not found
return 0;
}
};
// Attempt a resolution and test the results. If 'expected_addr_' is NULL
// assume that the resolution is meant to fail.
//
// On windows we can receive an IPv4 address even when an IPv6 is requested, if
// we're in this situation then we compare to 'expected_addr_v4_failover_'
// instead.
static void test_resolve (zmq::ip_resolver_options_t opts_,
const char *name_,
const char *expected_addr_,
uint16_t expected_port_ = 0,
uint16_t expected_zone_ = 0,
const char *expected_addr_v4_failover_ = NULL)
{
zmq::ip_addr_t addr;
int family = opts_.ipv6 () ? AF_INET6 : AF_INET;
if (family == AF_INET6 && !is_ipv6_available ()) {
TEST_IGNORE_MESSAGE ("ipv6 is not available");
}
// Generate an invalid but well-defined 'ip_addr_t'. Avoids testing
// uninitialized values if the code is buggy.
memset (&addr, 0xba, sizeof (addr));
test_ip_resolver_t resolver (opts_);
int rc = resolver.resolve (&addr, name_);
if (expected_addr_ == NULL) {
// TODO also check the expected errno
TEST_ASSERT_EQUAL (-1, rc);
return;
}
TEST_ASSERT_SUCCESS_ERRNO (rc);
validate_address (family, &addr, expected_addr_, expected_port_,
expected_zone_, expected_addr_v4_failover_);
}
// Helper macro to define the v4/v6 function pairs
#define MAKE_TEST_V4V6(_test) \
static void _test##_ipv4 () { _test (false); } \
\
static void _test##_ipv6 () { _test (true); }
static void test_bind_any (bool ipv6_)
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.bindable (true).expect_port (true).ipv6 (ipv6_);
const char *expected = ipv6_ ? "::" : "0.0.0.0";
test_resolve (resolver_opts, "*:*", expected, 0);
}
MAKE_TEST_V4V6 (test_bind_any)
static void test_bind_any_port0 (bool ipv6_)
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.bindable (true).expect_port (true).ipv6 (ipv6_);
// Should be equivalent to "*:*"
const char *expected = ipv6_ ? "::" : "0.0.0.0";
test_resolve (resolver_opts, "*:0", expected, 0);
}
MAKE_TEST_V4V6 (test_bind_any_port0)
static void test_nobind_any (bool ipv6_)
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true).ipv6 (ipv6_);
// Wildcard should be rejected if we're not looking for a
// bindable address
test_resolve (resolver_opts, "*:*", NULL);
}
MAKE_TEST_V4V6 (test_nobind_any)
static void test_nobind_any_port (bool ipv6_)
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true).ipv6 (ipv6_);
// Wildcard should be rejected if we're not looking for a
// bindable address
test_resolve (resolver_opts, "*:1234", NULL);
}
MAKE_TEST_V4V6 (test_nobind_any_port)
static void test_nobind_addr_anyport (bool ipv6_)
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true).ipv6 (ipv6_);
// Wildcard port should be rejected for non-bindable addresses
test_resolve (resolver_opts, "127.0.0.1:*", NULL);
}
MAKE_TEST_V4V6 (test_nobind_addr_anyport)
static void test_nobind_addr_port0 (bool ipv6_)
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true).ipv6 (ipv6_);
// Connecting to port 0 is allowed, although it might not be massively
// useful
const char *expected = ipv6_ ? "::ffff:127.0.0.1" : "127.0.0.1";
const char *fallback = ipv6_ ? "127.0.0.1" : NULL;
test_resolve (resolver_opts, "127.0.0.1:0", expected, 0, 0, fallback);
}
MAKE_TEST_V4V6 (test_nobind_addr_port0)
static void test_parse_ipv4_simple ()
{
zmq::ip_resolver_options_t resolver_opts;
test_resolve (resolver_opts, "1.2.128.129", "1.2.128.129");
}
static void test_parse_ipv4_zero ()
{
zmq::ip_resolver_options_t resolver_opts;
test_resolve (resolver_opts, "0.0.0.0", "0.0.0.0");
}
static void test_parse_ipv4_max ()
{
zmq::ip_resolver_options_t resolver_opts;
test_resolve (resolver_opts, "255.255.255.255", "255.255.255.255");
}
static void test_parse_ipv4_brackets ()
{
zmq::ip_resolver_options_t resolver_opts;
// Not particularly useful, but valid
test_resolve (resolver_opts, "[1.2.128.129]", "1.2.128.129");
}
static void test_parse_ipv4_brackets_missingl ()
{
zmq::ip_resolver_options_t resolver_opts;
test_resolve (resolver_opts, "1.2.128.129]", NULL);
}
static void test_parse_ipv4_brackets_missingr ()
{
zmq::ip_resolver_options_t resolver_opts;
test_resolve (resolver_opts, "[1.2.128.129", NULL);
}
static void test_parse_ipv4_brackets_bad ()
{
zmq::ip_resolver_options_t resolver_opts;
test_resolve (resolver_opts, "[1.2.128].129", NULL);
}
static void test_parse_ipv4_reject_port ()
{
zmq::ip_resolver_options_t resolver_opts;
// No port expected, should be rejected
test_resolve (resolver_opts, "1.2.128.129:123", NULL);
}
static void test_parse_ipv4_reject_any ()
{
zmq::ip_resolver_options_t resolver_opts;
// No port expected, should be rejected
test_resolve (resolver_opts, "1.2.128.129:*", NULL);
}
static void test_parse_ipv4_reject_ipv6 ()
{
zmq::ip_resolver_options_t resolver_opts;
// No port expected, should be rejected
test_resolve (resolver_opts, "::1", NULL);
}
static void test_parse_ipv4_port ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true);
test_resolve (resolver_opts, "1.2.128.129:123", "1.2.128.129", 123);
}
static void test_parse_ipv4_port0 ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true);
// Port 0 is accepted and is equivalent to *
test_resolve (resolver_opts, "1.2.128.129:0", "1.2.128.129", 0);
}
static void test_parse_ipv4_port_garbage ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true);
// The code doesn't validate that the port doesn't contain garbage
test_resolve (resolver_opts, "1.2.3.4:567bad", "1.2.3.4", 567);
}
static void test_parse_ipv4_port_missing ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true);
test_resolve (resolver_opts, "1.2.3.4", NULL);
}
static void test_parse_ipv4_port_bad ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true);
test_resolve (resolver_opts, "1.2.3.4:bad", NULL);
}
static void test_parse_ipv4_port_brackets ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true);
test_resolve (resolver_opts, "[192.168.1.1]:5555", "192.168.1.1", 5555);
}
static void test_parse_ipv4_port_brackets_bad ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true);
test_resolve (resolver_opts, "[192.168.1.1:]5555", NULL);
}
static void test_parse_ipv4_port_brackets_bad2 ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true);
test_resolve (resolver_opts, "[192.168.1.1:5555]", NULL);
}
static void test_parse_ipv4_wild_brackets_bad ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true);
test_resolve (resolver_opts, "[192.168.1.1:*]", NULL);
}
static void test_parse_ipv4_port_ipv6_reject ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true);
test_resolve (resolver_opts, "[::1]:1234", NULL);
}
static void test_parse_ipv6_simple ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
test_resolve (resolver_opts, "::1", "::1");
}
static void test_parse_ipv6_simple2 ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
test_resolve (resolver_opts, "abcd:1234::1:0:234", "abcd:1234::1:0:234");
}
static void test_parse_ipv6_zero ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
test_resolve (resolver_opts, "::", "::");
}
static void test_parse_ipv6_max ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
test_resolve (resolver_opts, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
}
static void test_parse_ipv6_brackets ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
test_resolve (resolver_opts, "[::1]", "::1");
}
static void test_parse_ipv6_brackets_missingl ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
test_resolve (resolver_opts, "::1]", NULL);
}
static void test_parse_ipv6_brackets_missingr ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
test_resolve (resolver_opts, "[::1", NULL);
}
static void test_parse_ipv6_brackets_bad ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
test_resolve (resolver_opts, "[abcd:1234::1:]0:234", NULL);
}
static void test_parse_ipv6_port ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true).expect_port (true);
test_resolve (resolver_opts, "[1234::1]:80", "1234::1", 80);
}
static void test_parse_ipv6_port_any ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true).expect_port (true).bindable (true);
test_resolve (resolver_opts, "[1234::1]:*", "1234::1", 0);
}
static void test_parse_ipv6_port_nobrackets ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true).expect_port (true);
// Should this be allowed? Seems error-prone but so far ZMQ accepts it.
test_resolve (resolver_opts, "abcd:1234::1:0:234:123", "abcd:1234::1:0:234",
123);
}
static void test_parse_ipv4_in_ipv6 ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
// Parsing IPv4 should also work if an IPv6 is requested, it returns an
// IPv6 with the IPv4 address embedded (except sometimes on Windows where
// we end up with an IPv4 anyway)
test_resolve (resolver_opts, "11.22.33.44", "::ffff:11.22.33.44", 0, 0,
"11.22.33.44");
}
static void test_parse_ipv4_in_ipv6_port ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true).expect_port (true);
test_resolve (resolver_opts, "11.22.33.44:55", "::ffff:11.22.33.44", 55, 0,
"11.22.33.44");
}
static void test_parse_ipv6_scope_int ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
test_resolve (resolver_opts, "3000:4:5::1:234%2", "3000:4:5::1:234", 0, 2);
}
static void test_parse_ipv6_scope_zero ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
test_resolve (resolver_opts, "3000:4:5::1:234%0", NULL);
}
static void test_parse_ipv6_scope_int_port ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true).ipv6 (true);
test_resolve (resolver_opts, "3000:4:5::1:234%2:1111", "3000:4:5::1:234",
1111, 2);
}
static void test_parse_ipv6_scope_if ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
test_resolve (resolver_opts, "3000:4:5::1:234%eth1", "3000:4:5::1:234", 0,
3);
}
static void test_parse_ipv6_scope_if_port ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true).ipv6 (true);
test_resolve (resolver_opts, "3000:4:5::1:234%eth0:8080", "3000:4:5::1:234",
8080, 2);
}
static void test_parse_ipv6_scope_if_port_brackets ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true).ipv6 (true);
test_resolve (resolver_opts, "[3000:4:5::1:234%eth0]:8080",
"3000:4:5::1:234", 8080, 2);
}
static void test_parse_ipv6_scope_badif ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true);
test_resolve (resolver_opts, "3000:4:5::1:234%bad0", NULL);
}
static void test_dns_ipv4_simple ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (true);
test_resolve (resolver_opts, "ip.zeromq.org", "10.100.0.1");
}
static void test_dns_ipv4_only ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (true);
test_resolve (resolver_opts, "ipv4only.zeromq.org", "10.100.0.2");
}
static void test_dns_ipv4_invalid ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (true);
test_resolve (resolver_opts, "invalid.zeromq.org", NULL);
}
static void test_dns_ipv4_ipv6 ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (true);
test_resolve (resolver_opts, "ipv6only.zeromq.org", NULL);
}
static void test_dns_ipv4_numeric ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (true);
// Numeric IPs should still work
test_resolve (resolver_opts, "5.4.3.2", "5.4.3.2");
}
static void test_dns_ipv4_port ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.expect_port (true).allow_dns (true);
test_resolve (resolver_opts, "ip.zeromq.org:1234", "10.100.0.1", 1234);
}
static void test_dns_ipv6_simple ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true).allow_dns (true);
test_resolve (resolver_opts, "ip.zeromq.org", "fdf5:d058:d656::1");
}
static void test_dns_ipv6_only ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true).allow_dns (true);
test_resolve (resolver_opts, "ipv6only.zeromq.org", "fdf5:d058:d656::2");
}
static void test_dns_ipv6_invalid ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true).allow_dns (true);
test_resolve (resolver_opts, "invalid.zeromq.org", NULL);
}
static void test_dns_ipv6_ipv4 ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true).allow_dns (true);
// If a host doesn't have an IPv6 then it should resolve as an embedded v4
// address in an IPv6
test_resolve (resolver_opts, "ipv4only.zeromq.org", "::ffff:10.100.0.2");
}
static void test_dns_ipv6_numeric ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true).allow_dns (true);
// Numeric IPs should still work
test_resolve (resolver_opts, "fdf5:d058:d656::1", "fdf5:d058:d656::1");
}
static void test_dns_ipv6_port ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (true).expect_port (true).allow_dns (true);
test_resolve (resolver_opts, "ip.zeromq.org:1234", "fdf5:d058:d656::1",
1234);
}
void test_dns_brackets ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (true);
test_resolve (resolver_opts, "[ip.zeromq.org]", "10.100.0.1");
}
void test_dns_brackets_bad ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (true);
test_resolve (resolver_opts, "[ip.zeromq].org", NULL);
}
void test_dns_brackets_port ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (true);
test_resolve (resolver_opts, "[ip.zeromq.org]:22", "10.100.0.1", 22);
}
void test_dns_brackets_port_bad ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (true);
test_resolve (resolver_opts, "[ip.zeromq.org:22]", NULL);
}
void test_dns_deny (bool ipv6_)
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (false).ipv6 (ipv6_);
// DNS resolution shouldn't work when disallowed
test_resolve (resolver_opts, "ip.zeromq.org", NULL);
}
MAKE_TEST_V4V6 (test_dns_deny)
void test_dns_ipv6_scope ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (true).ipv6 (true);
// Not sure if that's very useful but you could technically add a scope
// identifier to a hostname
test_resolve (resolver_opts, "ip.zeromq.org%lo0", "fdf5:d058:d656::1", 0,
1);
}
void test_dns_ipv6_scope_port ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (true).expect_port (true).ipv6 (true);
// Not sure if that's very useful but you could technically add a scope
// identifier to a hostname
test_resolve (resolver_opts, "ip.zeromq.org%lo0:4444", "fdf5:d058:d656::1",
4444, 1);
}
void test_dns_ipv6_scope_port_brackets ()
{
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.allow_dns (true).expect_port (true).ipv6 (true);
test_resolve (resolver_opts, "[ip.zeromq.org%lo0]:4444",
"fdf5:d058:d656::1", 4444, 1);
}
static void test_addr (int family_, const char *addr_, bool multicast_)
{
if (family_ == AF_INET6 && !is_ipv6_available ()) {
TEST_IGNORE_MESSAGE ("ipv6 is not available");
}
zmq::ip_resolver_options_t resolver_opts;
resolver_opts.ipv6 (family_ == AF_INET6);
test_ip_resolver_t resolver (resolver_opts);
zmq::ip_addr_t addr;
TEST_ASSERT_SUCCESS_ERRNO (resolver.resolve (&addr, addr_));
TEST_ASSERT_EQUAL (family_, addr.family ());
TEST_ASSERT_EQUAL (multicast_, addr.is_multicast ());
}
static void test_addr_unicast_ipv4 ()
{
test_addr (AF_INET, "1.2.3.4", false);
}
static void test_addr_unicast_ipv6 ()
{
test_addr (AF_INET6, "abcd::1", false);
}
static void test_addr_multicast_ipv4 ()
{
test_addr (AF_INET, "230.1.2.3", true);
}
static void test_addr_multicast_ipv6 ()
{
test_addr (AF_INET6, "ffab::1234", true);
}
static void test_addr_multicast_ipv4_min ()
{
test_addr (AF_INET, "224.0.0.0", true);
}
static void test_addr_multicast_ipv6_min ()
{
test_addr (AF_INET6, "ff00::", true);
}
static void test_addr_multicast_ipv4_max ()
{
test_addr (AF_INET, "239.255.255.255", true);
}
static void test_addr_multicast_ipv6_max ()
{
test_addr (AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", true);
}
static void test_addr_multicast_ipv4_sub ()
{
test_addr (AF_INET, "223.255.255.255", false);
}
static void test_addr_multicast_ipv6_sub ()
{
test_addr (AF_INET6, "feff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", false);
}
static void test_addr_multicast_ipv4_over ()
{
test_addr (AF_INET, "240.0.0.0", false);
}
int main (void)
{
zmq::initialize_network ();
setup_test_environment ();
UNITY_BEGIN ();
RUN_TEST (test_bind_any_ipv4);
RUN_TEST (test_bind_any_ipv6);
RUN_TEST (test_bind_any_port0_ipv4);
RUN_TEST (test_bind_any_port0_ipv6);
RUN_TEST (test_nobind_any_ipv4);
RUN_TEST (test_nobind_any_ipv6);
RUN_TEST (test_nobind_any_port_ipv4);
RUN_TEST (test_nobind_any_port_ipv6);
RUN_TEST (test_nobind_addr_anyport_ipv4);
RUN_TEST (test_nobind_addr_anyport_ipv6);
RUN_TEST (test_nobind_addr_port0_ipv4);
RUN_TEST (test_nobind_addr_port0_ipv6);
RUN_TEST (test_parse_ipv4_simple);
RUN_TEST (test_parse_ipv4_zero);
RUN_TEST (test_parse_ipv4_max);
RUN_TEST (test_parse_ipv4_brackets);
RUN_TEST (test_parse_ipv4_brackets_missingl);
RUN_TEST (test_parse_ipv4_brackets_missingr);
RUN_TEST (test_parse_ipv4_brackets_bad);
RUN_TEST (test_parse_ipv4_reject_port);
RUN_TEST (test_parse_ipv4_reject_any);
RUN_TEST (test_parse_ipv4_reject_ipv6);
RUN_TEST (test_parse_ipv4_port);
RUN_TEST (test_parse_ipv4_port0);
RUN_TEST (test_parse_ipv4_port_garbage);
RUN_TEST (test_parse_ipv4_port_missing);
RUN_TEST (test_parse_ipv4_port_bad);
RUN_TEST (test_parse_ipv4_port_brackets);
RUN_TEST (test_parse_ipv4_port_brackets_bad);
RUN_TEST (test_parse_ipv4_port_brackets_bad2);
RUN_TEST (test_parse_ipv4_wild_brackets_bad);
RUN_TEST (test_parse_ipv4_port_ipv6_reject);
RUN_TEST (test_parse_ipv6_simple);
RUN_TEST (test_parse_ipv6_simple2);
RUN_TEST (test_parse_ipv6_zero);
RUN_TEST (test_parse_ipv6_max);
RUN_TEST (test_parse_ipv6_brackets);
RUN_TEST (test_parse_ipv6_brackets_missingl);
RUN_TEST (test_parse_ipv6_brackets_missingr);
RUN_TEST (test_parse_ipv6_brackets_bad);
RUN_TEST (test_parse_ipv6_port);
RUN_TEST (test_parse_ipv6_port_any);
RUN_TEST (test_parse_ipv6_port_nobrackets);
RUN_TEST (test_parse_ipv4_in_ipv6);
RUN_TEST (test_parse_ipv4_in_ipv6_port);
RUN_TEST (test_parse_ipv6_scope_int);
RUN_TEST (test_parse_ipv6_scope_zero);
RUN_TEST (test_parse_ipv6_scope_int_port);
RUN_TEST (test_parse_ipv6_scope_if);
RUN_TEST (test_parse_ipv6_scope_if_port);
RUN_TEST (test_parse_ipv6_scope_if_port_brackets);
RUN_TEST (test_parse_ipv6_scope_badif);
RUN_TEST (test_dns_ipv4_simple);
RUN_TEST (test_dns_ipv4_only);
RUN_TEST (test_dns_ipv4_invalid);
RUN_TEST (test_dns_ipv4_ipv6);
RUN_TEST (test_dns_ipv4_numeric);
RUN_TEST (test_dns_ipv4_port);
RUN_TEST (test_dns_ipv6_simple);
RUN_TEST (test_dns_ipv6_only);
RUN_TEST (test_dns_ipv6_invalid);
RUN_TEST (test_dns_ipv6_ipv4);
RUN_TEST (test_dns_ipv6_numeric);
RUN_TEST (test_dns_ipv6_port);
RUN_TEST (test_dns_brackets);
RUN_TEST (test_dns_brackets_bad);
RUN_TEST (test_dns_deny_ipv4);
RUN_TEST (test_dns_deny_ipv6);
RUN_TEST (test_dns_ipv6_scope);
RUN_TEST (test_dns_ipv6_scope_port);
RUN_TEST (test_dns_ipv6_scope_port_brackets);
RUN_TEST (test_addr_unicast_ipv4);
RUN_TEST (test_addr_unicast_ipv6);
RUN_TEST (test_addr_multicast_ipv4);
RUN_TEST (test_addr_multicast_ipv6);
RUN_TEST (test_addr_multicast_ipv4_min);
RUN_TEST (test_addr_multicast_ipv6_min);
RUN_TEST (test_addr_multicast_ipv4_max);
RUN_TEST (test_addr_multicast_ipv6_max);
RUN_TEST (test_addr_multicast_ipv4_sub);
RUN_TEST (test_addr_multicast_ipv6_sub);
RUN_TEST (test_addr_multicast_ipv4_over);
zmq::shutdown_network ();
return UNITY_END ();
}

458
vendor/ZMQ/unittests/unittest_mtrie.cpp vendored Normal file
View File

@ -0,0 +1,458 @@
/*
Copyright (c) 2018 Contributors as noted in the AUTHORS file
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../tests/testutil.hpp"
#if defined(min)
#undef min
#endif
#include <generic_mtrie_impl.hpp>
#include <unity.h>
void setUp ()
{
}
void tearDown ()
{
}
int getlen (const zmq::generic_mtrie_t<int>::prefix_t &data_)
{
return static_cast<int> (strlen (reinterpret_cast<const char *> (data_)));
}
void test_create ()
{
zmq::generic_mtrie_t<int> mtrie;
}
void mtrie_count (int *pipe_, int *count_)
{
LIBZMQ_UNUSED (pipe_);
++*count_;
}
void test_check_empty_match_nonempty_data ()
{
zmq::generic_mtrie_t<int> mtrie;
const zmq::generic_mtrie_t<int>::prefix_t test_name =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> ("foo");
int count = 0;
mtrie.match (test_name, getlen (test_name), mtrie_count, &count);
TEST_ASSERT_EQUAL_INT (0, count);
}
void test_check_empty_match_empty_data ()
{
zmq::generic_mtrie_t<int> mtrie;
int count = 0;
mtrie.match (NULL, 0, mtrie_count, &count);
TEST_ASSERT_EQUAL_INT (0, count);
}
void test_add_single_entry_match_exact ()
{
int pipe;
zmq::generic_mtrie_t<int> mtrie;
const zmq::generic_mtrie_t<int>::prefix_t test_name =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> ("foo");
bool res = mtrie.add (test_name, getlen (test_name), &pipe);
TEST_ASSERT_TRUE (res);
int count = 0;
mtrie.match (test_name, getlen (test_name), mtrie_count, &count);
TEST_ASSERT_EQUAL_INT (1, count);
}
void test_add_single_entry_twice_match_exact ()
{
int pipe;
zmq::generic_mtrie_t<int> mtrie;
const zmq::generic_mtrie_t<int>::prefix_t test_name =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> ("foo");
bool res = mtrie.add (test_name, getlen (test_name), &pipe);
TEST_ASSERT_TRUE (res);
res = mtrie.add (test_name, getlen (test_name), &pipe);
TEST_ASSERT_FALSE (res);
int count = 0;
mtrie.match (test_name, getlen (test_name), mtrie_count, &count);
TEST_ASSERT_EQUAL_INT (1, count);
}
void test_add_two_entries_with_same_name_match_exact ()
{
int pipe_1, pipe_2;
zmq::generic_mtrie_t<int> mtrie;
const zmq::generic_mtrie_t<int>::prefix_t test_name =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> ("foo");
bool res = mtrie.add (test_name, getlen (test_name), &pipe_1);
TEST_ASSERT_TRUE (res);
res = mtrie.add (test_name, getlen (test_name), &pipe_2);
TEST_ASSERT_FALSE (res);
int count = 0;
mtrie.match (test_name, getlen (test_name), mtrie_count, &count);
TEST_ASSERT_EQUAL_INT (2, count);
}
void test_add_two_entries_match_prefix_and_exact ()
{
int pipe_1, pipe_2;
zmq::generic_mtrie_t<int> mtrie;
const zmq::generic_mtrie_t<int>::prefix_t test_name_prefix =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> ("foo");
const zmq::generic_mtrie_t<int>::prefix_t test_name_full =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> ("foobar");
bool res = mtrie.add (test_name_prefix, getlen (test_name_prefix), &pipe_1);
TEST_ASSERT_TRUE (res);
res = mtrie.add (test_name_full, getlen (test_name_full), &pipe_2);
TEST_ASSERT_TRUE (res);
int count = 0;
mtrie.match (test_name_full, getlen (test_name_full), mtrie_count, &count);
TEST_ASSERT_EQUAL_INT (2, count);
}
void test_add_rm_single_entry_match_exact ()
{
int pipe;
zmq::generic_mtrie_t<int> mtrie;
const zmq::generic_mtrie_t<int>::prefix_t test_name =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> ("foo");
mtrie.add (test_name, getlen (test_name), &pipe);
zmq::generic_mtrie_t<int>::rm_result res =
mtrie.rm (test_name, getlen (test_name), &pipe);
TEST_ASSERT_EQUAL (zmq::generic_mtrie_t<int>::last_value_removed, res);
int count = 0;
mtrie.match (test_name, getlen (test_name), mtrie_count, &count);
TEST_ASSERT_EQUAL_INT (0, count);
}
void test_rm_nonexistent_0_size_empty ()
{
int pipe;
zmq::generic_mtrie_t<int> mtrie;
zmq::generic_mtrie_t<int>::rm_result res = mtrie.rm (0, 0, &pipe);
TEST_ASSERT_EQUAL (zmq::generic_mtrie_t<int>::not_found, res);
}
void test_rm_nonexistent_empty ()
{
int pipe;
zmq::generic_mtrie_t<int> mtrie;
const zmq::generic_mtrie_t<int>::prefix_t test_name =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> ("foo");
zmq::generic_mtrie_t<int>::rm_result res =
mtrie.rm (test_name, getlen (test_name), &pipe);
TEST_ASSERT_EQUAL (zmq::generic_mtrie_t<int>::not_found, res);
int count = 0;
mtrie.match (test_name, getlen (test_name), mtrie_count, &count);
TEST_ASSERT_EQUAL_INT (0, count);
}
void test_add_and_rm_other (const char *add_name_, const char *rm_name_)
{
int addpipe, rmpipe;
zmq::generic_mtrie_t<int> mtrie;
const zmq::generic_mtrie_t<int>::prefix_t add_name_data =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> (add_name_);
const zmq::generic_mtrie_t<int>::prefix_t rm_name_data =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> (rm_name_);
mtrie.add (add_name_data, getlen (add_name_data), &addpipe);
zmq::generic_mtrie_t<int>::rm_result res =
mtrie.rm (rm_name_data, getlen (rm_name_data), &rmpipe);
TEST_ASSERT_EQUAL (zmq::generic_mtrie_t<int>::not_found, res);
{
int count = 0;
mtrie.match (add_name_data, getlen (add_name_data), mtrie_count,
&count);
TEST_ASSERT_EQUAL_INT (1, count);
}
if (strncmp (add_name_, rm_name_,
std::min (strlen (add_name_), strlen (rm_name_) + 1))
!= 0) {
int count = 0;
mtrie.match (rm_name_data, getlen (rm_name_data), mtrie_count, &count);
TEST_ASSERT_EQUAL_INT (0, count);
}
}
void test_rm_nonexistent_nonempty_samename ()
{
// TODO this triggers an assertion
test_add_and_rm_other ("foo", "foo");
}
void test_rm_nonexistent_nonempty_differentname ()
{
test_add_and_rm_other ("foo", "bar");
}
void test_rm_nonexistent_nonempty_prefix ()
{
// TODO here, a test assertion fails
test_add_and_rm_other ("foobar", "foo");
}
void test_rm_nonexistent_nonempty_prefixed ()
{
test_add_and_rm_other ("foo", "foobar");
}
void add_indexed_expect_unique (zmq::generic_mtrie_t<int> &mtrie_,
int *pipes_,
const char **names_,
size_t i_)
{
const zmq::generic_mtrie_t<int>::prefix_t name_data =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> (names_[i_]);
bool res = mtrie_.add (name_data, getlen (name_data), &pipes_[i_]);
TEST_ASSERT_EQUAL (zmq::generic_mtrie_t<int>::last_value_removed, res);
}
void test_rm_nonexistent_between ()
{
int pipes[3];
const char *names[] = {"foo1", "foo2", "foo3"};
zmq::generic_mtrie_t<int> mtrie;
add_indexed_expect_unique (mtrie, pipes, names, 0);
add_indexed_expect_unique (mtrie, pipes, names, 2);
const zmq::generic_mtrie_t<int>::prefix_t name_data =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> (names[1]);
zmq::generic_mtrie_t<int>::rm_result res =
mtrie.rm (name_data, getlen (name_data), &pipes[1]);
TEST_ASSERT_EQUAL (zmq::generic_mtrie_t<int>::not_found, res);
}
template <size_t N>
void add_entries (zmq::generic_mtrie_t<int> &mtrie_,
int (&pipes_)[N],
const char *(&names_)[N])
{
for (size_t i = 0; i < N; ++i) {
add_indexed_expect_unique (mtrie_, pipes_, names_, i);
}
}
void test_add_multiple ()
{
int pipes[3];
const char *names[] = {"foo1", "foo2", "foo3"};
zmq::generic_mtrie_t<int> mtrie;
add_entries (mtrie, pipes, names);
for (size_t i = 0; i < sizeof (names) / sizeof (names[0]); ++i) {
const zmq::generic_mtrie_t<int>::prefix_t name_data =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> (names[i]);
int count = 0;
mtrie.match (name_data, getlen (name_data), mtrie_count, &count);
TEST_ASSERT_EQUAL_INT (1, count);
}
}
void test_add_multiple_reverse ()
{
int pipes[3];
const char *names[] = {"foo1", "foo2", "foo3"};
zmq::generic_mtrie_t<int> mtrie;
for (int i = 2; i >= 0; --i) {
add_indexed_expect_unique (mtrie, pipes, names,
static_cast<size_t> (i));
}
for (size_t i = 0; i < 3; ++i) {
const zmq::generic_mtrie_t<int>::prefix_t name_data =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> (names[i]);
int count = 0;
mtrie.match (name_data, getlen (name_data), mtrie_count, &count);
TEST_ASSERT_EQUAL_INT (1, count);
}
}
template <size_t N> void add_and_rm_entries (const char *(&names_)[N])
{
int pipes[N];
zmq::generic_mtrie_t<int> mtrie;
add_entries (mtrie, pipes, names_);
for (size_t i = 0; i < N; ++i) {
const zmq::generic_mtrie_t<int>::prefix_t name_data =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> (names_[i]);
zmq::generic_mtrie_t<int>::rm_result res =
mtrie.rm (name_data, getlen (name_data), &pipes[i]);
TEST_ASSERT_EQUAL (zmq::generic_mtrie_t<int>::last_value_removed, res);
}
}
void test_rm_multiple_in_order ()
{
const char *names[] = {"foo1", "foo2", "foo3"};
add_and_rm_entries (names);
}
void test_rm_multiple_reverse_order ()
{
const char *names[] = {"foo3", "foo2", "foo1"};
add_and_rm_entries (names);
}
void check_name (zmq::generic_mtrie_t<int>::prefix_t data_,
size_t len_,
const char *name_)
{
TEST_ASSERT_EQUAL_UINT (strlen (name_), len_);
TEST_ASSERT_EQUAL_STRING_LEN (name_, data_, len_);
}
template <size_t N> void add_entries_rm_pipes_unique (const char *(&names_)[N])
{
int pipes[N];
zmq::generic_mtrie_t<int> mtrie;
add_entries (mtrie, pipes, names_);
for (size_t i = 0; i < N; ++i) {
mtrie.rm (&pipes[i], check_name, names_[i], false);
}
}
void test_rm_with_callback_multiple_in_order ()
{
const char *names[] = {"foo1", "foo2", "foo3"};
add_entries_rm_pipes_unique (names);
}
void test_rm_with_callback_multiple_reverse_order ()
{
const char *names[] = {"foo3", "foo2", "foo1"};
add_entries_rm_pipes_unique (names);
}
void check_count (zmq::generic_mtrie_t<int>::prefix_t data_,
size_t len_,
int *count_)
{
--(*count_);
TEST_ASSERT_GREATER_OR_EQUAL (0, *count_);
}
void add_duplicate_entry (zmq::generic_mtrie_t<int> &mtrie_, int (&pipes_)[2])
{
const char *name = "foo";
const zmq::generic_mtrie_t<int>::prefix_t name_data =
reinterpret_cast<zmq::generic_mtrie_t<int>::prefix_t> (name);
bool res = mtrie_.add (name_data, getlen (name_data), &pipes_[0]);
TEST_ASSERT_TRUE (res);
res = mtrie_.add (name_data, getlen (name_data), &pipes_[1]);
TEST_ASSERT_FALSE (res);
}
void test_rm_with_callback_duplicate ()
{
int pipes[2];
zmq::generic_mtrie_t<int> mtrie;
add_duplicate_entry (mtrie, pipes);
int count = 1;
mtrie.rm (&pipes[0], check_count, &count, false);
count = 1;
mtrie.rm (&pipes[1], check_count, &count, false);
}
void test_rm_with_callback_duplicate_uniq_only ()
{
int pipes[2];
zmq::generic_mtrie_t<int> mtrie;
add_duplicate_entry (mtrie, pipes);
int count = 0;
mtrie.rm (&pipes[0], check_count, &count, true);
count = 1;
mtrie.rm (&pipes[1], check_count, &count, true);
}
int main (void)
{
setup_test_environment ();
UNITY_BEGIN ();
RUN_TEST (test_create);
RUN_TEST (test_check_empty_match_nonempty_data);
RUN_TEST (test_check_empty_match_empty_data);
RUN_TEST (test_add_single_entry_match_exact);
RUN_TEST (test_add_single_entry_twice_match_exact);
RUN_TEST (test_add_rm_single_entry_match_exact);
RUN_TEST (test_add_two_entries_match_prefix_and_exact);
RUN_TEST (test_add_two_entries_with_same_name_match_exact);
RUN_TEST (test_rm_nonexistent_0_size_empty);
RUN_TEST (test_rm_nonexistent_empty);
RUN_TEST (test_rm_nonexistent_nonempty_samename);
RUN_TEST (test_rm_nonexistent_nonempty_differentname);
RUN_TEST (test_rm_nonexistent_nonempty_prefix);
RUN_TEST (test_rm_nonexistent_nonempty_prefixed);
RUN_TEST (test_rm_nonexistent_between);
RUN_TEST (test_add_multiple);
RUN_TEST (test_add_multiple_reverse);
RUN_TEST (test_rm_multiple_in_order);
RUN_TEST (test_rm_multiple_reverse_order);
RUN_TEST (test_rm_with_callback_multiple_in_order);
RUN_TEST (test_rm_with_callback_multiple_reverse_order);
RUN_TEST (test_rm_with_callback_duplicate);
RUN_TEST (test_rm_with_callback_duplicate_uniq_only);
return UNITY_END ();
}

280
vendor/ZMQ/unittests/unittest_poller.cpp vendored Normal file
View File

@ -0,0 +1,280 @@
/*
Copyright (c) 2018 Contributors as noted in the AUTHORS file
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../tests/testutil.hpp"
#include <poller.hpp>
#include <i_poll_events.hpp>
#include <ip.hpp>
#include <unity.h>
#ifndef _WIN32
#include <unistd.h>
#define closesocket close
#endif
void setUp ()
{
}
void tearDown ()
{
}
void test_create ()
{
zmq::thread_ctx_t thread_ctx;
zmq::poller_t poller (thread_ctx);
}
#if 0
// TODO this triggers an assertion. should it be a valid use case?
void test_start_empty ()
{
zmq::thread_ctx_t thread_ctx;
zmq::poller_t poller (thread_ctx);
poller.start ();
msleep (SETTLE_TIME);
}
#endif
struct test_events_t : zmq::i_poll_events
{
test_events_t (zmq::fd_t fd_, zmq::poller_t &poller_) :
_fd (fd_),
_poller (poller_)
{
(void) _fd;
}
void in_event () ZMQ_OVERRIDE
{
_poller.rm_fd (_handle);
_handle = (zmq::poller_t::handle_t) NULL;
// this must only be incremented after rm_fd
in_events.add (1);
}
void out_event () ZMQ_OVERRIDE
{
// TODO
}
void timer_event (int id_) ZMQ_OVERRIDE
{
LIBZMQ_UNUSED (id_);
_poller.rm_fd (_handle);
_handle = (zmq::poller_t::handle_t) NULL;
// this must only be incremented after rm_fd
timer_events.add (1);
}
void set_handle (zmq::poller_t::handle_t handle_) { _handle = handle_; }
zmq::atomic_counter_t in_events, timer_events;
private:
zmq::fd_t _fd;
zmq::poller_t &_poller;
zmq::poller_t::handle_t _handle;
};
void wait_in_events (test_events_t &events_)
{
void *watch = zmq_stopwatch_start ();
while (events_.in_events.get () < 1) {
msleep (1);
#ifdef ZMQ_BUILD_DRAFT
TEST_ASSERT_LESS_OR_EQUAL_MESSAGE (SETTLE_TIME,
zmq_stopwatch_intermediate (watch),
"Timeout waiting for in event");
#endif
}
zmq_stopwatch_stop (watch);
}
void wait_timer_events (test_events_t &events_)
{
void *watch = zmq_stopwatch_start ();
while (events_.timer_events.get () < 1) {
msleep (1);
#ifdef ZMQ_BUILD_DRAFT
TEST_ASSERT_LESS_OR_EQUAL_MESSAGE (SETTLE_TIME,
zmq_stopwatch_intermediate (watch),
"Timeout waiting for timer event");
#endif
}
zmq_stopwatch_stop (watch);
}
void create_nonblocking_fdpair (zmq::fd_t *r_, zmq::fd_t *w_)
{
int rc = zmq::make_fdpair (r_, w_);
TEST_ASSERT_EQUAL_INT (0, rc);
TEST_ASSERT_NOT_EQUAL (zmq::retired_fd, *r_);
TEST_ASSERT_NOT_EQUAL (zmq::retired_fd, *w_);
zmq::unblock_socket (*r_);
zmq::unblock_socket (*w_);
}
void send_signal (zmq::fd_t w_)
{
#if defined ZMQ_HAVE_EVENTFD
const uint64_t inc = 1;
ssize_t sz = write (w_, &inc, sizeof (inc));
assert (sz == sizeof (inc));
#else
{
char msg[] = "test";
int rc = send (w_, msg, sizeof (msg), 0);
assert (rc == sizeof (msg));
}
#endif
}
void close_fdpair (zmq::fd_t w_, zmq::fd_t r_)
{
int rc = closesocket (w_);
TEST_ASSERT_EQUAL_INT (0, rc);
#if !defined ZMQ_HAVE_EVENTFD
rc = closesocket (r_);
TEST_ASSERT_EQUAL_INT (0, rc);
#else
LIBZMQ_UNUSED (r_);
#endif
}
void test_add_fd_and_start_and_receive_data ()
{
zmq::thread_ctx_t thread_ctx;
zmq::poller_t poller (thread_ctx);
zmq::fd_t r, w;
create_nonblocking_fdpair (&r, &w);
test_events_t events (r, poller);
zmq::poller_t::handle_t handle = poller.add_fd (r, &events);
events.set_handle (handle);
poller.set_pollin (handle);
poller.start ();
send_signal (w);
wait_in_events (events);
// required cleanup
close_fdpair (w, r);
}
void test_add_fd_and_remove_by_timer ()
{
zmq::fd_t r, w;
create_nonblocking_fdpair (&r, &w);
zmq::thread_ctx_t thread_ctx;
zmq::poller_t poller (thread_ctx);
test_events_t events (r, poller);
zmq::poller_t::handle_t handle = poller.add_fd (r, &events);
events.set_handle (handle);
poller.add_timer (50, &events, 0);
poller.start ();
wait_timer_events (events);
// required cleanup
close_fdpair (w, r);
}
#ifdef _WIN32
void test_add_fd_with_pending_failing_connect ()
{
zmq::thread_ctx_t thread_ctx;
zmq::poller_t poller (thread_ctx);
zmq::fd_t bind_socket = socket (AF_INET, SOCK_STREAM, 0);
sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
addr.sin_port = 0;
TEST_ASSERT_EQUAL_INT (0, bind (bind_socket,
reinterpret_cast<const sockaddr *> (&addr),
sizeof (addr)));
int addr_len = static_cast<int> (sizeof (addr));
TEST_ASSERT_EQUAL_INT (0, getsockname (bind_socket,
reinterpret_cast<sockaddr *> (&addr),
&addr_len));
zmq::fd_t connect_socket = socket (AF_INET, SOCK_STREAM, 0);
zmq::unblock_socket (connect_socket);
TEST_ASSERT_EQUAL_INT (
-1, connect (connect_socket, reinterpret_cast<const sockaddr *> (&addr),
sizeof (addr)));
TEST_ASSERT_EQUAL_INT (WSAEWOULDBLOCK, WSAGetLastError ());
test_events_t events (connect_socket, poller);
zmq::poller_t::handle_t handle = poller.add_fd (connect_socket, &events);
events.set_handle (handle);
poller.set_pollin (handle);
poller.start ();
wait_in_events (events);
int value;
int value_len = sizeof (value);
TEST_ASSERT_EQUAL_INT (0, getsockopt (connect_socket, SOL_SOCKET, SO_ERROR,
reinterpret_cast<char *> (&value),
&value_len));
TEST_ASSERT_EQUAL_INT (WSAECONNREFUSED, value);
// required cleanup
close (connect_socket);
close (bind_socket);
}
#endif
int main (void)
{
UNITY_BEGIN ();
zmq::initialize_network ();
setup_test_environment ();
RUN_TEST (test_create);
RUN_TEST (test_add_fd_and_start_and_receive_data);
RUN_TEST (test_add_fd_and_remove_by_timer);
#if defined _WIN32
RUN_TEST (test_add_fd_with_pending_failing_connect);
#endif
zmq::shutdown_network ();
return UNITY_END ();
}

View File

@ -0,0 +1,290 @@
/*
Copyright (c) 2018 Contributors as noted in the AUTHORS file
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../tests/testutil.hpp"
#include <radix_tree.hpp>
#include <stdint.hpp>
#include <set>
#include <string>
#include <string.h>
#include <unity.h>
#include <vector>
void setUp ()
{
}
void tearDown ()
{
}
bool tree_add (zmq::radix_tree_t &tree_, const std::string &key_)
{
return tree_.add (reinterpret_cast<const unsigned char *> (key_.data ()),
key_.size ());
}
bool tree_rm (zmq::radix_tree_t &tree_, const std::string &key_)
{
return tree_.rm (reinterpret_cast<const unsigned char *> (key_.data ()),
key_.size ());
}
bool tree_check (zmq::radix_tree_t &tree_, const std::string &key_)
{
return tree_.check (reinterpret_cast<const unsigned char *> (key_.data ()),
key_.size ());
}
void test_empty ()
{
zmq::radix_tree_t tree;
TEST_ASSERT_TRUE (tree.size () == 0);
}
void test_add_single_entry ()
{
zmq::radix_tree_t tree;
TEST_ASSERT_TRUE (tree_add (tree, "foo"));
}
void test_add_same_entry_twice ()
{
zmq::radix_tree_t tree;
TEST_ASSERT_TRUE (tree_add (tree, "test"));
TEST_ASSERT_FALSE (tree_add (tree, "test"));
}
void test_rm_when_empty ()
{
zmq::radix_tree_t tree;
TEST_ASSERT_FALSE (tree_rm (tree, "test"));
}
void test_rm_single_entry ()
{
zmq::radix_tree_t tree;
tree_add (tree, "temporary");
TEST_ASSERT_TRUE (tree_rm (tree, "temporary"));
}
void test_rm_unique_entry_twice ()
{
zmq::radix_tree_t tree;
tree_add (tree, "test");
TEST_ASSERT_TRUE (tree_rm (tree, "test"));
TEST_ASSERT_FALSE (tree_rm (tree, "test"));
}
void test_rm_duplicate_entry ()
{
zmq::radix_tree_t tree;
tree_add (tree, "test");
tree_add (tree, "test");
TEST_ASSERT_FALSE (tree_rm (tree, "test"));
TEST_ASSERT_TRUE (tree_rm (tree, "test"));
}
void test_rm_common_prefix ()
{
zmq::radix_tree_t tree;
tree_add (tree, "checkpoint");
tree_add (tree, "checklist");
TEST_ASSERT_FALSE (tree_rm (tree, "check"));
}
void test_rm_common_prefix_entry ()
{
zmq::radix_tree_t tree;
tree_add (tree, "checkpoint");
tree_add (tree, "checklist");
tree_add (tree, "check");
TEST_ASSERT_TRUE (tree_rm (tree, "check"));
}
void test_rm_null_entry ()
{
zmq::radix_tree_t tree;
tree_add (tree, "");
TEST_ASSERT_TRUE (tree_rm (tree, ""));
}
void test_check_empty ()
{
zmq::radix_tree_t tree;
TEST_ASSERT_FALSE (tree_check (tree, "foo"));
}
void test_check_added_entry ()
{
zmq::radix_tree_t tree;
tree_add (tree, "entry");
TEST_ASSERT_TRUE (tree_check (tree, "entry"));
}
void test_check_common_prefix ()
{
zmq::radix_tree_t tree;
tree_add (tree, "introduce");
tree_add (tree, "introspect");
TEST_ASSERT_FALSE (tree_check (tree, "intro"));
}
void test_check_prefix ()
{
zmq::radix_tree_t tree;
tree_add (tree, "toasted");
TEST_ASSERT_FALSE (tree_check (tree, "toast"));
TEST_ASSERT_FALSE (tree_check (tree, "toaste"));
TEST_ASSERT_FALSE (tree_check (tree, "toaster"));
}
void test_check_nonexistent_entry ()
{
zmq::radix_tree_t tree;
tree_add (tree, "red");
TEST_ASSERT_FALSE (tree_check (tree, "blue"));
}
void test_check_query_longer_than_entry ()
{
zmq::radix_tree_t tree;
tree_add (tree, "foo");
TEST_ASSERT_TRUE (tree_check (tree, "foobar"));
}
void test_check_null_entry_added ()
{
zmq::radix_tree_t tree;
tree_add (tree, "");
TEST_ASSERT_TRUE (tree_check (tree, "all queries return true"));
}
void test_size ()
{
zmq::radix_tree_t tree;
// Adapted from the example on wikipedia.
std::vector<std::string> keys;
keys.push_back ("tester");
keys.push_back ("water");
keys.push_back ("slow");
keys.push_back ("slower");
keys.push_back ("test");
keys.push_back ("team");
keys.push_back ("toast");
for (size_t i = 0; i < keys.size (); ++i)
TEST_ASSERT_TRUE (tree_add (tree, keys[i]));
TEST_ASSERT_TRUE (tree.size () == keys.size ());
for (size_t i = 0; i < keys.size (); ++i)
TEST_ASSERT_FALSE (tree_add (tree, keys[i]));
TEST_ASSERT_TRUE (tree.size () == 2 * keys.size ());
for (size_t i = 0; i < keys.size (); ++i)
TEST_ASSERT_FALSE (tree_rm (tree, keys[i]));
TEST_ASSERT_TRUE (tree.size () == keys.size ());
for (size_t i = 0; i < keys.size (); ++i)
TEST_ASSERT_TRUE (tree_rm (tree, keys[i]));
TEST_ASSERT_TRUE (tree.size () == 0);
}
void return_key (unsigned char *data_, size_t size_, void *arg_)
{
std::vector<std::string> *vec =
reinterpret_cast<std::vector<std::string> *> (arg_);
std::string key;
for (size_t i = 0; i < size_; ++i)
key.push_back (static_cast<char> (data_[i]));
vec->push_back (key);
}
void test_apply ()
{
zmq::radix_tree_t tree;
std::set<std::string> keys;
keys.insert ("tester");
keys.insert ("water");
keys.insert ("slow");
keys.insert ("slower");
keys.insert ("test");
keys.insert ("team");
keys.insert ("toast");
const std::set<std::string>::iterator end = keys.end ();
for (std::set<std::string>::iterator it = keys.begin (); it != end; ++it)
tree_add (tree, *it);
std::vector<std::string> *vec = new std::vector<std::string> ();
tree.apply (return_key, static_cast<void *> (vec));
for (size_t i = 0; i < vec->size (); ++i)
TEST_ASSERT_TRUE (keys.count ((*vec)[i]) > 0);
delete vec;
}
int main (void)
{
setup_test_environment ();
UNITY_BEGIN ();
RUN_TEST (test_empty);
RUN_TEST (test_add_single_entry);
RUN_TEST (test_add_same_entry_twice);
RUN_TEST (test_rm_when_empty);
RUN_TEST (test_rm_single_entry);
RUN_TEST (test_rm_unique_entry_twice);
RUN_TEST (test_rm_duplicate_entry);
RUN_TEST (test_rm_common_prefix);
RUN_TEST (test_rm_common_prefix_entry);
RUN_TEST (test_rm_null_entry);
RUN_TEST (test_check_empty);
RUN_TEST (test_check_added_entry);
RUN_TEST (test_check_common_prefix);
RUN_TEST (test_check_prefix);
RUN_TEST (test_check_nonexistent_entry);
RUN_TEST (test_check_query_longer_than_entry);
RUN_TEST (test_check_null_entry_added);
RUN_TEST (test_size);
RUN_TEST (test_apply);
return UNITY_END ();
}

View File

@ -0,0 +1,77 @@
/*
Copyright (c) 2018 Contributors as noted in the AUTHORS file
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __UNITTEST_RESOLVER_COMMON_INCLUDED__
#define __UNITTEST_RESOLVER_COMMON_INCLUDED__
#include <ip_resolver.hpp>
#include <string.h>
// Attempt a resolution and test the results.
//
// On windows we can receive an IPv4 address even when an IPv6 is requested, if
// we're in this situation then we compare to 'expected_addr_v4_failover_'
// instead.
void validate_address (int family,
const zmq::ip_addr_t *addr_,
const char *expected_addr_,
uint16_t expected_port_ = 0,
uint16_t expected_zone_ = 0,
const char *expected_addr_v4_failover_ = NULL)
{
#if defined ZMQ_HAVE_WINDOWS
if (family == AF_INET6 && expected_addr_v4_failover_ != NULL
&& addr_->family () == AF_INET) {
// We've requested an IPv6 but the system gave us an IPv4, use the
// failover address
family = AF_INET;
expected_addr_ = expected_addr_v4_failover_;
}
#else
(void) expected_addr_v4_failover_;
#endif
TEST_ASSERT_EQUAL (family, addr_->family ());
if (family == AF_INET6) {
struct in6_addr expected_addr;
const sockaddr_in6 *ip6_addr = &addr_->ipv6;
TEST_ASSERT_EQUAL (
1, test_inet_pton (AF_INET6, expected_addr_, &expected_addr));
int neq = memcmp (&ip6_addr->sin6_addr, &expected_addr,
sizeof (expected_addr_));
TEST_ASSERT_EQUAL (0, neq);
TEST_ASSERT_EQUAL (htons (expected_port_), ip6_addr->sin6_port);
TEST_ASSERT_EQUAL (expected_zone_, ip6_addr->sin6_scope_id);
} else {
struct in_addr expected_addr;
const sockaddr_in *ip4_addr = &addr_->ipv4;
TEST_ASSERT_EQUAL (
1, test_inet_pton (AF_INET, expected_addr_, &expected_addr));
TEST_ASSERT_EQUAL (expected_addr.s_addr, ip4_addr->sin_addr.s_addr);
TEST_ASSERT_EQUAL (htons (expected_port_), ip4_addr->sin_port);
}
}
#endif // __UNITTEST_RESOLVER_COMMON_INCLUDED__

View File

@ -0,0 +1,335 @@
/*
Copyright (c) 2018 Contributors as noted in the AUTHORS file
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unity.h>
#include "../tests/testutil.hpp"
#include "../unittests/unittest_resolver_common.hpp"
#include <ip.hpp>
#include <udp_address.hpp>
void setUp ()
{
}
void tearDown ()
{
}
// Test an UDP address resolution. If 'dest_addr_' is NULL assume the
// resolution is supposed to fail.
static void test_resolve (bool bind_,
int family_,
const char *name_,
const char *target_addr_,
uint16_t expected_port_,
const char *bind_addr_,
bool multicast_)
{
if (family_ == AF_INET6 && !is_ipv6_available ()) {
TEST_IGNORE_MESSAGE ("ipv6 is not available");
}
zmq::udp_address_t addr;
int rc = addr.resolve (name_, bind_, family_ == AF_INET6);
if (target_addr_ == NULL) {
TEST_ASSERT_EQUAL (-1, rc);
TEST_ASSERT_EQUAL (EINVAL, errno);
return;
}
TEST_ASSERT_EQUAL (0, rc);
TEST_ASSERT_EQUAL (multicast_, addr.is_mcast ());
if (bind_addr_ == NULL) {
// Bind ANY
if (family_ == AF_INET) {
bind_addr_ = "0.0.0.0";
} else {
bind_addr_ = "::";
}
}
validate_address (family_, addr.target_addr (), target_addr_,
expected_port_);
validate_address (family_, addr.bind_addr (), bind_addr_, expected_port_);
}
static void test_resolve_bind (int family_,
const char *name_,
const char *dest_addr_,
uint16_t expected_port_ = 0,
const char *bind_addr_ = NULL,
bool multicast_ = false)
{
test_resolve (true, family_, name_, dest_addr_, expected_port_, bind_addr_,
multicast_);
}
static void test_resolve_connect (int family_,
const char *name_,
const char *dest_addr_,
uint16_t expected_port_ = 0,
const char *bind_addr_ = NULL,
bool multicast_ = false)
{
test_resolve (false, family_, name_, dest_addr_, expected_port_, bind_addr_,
multicast_);
}
static void test_resolve_ipv4_simple ()
{
test_resolve_connect (AF_INET, "127.0.0.1:5555", "127.0.0.1", 5555);
}
static void test_resolve_ipv6_simple ()
{
test_resolve_connect (AF_INET6, "[::1]:123", "::1", 123);
}
static void test_resolve_ipv4_bind ()
{
test_resolve_bind (AF_INET, "127.0.0.1:5555", "127.0.0.1", 5555,
"127.0.0.1");
}
static void test_resolve_ipv6_bind ()
{
test_resolve_bind (AF_INET6, "[abcd::1234:1]:5555", "abcd::1234:1", 5555,
"abcd::1234:1");
}
static void test_resolve_ipv4_bind_any ()
{
test_resolve_bind (AF_INET, "*:*", "0.0.0.0", 0, "0.0.0.0");
}
static void test_resolve_ipv6_bind_any ()
{
test_resolve_bind (AF_INET6, "*:*", "::", 0, "::");
}
static void test_resolve_ipv4_bind_anyport ()
{
test_resolve_bind (AF_INET, "127.0.0.1:*", "127.0.0.1", 0, "127.0.0.1");
}
static void test_resolve_ipv6_bind_anyport ()
{
test_resolve_bind (AF_INET6, "[1:2:3:4::5]:*", "1:2:3:4::5", 0,
"1:2:3:4::5");
}
static void test_resolve_ipv4_bind_any_port ()
{
test_resolve_bind (AF_INET, "*:5555", "0.0.0.0", 5555, "0.0.0.0");
}
static void test_resolve_ipv6_bind_any_port ()
{
test_resolve_bind (AF_INET6, "*:5555", "::", 5555, "::");
}
static void test_resolve_ipv4_connect_any ()
{
// Cannot use wildcard for connection
test_resolve_connect (AF_INET, "*:5555", NULL);
}
static void test_resolve_ipv6_connect_any ()
{
// Cannot use wildcard for connection
test_resolve_connect (AF_INET6, "*:5555", NULL);
}
static void test_resolve_ipv4_connect_anyport ()
{
test_resolve_connect (AF_INET, "127.0.0.1:*", NULL);
}
static void test_resolve_ipv6_connect_anyport ()
{
test_resolve_connect (AF_INET6, "[::1]:*", NULL);
}
static void test_resolve_ipv4_connect_port0 ()
{
test_resolve_connect (AF_INET, "127.0.0.1:0", "127.0.0.1", 0);
}
static void test_resolve_ipv6_connect_port0 ()
{
test_resolve_connect (AF_INET6, "[2000:abcd::1]:0", "2000:abcd::1", 0);
}
static void test_resolve_ipv4_bind_mcast ()
{
test_resolve_bind (AF_INET, "239.0.0.1:1234", "239.0.0.1", 1234, "0.0.0.0",
true);
}
static void test_resolve_ipv6_bind_mcast ()
{
test_resolve_bind (AF_INET6, "[ff00::1]:1234", "ff00::1", 1234, "::", true);
}
static void test_resolve_ipv4_connect_mcast ()
{
test_resolve_connect (AF_INET, "239.0.0.1:2222", "239.0.0.1", 2222, NULL,
true);
}
static void test_resolve_ipv6_connect_mcast ()
{
test_resolve_connect (AF_INET6, "[ff00::1]:2222", "ff00::1", 2222, NULL,
true);
}
static void test_resolve_ipv4_mcast_src_bind ()
{
test_resolve_bind (AF_INET, "127.0.0.1;230.2.8.12:5555", "230.2.8.12", 5555,
"127.0.0.1", true);
}
static void test_resolve_ipv6_mcast_src_bind ()
{
if (!is_ipv6_available ()) {
TEST_IGNORE_MESSAGE ("ipv6 is not available");
}
zmq::udp_address_t addr;
int rc = addr.resolve ("[::1];[ffab::4]:5555", true, true);
// For the time being this fails because we only support binding multicast
// by interface name, not interface IP
TEST_ASSERT_EQUAL (-1, rc);
TEST_ASSERT_EQUAL (ENODEV, errno);
}
static void test_resolve_ipv4_mcast_src_bind_any ()
{
test_resolve_bind (AF_INET, "*;230.2.8.12:5555", "230.2.8.12", 5555,
"0.0.0.0", true);
}
static void test_resolve_ipv6_mcast_src_bind_any ()
{
test_resolve_bind (AF_INET6, "*;[ffff::]:5555", "ffff::", 5555, "::", true);
}
static void test_resolve_ipv4_mcast_src_connect ()
{
test_resolve_connect (AF_INET, "8.9.10.11;230.2.8.12:5555", "230.2.8.12",
5555, "8.9.10.11", true);
}
static void test_resolve_ipv6_mcast_src_connect ()
{
if (!is_ipv6_available ()) {
TEST_IGNORE_MESSAGE ("ipv6 is not available");
}
zmq::udp_address_t addr;
int rc = addr.resolve ("[1:2:3::4];[ff01::1]:5555", false, true);
// For the time being this fails because we only support binding multicast
// by interface name, not interface IP
TEST_ASSERT_EQUAL (-1, rc);
TEST_ASSERT_EQUAL (ENODEV, errno);
}
static void test_resolve_ipv4_mcast_src_connect_any ()
{
test_resolve_connect (AF_INET, "*;230.2.8.12:5555", "230.2.8.12", 5555,
"0.0.0.0", true);
}
static void test_resolve_ipv6_mcast_src_connect_any ()
{
test_resolve_connect (AF_INET6, "*;[ff10::1]:5555", "ff10::1", 5555,
"::", true);
}
static void test_resolve_ipv4_mcast_src_bind_bad ()
{
test_resolve_bind (AF_INET, "127.0.0.1;1.2.3.4:5555", NULL);
}
static void test_resolve_ipv6_mcast_src_bind_bad ()
{
test_resolve_bind (AF_INET6, "[::1];[fe00::1]:5555", NULL);
}
static void test_resolve_ipv4_mcast_src_connect_bad ()
{
test_resolve_connect (AF_INET, "127.0.0.1;1.2.3.4:5555", NULL);
}
static void test_resolve_ipv6_mcast_src_connect_bad ()
{
test_resolve_connect (AF_INET6, "[::1];[fe00:1]:5555", NULL);
}
int main (void)
{
zmq::initialize_network ();
setup_test_environment ();
UNITY_BEGIN ();
RUN_TEST (test_resolve_ipv4_simple);
RUN_TEST (test_resolve_ipv6_simple);
RUN_TEST (test_resolve_ipv4_bind);
RUN_TEST (test_resolve_ipv6_bind);
RUN_TEST (test_resolve_ipv4_bind_any);
RUN_TEST (test_resolve_ipv6_bind_any);
RUN_TEST (test_resolve_ipv4_bind_anyport);
RUN_TEST (test_resolve_ipv6_bind_anyport);
RUN_TEST (test_resolve_ipv4_bind_any_port);
RUN_TEST (test_resolve_ipv6_bind_any_port);
RUN_TEST (test_resolve_ipv4_connect_any);
RUN_TEST (test_resolve_ipv6_connect_any);
RUN_TEST (test_resolve_ipv4_connect_anyport);
RUN_TEST (test_resolve_ipv6_connect_anyport);
RUN_TEST (test_resolve_ipv4_connect_port0);
RUN_TEST (test_resolve_ipv6_connect_port0);
RUN_TEST (test_resolve_ipv4_bind_mcast);
RUN_TEST (test_resolve_ipv6_bind_mcast);
RUN_TEST (test_resolve_ipv4_connect_mcast);
RUN_TEST (test_resolve_ipv6_connect_mcast);
RUN_TEST (test_resolve_ipv4_mcast_src_bind);
RUN_TEST (test_resolve_ipv6_mcast_src_bind);
RUN_TEST (test_resolve_ipv4_mcast_src_bind_any);
RUN_TEST (test_resolve_ipv6_mcast_src_bind_any);
RUN_TEST (test_resolve_ipv4_mcast_src_connect);
RUN_TEST (test_resolve_ipv6_mcast_src_connect);
RUN_TEST (test_resolve_ipv4_mcast_src_connect_any);
RUN_TEST (test_resolve_ipv6_mcast_src_connect_any);
RUN_TEST (test_resolve_ipv4_mcast_src_bind_bad);
RUN_TEST (test_resolve_ipv6_mcast_src_bind_bad);
RUN_TEST (test_resolve_ipv4_mcast_src_connect_bad);
RUN_TEST (test_resolve_ipv6_mcast_src_connect_bad);
zmq::shutdown_network ();
return UNITY_END ();
}

87
vendor/ZMQ/unittests/unittest_ypipe.cpp vendored Normal file
View File

@ -0,0 +1,87 @@
/*
Copyright (c) 2018 Contributors as noted in the AUTHORS file
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../tests/testutil.hpp"
#include <ypipe.hpp>
#include <unity.h>
void setUp ()
{
}
void tearDown ()
{
}
void test_create ()
{
zmq::ypipe_t<int, 1> ypipe;
}
void test_check_read_empty ()
{
zmq::ypipe_t<int, 1> ypipe;
TEST_ASSERT_FALSE (ypipe.check_read ());
}
void test_read_empty ()
{
zmq::ypipe_t<int, 1> ypipe;
int read_value = -1;
TEST_ASSERT_FALSE (ypipe.read (&read_value));
TEST_ASSERT_EQUAL (-1, read_value);
}
void test_write_complete_and_check_read_and_read ()
{
const int value = 42;
zmq::ypipe_t<int, 1> ypipe;
ypipe.write (value, false);
TEST_ASSERT_FALSE (ypipe.check_read ());
int read_value = -1;
TEST_ASSERT_FALSE (ypipe.read (&read_value));
TEST_ASSERT_EQUAL_INT (-1, read_value);
}
void test_write_complete_and_flush_and_check_read_and_read ()
{
const int value = 42;
zmq::ypipe_t<int, 1> ypipe;
ypipe.write (value, false);
ypipe.flush ();
TEST_ASSERT_TRUE (ypipe.check_read ());
int read_value = -1;
TEST_ASSERT_TRUE (ypipe.read (&read_value));
TEST_ASSERT_EQUAL_INT (value, read_value);
}
int main (void)
{
setup_test_environment ();
UNITY_BEGIN ();
RUN_TEST (test_create);
RUN_TEST (test_check_read_empty);
RUN_TEST (test_read_empty);
RUN_TEST (test_write_complete_and_check_read_and_read);
RUN_TEST (test_write_complete_and_flush_and_check_read_and_read);
return UNITY_END ();
}