1 /*
2  * Copyright (c) 2020 Friedt Professional Engineering Services, Inc
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @brief Tests for the Pipe read / write availability
9  * @ingroup kernel_pipe_tests
10  * @{
11  */
12 
13 #include <zephyr/ztest.h>
14 
15 static ZTEST_DMEM unsigned char __aligned(4) data[] = "abcdefgh";
16 static struct k_pipe pipe = {
17 	.buffer = data,
18 	.size = sizeof(data) - 1 /* '\0' */,
19 };
20 
21 static struct k_pipe bufferless;
22 
23 static struct k_pipe bufferless1 = {
24 	.buffer = data,
25 	.size = 0,
26 };
27 
28 /**
29  * @brief Pipes with no buffer or size 0 should return 0 bytes available
30  *
31  * Pipes can be created to be bufferless (i.e. @ref k_pipe.buffer is `NULL`
32  * or @ref k_pipe.size is 0).
33  *
34  * If either of those conditions is true, then @ref k_pipe_read_avail and
35  * @ref k_pipe_write_avail should return 0.
36  *
37  * @note
38  * A distinction can be made between buffered and bufferless pipes in that
39  * @ref k_pipe_read_avail and @ref k_pipe_write_avail will never
40  * simultaneously return 0 for a buffered pipe, but they will both return 0
41  * for an unbuffered pipe.
42  */
ZTEST(pipe_api,test_pipe_avail_no_buffer)43 ZTEST(pipe_api, test_pipe_avail_no_buffer)
44 {
45 	size_t r_avail;
46 	size_t w_avail;
47 
48 	r_avail = k_pipe_read_avail(&bufferless);
49 	zassert_equal(r_avail, 0, "read: expected: 0 actual: %u", r_avail);
50 
51 	w_avail = k_pipe_write_avail(&bufferless);
52 	zassert_equal(w_avail, 0, "write: expected: 0 actual: %u", w_avail);
53 
54 	r_avail = k_pipe_read_avail(&bufferless1);
55 	zassert_equal(r_avail, 0, "read: expected: 0 actual: %u", r_avail);
56 
57 	w_avail = k_pipe_write_avail(&bufferless1);
58 	zassert_equal(w_avail, 0, "write: expected: 0 actual: %u", w_avail);
59 }
60 
61 /**
62  * @brief Test available read / write space for r < w
63  *
64  * This test case is for buffered @ref k_pipe objects and covers the case
65  * where @ref k_pipe.read_index is less than @ref k_pipe.write_index.
66  *
67  * In this case, @ref k_pipe.bytes_used is not relevant.
68  *
69  *      r     w
70  *     |a|b|c|d|e|f|g|h|
71  *     |0|1|2|3|4|5|6|7|
72  *
73  * As shown above, the pipe will be able to read 3 bytes without blocking
74  * and write 5 bytes without blocking.
75  *
76  * Thus
77  *     r_avail = w - r = 3
78  *     would read: a b c d
79  *
80  *     w_avail = N - (w - r) = 5
81  *     would overwrite: e f g h
82  */
ZTEST(pipe_api,test_pipe_avail_r_lt_w)83 ZTEST(pipe_api, test_pipe_avail_r_lt_w)
84 {
85 	size_t r_avail;
86 	size_t w_avail;
87 
88 	pipe.read_index = 0;
89 	pipe.write_index = 3;
90 	/* pipe.bytes_used is irrelevant */
91 
92 	r_avail = k_pipe_read_avail(&pipe);
93 	zassert_equal(r_avail, 3, "read: expected: 3 actual: %u", r_avail);
94 
95 	w_avail = k_pipe_write_avail(&pipe);
96 	zassert_equal(w_avail, 5, "write: expected: 5 actual: %u", w_avail);
97 }
98 
99 /**
100  * @brief Test available read / write space for w < r
101  *
102  * This test case is for buffered @ref k_pipe objects and covers the case
103  * where @ref k_pipe.write_index is less than @ref k_pipe.read_index.
104  *
105  * In this case, @ref k_pipe.bytes_used is not relevant.
106  *
107  *      w     r
108  *     |a|b|c|d|e|f|g|h|
109  *     |0|1|2|3|4|5|6|7|
110  *
111  *
112  * As shown above, the pipe will fbe able to read 5 bytes without blocking
113  * and write 3 bytes without blocking.
114  *
115  * Thus
116  *     r_avail = N - (r - w) = 5
117  *     would read: e f g h
118  *
119  *     w_avail = r - w = 3
120  *     would overwrite: a b c d
121  */
ZTEST(pipe_api,test_pipe_avail_w_lt_r)122 ZTEST(pipe_api, test_pipe_avail_w_lt_r)
123 {
124 	size_t r_avail;
125 	size_t w_avail;
126 
127 	pipe.read_index = 3;
128 	pipe.write_index = 0;
129 	/* pipe.bytes_used is irrelevant */
130 
131 	r_avail = k_pipe_read_avail(&pipe);
132 	zassert_equal(r_avail, 5, "read: expected: 4 actual: %u", r_avail);
133 
134 	w_avail = k_pipe_write_avail(&pipe);
135 	zassert_equal(w_avail, 3, "write: expected: 4 actual: %u", w_avail);
136 }
137 
138 /**
139  * @brief Test available read / write space for `r == w` and an empty buffer
140  *
141  * This test case is for buffered @ref k_pipe objects and covers the case
142  * where @ref k_pipe.read_index is equal to @ref k_pipe.write_index and
143  * @ref k_pipe.bytes_used is zero.
144  *
145  * In this case, @ref k_pipe.bytes_used is relevant because the read and
146  * write indices are equal.
147  *
148  *            r
149  *            w
150  *     |a|b|c|d|e|f|g|h|
151  *     |0|1|2|3|4|5|6|7|
152  *
153  * Regardless of whether the buffer is full or empty, the following holds:
154  *
155  *     r_avail = bytes_used
156  *     w_avail = N - bytes_used
157  *
158  * Thus:
159  *     r_avail = 0
160  *     would read:
161  *
162  *     w_avail = N - 0 = 8
163  *     would overwrite: e f g h a b c d
164  */
ZTEST(pipe_api,test_pipe_avail_r_eq_w_empty)165 ZTEST(pipe_api, test_pipe_avail_r_eq_w_empty)
166 {
167 	size_t r_avail;
168 	size_t w_avail;
169 
170 	pipe.read_index = 4;
171 	pipe.write_index = 4;
172 	pipe.bytes_used = 0;
173 
174 	r_avail = k_pipe_read_avail(&pipe);
175 	zassert_equal(r_avail, 0, "read: expected: 0 actual: %u", r_avail);
176 
177 	w_avail = k_pipe_write_avail(&pipe);
178 	zassert_equal(w_avail, 8, "write: expected: 8 actual: %u", w_avail);
179 }
180 
181 /**
182  * @brief Test available read / write space for `r == w` and a full buffer
183  *
184  * This test case is for buffered @ref k_pipe objects and covers the case
185  * where @ref k_pipe.read_index is equal to @ref k_pipe.write_index and
186  * @ref k_pipe.bytes_used is equal to @ref k_pipe.size.
187  *
188  * In this case, @ref k_pipe.bytes_used is relevant because the read and
189  * write indices are equal.
190  *
191  *            r
192  *            w
193  *     |a|b|c|d|e|f|g|h|
194  *     |0|1|2|3|4|5|6|7|
195  *
196  * Regardless of whether the buffer is full or empty, the following holds:
197  *
198  *     r_avail = bytes_used
199  *     w_avail = N - bytes_used
200  *
201  * Thus
202  *     r_avail = N = 8
203  *     would read: e f g h a b c d
204  *
205  *     w_avail = N - 8 = 0
206  *     would overwrite:
207  */
ZTEST(pipe_api,test_pipe_avail_r_eq_w_full)208 ZTEST(pipe_api, test_pipe_avail_r_eq_w_full)
209 {
210 	size_t r_avail;
211 	size_t w_avail;
212 
213 	pipe.read_index = 4;
214 	pipe.write_index = 4;
215 	pipe.bytes_used = pipe.size;
216 
217 	r_avail = k_pipe_read_avail(&pipe);
218 	zassert_equal(r_avail, 8, "read: expected: 8 actual: %u", r_avail);
219 
220 	w_avail = k_pipe_write_avail(&pipe);
221 	zassert_equal(w_avail, 0, "write: expected: 0 actual: %u", w_avail);
222 }
223 
224 /**
225  * @}
226  */
227