1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/* SPDX-License-Identifier: MPL-2.0 */
#include "testutil.hpp"
#include "testutil_unity.hpp"
#include <string.h>
#if defined _WIN32
#include "../src/windows.hpp"
#endif
SETUP_TEARDOWN_TESTCONTEXT
typedef void (*extra_func_t) (void *socket_);
#ifdef ZMQ_BUILD_DRAFT
void set_sockopt_fastpath (void *socket)
{
int value = 1;
int rc =
zmq_setsockopt (socket, ZMQ_LOOPBACK_FASTPATH, &value, sizeof value);
assert (rc == 0);
}
#endif
void test_pair_tcp (extra_func_t extra_func_ = NULL)
{
void *sb = test_context_socket (ZMQ_PAIR);
if (extra_func_)
extra_func_ (sb);
char my_endpoint[MAX_SOCKET_STRING];
bind_loopback_ipv4 (sb, my_endpoint, sizeof my_endpoint);
void *sc = test_context_socket (ZMQ_PAIR);
if (extra_func_)
extra_func_ (sc);
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, my_endpoint));
bounce (sb, sc);
test_context_socket_close (sc);
test_context_socket_close (sb);
}
void test_pair_tcp_regular ()
{
test_pair_tcp ();
}
void test_pair_tcp_connect_by_name ()
{
// all other tcp test cases bind to a loopback wildcard address, then
// retrieve the bound endpoint, which is numerical, and use that to
// connect. this test cases specifically uses "localhost" to connect
// to ensure that names are correctly resolved
void *sb = test_context_socket (ZMQ_PAIR);
char bound_endpoint[MAX_SOCKET_STRING];
bind_loopback_ipv4 (sb, bound_endpoint, sizeof bound_endpoint);
// extract the bound port number
const char *pos = strrchr (bound_endpoint, ':');
TEST_ASSERT_NOT_NULL (pos);
const char connect_endpoint_prefix[] = "tcp://localhost";
char connect_endpoint[MAX_SOCKET_STRING];
strcpy (connect_endpoint, connect_endpoint_prefix);
strcat (connect_endpoint, pos);
void *sc = test_context_socket (ZMQ_PAIR);
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sc, connect_endpoint));
bounce (sb, sc);
test_context_socket_close (sc);
test_context_socket_close (sb);
}
#ifdef ZMQ_BUILD_DRAFT
void test_pair_tcp_fastpath ()
{
test_pair_tcp (set_sockopt_fastpath);
}
#endif
#ifdef _WIN32
void test_io_completion_port ()
{
void *const s = test_context_socket (ZMQ_PAIR);
SOCKET fd;
size_t fd_size = sizeof fd;
TEST_ASSERT_SUCCESS_ERRNO (zmq_getsockopt (s, ZMQ_FD, &fd, &fd_size));
::WSAPROTOCOL_INFO pi;
TEST_ASSERT_SUCCESS_RAW_ERRNO (
::WSADuplicateSocket (fd, ::GetCurrentProcessId (), &pi));
const SOCKET socket = ::WSASocket (pi.iAddressFamily /*AF_INET*/,
pi.iSocketType /*SOCK_STREAM*/,
pi.iProtocol /*IPPROTO_TCP*/, &pi, 0, 0);
const HANDLE iocp =
::CreateIoCompletionPort (INVALID_HANDLE_VALUE, NULL, 0, 0);
TEST_ASSERT_NOT_EQUAL (NULL, iocp);
const HANDLE res =
::CreateIoCompletionPort (reinterpret_cast<HANDLE> (socket), iocp, 0, 0);
TEST_ASSERT_NOT_EQUAL (NULL, res);
TEST_ASSERT_SUCCESS_RAW_ERRNO (closesocket (socket));
TEST_ASSERT_TRUE (CloseHandle (iocp));
test_context_socket_close (s);
}
#endif
int main ()
{
setup_test_environment ();
UNITY_BEGIN ();
RUN_TEST (test_pair_tcp_regular);
RUN_TEST (test_pair_tcp_connect_by_name);
#ifdef ZMQ_BUILD_DRAFT
RUN_TEST (test_pair_tcp_fastpath);
#endif
#ifdef _WIN32
RUN_TEST (test_io_completion_port);
#endif
return UNITY_END ();
}
|