1 /*
2  * Copyright (c) 2020 Friedt Professional Engineering Services, Inc
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "_main.h"
8 
9 struct ctx {
10 	bool should_write;
11 	int *fd;
12 	k_timeout_t delay;
13 };
14 static ZTEST_BMEM struct ctx ctx;
15 static ZTEST_BMEM struct k_work work;
16 
17 /*
18  * Timeout should work the same for blocking & non-blocking threads
19  *
20  *   - no bytes available to read after timeout, r: 0 (timeout)
21  *   - no bytes available to write after timeout, r: 0 (timeout)
22  */
23 
test_socketpair_poll_timeout_common(struct net_socketpair_fixture * fixture)24 static void test_socketpair_poll_timeout_common(struct net_socketpair_fixture *fixture)
25 {
26 	int res;
27 	struct zsock_pollfd fds[1];
28 
29 	memset(fds, 0, sizeof(fds));
30 	fds[0].fd = fixture->sv[0];
31 	fds[0].events |= ZSOCK_POLLIN;
32 	res = zsock_poll(fds, 1, 1);
33 	zassert_equal(res, 0, "poll: expected: 0 actual: %d", res);
34 
35 	for (size_t i = 0; i < CONFIG_NET_SOCKETPAIR_BUFFER_SIZE; ++i) {
36 		res = zsock_send(fixture->sv[0], "x", 1, 0);
37 		zassert_equal(res, 1, "send() failed: %d", res);
38 	}
39 
40 	memset(fds, 0, sizeof(fds));
41 	fds[0].fd = fixture->sv[0];
42 	fds[0].events |= ZSOCK_POLLOUT;
43 	res = zsock_poll(fds, 1, 1);
44 	zassert_equal(res, 0, "poll: expected: 0 actual: %d", res);
45 }
46 
ZTEST_USER_F(net_socketpair,test_poll_timeout)47 ZTEST_USER_F(net_socketpair, test_poll_timeout)
48 {
49 	test_socketpair_poll_timeout_common(fixture);
50 }
51 
52 /* O_NONBLOCK should have no affect on poll(2) */
ZTEST_USER_F(net_socketpair,test_poll_timeout_nonblocking)53 ZTEST_USER_F(net_socketpair, test_poll_timeout_nonblocking)
54 {
55 	int res;
56 
57 	res = zsock_fcntl(fixture->sv[0], F_GETFL, 0);
58 	zassert_not_equal(res, -1, "fcntl failed: %d", errno);
59 
60 	int flags = res;
61 
62 	res = zsock_fcntl(fixture->sv[0], F_SETFL, O_NONBLOCK | flags);
63 	zassert_not_equal(res, -1, "fcntl failed: %d", errno);
64 
65 	res = zsock_fcntl(fixture->sv[1], F_SETFL, O_NONBLOCK | flags);
66 	zassert_not_equal(res, -1, "fcntl failed: %d", errno);
67 
68 	test_socketpair_poll_timeout_common(fixture);
69 }
70 
close_fun(struct k_work * w)71 static void close_fun(struct k_work *w)
72 {
73 	(void)w;
74 
75 	if (!(K_TIMEOUT_EQ(ctx.delay, K_NO_WAIT)
76 		|| K_TIMEOUT_EQ(ctx.delay, K_FOREVER))) {
77 		k_sleep(ctx.delay);
78 	}
79 
80 	LOG_DBG("about to close fd %d", *ctx.fd);
81 	zsock_close(*ctx.fd);
82 	*ctx.fd = -1;
83 }
84 
85 /*
86  * Hangup should cause the following behaviour
87  *   - close remote fd while the local fd is blocking in poll. r: 1,
88  *     POLLIN, read -> r: 0, errno: 0 -> EOF
89  *   - close remote fd while the local fd is blocking in poll. r: 1,
90  *     POLLOUT, write -> r: -1, errno: EPIPE.
91  */
ZTEST_F(net_socketpair,test_poll_close_remote_end_POLLIN)92 ZTEST_F(net_socketpair, test_poll_close_remote_end_POLLIN)
93 {
94 	int res;
95 	char c;
96 	struct zsock_pollfd fds[1];
97 
98 	/*
99 	 * poll until there are bytes to read.
100 	 * But rather than writing, close the other end of the channel
101 	 */
102 
103 	memset(fds, 0, sizeof(fds));
104 	fds[0].fd = fixture->sv[0];
105 	fds[0].events |= ZSOCK_POLLIN;
106 
107 	memset(&ctx, 0, sizeof(ctx));
108 	ctx.fd = &fixture->sv[1];
109 	ctx.delay = K_MSEC(1000);
110 
111 	LOG_DBG("scheduling work");
112 	k_work_init(&work, close_fun);
113 	k_work_submit(&work);
114 
115 	res = zsock_poll(fds, 1, -1);
116 	zassert_equal(res, 1, "poll() failed: %d", res);
117 	zassert_equal(fds[0].revents & ZSOCK_POLLIN, ZSOCK_POLLIN, "POLLIN not set");
118 
119 	res = zsock_recv(fixture->sv[0], &c, 1, 0);
120 	zassert_equal(res, 0, "read did not return EOF");
121 }
122 
ZTEST_F(net_socketpair,test_poll_close_remote_end_POLLOUT)123 ZTEST_F(net_socketpair, test_poll_close_remote_end_POLLOUT)
124 {
125 	int res;
126 	struct zsock_pollfd fds[1];
127 
128 	/*
129 	 * Fill up the remote q and then poll until write space is available.
130 	 * But rather than reading, close the other end of the channel
131 	 */
132 
133 	res = zsock_socketpair(AF_UNIX, SOCK_STREAM, 0, fixture->sv);
134 	zassert_not_equal(res, -1, "socketpair() failed: %d", errno);
135 
136 	for (size_t i = 0; i < CONFIG_NET_SOCKETPAIR_BUFFER_SIZE; ++i) {
137 		res = zsock_send(fixture->sv[0], "x", 1, 0);
138 		zassert_equal(res, 1, "send failed: %d", res);
139 	}
140 
141 	memset(fds, 0, sizeof(fds));
142 	fds[0].fd = fixture->sv[0];
143 	fds[0].events |= ZSOCK_POLLOUT;
144 
145 	memset(&ctx, 0, sizeof(ctx));
146 	ctx.fd = &fixture->sv[1];
147 	ctx.delay = K_MSEC(1000);
148 
149 	LOG_DBG("scheduling work");
150 	k_work_init(&work, close_fun);
151 	k_work_submit(&work);
152 
153 	res = zsock_poll(fds, 1, -1);
154 	zassert_equal(res, 1, "poll() failed: %d", res);
155 	zassert_equal(fds[0].revents & ZSOCK_POLLHUP, ZSOCK_POLLHUP, "POLLHUP not set");
156 
157 	res = zsock_send(fixture->sv[0], "x", 1, 0);
158 	zassert_equal(res, -1, "send(): expected: -1 actual: %d", res);
159 	zassert_equal(errno, EPIPE, "errno: expected: EPIPE actual: %d", errno);
160 }
161 
162 /*
163  * Data available immediately
164  *   - even with a timeout value of 0 us, poll should return immediately with
165  *     a value of 1 (for either read or write cases)
166  *   - even with a timeout value of 0us, poll should return immediately with
167  *     a value of 2 if both read and write are available
168  */
ZTEST_USER_F(net_socketpair,test_poll_immediate_data)169 ZTEST_USER_F(net_socketpair, test_poll_immediate_data)
170 {
171 	int res;
172 	struct zsock_pollfd fds[2];
173 
174 	memset(fds, 0, sizeof(fds));
175 	fds[0].fd = fixture->sv[0];
176 	fds[0].events |= ZSOCK_POLLOUT;
177 	res = zsock_poll(fds, 1, 0);
178 	zassert_not_equal(res, -1, "poll() failed: %d", errno);
179 	zassert_equal(res, 1, "poll(): expected: 1 actual: %d", res);
180 	zassert_not_equal(fds[0].revents & ZSOCK_POLLOUT, 0, "POLLOUT not set");
181 
182 	res = zsock_send(fixture->sv[0], "x", 1, 0);
183 	zassert_not_equal(res, -1, "send() failed: %d", errno);
184 	zassert_equal(res, 1, "write(): expected: 1 actual: %d", res);
185 
186 	memset(fds, 0, sizeof(fds));
187 	fds[0].fd = fixture->sv[1];
188 	fds[0].events |= ZSOCK_POLLIN;
189 	res = zsock_poll(fds, 1, 0);
190 	zassert_not_equal(res, -1, "poll() failed: %d", errno);
191 	zassert_equal(res, 1, "poll(): expected: 1 actual: %d", res);
192 	zassert_not_equal(fds[0].revents & ZSOCK_POLLIN, 0, "POLLIN not set");
193 
194 	memset(fds, 0, sizeof(fds));
195 	fds[0].fd = fixture->sv[0];
196 	fds[0].events |= ZSOCK_POLLOUT;
197 	fds[1].fd = fixture->sv[1];
198 	fds[1].events |= ZSOCK_POLLIN;
199 	res = zsock_poll(fds, 2, 0);
200 	zassert_not_equal(res, -1, "poll() failed: %d", errno);
201 	zassert_equal(res, 2, "poll(): expected: 1 actual: %d", res);
202 	zassert_not_equal(fds[0].revents & ZSOCK_POLLOUT, 0, "POLLOUT not set");
203 	zassert_not_equal(fds[1].revents & ZSOCK_POLLIN, 0, "POLLIN not set");
204 }
205 
rw_fun(struct k_work * w)206 static void rw_fun(struct k_work *w)
207 {
208 	(void)w;
209 
210 	int res;
211 	char c;
212 
213 	if (!(K_TIMEOUT_EQ(ctx.delay, K_NO_WAIT)
214 		|| K_TIMEOUT_EQ(ctx.delay, K_FOREVER))) {
215 		k_sleep(ctx.delay);
216 	}
217 
218 	if (ctx.should_write) {
219 		LOG_DBG("about to write 1 byte");
220 		res = zsock_send(*ctx.fd, "x", 1, 0);
221 		if (-1 == res) {
222 			LOG_DBG("send() failed: %d", errno);
223 		} else {
224 			LOG_DBG("wrote 1 byte");
225 		}
226 	} else {
227 		LOG_DBG("about to read 1 byte");
228 		res = zsock_recv(*ctx.fd, &c, 1, 0);
229 		if (-1 == res) {
230 			LOG_DBG("recv() failed: %d", errno);
231 		} else {
232 			LOG_DBG("read 1 byte");
233 		}
234 	}
235 }
236 
237 /*
238  * Data only available but after some short period
239  *   - say there is a timeout value of 5 s, poll should return immediately
240  *     with the a value of 1 (for either read or write cases)
241  */
ZTEST_F(net_socketpair,test_poll_delayed_data)242 ZTEST_F(net_socketpair, test_poll_delayed_data)
243 {
244 	int res;
245 	struct zsock_pollfd fds[1];
246 
247 	memset(fds, 0, sizeof(fds));
248 	fds[0].fd = fixture->sv[0];
249 	fds[0].events |= ZSOCK_POLLIN;
250 
251 	memset(&ctx, 0, sizeof(ctx));
252 	ctx.fd = &fixture->sv[1];
253 	ctx.should_write = true;
254 	ctx.delay = K_MSEC(100);
255 
256 	LOG_DBG("scheduling work");
257 	k_work_init(&work, rw_fun);
258 	k_work_submit(&work);
259 
260 	res = zsock_poll(fds, 1, 5000);
261 	zassert_not_equal(res, -1, "poll() failed: %d", errno);
262 	zassert_equal(res, 1, "poll(): expected: 1 actual: %d", res);
263 	zassert_not_equal(fds[0].revents & ZSOCK_POLLIN, 0, "POLLIN not set");
264 
265 	for (size_t i = 0; i < CONFIG_NET_SOCKETPAIR_BUFFER_SIZE; ++i) {
266 		res = zsock_send(fixture->sv[0], "x", 1, 0);
267 		zassert_equal(res, 1, "send() failed: %d", res);
268 	}
269 
270 	memset(fds, 0, sizeof(fds));
271 	fds[0].fd = fixture->sv[0];
272 	fds[0].events |= ZSOCK_POLLOUT;
273 
274 	memset(&ctx, 0, sizeof(ctx));
275 	ctx.fd = &fixture->sv[1];
276 	ctx.should_write = false;
277 	ctx.delay = K_MSEC(100);
278 
279 	LOG_DBG("scheduling work");
280 	k_work_init(&work, rw_fun);
281 	k_work_submit(&work);
282 
283 	res = zsock_poll(fds, 1, 5000);
284 	zassert_not_equal(res, -1, "poll() failed: %d", errno);
285 	zassert_equal(res, 1, "poll(): expected: 1 actual: %d", res);
286 	zassert_not_equal(fds[0].revents & ZSOCK_POLLOUT, 0, "POLLOUT was not set");
287 }
288 
289 /*
290  * Verify that POLLIN is correctly signalled
291  *   - right after socket creation, POLLIN should not be reported
292  *   - after data is written to a remote socket, POLLIN should be reported, even
293  *     if the poll was called after the data was written
294  *   - after reading data from a remote socket, POLLIN shouldn't be reported
295  */
ZTEST_USER_F(net_socketpair,test_poll_signalling_POLLIN)296 ZTEST_USER_F(net_socketpair, test_poll_signalling_POLLIN)
297 {
298 	int res;
299 	char c;
300 	int64_t timestamp, delta;
301 	struct zsock_pollfd fds[1];
302 
303 	memset(fds, 0, sizeof(fds));
304 	fds[0].fd = fixture->sv[1];
305 	fds[0].events |= ZSOCK_POLLIN;
306 	res = zsock_poll(fds, 1, 0);
307 	zassert_not_equal(res, -1, "poll failed: %d", errno);
308 	zassert_equal(res, 0, "poll: expected: 0 actual: %d", res);
309 	zassert_not_equal(fds[0].revents & ZSOCK_POLLIN, ZSOCK_POLLIN, "POLLIN set");
310 
311 	res = zsock_send(fixture->sv[0], "x", 1, 0);
312 	zassert_equal(res, 1, "send failed: %d", res);
313 
314 	timestamp = k_uptime_get();
315 
316 	memset(fds, 0, sizeof(fds));
317 	fds[0].fd = fixture->sv[1];
318 	fds[0].events |= ZSOCK_POLLIN;
319 	res = zsock_poll(fds, 1, 1000);
320 	zassert_not_equal(res, -1, "poll failed: %d", errno);
321 	zassert_equal(res, 1, "poll: expected: 1 actual: %d", res);
322 	zassert_not_equal(fds[0].revents & ZSOCK_POLLIN, 0, "POLLIN not set");
323 
324 	delta = k_uptime_delta(&timestamp);
325 	zassert_true(delta < 100, "poll did not exit immediately");
326 
327 	res = zsock_recv(fixture->sv[1], &c, 1, 0);
328 	zassert_equal(res, 1, "recv failed: %d", res);
329 
330 	memset(fds, 0, sizeof(fds));
331 	fds[0].fd = fixture->sv[1];
332 	fds[0].events |= ZSOCK_POLLIN;
333 	res = zsock_poll(fds, 1, 0);
334 	zassert_not_equal(res, -1, "poll failed: %d", errno);
335 	zassert_equal(res, 0, "poll: expected: 0 actual: %d", res);
336 	zassert_not_equal(fds[0].revents & ZSOCK_POLLIN, ZSOCK_POLLIN, "POLLIN set");
337 }
338 
339 /*
340  * Verify that POLLOUT is correctly signalled
341  *   - right after socket creation, POLLOUT should be reported
342  *   - after remote buffer is filled up, POLLOUT shouldn't be reported
343  *   - after reading data from a remote socket, POLLOUT should be reported
344  *     again
345  */
ZTEST_USER_F(net_socketpair,test_poll_signalling_POLLOUT)346 ZTEST_USER_F(net_socketpair, test_poll_signalling_POLLOUT)
347 {
348 	int res;
349 	char c;
350 	int64_t timestamp, delta;
351 	struct zsock_pollfd fds[1];
352 
353 	timestamp = k_uptime_get();
354 
355 	memset(fds, 0, sizeof(fds));
356 	fds[0].fd = fixture->sv[0];
357 	fds[0].events |= ZSOCK_POLLOUT;
358 	res = zsock_poll(fds, 1, 1000);
359 	zassert_not_equal(res, -1, "poll failed: %d", errno);
360 	zassert_equal(res, 1, "poll: expected: 1 actual: %d", res);
361 	zassert_not_equal(fds[0].revents & ZSOCK_POLLOUT, 0, "POLLOUT not set");
362 
363 	delta = k_uptime_delta(&timestamp);
364 	zassert_true(delta < 100, "poll did not exit immediately");
365 
366 	/* Fill up the remote buffer */
367 	for (size_t i = 0; i < CONFIG_NET_SOCKETPAIR_BUFFER_SIZE; ++i) {
368 		res = zsock_send(fixture->sv[0], "x", 1, 0);
369 		zassert_equal(res, 1, "send() failed: %d", res);
370 	}
371 
372 	memset(fds, 0, sizeof(fds));
373 	fds[0].fd = fixture->sv[0];
374 	fds[0].events |= ZSOCK_POLLOUT;
375 	res = zsock_poll(fds, 1, 0);
376 	zassert_not_equal(res, -1, "poll failed: %d", errno);
377 	zassert_equal(res, 0, "poll: expected: 0 actual: %d", res);
378 	zassert_not_equal(fds[0].revents & ZSOCK_POLLOUT, ZSOCK_POLLOUT, "POLLOUT is set");
379 
380 	res = zsock_recv(fixture->sv[1], &c, 1, 0);
381 	zassert_equal(res, 1, "recv() failed: %d", res);
382 
383 	timestamp = k_uptime_get();
384 
385 	memset(fds, 0, sizeof(fds));
386 	fds[0].fd = fixture->sv[0];
387 	fds[0].events |= ZSOCK_POLLOUT;
388 	res = zsock_poll(fds, 1, 1000);
389 	zassert_not_equal(res, -1, "poll failed: %d", errno);
390 	zassert_equal(res, 1, "poll: expected: 1 actual: %d", res);
391 	zassert_not_equal(fds[0].revents & ZSOCK_POLLOUT, 0, "POLLOUT not set");
392 
393 	delta = k_uptime_delta(&timestamp);
394 	zassert_true(delta < 100, "poll did not exit immediately");
395 }
396