1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse * Copyright (C) 2019 Intel Corporation.
3b7ad9426SBen Walker * All rights reserved.
4b7ad9426SBen Walker */
5b7ad9426SBen Walker
6b7ad9426SBen Walker #include "spdk/stdinc.h"
7b7ad9426SBen Walker #include "spdk/util.h"
8b7ad9426SBen Walker
9b7ad9426SBen Walker #include "spdk_internal/mock.h"
10b7ad9426SBen Walker
11ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h"
12b7ad9426SBen Walker
135379aa95SBen Walker #include "common/lib/test_env.c"
14b7ad9426SBen Walker #include "sock/posix/posix.c"
15b7ad9426SBen Walker
165379aa95SBen Walker DEFINE_STUB(spdk_sock_map_insert, int, (struct spdk_sock_map *map, int placement_id,
174e347038SBen Walker struct spdk_sock_group_impl *group), 0);
185379aa95SBen Walker DEFINE_STUB_V(spdk_sock_map_release, (struct spdk_sock_map *map, int placement_id));
195379aa95SBen Walker DEFINE_STUB(spdk_sock_map_lookup, int, (struct spdk_sock_map *map, int placement_id,
206301f891STomasz Zawadzki struct spdk_sock_group_impl **group, struct spdk_sock_group_impl *hint), 0);
212f9271b8SBen Walker DEFINE_STUB(spdk_sock_map_find_free, int, (struct spdk_sock_map *map), -1);
225379aa95SBen Walker DEFINE_STUB_V(spdk_sock_map_cleanup, (struct spdk_sock_map *map));
235379aa95SBen Walker
24*7521dc6fSKrzysztof Karas DEFINE_STUB_V(spdk_net_impl_register, (struct spdk_net_impl *impl));
25*7521dc6fSKrzysztof Karas DEFINE_STUB(spdk_sock_set_default_impl, int, (const char *impl_name), 0);
26b7ad9426SBen Walker DEFINE_STUB(spdk_sock_close, int, (struct spdk_sock **s), 0);
27d9f9e265SBen Walker DEFINE_STUB(spdk_sock_group_provide_buf, int, (struct spdk_sock_group *group, void *buf,
28d9f9e265SBen Walker size_t len, void *ctx), 0);
29d9f9e265SBen Walker DEFINE_STUB(spdk_sock_group_get_buf, size_t, (struct spdk_sock_group *group, void **buf,
30d9f9e265SBen Walker void **ctx), 0);
31b7ad9426SBen Walker
32b7ad9426SBen Walker static void
_req_cb(void * cb_arg,int len)33b7ad9426SBen Walker _req_cb(void *cb_arg, int len)
34b7ad9426SBen Walker {
35b7ad9426SBen Walker *(bool *)cb_arg = true;
36b7ad9426SBen Walker CU_ASSERT(len == 0);
37b7ad9426SBen Walker }
38b7ad9426SBen Walker
39b7ad9426SBen Walker static void
flush(void)40b7ad9426SBen Walker flush(void)
41b7ad9426SBen Walker {
42b7ad9426SBen Walker struct spdk_posix_sock_group_impl group = {};
43b7ad9426SBen Walker struct spdk_posix_sock psock = {};
44b7ad9426SBen Walker struct spdk_sock *sock = &psock.base;
45b7ad9426SBen Walker struct spdk_sock_request *req1, *req2;
46b7ad9426SBen Walker bool cb_arg1, cb_arg2;
47b7ad9426SBen Walker int rc;
48b7ad9426SBen Walker
49b7ad9426SBen Walker /* Set up data structures */
50b7ad9426SBen Walker TAILQ_INIT(&sock->queued_reqs);
51ab22d249SBen Walker TAILQ_INIT(&sock->pending_reqs);
52b7ad9426SBen Walker sock->group_impl = &group.base;
53b7ad9426SBen Walker
54b7ad9426SBen Walker req1 = calloc(1, sizeof(struct spdk_sock_request) + 2 * sizeof(struct iovec));
55b7ad9426SBen Walker SPDK_CU_ASSERT_FATAL(req1 != NULL);
56b7ad9426SBen Walker SPDK_SOCK_REQUEST_IOV(req1, 0)->iov_base = (void *)100;
57b7ad9426SBen Walker SPDK_SOCK_REQUEST_IOV(req1, 0)->iov_len = 32;
58b7ad9426SBen Walker SPDK_SOCK_REQUEST_IOV(req1, 1)->iov_base = (void *)200;
59b7ad9426SBen Walker SPDK_SOCK_REQUEST_IOV(req1, 1)->iov_len = 32;
60b7ad9426SBen Walker req1->iovcnt = 2;
61b7ad9426SBen Walker req1->cb_fn = _req_cb;
62b7ad9426SBen Walker req1->cb_arg = &cb_arg1;
63b7ad9426SBen Walker
64b7ad9426SBen Walker req2 = calloc(1, sizeof(struct spdk_sock_request) + 2 * sizeof(struct iovec));
65b7ad9426SBen Walker SPDK_CU_ASSERT_FATAL(req2 != NULL);
66b7ad9426SBen Walker SPDK_SOCK_REQUEST_IOV(req2, 0)->iov_base = (void *)100;
67b7ad9426SBen Walker SPDK_SOCK_REQUEST_IOV(req2, 0)->iov_len = 32;
68b7ad9426SBen Walker SPDK_SOCK_REQUEST_IOV(req2, 1)->iov_base = (void *)200;
69b7ad9426SBen Walker SPDK_SOCK_REQUEST_IOV(req2, 1)->iov_len = 32;
70b7ad9426SBen Walker req2->iovcnt = 2;
71b7ad9426SBen Walker req2->cb_fn = _req_cb;
72b7ad9426SBen Walker req2->cb_arg = &cb_arg2;
73b7ad9426SBen Walker
74b7ad9426SBen Walker /* Simple test - a request with a 2 element iovec
757db1ed8bSBen Walker * that gets submitted in a single sendmsg. */
76b7ad9426SBen Walker spdk_sock_request_queue(sock, req1);
777db1ed8bSBen Walker MOCK_SET(sendmsg, 64);
78b7ad9426SBen Walker cb_arg1 = false;
79b7ad9426SBen Walker rc = _sock_flush(sock);
805433004eSBen Walker CU_ASSERT(rc == 64);
81b7ad9426SBen Walker CU_ASSERT(cb_arg1 == true);
82b7ad9426SBen Walker CU_ASSERT(TAILQ_EMPTY(&sock->queued_reqs));
83b7ad9426SBen Walker
84b7ad9426SBen Walker /* Two requests, where both can fully send. */
85b7ad9426SBen Walker spdk_sock_request_queue(sock, req1);
86b7ad9426SBen Walker spdk_sock_request_queue(sock, req2);
877db1ed8bSBen Walker MOCK_SET(sendmsg, 128);
88b7ad9426SBen Walker cb_arg1 = false;
89b7ad9426SBen Walker cb_arg2 = false;
90b7ad9426SBen Walker rc = _sock_flush(sock);
915433004eSBen Walker CU_ASSERT(rc == 128);
92b7ad9426SBen Walker CU_ASSERT(cb_arg1 == true);
93b7ad9426SBen Walker CU_ASSERT(cb_arg2 == true);
94b7ad9426SBen Walker CU_ASSERT(TAILQ_EMPTY(&sock->queued_reqs));
95b7ad9426SBen Walker
96b7ad9426SBen Walker /* Two requests. Only first one can send */
97b7ad9426SBen Walker spdk_sock_request_queue(sock, req1);
98b7ad9426SBen Walker spdk_sock_request_queue(sock, req2);
997db1ed8bSBen Walker MOCK_SET(sendmsg, 64);
100b7ad9426SBen Walker cb_arg1 = false;
101b7ad9426SBen Walker cb_arg2 = false;
102b7ad9426SBen Walker rc = _sock_flush(sock);
1035433004eSBen Walker CU_ASSERT(rc == 64);
104b7ad9426SBen Walker CU_ASSERT(cb_arg1 == true);
105b7ad9426SBen Walker CU_ASSERT(cb_arg2 == false);
106b7ad9426SBen Walker CU_ASSERT(TAILQ_FIRST(&sock->queued_reqs) == req2);
107b7ad9426SBen Walker TAILQ_REMOVE(&sock->queued_reqs, req2, internal.link);
108b7ad9426SBen Walker CU_ASSERT(TAILQ_EMPTY(&sock->queued_reqs));
109b7ad9426SBen Walker
110b7ad9426SBen Walker /* One request. Partial send. */
111b7ad9426SBen Walker spdk_sock_request_queue(sock, req1);
1127db1ed8bSBen Walker MOCK_SET(sendmsg, 10);
113b7ad9426SBen Walker cb_arg1 = false;
114b7ad9426SBen Walker rc = _sock_flush(sock);
1155433004eSBen Walker CU_ASSERT(rc == 10);
116b7ad9426SBen Walker CU_ASSERT(cb_arg1 == false);
117b7ad9426SBen Walker CU_ASSERT(TAILQ_FIRST(&sock->queued_reqs) == req1);
118b7ad9426SBen Walker
119b7ad9426SBen Walker /* Do a second flush that partial sends again. */
1207db1ed8bSBen Walker MOCK_SET(sendmsg, 24);
121b7ad9426SBen Walker cb_arg1 = false;
122b7ad9426SBen Walker rc = _sock_flush(sock);
1235433004eSBen Walker CU_ASSERT(rc == 24);
124b7ad9426SBen Walker CU_ASSERT(cb_arg1 == false);
125b7ad9426SBen Walker CU_ASSERT(TAILQ_FIRST(&sock->queued_reqs) == req1);
126b7ad9426SBen Walker
127b7ad9426SBen Walker /* Flush the rest of the data */
1287db1ed8bSBen Walker MOCK_SET(sendmsg, 30);
129b7ad9426SBen Walker cb_arg1 = false;
130b7ad9426SBen Walker rc = _sock_flush(sock);
1315433004eSBen Walker CU_ASSERT(rc == 30);
132b7ad9426SBen Walker CU_ASSERT(cb_arg1 == true);
133b7ad9426SBen Walker CU_ASSERT(TAILQ_EMPTY(&sock->queued_reqs));
134b7ad9426SBen Walker
135b7ad9426SBen Walker free(req1);
136b7ad9426SBen Walker free(req2);
137b7ad9426SBen Walker }
138b7ad9426SBen Walker
139b7ad9426SBen Walker int
main(int argc,char ** argv)140b7ad9426SBen Walker main(int argc, char **argv)
141b7ad9426SBen Walker {
142b7ad9426SBen Walker CU_pSuite suite = NULL;
143b7ad9426SBen Walker unsigned int num_failures;
144b7ad9426SBen Walker
14578b696bcSVitaliy Mysak CU_initialize_registry();
146b7ad9426SBen Walker
147b7ad9426SBen Walker suite = CU_add_suite("posix", NULL, NULL);
148b7ad9426SBen Walker
149dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, flush);
150b7ad9426SBen Walker
151b7ad9426SBen Walker
152ea941caeSKonrad Sztyber num_failures = spdk_ut_run_tests(argc, argv, NULL);
153b7ad9426SBen Walker
154b7ad9426SBen Walker CU_cleanup_registry();
155b7ad9426SBen Walker
156b7ad9426SBen Walker return num_failures;
157b7ad9426SBen Walker }
158