1 /*
2 * Arm SCP/MCP Software
3 * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include <fwk_macros.h>
9 #include <fwk_ring.h>
10 #include <fwk_status.h>
11 #include <fwk_test.h>
12
13 #include <assert.h>
14 #include <stddef.h>
15
16 static struct fwk_ring ring;
17
test_suite_setup(void)18 static int test_suite_setup(void)
19 {
20 static char ring_storage[4] = { 0 };
21
22 fwk_ring_init(&ring, ring_storage, sizeof(ring_storage));
23
24 return FWK_SUCCESS;
25 }
26
test_case_setup(void)27 static void test_case_setup(void)
28 {
29 fwk_ring_clear(&ring);
30 }
31
test_fwk_ring_pop_empty(void)32 static void test_fwk_ring_pop_empty(void)
33 {
34 char data_out[4] = { 127, 127, 127, 127 };
35
36 size_t data_length = fwk_ring_pop(&ring, data_out, 4);
37 assert(data_length == 0);
38
39 assert(fwk_ring_get_length(&ring) == 0);
40 assert(fwk_ring_is_empty(&ring) == true);
41 assert(fwk_ring_is_full(&ring) == false);
42
43 assert(data_out[0] == 127);
44 assert(data_out[1] == 127);
45 assert(data_out[2] == 127);
46 assert(data_out[3] == 127);
47 }
48
test_fwk_ring_pop_linear(void)49 static void test_fwk_ring_pop_linear(void)
50 {
51 size_t data_length;
52
53 const char data_in[4] = { 0, 1, 2, 3 };
54 char data_out[4] = { 127, 127, 127, 127 };
55
56 fwk_ring_push(&ring, data_in, 4);
57
58 data_length = fwk_ring_pop(&ring, data_out, 4);
59 assert(data_length == 4);
60
61 assert(fwk_ring_get_length(&ring) == 0);
62 assert(fwk_ring_is_empty(&ring) == true);
63 assert(fwk_ring_is_full(&ring) == false);
64
65 assert(data_out[0] == 0);
66 assert(data_out[1] == 1);
67 assert(data_out[2] == 2);
68 assert(data_out[3] == 3);
69 }
70
test_fwk_ring_pop_fragmented(void)71 static void test_fwk_ring_pop_fragmented(void)
72 {
73 size_t data_length;
74
75 const char data_in[6] = { 0, 1, 2, 3, 4, 5 };
76 char data_out[4] = { 127, 127, 127, 127 };
77
78 fwk_ring_push(&ring, &data_in[0], 4);
79 fwk_ring_push(&ring, &data_in[4], 2);
80
81 data_length = fwk_ring_pop(&ring, data_out, 4);
82 assert(data_length == 4);
83
84 assert(fwk_ring_get_length(&ring) == 0);
85 assert(fwk_ring_is_empty(&ring) == true);
86 assert(fwk_ring_is_full(&ring) == false);
87
88 assert(data_out[0] == 2);
89 assert(data_out[1] == 3);
90 assert(data_out[2] == 4);
91 assert(data_out[3] == 5);
92 }
93
test_fwk_ring_pop_exceeds_length(void)94 static void test_fwk_ring_pop_exceeds_length(void)
95 {
96 size_t data_length;
97
98 const char data_in[2] = { 0, 1 };
99 char data_out[4] = { 127, 127, 127, 127 };
100
101 fwk_ring_push(&ring, data_in, 2);
102
103 data_length = fwk_ring_pop(&ring, data_out, 4);
104 assert(data_length == 2);
105
106 assert(fwk_ring_get_length(&ring) == 0);
107 assert(fwk_ring_is_empty(&ring) == true);
108 assert(fwk_ring_is_full(&ring) == false);
109
110 assert(data_out[0] == 0);
111 assert(data_out[1] == 1);
112 assert(data_out[2] == 127);
113 assert(data_out[3] == 127);
114 }
115
test_fwk_ring_pop_partial_length(void)116 static void test_fwk_ring_pop_partial_length(void)
117 {
118 size_t data_length;
119
120 const char data_in[4] = { 0, 1, 2, 3 };
121 char data_out[4] = { 127, 127, 127, 127 };
122
123 fwk_ring_push(&ring, data_in, 4);
124
125 data_length = fwk_ring_pop(&ring, data_out, 3);
126 assert(data_length == 3);
127
128 assert(fwk_ring_get_length(&ring) == 1);
129 assert(fwk_ring_is_empty(&ring) == false);
130 assert(fwk_ring_is_full(&ring) == false);
131
132 assert(data_out[0] == 0);
133 assert(data_out[1] == 1);
134 assert(data_out[2] == 2);
135 assert(data_out[3] == 127);
136 }
137
test_fwk_ring_pop_zero_length(void)138 static void test_fwk_ring_pop_zero_length(void)
139 {
140 size_t data_length;
141
142 const char data_in[4] = { 0, 1, 2, 3 };
143 char data_out[4] = { 127, 127, 127, 127 };
144
145 fwk_ring_push(&ring, data_in, 4);
146
147 data_length = fwk_ring_pop(&ring, data_out, 0);
148 assert(data_length == 0);
149
150 assert(fwk_ring_get_length(&ring) == 4);
151 assert(fwk_ring_is_empty(&ring) == false);
152 assert(fwk_ring_is_full(&ring) == true);
153
154 assert(data_out[0] == 127);
155 assert(data_out[1] == 127);
156 assert(data_out[2] == 127);
157 assert(data_out[3] == 127);
158 }
159
test_fwk_ring_pop_null(void)160 static void test_fwk_ring_pop_null(void)
161 {
162 size_t data_length;
163
164 const char data_in[4] = { 0, 1, 2, 3 };
165 char data_out[4] = { 127, 127, 127, 127 };
166
167 fwk_ring_push(&ring, data_in, 4);
168
169 data_length = fwk_ring_pop(&ring, NULL, 3);
170 assert(data_length == 3);
171
172 assert(fwk_ring_get_length(&ring) == 1);
173 assert(fwk_ring_is_empty(&ring) == false);
174 assert(fwk_ring_is_full(&ring) == false);
175
176 data_length = fwk_ring_peek(&ring, data_out, 1);
177 assert(data_length == 1);
178
179 assert(data_out[0] == 3);
180 assert(data_out[1] == 127);
181 assert(data_out[2] == 127);
182 assert(data_out[3] == 127);
183 }
184
test_fwk_ring_push_exceeds_capacity(void)185 static void test_fwk_ring_push_exceeds_capacity(void)
186 {
187 size_t data_length;
188
189 const char data_in[6] = { 0, 1, 2, 3, 4, 5 };
190 char data_out[4] = { 127, 127, 127, 127 };
191
192 data_length = fwk_ring_push(&ring, data_in, 6);
193 assert(data_length == 4);
194
195 assert(fwk_ring_get_length(&ring) == 4);
196 assert(fwk_ring_is_empty(&ring) == false);
197 assert(fwk_ring_is_full(&ring) == true);
198
199 fwk_ring_pop(&ring, data_out, 4);
200
201 assert(data_out[0] == 2);
202 assert(data_out[1] == 3);
203 assert(data_out[2] == 4);
204 assert(data_out[3] == 5);
205 }
206
test_fwk_ring_push_multiple_linear(void)207 static void test_fwk_ring_push_multiple_linear(void)
208 {
209 size_t data_length;
210
211 const char data_in[4] = { 0, 1, 2, 3 };
212 char data_out[4] = { 127, 127, 127, 127 };
213
214 data_length = fwk_ring_push(&ring, &data_in[0], 2);
215 assert(data_length == 2);
216
217 assert(fwk_ring_get_length(&ring) == 2);
218 assert(fwk_ring_is_empty(&ring) == false);
219 assert(fwk_ring_is_full(&ring) == false);
220
221 data_length = fwk_ring_push(&ring, &data_in[2], 2);
222 assert(data_length == 2);
223
224 assert(fwk_ring_get_length(&ring) == 4);
225 assert(fwk_ring_is_empty(&ring) == false);
226 assert(fwk_ring_is_full(&ring) == true);
227
228 fwk_ring_pop(&ring, data_out, 4);
229
230 assert(data_out[0] == 0);
231 assert(data_out[1] == 1);
232 assert(data_out[2] == 2);
233 assert(data_out[3] == 3);
234 }
235
test_fwk_ring_push_multiple_fragmented(void)236 static void test_fwk_ring_push_multiple_fragmented(void)
237 {
238 size_t data_length;
239
240 const char data_in[6] = { 0, 1, 2, 3, 4, 5 };
241 char data_out[4] = { 127, 127, 127, 127 };
242
243 data_length = fwk_ring_push(&ring, &data_in[0], 3);
244 assert(data_length == 3);
245
246 assert(fwk_ring_get_length(&ring) == 3);
247 assert(fwk_ring_is_empty(&ring) == false);
248 assert(fwk_ring_is_full(&ring) == false);
249
250 data_length = fwk_ring_push(&ring, &data_in[3], 3);
251 assert(data_length == 3);
252
253 assert(fwk_ring_get_length(&ring) == 4);
254 assert(fwk_ring_is_empty(&ring) == false);
255 assert(fwk_ring_is_full(&ring) == true);
256
257 fwk_ring_pop(&ring, data_out, 4);
258
259 assert(data_out[0] == 2);
260 assert(data_out[1] == 3);
261 assert(data_out[2] == 4);
262 assert(data_out[3] == 5);
263 }
264
265 static const struct fwk_test_case_desc test_case_table[] = {
266 FWK_TEST_CASE(test_fwk_ring_pop_empty),
267 FWK_TEST_CASE(test_fwk_ring_pop_linear),
268 FWK_TEST_CASE(test_fwk_ring_pop_fragmented),
269 FWK_TEST_CASE(test_fwk_ring_pop_exceeds_length),
270 FWK_TEST_CASE(test_fwk_ring_pop_partial_length),
271 FWK_TEST_CASE(test_fwk_ring_pop_zero_length),
272 FWK_TEST_CASE(test_fwk_ring_pop_null),
273 FWK_TEST_CASE(test_fwk_ring_push_exceeds_capacity),
274 FWK_TEST_CASE(test_fwk_ring_push_multiple_linear),
275 FWK_TEST_CASE(test_fwk_ring_push_multiple_fragmented),
276 };
277
278 struct fwk_test_suite_desc test_suite = {
279 .name = "fwk_ring",
280
281 .test_suite_setup = test_suite_setup,
282 .test_case_setup = test_case_setup,
283
284 .test_case_count = FWK_ARRAY_SIZE(test_case_table),
285 .test_case_table = test_case_table,
286 };
287