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