/src/libzmq/tests/testutil.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: MPL-2.0 */ |
2 | | |
3 | | #ifndef __TESTUTIL_HPP_INCLUDED__ |
4 | | #define __TESTUTIL_HPP_INCLUDED__ |
5 | | |
6 | | #if defined ZMQ_CUSTOM_PLATFORM_HPP |
7 | | #include "platform.hpp" |
8 | | #else |
9 | | #include "../src/platform.hpp" |
10 | | #endif |
11 | | #include "../include/zmq.h" |
12 | | #include "../src/stdint.hpp" |
13 | | |
14 | | // For AF_INET and IPPROTO_TCP |
15 | | #if defined _WIN32 |
16 | | #include "../src/windows.hpp" |
17 | | #if defined(__MINGW32__) |
18 | | #include <unistd.h> |
19 | | #endif |
20 | | #else |
21 | | #include <sys/socket.h> |
22 | | #include <netinet/in.h> |
23 | | #include <arpa/inet.h> |
24 | | #include <unistd.h> |
25 | | #include <stdlib.h> |
26 | | #endif |
27 | | |
28 | | // This defines the settle time used in tests; raise this if we |
29 | | // get test failures on slower systems due to binds/connects not |
30 | | // settled. Tested to work reliably at 1 msec on a fast PC. |
31 | | #define SETTLE_TIME 300 // In msec |
32 | | // Commonly used buffer size for ZMQ_LAST_ENDPOINT |
33 | | // this used to be sizeof ("tcp://[::ffff:127.127.127.127]:65536"), but this |
34 | | // may be too short for ipc wildcard binds, e.g. |
35 | | #define MAX_SOCKET_STRING 256 |
36 | | |
37 | | // We need to test codepaths with non-random bind ports. List them here to |
38 | | // keep them unique, to allow parallel test runs. |
39 | | #define ENDPOINT_0 "tcp://127.0.0.1:5555" |
40 | | #define ENDPOINT_1 "tcp://127.0.0.1:5556" |
41 | | #define ENDPOINT_2 "tcp://127.0.0.1:5557" |
42 | | #define ENDPOINT_3 "tcp://127.0.0.1:5558" |
43 | | #define ENDPOINT_4 "udp://127.0.0.1:5559" |
44 | | #define ENDPOINT_5 "udp://127.0.0.1:5560" |
45 | | #define PORT_6 5561 |
46 | | |
47 | | // For tests that mock ZMTP |
48 | | const uint8_t zmtp_greeting_null[64] = { |
49 | | 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0x7f, 3, 0, 'N', 'U', 'L', 'L', |
50 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
51 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
52 | | |
53 | | const uint8_t zmtp_greeting_curve[64] = { |
54 | | 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0x7f, 3, 0, 'C', 'U', 'R', 'V', |
55 | | 'E', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
56 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
57 | | const uint8_t zmtp_ready_dealer[43] = { |
58 | | 4, 41, 5, 'R', 'E', 'A', 'D', 'Y', 11, 'S', 'o', 'c', 'k', 'e', 't', |
59 | | '-', 'T', 'y', 'p', 'e', 0, 0, 0, 6, 'D', 'E', 'A', 'L', 'E', 'R', |
60 | | 8, 'I', 'd', 'e', 'n', 't', 'i', 't', 'y', 0, 0, 0, 0}; |
61 | | const uint8_t zmtp_ready_xpub[28] = { |
62 | | 4, 26, 5, 'R', 'E', 'A', 'D', 'Y', 11, 'S', 'o', 'c', 'k', 'e', |
63 | | 't', '-', 'T', 'y', 'p', 'e', 0, 0, 0, 4, 'X', 'P', 'U', 'B'}; |
64 | | const uint8_t zmtp_ready_sub[27] = { |
65 | | 4, 25, 5, 'R', 'E', 'A', 'D', 'Y', 11, 'S', 'o', 'c', 'k', 'e', |
66 | | 't', '-', 'T', 'y', 'p', 'e', 0, 0, 0, 3, 'S', 'U', 'B'}; |
67 | | |
68 | | #undef NDEBUG |
69 | | |
70 | | #ifndef MSG_NOSIGNAL |
71 | | #define MSG_NOSIGNAL 0 |
72 | | #endif |
73 | | |
74 | | // duplicated from fd.hpp |
75 | | #ifdef ZMQ_HAVE_WINDOWS |
76 | | #ifndef NOMINMAX |
77 | | #define NOMINMAX // Macros min(a,b) and max(a,b) |
78 | | #endif |
79 | | |
80 | | #include <winsock2.h> |
81 | | #include <ws2tcpip.h> |
82 | | #include <stdexcept> |
83 | | #define close closesocket |
84 | | typedef int socket_size_t; |
85 | | inline const char *as_setsockopt_opt_t (const void *opt) |
86 | | { |
87 | | return static_cast<const char *> (opt); |
88 | | } |
89 | | #else |
90 | | typedef size_t socket_size_t; |
91 | | inline const void *as_setsockopt_opt_t (const void *opt_) |
92 | 0 | { |
93 | 0 | return opt_; |
94 | 0 | } |
95 | | #endif |
96 | | |
97 | | // duplicated from fd.hpp |
98 | | typedef zmq_fd_t fd_t; |
99 | | #ifdef ZMQ_HAVE_WINDOWS |
100 | | #if defined _MSC_VER && _MSC_VER <= 1400 |
101 | | enum |
102 | | { |
103 | | retired_fd = (zmq_fd_t) (~0) |
104 | | }; |
105 | | #else |
106 | | enum |
107 | | #if _MSC_VER >= 1800 |
108 | | : zmq_fd_t |
109 | | #endif |
110 | | { |
111 | | retired_fd = INVALID_SOCKET |
112 | | }; |
113 | | #endif |
114 | | #else |
115 | | enum |
116 | | { |
117 | | retired_fd = -1 |
118 | | }; |
119 | | #endif |
120 | | |
121 | | // In MSVC prior to v14, snprintf is not available |
122 | | // The closest implementation is the _snprintf_s function |
123 | | #if defined _MSC_VER && _MSC_VER < 1900 |
124 | | #define snprintf(buffer_, count_, format_, ...) \ |
125 | | _snprintf_s (buffer_, count_, _TRUNCATE, format_, __VA_ARGS__) |
126 | | #endif |
127 | | |
128 | | #define LIBZMQ_UNUSED(object) (void) object |
129 | | |
130 | | // Bounce a message from client to server and back |
131 | | // For REQ/REP or DEALER/DEALER pairs only |
132 | | void bounce (void *server_, void *client_); |
133 | | |
134 | | // Same as bounce, but expect messages to never arrive |
135 | | // for security or subscriber reasons. |
136 | | void expect_bounce_fail (void *server_, void *client_); |
137 | | |
138 | | // Receive 0MQ string from socket and convert into C string |
139 | | // Caller must free returned string. Returns NULL if the context |
140 | | // is being terminated. |
141 | | char *s_recv (void *socket_); |
142 | | |
143 | | bool streq (const char *lhs, const char *rhs); |
144 | | bool strneq (const char *lhs, const char *rhs); |
145 | | |
146 | | extern const char *SEQ_END; |
147 | | |
148 | | // Sends a message composed of frames that are C strings or null frames. |
149 | | // The list must be terminated by SEQ_END. |
150 | | // Example: s_send_seq (req, "ABC", 0, "DEF", SEQ_END); |
151 | | |
152 | | void s_send_seq (void *socket_, ...); |
153 | | |
154 | | // Receives message a number of frames long and checks that the frames have |
155 | | // the given data which can be either C strings or 0 for a null frame. |
156 | | // The list must be terminated by SEQ_END. |
157 | | // Example: s_recv_seq (rep, "ABC", 0, "DEF", SEQ_END); |
158 | | |
159 | | void s_recv_seq (void *socket_, ...); |
160 | | |
161 | | |
162 | | // Sets a zero linger period on a socket and closes it. |
163 | | void close_zero_linger (void *socket_); |
164 | | |
165 | | // Setups the test environment. Must be called at the beginning of each test |
166 | | // executable. On POSIX systems, it sets an alarm to the specified number of |
167 | | // seconds, after which the test will be killed. Set to 0 to disable this |
168 | | // timeout. |
169 | | void setup_test_environment (int timeout_seconds_ = 60); |
170 | | |
171 | | // Provide portable millisecond sleep |
172 | | // http://www.cplusplus.com/forum/unices/60161/ |
173 | | // http://en.cppreference.com/w/cpp/thread/sleep_for |
174 | | |
175 | | void msleep (int milliseconds_); |
176 | | |
177 | | // check if IPv6 is available (0/false if not, 1/true if it is) |
178 | | // only way to reliably check is to actually open a socket and try to bind it |
179 | | int is_ipv6_available (void); |
180 | | |
181 | | // check if tipc is available (0/false if not, 1/true if it is) |
182 | | // only way to reliably check is to actually open a socket and try to bind it |
183 | | // as it depends on a non-default kernel module to be already loaded |
184 | | int is_tipc_available (void); |
185 | | |
186 | | // Wrapper around 'inet_pton' for systems that don't support it (e.g. Windows |
187 | | // XP) |
188 | | int test_inet_pton (int af_, const char *src_, void *dst_); |
189 | | |
190 | | // Binds an ipv4 BSD socket to an ephemeral port, returns the compiled sockaddr |
191 | | struct sockaddr_in bind_bsd_socket (int socket); |
192 | | |
193 | | // Some custom definitions in addition to IPPROTO_TCP and IPPROTO_UDP |
194 | | #define IPPROTO_WS 10000 |
195 | 0 | #define IPPROTO_WSS 10001 |
196 | | |
197 | | // Connects a BSD socket to the ZMQ endpoint. Works with ipv4/ipv6/unix. |
198 | | fd_t connect_socket (const char *endpoint_, |
199 | | const int af_ = AF_INET, |
200 | | const int protocol_ = IPPROTO_TCP); |
201 | | |
202 | | // Binds a BSD socket to an ephemeral port, returns the file descriptor. |
203 | | // The resulting ZMQ endpoint will be stored in my_endpoint, including the protocol |
204 | | // prefix, so ensure it is writable and of appropriate size. |
205 | | // Works with ipv4/ipv6/unix. With unix sockets address_/port_ can be empty and |
206 | | // my_endpoint_ will contain a random path. |
207 | | fd_t bind_socket_resolve_port (const char *address_, |
208 | | const char *port_, |
209 | | char *my_endpoint_, |
210 | | const int af_ = AF_INET, |
211 | | const int protocol_ = IPPROTO_TCP); |
212 | | |
213 | | int fuzzer_corpus_encode (const char *filename, |
214 | | uint8_t ***data, |
215 | | size_t **len, |
216 | | size_t *num_cases); |
217 | | |
218 | | #endif |