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:
73
vendor/ZMQ/unittests/CMakeLists.txt
vendored
Normal file
73
vendor/ZMQ/unittests/CMakeLists.txt
vendored
Normal 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()
|
155
vendor/ZMQ/unittests/unittest_curve_encoding.cpp
vendored
Normal file
155
vendor/ZMQ/unittests/unittest_curve_encoding.cpp
vendored
Normal 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 ();
|
||||
}
|
969
vendor/ZMQ/unittests/unittest_ip_resolver.cpp
vendored
Normal file
969
vendor/ZMQ/unittests/unittest_ip_resolver.cpp
vendored
Normal 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
458
vendor/ZMQ/unittests/unittest_mtrie.cpp
vendored
Normal 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
280
vendor/ZMQ/unittests/unittest_poller.cpp
vendored
Normal 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 ();
|
||||
}
|
290
vendor/ZMQ/unittests/unittest_radix_tree.cpp
vendored
Normal file
290
vendor/ZMQ/unittests/unittest_radix_tree.cpp
vendored
Normal 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 ();
|
||||
}
|
77
vendor/ZMQ/unittests/unittest_resolver_common.hpp
vendored
Normal file
77
vendor/ZMQ/unittests/unittest_resolver_common.hpp
vendored
Normal 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__
|
335
vendor/ZMQ/unittests/unittest_udp_address.cpp
vendored
Normal file
335
vendor/ZMQ/unittests/unittest_udp_address.cpp
vendored
Normal 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
87
vendor/ZMQ/unittests/unittest_ypipe.cpp
vendored
Normal 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 ();
|
||||
}
|
Reference in New Issue
Block a user