xref: /spdk/test/unit/lib/sock/sock.c/sock_ut.c (revision ae7b5890ef728af40bd233a5011b924c482603bf)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/stdinc.h"
35 #include "spdk/util.h"
36 
37 #include "spdk_cunit.h"
38 
39 #include "sock/sock.c"
40 #include "sock/posix/posix.c"
41 
42 #define UT_IP	"test_ip"
43 #define UT_PORT	1234
44 
45 bool g_read_data_called;
46 ssize_t g_bytes_read;
47 char g_buf[256];
48 struct spdk_sock *g_server_sock_read;
49 int g_ut_accept_count;
50 struct spdk_ut_sock *g_ut_listen_sock;
51 struct spdk_ut_sock *g_ut_client_sock;
52 
53 struct spdk_ut_sock {
54 	struct spdk_sock	base;
55 	struct spdk_ut_sock	*peer;
56 	size_t			bytes_avail;
57 	char			buf[256];
58 };
59 
60 struct spdk_ut_sock_group_impl {
61 	struct spdk_sock_group_impl	base;
62 	struct spdk_ut_sock		*sock;
63 };
64 
65 #define __ut_sock(sock) (struct spdk_ut_sock *)sock
66 #define __ut_group(group) (struct spdk_ut_sock_group_impl *)group
67 
68 static int
69 spdk_ut_sock_getaddr(struct spdk_sock *_sock, char *saddr, int slen, uint16_t *sport,
70 		     char *caddr, int clen, uint16_t *cport)
71 {
72 	return 0;
73 }
74 
75 static struct spdk_sock *
76 spdk_ut_sock_listen(const char *ip, int port)
77 {
78 	struct spdk_ut_sock *sock;
79 
80 	if (strcmp(ip, UT_IP) || port != UT_PORT) {
81 		return NULL;
82 	}
83 
84 	CU_ASSERT(g_ut_listen_sock == NULL);
85 
86 	sock = calloc(1, sizeof(*sock));
87 	SPDK_CU_ASSERT_FATAL(sock != NULL);
88 	g_ut_listen_sock = sock;
89 
90 	return &sock->base;
91 }
92 
93 static struct spdk_sock *
94 spdk_ut_sock_connect(const char *ip, int port)
95 {
96 	struct spdk_ut_sock *sock;
97 
98 	if (strcmp(ip, UT_IP) || port != UT_PORT) {
99 		return NULL;
100 	}
101 
102 	sock = calloc(1, sizeof(*sock));
103 	SPDK_CU_ASSERT_FATAL(sock != NULL);
104 	g_ut_accept_count++;
105 	CU_ASSERT(g_ut_client_sock == NULL);
106 	g_ut_client_sock = sock;
107 
108 	return &sock->base;
109 }
110 
111 static struct spdk_sock *
112 spdk_ut_sock_accept(struct spdk_sock *_sock)
113 {
114 	struct spdk_ut_sock *sock = __ut_sock(_sock);
115 	struct spdk_ut_sock *new_sock;
116 
117 	CU_ASSERT(sock == g_ut_listen_sock);
118 
119 	if (g_ut_accept_count == 0) {
120 		errno = EAGAIN;
121 		return NULL;
122 	}
123 
124 	g_ut_accept_count--;
125 	new_sock = calloc(1, sizeof(*sock));
126 	if (new_sock == NULL) {
127 		SPDK_ERRLOG("sock allocation failed\n");
128 		return NULL;
129 	}
130 
131 	SPDK_CU_ASSERT_FATAL(g_ut_client_sock != NULL);
132 	g_ut_client_sock->peer = new_sock;
133 
134 	return &new_sock->base;
135 }
136 
137 static int
138 spdk_ut_sock_close(struct spdk_sock *_sock)
139 {
140 	struct spdk_ut_sock *sock = __ut_sock(_sock);
141 
142 	if (sock == g_ut_listen_sock) {
143 		g_ut_listen_sock = NULL;
144 	}
145 	if (sock == g_ut_client_sock) {
146 		g_ut_client_sock = NULL;
147 	}
148 	free(_sock);
149 
150 	return 0;
151 }
152 
153 static ssize_t
154 spdk_ut_sock_recv(struct spdk_sock *_sock, void *buf, size_t len)
155 {
156 	struct spdk_ut_sock *sock = __ut_sock(_sock);
157 	char tmp[256];
158 
159 	len = spdk_min(len, sock->bytes_avail);
160 
161 	if (len == 0) {
162 		errno = EAGAIN;
163 		return -1;
164 	}
165 
166 	memcpy(buf, sock->buf, len);
167 	memcpy(tmp, &sock->buf[len], sock->bytes_avail - len);
168 	memcpy(sock->buf, tmp, sock->bytes_avail - len);
169 	sock->bytes_avail -= len;
170 
171 	return len;
172 }
173 
174 static ssize_t
175 spdk_ut_sock_readv(struct spdk_sock *_sock, struct iovec *iov, int iovcnt)
176 {
177 	struct spdk_ut_sock *sock = __ut_sock(_sock);
178 	size_t len;
179 	char tmp[256];
180 
181 	/* Test implementation only supports single iov for now. */
182 	CU_ASSERT(iovcnt == 1);
183 
184 	len = spdk_min(iov[0].iov_len, sock->bytes_avail);
185 
186 	if (len == 0) {
187 		errno = EAGAIN;
188 		return -1;
189 	}
190 
191 	memcpy(iov[0].iov_base, sock->buf, len);
192 	memcpy(tmp, &sock->buf[len], sock->bytes_avail - len);
193 	memcpy(sock->buf, tmp, sock->bytes_avail - len);
194 	sock->bytes_avail -= len;
195 
196 	return len;
197 }
198 
199 static ssize_t
200 spdk_ut_sock_writev(struct spdk_sock *_sock, struct iovec *iov, int iovcnt)
201 {
202 	struct spdk_ut_sock *sock = __ut_sock(_sock);
203 	struct spdk_ut_sock *peer;
204 
205 	SPDK_CU_ASSERT_FATAL(sock->peer != NULL);
206 	peer = sock->peer;
207 
208 	/* Test implementation only supports single iov for now. */
209 	CU_ASSERT(iovcnt == 1);
210 
211 	memcpy(&peer->buf[peer->bytes_avail], iov[0].iov_base, iov[0].iov_len);
212 	peer->bytes_avail += iov[0].iov_len;
213 
214 	return iov[0].iov_len;
215 }
216 
217 static int
218 spdk_ut_sock_set_recvlowat(struct spdk_sock *_sock, int nbytes)
219 {
220 	return 0;
221 }
222 
223 static int
224 spdk_ut_sock_set_recvbuf(struct spdk_sock *_sock, int sz)
225 {
226 	return 0;
227 }
228 
229 static int
230 spdk_ut_sock_set_sendbuf(struct spdk_sock *_sock, int sz)
231 {
232 	return 0;
233 }
234 
235 static bool
236 spdk_ut_sock_is_ipv6(struct spdk_sock *_sock)
237 {
238 	return false;
239 }
240 
241 static bool
242 spdk_ut_sock_is_ipv4(struct spdk_sock *_sock)
243 {
244 	return true;
245 }
246 
247 static int
248 spdk_ut_sock_get_placement_id(struct spdk_sock *_sock, int *placement_id)
249 {
250 	return -1;
251 }
252 
253 static int
254 spdk_ut_sock_set_priority(struct spdk_sock *_sock, int priority)
255 {
256 	return 0;
257 }
258 
259 static struct spdk_sock_group_impl *
260 spdk_ut_sock_group_impl_create(void)
261 {
262 	struct spdk_ut_sock_group_impl *group_impl;
263 
264 	group_impl = calloc(1, sizeof(*group_impl));
265 	SPDK_CU_ASSERT_FATAL(group_impl != NULL);
266 
267 	return &group_impl->base;
268 }
269 
270 static int
271 spdk_ut_sock_group_impl_add_sock(struct spdk_sock_group_impl *_group, struct spdk_sock *_sock)
272 {
273 	struct spdk_ut_sock_group_impl *group = __ut_group(_group);
274 	struct spdk_ut_sock *sock = __ut_sock(_sock);
275 
276 	group->sock = sock;
277 
278 	return 0;
279 }
280 
281 static int
282 spdk_ut_sock_group_impl_remove_sock(struct spdk_sock_group_impl *_group, struct spdk_sock *_sock)
283 {
284 	struct spdk_ut_sock_group_impl *group = __ut_group(_group);
285 	struct spdk_ut_sock *sock = __ut_sock(_sock);
286 
287 	CU_ASSERT(group->sock == sock);
288 	group->sock = NULL;
289 
290 	return 0;
291 }
292 
293 static int
294 spdk_ut_sock_group_impl_poll(struct spdk_sock_group_impl *_group, int max_events,
295 			     struct spdk_sock **socks)
296 {
297 	struct spdk_ut_sock_group_impl *group = __ut_group(_group);
298 
299 	if (group->sock != NULL && group->sock->bytes_avail > 0) {
300 		socks[0] = &group->sock->base;
301 		return 1;
302 	}
303 
304 	return 0;
305 }
306 
307 static int
308 spdk_ut_sock_group_impl_close(struct spdk_sock_group_impl *_group)
309 {
310 	struct spdk_ut_sock_group_impl *group = __ut_group(_group);
311 
312 	CU_ASSERT(group->sock == NULL);
313 
314 	return 0;
315 }
316 
317 static struct spdk_net_impl g_ut_net_impl = {
318 	.name		= "ut",
319 	.getaddr	= spdk_ut_sock_getaddr,
320 	.connect	= spdk_ut_sock_connect,
321 	.listen		= spdk_ut_sock_listen,
322 	.accept		= spdk_ut_sock_accept,
323 	.close		= spdk_ut_sock_close,
324 	.recv		= spdk_ut_sock_recv,
325 	.readv		= spdk_ut_sock_readv,
326 	.writev		= spdk_ut_sock_writev,
327 	.set_recvlowat	= spdk_ut_sock_set_recvlowat,
328 	.set_recvbuf	= spdk_ut_sock_set_recvbuf,
329 	.set_sendbuf	= spdk_ut_sock_set_sendbuf,
330 	.set_priority	= spdk_ut_sock_set_priority,
331 	.is_ipv6	= spdk_ut_sock_is_ipv6,
332 	.is_ipv4	= spdk_ut_sock_is_ipv4,
333 	.get_placement_id	= spdk_ut_sock_get_placement_id,
334 	.group_impl_create	= spdk_ut_sock_group_impl_create,
335 	.group_impl_add_sock	= spdk_ut_sock_group_impl_add_sock,
336 	.group_impl_remove_sock = spdk_ut_sock_group_impl_remove_sock,
337 	.group_impl_poll	= spdk_ut_sock_group_impl_poll,
338 	.group_impl_close	= spdk_ut_sock_group_impl_close,
339 };
340 
341 SPDK_NET_IMPL_REGISTER(ut, &g_ut_net_impl);
342 
343 static void
344 _sock(const char *ip, int port)
345 {
346 	struct spdk_sock *listen_sock;
347 	struct spdk_sock *server_sock;
348 	struct spdk_sock *client_sock;
349 	char *test_string = "abcdef";
350 	char buffer[64];
351 	ssize_t bytes_read, bytes_written;
352 	struct iovec iov;
353 	int rc;
354 
355 	listen_sock = spdk_sock_listen(ip, port);
356 	SPDK_CU_ASSERT_FATAL(listen_sock != NULL);
357 
358 	server_sock = spdk_sock_accept(listen_sock);
359 	CU_ASSERT(server_sock == NULL);
360 	CU_ASSERT(errno == EAGAIN || errno == EWOULDBLOCK);
361 
362 	client_sock = spdk_sock_connect(ip, port);
363 	SPDK_CU_ASSERT_FATAL(client_sock != NULL);
364 
365 	/*
366 	 * Delay a bit here before checking if server socket is
367 	 *  ready.
368 	 */
369 	usleep(1000);
370 
371 	server_sock = spdk_sock_accept(listen_sock);
372 	SPDK_CU_ASSERT_FATAL(server_sock != NULL);
373 
374 	/* Test spdk_sock_recv */
375 	iov.iov_base = test_string;
376 	iov.iov_len = 7;
377 	bytes_written = spdk_sock_writev(client_sock, &iov, 1);
378 	CU_ASSERT(bytes_written == 7);
379 
380 	usleep(1000);
381 
382 	bytes_read = spdk_sock_recv(server_sock, buffer, 2);
383 	CU_ASSERT(bytes_read == 2);
384 
385 	usleep(1000);
386 
387 	bytes_read += spdk_sock_recv(server_sock, buffer + 2, 5);
388 	CU_ASSERT(bytes_read == 7);
389 
390 	CU_ASSERT(strncmp(test_string, buffer, 7) == 0);
391 
392 	/* Test spdk_sock_readv */
393 	iov.iov_base = test_string;
394 	iov.iov_len = 7;
395 	bytes_written = spdk_sock_writev(client_sock, &iov, 1);
396 	CU_ASSERT(bytes_written == 7);
397 
398 	usleep(1000);
399 
400 	iov.iov_base = buffer;
401 	iov.iov_len = 2;
402 	bytes_read = spdk_sock_readv(server_sock, &iov, 1);
403 	CU_ASSERT(bytes_read == 2);
404 
405 	usleep(1000);
406 
407 	iov.iov_base = buffer + 2;
408 	iov.iov_len = 5;
409 	bytes_read += spdk_sock_readv(server_sock, &iov, 1);
410 	CU_ASSERT(bytes_read == 7);
411 
412 	usleep(1000);
413 
414 	CU_ASSERT(strncmp(test_string, buffer, 7) == 0);
415 
416 	rc = spdk_sock_close(&client_sock);
417 	CU_ASSERT(client_sock == NULL);
418 	CU_ASSERT(rc == 0);
419 
420 	rc = spdk_sock_close(&server_sock);
421 	CU_ASSERT(server_sock == NULL);
422 	CU_ASSERT(rc == 0);
423 
424 	rc = spdk_sock_close(&listen_sock);
425 	CU_ASSERT(listen_sock == NULL);
426 	CU_ASSERT(rc == 0);
427 }
428 
429 static void
430 posix_sock(void)
431 {
432 	_sock("127.0.0.1", UT_PORT);
433 }
434 
435 static void
436 ut_sock(void)
437 {
438 	_sock(UT_IP, UT_PORT);
439 }
440 
441 static void
442 read_data(void *cb_arg, struct spdk_sock_group *group, struct spdk_sock *sock)
443 {
444 	struct spdk_sock *server_sock = cb_arg;
445 
446 	CU_ASSERT(server_sock == sock);
447 
448 	g_read_data_called = true;
449 	g_bytes_read += spdk_sock_recv(server_sock, g_buf + g_bytes_read, sizeof(g_buf) - g_bytes_read);
450 }
451 
452 static void
453 _sock_group(const char *ip, int port)
454 {
455 	struct spdk_sock_group *group;
456 	struct spdk_sock *listen_sock;
457 	struct spdk_sock *server_sock;
458 	struct spdk_sock *client_sock;
459 	char *test_string = "abcdef";
460 	ssize_t bytes_written;
461 	struct iovec iov;
462 	int rc;
463 
464 	listen_sock = spdk_sock_listen(ip, port);
465 	SPDK_CU_ASSERT_FATAL(listen_sock != NULL);
466 
467 	server_sock = spdk_sock_accept(listen_sock);
468 	CU_ASSERT(server_sock == NULL);
469 	CU_ASSERT(errno == EAGAIN || errno == EWOULDBLOCK);
470 
471 	client_sock = spdk_sock_connect(ip, port);
472 	SPDK_CU_ASSERT_FATAL(client_sock != NULL);
473 
474 	usleep(1000);
475 
476 	server_sock = spdk_sock_accept(listen_sock);
477 	SPDK_CU_ASSERT_FATAL(server_sock != NULL);
478 
479 	group = spdk_sock_group_create(NULL);
480 	SPDK_CU_ASSERT_FATAL(group != NULL);
481 
482 	/* pass null cb_fn */
483 	rc = spdk_sock_group_add_sock(group, server_sock, NULL, NULL);
484 	CU_ASSERT(rc == -1);
485 	CU_ASSERT(errno == EINVAL);
486 
487 	rc = spdk_sock_group_add_sock(group, server_sock, read_data, server_sock);
488 	CU_ASSERT(rc == 0);
489 
490 	/* try adding sock a second time */
491 	rc = spdk_sock_group_add_sock(group, server_sock, read_data, server_sock);
492 	CU_ASSERT(rc == -1);
493 	CU_ASSERT(errno == EBUSY);
494 
495 	g_read_data_called = false;
496 	g_bytes_read = 0;
497 	rc = spdk_sock_group_poll(group);
498 
499 	CU_ASSERT(rc == 0);
500 	CU_ASSERT(g_read_data_called == false);
501 
502 	iov.iov_base = test_string;
503 	iov.iov_len = 7;
504 	bytes_written = spdk_sock_writev(client_sock, &iov, 1);
505 	CU_ASSERT(bytes_written == 7);
506 
507 	usleep(1000);
508 
509 	g_read_data_called = false;
510 	g_bytes_read = 0;
511 	rc = spdk_sock_group_poll(group);
512 
513 	CU_ASSERT(rc == 1);
514 	CU_ASSERT(g_read_data_called == true);
515 	CU_ASSERT(g_bytes_read == 7);
516 
517 	CU_ASSERT(strncmp(test_string, g_buf, 7) == 0);
518 
519 	rc = spdk_sock_close(&client_sock);
520 	CU_ASSERT(client_sock == NULL);
521 	CU_ASSERT(rc == 0);
522 
523 	/* Try to close sock_group while it still has sockets. */
524 	rc = spdk_sock_group_close(&group);
525 	CU_ASSERT(rc == -1);
526 	CU_ASSERT(errno == EBUSY);
527 
528 	/* Try to close sock while it is still part of a sock_group. */
529 	rc = spdk_sock_close(&server_sock);
530 	CU_ASSERT(rc == -1);
531 	CU_ASSERT(errno == EBUSY);
532 
533 	rc = spdk_sock_group_remove_sock(group, server_sock);
534 	CU_ASSERT(rc == 0);
535 
536 	rc = spdk_sock_group_close(&group);
537 	CU_ASSERT(group == NULL);
538 	CU_ASSERT(rc == 0);
539 
540 	rc = spdk_sock_close(&server_sock);
541 	CU_ASSERT(server_sock == NULL);
542 	CU_ASSERT(rc == 0);
543 
544 	rc = spdk_sock_close(&listen_sock);
545 	CU_ASSERT(listen_sock == NULL);
546 	CU_ASSERT(rc == 0);
547 }
548 
549 static void
550 posix_sock_group(void)
551 {
552 	_sock_group("127.0.0.1", UT_PORT);
553 }
554 
555 static void
556 ut_sock_group(void)
557 {
558 	_sock_group(UT_IP, UT_PORT);
559 }
560 
561 static void
562 read_data_fairness(void *cb_arg, struct spdk_sock_group *group, struct spdk_sock *sock)
563 {
564 	struct spdk_sock *server_sock = cb_arg;
565 	ssize_t bytes_read;
566 	char buf[1];
567 
568 	CU_ASSERT(g_server_sock_read == NULL);
569 	CU_ASSERT(server_sock == sock);
570 
571 	g_server_sock_read = server_sock;
572 	bytes_read = spdk_sock_recv(server_sock, buf, 1);
573 	CU_ASSERT(bytes_read == 1);
574 }
575 
576 static void
577 posix_sock_group_fairness(void)
578 {
579 	struct spdk_sock_group *group;
580 	struct spdk_sock *listen_sock;
581 	struct spdk_sock *server_sock[3];
582 	struct spdk_sock *client_sock[3];
583 	char test_char = 'a';
584 	ssize_t bytes_written;
585 	struct iovec iov;
586 	int i, rc;
587 
588 	listen_sock = spdk_sock_listen("127.0.0.1", UT_PORT);
589 	SPDK_CU_ASSERT_FATAL(listen_sock != NULL);
590 
591 	group = spdk_sock_group_create(NULL);
592 	SPDK_CU_ASSERT_FATAL(group != NULL);
593 
594 	for (i = 0; i < 3; i++) {
595 		client_sock[i] = spdk_sock_connect("127.0.0.1", UT_PORT);
596 		SPDK_CU_ASSERT_FATAL(client_sock[i] != NULL);
597 
598 		usleep(1000);
599 
600 		server_sock[i] = spdk_sock_accept(listen_sock);
601 		SPDK_CU_ASSERT_FATAL(server_sock[i] != NULL);
602 
603 		rc = spdk_sock_group_add_sock(group, server_sock[i],
604 					      read_data_fairness, server_sock[i]);
605 		CU_ASSERT(rc == 0);
606 	}
607 
608 	iov.iov_base = &test_char;
609 	iov.iov_len = 1;
610 
611 	for (i = 0; i < 3; i++) {
612 		bytes_written = spdk_sock_writev(client_sock[i], &iov, 1);
613 		CU_ASSERT(bytes_written == 1);
614 	}
615 
616 	usleep(1000);
617 
618 	/*
619 	 * Poll for just one event - this should be server sock 0, since that
620 	 *  is the peer of the first client sock that we wrote to.
621 	 */
622 	g_server_sock_read = NULL;
623 	rc = spdk_sock_group_poll_count(group, 1);
624 	CU_ASSERT(rc == 1);
625 	CU_ASSERT(g_server_sock_read == server_sock[0]);
626 
627 	/*
628 	 * Now write another byte to client sock 0.  We want to ensure that
629 	 *  the sock group does not unfairly process the event for this sock
630 	 *  before the socks that were written to earlier.
631 	 */
632 	bytes_written = spdk_sock_writev(client_sock[0], &iov, 1);
633 	CU_ASSERT(bytes_written == 1);
634 
635 	usleep(1000);
636 
637 	g_server_sock_read = NULL;
638 	rc = spdk_sock_group_poll_count(group, 1);
639 	CU_ASSERT(rc == 1);
640 	CU_ASSERT(g_server_sock_read == server_sock[1]);
641 
642 	g_server_sock_read = NULL;
643 	rc = spdk_sock_group_poll_count(group, 1);
644 	CU_ASSERT(rc == 1);
645 	CU_ASSERT(g_server_sock_read == server_sock[2]);
646 
647 	g_server_sock_read = NULL;
648 	rc = spdk_sock_group_poll_count(group, 1);
649 	CU_ASSERT(rc == 1);
650 	CU_ASSERT(g_server_sock_read == server_sock[0]);
651 
652 	for (i = 0; i < 3; i++) {
653 		rc = spdk_sock_group_remove_sock(group, server_sock[i]);
654 		CU_ASSERT(rc == 0);
655 
656 		rc = spdk_sock_close(&client_sock[i]);
657 		CU_ASSERT(client_sock[i] == NULL);
658 		CU_ASSERT(rc == 0);
659 
660 		rc = spdk_sock_close(&server_sock[i]);
661 		CU_ASSERT(server_sock[i] == NULL);
662 		CU_ASSERT(rc == 0);
663 	}
664 
665 	rc = spdk_sock_group_close(&group);
666 	CU_ASSERT(group == NULL);
667 	CU_ASSERT(rc == 0);
668 
669 	rc = spdk_sock_close(&listen_sock);
670 	CU_ASSERT(listen_sock == NULL);
671 	CU_ASSERT(rc == 0);
672 }
673 
674 int
675 main(int argc, char **argv)
676 {
677 	CU_pSuite	suite = NULL;
678 	unsigned int	num_failures;
679 
680 	if (CU_initialize_registry() != CUE_SUCCESS) {
681 		return CU_get_error();
682 	}
683 
684 	suite = CU_add_suite("sock", NULL, NULL);
685 	if (suite == NULL) {
686 		CU_cleanup_registry();
687 		return CU_get_error();
688 	}
689 
690 	if (
691 		CU_add_test(suite, "posix_sock", posix_sock) == NULL ||
692 		CU_add_test(suite, "ut_sock", ut_sock) == NULL ||
693 		CU_add_test(suite, "posix_sock_group", posix_sock_group) == NULL ||
694 		CU_add_test(suite, "ut_sock_group", ut_sock_group) == NULL ||
695 		CU_add_test(suite, "posix_sock_group_fairness", posix_sock_group_fairness) == NULL) {
696 		CU_cleanup_registry();
697 		return CU_get_error();
698 	}
699 
700 	CU_basic_set_mode(CU_BRM_VERBOSE);
701 
702 	CU_basic_run_tests();
703 
704 	num_failures = CU_get_number_of_failures();
705 	CU_cleanup_registry();
706 
707 	return num_failures;
708 }
709