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