s3:utils: Fix 'Usage:' for 'net ads enctypes'
[samba4-gss.git] / lib / tsocket / tests / test_tstream.c
blob47008bb8bf8e6f5d9d1629ce71d759d9efc96cf4
1 /*
2 * Unix SMB/CIFS implementation.
4 * Copyright (C) 2022 Andrew Bartlett <abartlet@samba.org>
5 * Copyright (C) 2021 Andreas Schneider <asn@samba.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <stdarg.h>
22 #include <stddef.h>
23 #include <stdint.h>
24 #include <setjmp.h>
25 #include <cmocka.h>
26 #include "includes.h"
27 #include "system/network.h"
28 #include "socketpair_tcp.h"
29 #include "tsocket.h"
31 enum socket_pair_selector {
32 SOCKET_SERVER = 0,
33 SOCKET_CLIENT = 1,
36 struct socket_pair {
37 struct tevent_context *ev;
38 int socket_server;
39 int socket_client;
41 /* for tstream tests */
42 int rc;
43 int sys_errno;
44 int expected_errno;
45 struct timeval endtime;
46 size_t max_loops;
47 size_t num_loops;
50 /* If this is too large, we get EPIPE rather than EAGAIN */
51 static const uint8_t TEST_STRING[128] = { 0 };
53 static int sigpipe_setup(void **state)
55 BlockSignals(true, SIGPIPE);
56 return 0;
59 static int setup_socketpair_tcp_context(void **state)
61 int fd[2];
62 struct socket_pair *sp = talloc_zero(NULL, struct socket_pair);
63 assert_non_null(sp);
65 /* Set up a socketpair over TCP to test with */
66 assert_return_code(socketpair_tcp(fd), errno);
68 sp->socket_server = fd[SOCKET_SERVER];
69 sp->socket_client = fd[SOCKET_CLIENT];
71 sp->ev = tevent_context_init(sp);
72 assert_non_null(sp->ev);
74 *state = sp;
75 return 0;
78 static int setup_socketpair_context(void **state)
80 int fd[2];
81 struct socket_pair *sp = talloc_zero(NULL, struct socket_pair);
82 assert_non_null(sp);
84 /* Set up a socketpair over TCP to test with */
85 assert_return_code(socketpair(AF_UNIX, SOCK_STREAM, 0, fd), errno);
87 sp->socket_server = fd[SOCKET_SERVER];
88 sp->socket_client = fd[SOCKET_CLIENT];
90 sp->ev = tevent_context_init(sp);
91 assert_non_null(sp->ev);
93 *state = sp;
94 return 0;
97 static int teardown_socketpair_context(void **state)
99 struct socket_pair *sp = *state;
100 struct socket_pair sp_save = *sp;
102 TALLOC_FREE(sp);
105 * Close these after the TALLOC_FREE() to allow clean shutdown
106 * of epoll() in tstream
108 if (sp_save.socket_client != -1) {
109 close(sp_save.socket_client);
111 if (sp_save.socket_server != -1) {
112 close(sp_save.socket_server);
114 return 0;
118 /* Test socket behaviour */
119 static void test_simple_socketpair(void **state) {
121 struct socket_pair *sp = *state;
123 char buf[sizeof(TEST_STRING)];
125 assert_int_equal(write(sp->socket_server, TEST_STRING, sizeof(TEST_STRING)),
126 sizeof(TEST_STRING));
127 assert_int_equal(read(sp->socket_client, buf, sizeof(buf)),
128 sizeof(buf));
133 /* Test socket behaviour */
134 static void test_read_client_after_close_server_socket(void **state) {
136 struct socket_pair *sp = *state;
137 int rc;
138 char buf[sizeof(TEST_STRING)];
140 rc = write(sp->socket_server, TEST_STRING, sizeof(TEST_STRING));
141 assert_return_code(rc, errno);
142 assert_int_equal(rc, sizeof(TEST_STRING));
144 assert_return_code(close(sp->socket_server), 0);
146 rc = read(sp->socket_client, buf, sizeof(buf));
148 assert_return_code(rc, errno);
149 assert_int_equal(rc, sizeof(buf));
152 static void test_write_server_after_close_client_socket(void **state) {
154 struct socket_pair *sp = *state;
155 int rc;
157 assert_return_code(close(sp->socket_client), 0);
158 sp->socket_client = -1;
160 rc = write(sp->socket_server, TEST_STRING, sizeof(TEST_STRING));
161 assert_return_code(rc, errno);
162 assert_int_equal(rc, sizeof(TEST_STRING));
165 static void test_fill_socket(int sock)
167 size_t num_busy = 0;
168 int rc;
170 while (true) {
171 rc = write(sock, TEST_STRING, sizeof(TEST_STRING));
172 if (rc == -1 && errno == EAGAIN) {
174 * This makes sure we write until we get a whole second
175 * only with EAGAIN every 50 ms (20 times)
177 * Otherwise the tests are not reliable...
179 num_busy++;
180 if (num_busy > 20) {
181 break;
183 smb_msleep(50);
184 continue;
186 /* try again next time */
187 num_busy = 0;
190 assert_int_equal(rc, -1);
191 assert_int_equal(errno, EAGAIN);
194 static void test_big_write_server(void **state) {
196 struct socket_pair *sp = *state;
197 int rc;
199 rc = write(sp->socket_server, TEST_STRING, sizeof(TEST_STRING));
200 assert_return_code(rc, errno);
201 assert_int_equal(rc, sizeof(TEST_STRING));
203 rc = set_blocking(sp->socket_server, 0);
204 assert_return_code(rc, errno);
206 test_fill_socket(sp->socket_server);
209 static void test_big_write_server_close_write(void **state) {
211 struct socket_pair *sp = *state;
212 int rc;
214 rc = write(sp->socket_server, TEST_STRING, sizeof(TEST_STRING));
215 assert_return_code(rc, errno);
216 assert_int_equal(rc, sizeof(TEST_STRING));
218 rc = set_blocking(sp->socket_server, 0);
219 assert_return_code(rc, errno);
221 test_fill_socket(sp->socket_server);
223 assert_return_code(close(sp->socket_client), 0);
224 sp->socket_client = -1;
226 rc = write(sp->socket_server, TEST_STRING, sizeof(TEST_STRING));
227 assert_int_equal(errno, ECONNRESET);
231 static void test_big_write_server_shutdown_wr_write(void **state) {
233 struct socket_pair *sp = *state;
234 int rc;
236 rc = write(sp->socket_server, TEST_STRING, sizeof(TEST_STRING));
237 assert_return_code(rc, errno);
238 assert_int_equal(rc, sizeof(TEST_STRING));
240 rc = set_blocking(sp->socket_server, 0);
241 assert_return_code(rc, errno);
243 test_fill_socket(sp->socket_server);
245 assert_return_code(shutdown(sp->socket_client, SHUT_WR), 0);
246 sp->socket_client = -1;
248 rc = write(sp->socket_server, TEST_STRING, sizeof(TEST_STRING));
249 assert_int_equal(rc, -1);
250 assert_int_equal(errno, EAGAIN);
253 static void test_big_write_server_shutdown_rd_write(void **state) {
255 struct socket_pair *sp = *state;
256 int rc;
258 rc = write(sp->socket_server, TEST_STRING, sizeof(TEST_STRING));
259 assert_return_code(rc, errno);
260 assert_int_equal(rc, sizeof(TEST_STRING));
262 rc = set_blocking(sp->socket_server, 0);
263 assert_return_code(rc, errno);
265 test_fill_socket(sp->socket_server);
267 assert_return_code(shutdown(sp->socket_client, SHUT_RD), 0);
268 sp->socket_client = -1;
270 rc = write(sp->socket_server, TEST_STRING, sizeof(TEST_STRING));
271 assert_int_equal(rc, -1);
272 assert_int_equal(errno, EAGAIN);
275 static void test_call_writev_done(struct tevent_req *subreq)
277 struct socket_pair *sp =
278 tevent_req_callback_data(subreq,
279 struct socket_pair);
280 int rc;
282 rc = tstream_writev_recv(subreq, &sp->sys_errno);
283 TALLOC_FREE(subreq);
285 sp->rc = rc;
288 static void test_tstream_server_spin_client_shutdown(struct socket_pair *sp)
290 int rc;
292 rc = shutdown(sp->socket_client, SHUT_WR);
293 assert_return_code(rc, errno);
295 * It should only take a few additional loop to realise that this socket is
296 * in CLOSE_WAIT
298 sp->max_loops = sp->num_loops + 2;
299 sp->expected_errno = ECONNRESET;
302 static void test_tstream_server_spin_client_write(struct socket_pair *sp)
304 int rc;
305 int timeout = 5000;
307 sp->endtime = timeval_current_ofs_msec(timeout);
309 rc = write(sp->socket_client, TEST_STRING, sizeof(TEST_STRING));
310 assert_return_code(rc, errno);
311 sp->expected_errno = ETIMEDOUT;
314 static void test_tstream_server_spin_client_tcp_user_timeout(struct socket_pair *sp)
316 int rc;
317 int timeout = 5000;
319 rc = setsockopt(sp->socket_server, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout, sizeof(timeout));
320 assert_return_code(rc, errno);
322 rc = write(sp->socket_client, TEST_STRING, sizeof(TEST_STRING));
323 assert_return_code(rc, errno);
324 sp->expected_errno = ETIMEDOUT;
325 sp->max_loops = 30;
328 static void test_tstream_server_spin_client_both_timer(struct tevent_context *ev,
329 struct tevent_timer *te,
330 struct timeval current_time,
331 void *private_data)
333 struct socket_pair *sp =
334 talloc_get_type_abort(private_data,
335 struct socket_pair);
337 test_tstream_server_spin_client_shutdown(sp);
340 static void test_tstream_server_spin_client_both(struct socket_pair *sp)
342 struct tevent_timer *te = NULL;
343 struct timeval endtime;
345 test_tstream_server_spin_client_write(sp);
347 endtime = timeval_current_ofs_msec(2500);
349 te = tevent_add_timer(sp->ev,
351 endtime,
352 test_tstream_server_spin_client_both_timer,
353 sp);
354 assert_non_null(te);
355 sp->expected_errno = ENXIO;
358 static void test_tstream_server_spin(struct socket_pair *sp,
359 void (*client_fn)(struct socket_pair *sp))
361 struct tstream_context *stream = NULL;
362 struct tevent_req *req = NULL;
363 struct iovec iov;
364 int rc;
366 rc = write(sp->socket_server, TEST_STRING, sizeof(TEST_STRING));
367 assert_return_code(rc, errno);
368 assert_int_equal(rc, sizeof(TEST_STRING));
370 rc = set_blocking(sp->socket_server, 0);
371 assert_return_code(rc, errno);
373 test_fill_socket(sp->socket_server);
376 * by default we don't expect more then 2 loop iterations
377 * for a timeout of 5 seconds.
379 sp->max_loops = 10;
381 client_fn(sp);
383 rc = write(sp->socket_server, TEST_STRING, sizeof(TEST_STRING));
384 assert_int_equal(rc, -1);
385 assert_int_equal(errno, EAGAIN);
387 /* OK, so we now know the socket is in CLOSE_WAIT */
389 rc = tstream_bsd_existing_socket(sp->ev, sp->socket_server, &stream);
390 assert_return_code(rc, errno);
391 sp->socket_server = -1;
393 iov.iov_base = discard_const_p(char, TEST_STRING);
394 iov.iov_len = sizeof(TEST_STRING);
396 req = tstream_writev_send(stream, sp->ev, stream, &iov, 1);
397 assert_non_null(req);
398 if (!timeval_is_zero(&sp->endtime)) {
399 assert_true(tevent_req_set_endtime(req, sp->ev, sp->endtime));
401 tevent_req_set_callback(req, test_call_writev_done, sp);
403 while (tevent_req_is_in_progress(req)) {
404 if (sp->num_loops >= sp->max_loops) {
405 assert_int_not_equal(sp->num_loops, sp->max_loops);
406 assert_int_equal(sp->num_loops, sp->max_loops);
408 sp->num_loops += 1;
410 rc = tevent_loop_once(sp->ev);
411 assert_int_equal(rc, 0);
414 assert_int_equal(sp->rc, -1);
415 assert_int_equal(sp->sys_errno, sp->expected_errno);
416 return;
420 * We need two names to run this with the two different setup
421 * routines
423 static void test_tstream_disconnected_tcp_client_spin(void **state)
425 struct socket_pair *sp = *state;
426 test_tstream_server_spin(sp, test_tstream_server_spin_client_shutdown);
429 static void test_tstream_disconnected_unix_client_spin(void **state)
431 struct socket_pair *sp = *state;
432 test_tstream_server_spin(sp, test_tstream_server_spin_client_shutdown);
435 static void test_tstream_more_tcp_client_spin(void **state)
437 struct socket_pair *sp = *state;
438 test_tstream_server_spin(sp, test_tstream_server_spin_client_write);
441 static void test_tstream_more_unix_client_spin(void **state)
443 struct socket_pair *sp = *state;
444 test_tstream_server_spin(sp, test_tstream_server_spin_client_write);
447 static void test_tstream_more_disconnect_tcp_client_spin(void **state)
449 struct socket_pair *sp = *state;
450 test_tstream_server_spin(sp, test_tstream_server_spin_client_both);
453 static void test_tstream_more_disconnect_unix_client_spin(void **state)
455 struct socket_pair *sp = *state;
456 test_tstream_server_spin(sp, test_tstream_server_spin_client_both);
459 static void test_tstream_more_tcp_user_timeout_spin(void **state)
461 struct socket_pair *sp = *state;
462 if (socket_wrapper_enabled()) {
463 skip();
465 test_tstream_server_spin(sp, test_tstream_server_spin_client_tcp_user_timeout);
468 int main(void) {
469 const struct CMUnitTest tests[] = {
470 cmocka_unit_test_setup_teardown(test_simple_socketpair,
471 setup_socketpair_tcp_context,
472 teardown_socketpair_context),
473 cmocka_unit_test_setup_teardown(test_read_client_after_close_server_socket,
474 setup_socketpair_tcp_context,
475 teardown_socketpair_context),
476 cmocka_unit_test_setup_teardown(test_write_server_after_close_client_socket,
477 setup_socketpair_tcp_context,
478 teardown_socketpair_context),
479 cmocka_unit_test_setup_teardown(test_big_write_server,
480 setup_socketpair_tcp_context,
481 teardown_socketpair_context),
482 cmocka_unit_test_setup_teardown(test_big_write_server_close_write,
483 setup_socketpair_tcp_context,
484 teardown_socketpair_context),
485 cmocka_unit_test_setup_teardown(test_big_write_server_shutdown_wr_write,
486 setup_socketpair_tcp_context,
487 teardown_socketpair_context),
488 cmocka_unit_test_setup_teardown(test_big_write_server_shutdown_rd_write,
489 setup_socketpair_tcp_context,
490 teardown_socketpair_context),
491 cmocka_unit_test_setup_teardown(test_tstream_disconnected_tcp_client_spin,
492 setup_socketpair_tcp_context,
493 teardown_socketpair_context),
494 cmocka_unit_test_setup_teardown(test_tstream_disconnected_unix_client_spin,
495 setup_socketpair_context,
496 teardown_socketpair_context),
497 cmocka_unit_test_setup_teardown(test_tstream_more_tcp_client_spin,
498 setup_socketpair_tcp_context,
499 teardown_socketpair_context),
500 cmocka_unit_test_setup_teardown(test_tstream_more_unix_client_spin,
501 setup_socketpair_context,
502 teardown_socketpair_context),
503 cmocka_unit_test_setup_teardown(test_tstream_more_disconnect_tcp_client_spin,
504 setup_socketpair_tcp_context,
505 teardown_socketpair_context),
506 cmocka_unit_test_setup_teardown(test_tstream_more_disconnect_unix_client_spin,
507 setup_socketpair_context,
508 teardown_socketpair_context),
509 cmocka_unit_test_setup_teardown(test_tstream_more_tcp_user_timeout_spin,
510 setup_socketpair_tcp_context,
511 teardown_socketpair_context),
514 cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
516 return cmocka_run_group_tests(tests, sigpipe_setup, NULL);