1 /* Copyright (c) 2008 The NetBSD Foundation, Inc.
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
25
26 #include "atf-c/detail/list.h"
27
28 #include <stdio.h>
29 #include <string.h>
30
31 #include <atf-c.h>
32
33 #include "atf-c/detail/test_helpers.h"
34 #include "atf-c/utils.h"
35
36 /* ---------------------------------------------------------------------
37 * Tests for the "atf_list" type.
38 * --------------------------------------------------------------------- */
39
40 /*
41 * Constructors and destructors.
42 */
43
44 ATF_TC(list_init);
ATF_TC_HEAD(list_init,tc)45 ATF_TC_HEAD(list_init, tc)
46 {
47 atf_tc_set_md_var(tc, "descr", "Checks the atf_list_init function");
48 }
ATF_TC_BODY(list_init,tc)49 ATF_TC_BODY(list_init, tc)
50 {
51 atf_list_t list;
52
53 RE(atf_list_init(&list));
54 ATF_REQUIRE_EQ(atf_list_size(&list), 0);
55 atf_list_fini(&list);
56 }
57
58 /*
59 * Getters.
60 */
61
62 ATF_TC(list_index);
ATF_TC_HEAD(list_index,tc)63 ATF_TC_HEAD(list_index, tc)
64 {
65 atf_tc_set_md_var(tc, "descr", "Checks the atf_list_index function");
66 }
ATF_TC_BODY(list_index,tc)67 ATF_TC_BODY(list_index, tc)
68 {
69 atf_list_t list;
70 int i1 = 1;
71 int i2 = 5;
72 int i3 = 9;
73
74 RE(atf_list_init(&list));
75 RE(atf_list_append(&list, &i1, false));
76 RE(atf_list_append(&list, &i2, false));
77 RE(atf_list_append(&list, &i3, false));
78
79 ATF_CHECK_EQ(*(int *)atf_list_index(&list, 0), 1);
80 ATF_CHECK_EQ(*(int *)atf_list_index(&list, 1), 5);
81 ATF_CHECK_EQ(*(int *)atf_list_index(&list, 2), 9);
82
83 atf_list_fini(&list);
84 }
85
86 ATF_TC(list_index_c);
ATF_TC_HEAD(list_index_c,tc)87 ATF_TC_HEAD(list_index_c, tc)
88 {
89 atf_tc_set_md_var(tc, "descr", "Checks the atf_list_index_c function");
90 }
ATF_TC_BODY(list_index_c,tc)91 ATF_TC_BODY(list_index_c, tc)
92 {
93 atf_list_t list;
94 int i1 = 1;
95 int i2 = 5;
96 int i3 = 9;
97
98 RE(atf_list_init(&list));
99 RE(atf_list_append(&list, &i1, false));
100 RE(atf_list_append(&list, &i2, false));
101 RE(atf_list_append(&list, &i3, false));
102
103 ATF_CHECK_EQ(*(const int *)atf_list_index_c(&list, 0), 1);
104 ATF_CHECK_EQ(*(const int *)atf_list_index_c(&list, 1), 5);
105 ATF_CHECK_EQ(*(const int *)atf_list_index_c(&list, 2), 9);
106
107 atf_list_fini(&list);
108 }
109
110 ATF_TC_WITHOUT_HEAD(list_to_charpp_empty);
ATF_TC_BODY(list_to_charpp_empty,tc)111 ATF_TC_BODY(list_to_charpp_empty, tc)
112 {
113 atf_list_t list;
114 char **array;
115
116 RE(atf_list_init(&list));
117 ATF_REQUIRE((array = atf_list_to_charpp(&list)) != NULL);
118 atf_list_fini(&list);
119
120 ATF_CHECK_EQ(NULL, array[0]);
121 atf_utils_free_charpp(array);
122 }
123
124 ATF_TC_WITHOUT_HEAD(list_to_charpp_some);
ATF_TC_BODY(list_to_charpp_some,tc)125 ATF_TC_BODY(list_to_charpp_some, tc)
126 {
127 atf_list_t list;
128 char **array;
129
130 char s1[] = "one";
131 char s2[] = "two";
132 char s3[] = "three";
133
134 RE(atf_list_init(&list));
135 RE(atf_list_append(&list, s1, false));
136 RE(atf_list_append(&list, s2, false));
137 RE(atf_list_append(&list, s3, false));
138 ATF_REQUIRE((array = atf_list_to_charpp(&list)) != NULL);
139 atf_list_fini(&list);
140
141 ATF_CHECK_STREQ("one", array[0]);
142 ATF_CHECK_STREQ("two", array[1]);
143 ATF_CHECK_STREQ("three", array[2]);
144 ATF_CHECK_EQ(NULL, array[3]);
145 atf_utils_free_charpp(array);
146 }
147
148 /*
149 * Modifiers.
150 */
151
152 ATF_TC(list_append);
ATF_TC_HEAD(list_append,tc)153 ATF_TC_HEAD(list_append, tc)
154 {
155 atf_tc_set_md_var(tc, "descr", "Checks the atf_list_append function");
156 }
ATF_TC_BODY(list_append,tc)157 ATF_TC_BODY(list_append, tc)
158 {
159 atf_list_t list;
160 size_t i;
161 char buf[] = "Test string";
162
163 RE(atf_list_init(&list));
164 for (i = 0; i < 1024; i++) {
165 ATF_REQUIRE_EQ(atf_list_size(&list), i);
166 RE(atf_list_append(&list, buf, false));
167 }
168 atf_list_fini(&list);
169 }
170
171 ATF_TC(list_append_list);
ATF_TC_HEAD(list_append_list,tc)172 ATF_TC_HEAD(list_append_list, tc)
173 {
174 atf_tc_set_md_var(tc, "descr", "Checks the atf_list_append_list "
175 "function");
176 }
ATF_TC_BODY(list_append_list,tc)177 ATF_TC_BODY(list_append_list, tc)
178 {
179 {
180 atf_list_t l1, l2;
181
182 RE(atf_list_init(&l1));
183 RE(atf_list_init(&l2));
184
185 atf_list_append_list(&l1, &l2);
186 ATF_CHECK_EQ(atf_list_size(&l1), 0);
187
188 atf_list_fini(&l1);
189 }
190
191 {
192 atf_list_t l1, l2;
193 int item = 5;
194
195 RE(atf_list_init(&l1));
196 RE(atf_list_append(&l1, &item, false));
197 RE(atf_list_init(&l2));
198
199 atf_list_append_list(&l1, &l2);
200 ATF_CHECK_EQ(atf_list_size(&l1), 1);
201 ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 0), item);
202
203 atf_list_fini(&l1);
204 }
205
206 {
207 atf_list_t l1, l2;
208 int item = 5;
209
210 RE(atf_list_init(&l1));
211 RE(atf_list_init(&l2));
212 RE(atf_list_append(&l2, &item, false));
213
214 atf_list_append_list(&l1, &l2);
215 ATF_CHECK_EQ(atf_list_size(&l1), 1);
216 ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 0), item);
217
218 atf_list_fini(&l1);
219 }
220
221 {
222 atf_list_t l1, l2;
223 int item1 = 5;
224 int item2 = 9;
225
226 RE(atf_list_init(&l1));
227 RE(atf_list_append(&l1, &item1, false));
228 RE(atf_list_init(&l2));
229 RE(atf_list_append(&l2, &item2, false));
230
231 atf_list_append_list(&l1, &l2);
232 ATF_CHECK_EQ(atf_list_size(&l1), 2);
233 ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 0), item1);
234 ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 1), item2);
235
236 atf_list_fini(&l1);
237 }
238
239 {
240 atf_list_t l1, l2;
241 atf_list_citer_t end1, end2;
242
243 RE(atf_list_init(&l1));
244 RE(atf_list_init(&l2));
245
246 end1 = atf_list_end_c(&l1);
247 end2 = atf_list_end_c(&l2);
248 /* XXX Shouldn't query m_entry here. */
249 ATF_CHECK(end1.m_entry != end2.m_entry);
250
251 atf_list_append_list(&l1, &l2);
252 ATF_CHECK(atf_list_end_c(&l1).m_entry == end2.m_entry);
253
254 atf_list_fini(&l1);
255 }
256 }
257
258 /*
259 * Macros.
260 */
261
262 ATF_TC(list_for_each);
ATF_TC_HEAD(list_for_each,tc)263 ATF_TC_HEAD(list_for_each, tc)
264 {
265 atf_tc_set_md_var(tc, "descr", "Checks the atf_list_for_each macro");
266 }
ATF_TC_BODY(list_for_each,tc)267 ATF_TC_BODY(list_for_each, tc)
268 {
269 atf_list_t list;
270 atf_list_iter_t iter;
271 size_t count, i, size;
272 int nums[10];
273
274 printf("Iterating over empty list\n");
275 RE(atf_list_init(&list));
276 count = 0;
277 atf_list_for_each(iter, &list) {
278 count++;
279 printf("Item count is now %zd\n", count);
280 }
281 ATF_REQUIRE_EQ(count, 0);
282 atf_list_fini(&list);
283
284 for (size = 0; size <= 10; size++) {
285 printf("Iterating over list of %zd elements\n", size);
286 RE(atf_list_init(&list));
287 for (i = 0; i < size; i++) {
288 nums[i] = i + 1;
289 RE(atf_list_append(&list, &nums[i], false));
290 }
291 count = 0;
292 atf_list_for_each(iter, &list) {
293 printf("Retrieved item: %d\n", *(int *)atf_list_iter_data(iter));
294 count++;
295 }
296 ATF_REQUIRE_EQ(count, size);
297 atf_list_fini(&list);
298 }
299 }
300
301 ATF_TC(list_for_each_c);
ATF_TC_HEAD(list_for_each_c,tc)302 ATF_TC_HEAD(list_for_each_c, tc)
303 {
304 atf_tc_set_md_var(tc, "descr", "Checks the atf_list_for_each_c macro");
305 }
ATF_TC_BODY(list_for_each_c,tc)306 ATF_TC_BODY(list_for_each_c, tc)
307 {
308 atf_list_t list;
309 atf_list_citer_t iter;
310 size_t count, i, size;
311 int nums[10];
312
313 printf("Iterating over empty list\n");
314 RE(atf_list_init(&list));
315 count = 0;
316 atf_list_for_each_c(iter, &list) {
317 count++;
318 printf("Item count is now %zd\n", count);
319 }
320 ATF_REQUIRE_EQ(count, 0);
321 atf_list_fini(&list);
322
323 for (size = 0; size <= 10; size++) {
324 printf("Iterating over list of %zd elements\n", size);
325 RE(atf_list_init(&list));
326 for (i = 0; i < size; i++) {
327 nums[i] = i + 1;
328 RE(atf_list_append(&list, &nums[i], false));
329 }
330 count = 0;
331 atf_list_for_each_c(iter, &list) {
332 printf("Retrieved item: %d\n",
333 *(const int *)atf_list_citer_data(iter));
334 count++;
335 }
336 ATF_REQUIRE_EQ(count, size);
337 atf_list_fini(&list);
338 }
339 }
340
341 /* ---------------------------------------------------------------------
342 * Main.
343 * --------------------------------------------------------------------- */
344
ATF_TP_ADD_TCS(tp)345 ATF_TP_ADD_TCS(tp)
346 {
347 /* Constructors and destructors. */
348 ATF_TP_ADD_TC(tp, list_init);
349
350 /* Getters. */
351 ATF_TP_ADD_TC(tp, list_index);
352 ATF_TP_ADD_TC(tp, list_index_c);
353 ATF_TP_ADD_TC(tp, list_to_charpp_empty);
354 ATF_TP_ADD_TC(tp, list_to_charpp_some);
355
356 /* Modifiers. */
357 ATF_TP_ADD_TC(tp, list_append);
358 ATF_TP_ADD_TC(tp, list_append_list);
359
360 /* Macros. */
361 ATF_TP_ADD_TC(tp, list_for_each);
362 ATF_TP_ADD_TC(tp, list_for_each_c);
363
364 return atf_no_error();
365 }
366