xref: /freebsd/contrib/atf/atf-c/detail/map_test.c (revision 145992504973bd16cf3518af9ba5ce185fefa82a)
1 /*
2  * Automated Testing Framework (atf)
3  *
4  * Copyright (c) 2008 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <stdio.h>
31 #include <string.h>
32 
33 #include <atf-c.h>
34 
35 #include "atf-c/utils.h"
36 
37 #include "map.h"
38 #include "test_helpers.h"
39 
40 /* ---------------------------------------------------------------------
41  * Tests for the "atf_map" type.
42  * --------------------------------------------------------------------- */
43 
44 /*
45  * Constructors and destructors.
46  */
47 
48 ATF_TC(map_init);
49 ATF_TC_HEAD(map_init, tc)
50 {
51     atf_tc_set_md_var(tc, "descr", "Checks the atf_map_init function");
52 }
53 ATF_TC_BODY(map_init, tc)
54 {
55     atf_map_t map;
56 
57     RE(atf_map_init(&map));
58     ATF_REQUIRE_EQ(atf_map_size(&map), 0);
59     atf_map_fini(&map);
60 }
61 
62 ATF_TC_WITHOUT_HEAD(map_init_charpp_null);
63 ATF_TC_BODY(map_init_charpp_null, tc)
64 {
65     atf_map_t map;
66 
67     RE(atf_map_init_charpp(&map, NULL));
68     ATF_REQUIRE_EQ(atf_map_size(&map), 0);
69     atf_map_fini(&map);
70 }
71 
72 ATF_TC_WITHOUT_HEAD(map_init_charpp_empty);
73 ATF_TC_BODY(map_init_charpp_empty, tc)
74 {
75     const char *const array[] = { NULL };
76     atf_map_t map;
77 
78     RE(atf_map_init_charpp(&map, array));
79     ATF_REQUIRE_EQ(atf_map_size(&map), 0);
80     atf_map_fini(&map);
81 }
82 
83 ATF_TC_WITHOUT_HEAD(map_init_charpp_some);
84 ATF_TC_BODY(map_init_charpp_some, tc)
85 {
86     const char *const array[] = { "K1", "V1", "K2", "V2", NULL };
87     atf_map_t map;
88     atf_map_citer_t iter;
89 
90     RE(atf_map_init_charpp(&map, array));
91     ATF_REQUIRE_EQ(atf_map_size(&map), 2);
92 
93     iter = atf_map_find_c(&map, "K1");
94     ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
95     ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K1") == 0);
96     ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V1") == 0);
97 
98     iter = atf_map_find_c(&map, "K2");
99     ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
100     ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K2") == 0);
101     ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V2") == 0);
102 
103     atf_map_fini(&map);
104 }
105 
106 ATF_TC_WITHOUT_HEAD(map_init_charpp_short);
107 ATF_TC_BODY(map_init_charpp_short, tc)
108 {
109     const char *const array[] = { "K1", "V1", "K2", NULL };
110     atf_map_t map;
111 
112     atf_error_t err = atf_map_init_charpp(&map, array);
113     ATF_REQUIRE(atf_is_error(err));
114     ATF_REQUIRE(atf_error_is(err, "libc"));
115 }
116 
117 /*
118  * Getters.
119  */
120 
121 ATF_TC(find);
122 ATF_TC_HEAD(find, tc)
123 {
124     atf_tc_set_md_var(tc, "descr", "Checks the atf_map_find function");
125 }
126 ATF_TC_BODY(find, tc)
127 {
128     atf_map_t map;
129     char val1[] = "V1";
130     char val2[] = "V2";
131     atf_map_iter_t iter;
132 
133     RE(atf_map_init(&map));
134     RE(atf_map_insert(&map, "K1", val1, false));
135     RE(atf_map_insert(&map, "K2", val2, false));
136 
137     iter = atf_map_find(&map, "K0");
138     ATF_REQUIRE(atf_equal_map_iter_map_iter(iter, atf_map_end(&map)));
139 
140     iter = atf_map_find(&map, "K1");
141     ATF_REQUIRE(!atf_equal_map_iter_map_iter(iter, atf_map_end(&map)));
142     ATF_REQUIRE(strcmp(atf_map_iter_key(iter), "K1") == 0);
143     ATF_REQUIRE(strcmp(atf_map_iter_data(iter), "V1") == 0);
144     strcpy(atf_map_iter_data(iter), "Z1");
145 
146     iter = atf_map_find(&map, "K1");
147     ATF_REQUIRE(!atf_equal_map_iter_map_iter(iter, atf_map_end(&map)));
148     ATF_REQUIRE(strcmp(atf_map_iter_key(iter), "K1") == 0);
149     ATF_REQUIRE(strcmp(atf_map_iter_data(iter), "Z1") == 0);
150 
151     iter = atf_map_find(&map, "K2");
152     ATF_REQUIRE(!atf_equal_map_iter_map_iter(iter, atf_map_end(&map)));
153     ATF_REQUIRE(strcmp(atf_map_iter_key(iter), "K2") == 0);
154     ATF_REQUIRE(strcmp(atf_map_iter_data(iter), "V2") == 0);
155 
156     atf_map_fini(&map);
157 }
158 
159 ATF_TC(find_c);
160 ATF_TC_HEAD(find_c, tc)
161 {
162     atf_tc_set_md_var(tc, "descr", "Checks the atf_map_find_c function");
163 }
164 ATF_TC_BODY(find_c, tc)
165 {
166     atf_map_t map;
167     char val1[] = "V1";
168     char val2[] = "V2";
169     atf_map_citer_t iter;
170 
171     RE(atf_map_init(&map));
172     RE(atf_map_insert(&map, "K1", val1, false));
173     RE(atf_map_insert(&map, "K2", val2, false));
174 
175     iter = atf_map_find_c(&map, "K0");
176     ATF_REQUIRE(atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
177 
178     iter = atf_map_find_c(&map, "K1");
179     ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
180     ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K1") == 0);
181     ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V1") == 0);
182 
183     iter = atf_map_find_c(&map, "K2");
184     ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
185     ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K2") == 0);
186     ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V2") == 0);
187 
188     atf_map_fini(&map);
189 }
190 
191 ATF_TC_WITHOUT_HEAD(to_charpp_empty);
192 ATF_TC_BODY(to_charpp_empty, tc)
193 {
194     atf_map_t map;
195     char **array;
196 
197     RE(atf_map_init(&map));
198     ATF_REQUIRE((array = atf_map_to_charpp(&map)) != NULL);
199     atf_map_fini(&map);
200 
201     ATF_CHECK_EQ(NULL, array[0]);
202     atf_utils_free_charpp(array);
203 }
204 
205 ATF_TC_WITHOUT_HEAD(to_charpp_some);
206 ATF_TC_BODY(to_charpp_some, tc)
207 {
208     atf_map_t map;
209     char **array;
210 
211     char s1[] = "one";
212     char s2[] = "two";
213     char s3[] = "three";
214 
215     RE(atf_map_init(&map));
216     RE(atf_map_insert(&map, "K1", s1, false));
217     RE(atf_map_insert(&map, "K2", s2, false));
218     RE(atf_map_insert(&map, "K3", s3, false));
219     ATF_REQUIRE((array = atf_map_to_charpp(&map)) != NULL);
220     atf_map_fini(&map);
221 
222     ATF_CHECK_STREQ("K1", array[0]);
223     ATF_CHECK_STREQ("one", array[1]);
224     ATF_CHECK_STREQ("K2", array[2]);
225     ATF_CHECK_STREQ("two", array[3]);
226     ATF_CHECK_STREQ("K3", array[4]);
227     ATF_CHECK_STREQ("three", array[5]);
228     ATF_CHECK_EQ(NULL, array[6]);
229     atf_utils_free_charpp(array);
230 }
231 
232 /*
233  * Modifiers.
234  */
235 
236 ATF_TC(map_insert);
237 ATF_TC_HEAD(map_insert, tc)
238 {
239     atf_tc_set_md_var(tc, "descr", "Checks the atf_map_insert function");
240 }
241 ATF_TC_BODY(map_insert, tc)
242 {
243     atf_map_t map;
244     char buf[] = "1st test string";
245     char buf2[] = "2nd test string";
246     const char *ptr;
247     atf_map_citer_t iter;
248 
249     RE(atf_map_init(&map));
250 
251     printf("Inserting some values\n");
252     ATF_REQUIRE_EQ(atf_map_size(&map), 0);
253     RE(atf_map_insert(&map, "K1", buf, false));
254     ATF_REQUIRE_EQ(atf_map_size(&map), 1);
255     RE(atf_map_insert(&map, "K2", buf, false));
256     ATF_REQUIRE_EQ(atf_map_size(&map), 2);
257     RE(atf_map_insert(&map, "K3", buf, false));
258     ATF_REQUIRE_EQ(atf_map_size(&map), 3);
259 
260     printf("Replacing a value\n");
261     iter = atf_map_find_c(&map, "K3");
262     ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
263     ptr = atf_map_citer_data(iter);
264     ATF_REQUIRE_EQ(ptr, buf);
265     RE(atf_map_insert(&map, "K3", buf2, false));
266     ATF_REQUIRE_EQ(atf_map_size(&map), 3);
267     iter = atf_map_find_c(&map, "K3");
268     ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
269     ptr = atf_map_citer_data(iter);
270     ATF_REQUIRE_EQ(ptr, buf2);
271 
272     atf_map_fini(&map);
273 }
274 
275 /*
276  * Macros.
277  */
278 
279 ATF_TC(map_for_each);
280 ATF_TC_HEAD(map_for_each, tc)
281 {
282     atf_tc_set_md_var(tc, "descr", "Checks the atf_map_for_each macro");
283 }
284 ATF_TC_BODY(map_for_each, tc)
285 {
286     atf_map_t map;
287     atf_map_iter_t iter;
288     size_t count, i, size;
289     char keys[10][5];
290     int nums[10];
291 
292     printf("Iterating over empty map\n");
293     RE(atf_map_init(&map));
294     count = 0;
295     atf_map_for_each(iter, &map) {
296         count++;
297         printf("Item count is now %zd\n", count);
298     }
299     ATF_REQUIRE_EQ(count, 0);
300     atf_map_fini(&map);
301 
302     for (size = 0; size <= 10; size++) {
303         printf("Iterating over map of %zd elements\n", size);
304         RE(atf_map_init(&map));
305         for (i = 0; i < size; i++) {
306             nums[i] = i + 1;
307             snprintf(keys[i], sizeof(keys[i]), "%d", nums[i]);
308             RE(atf_map_insert(&map, keys[i], &nums[i], false));
309         }
310         count = 0;
311         atf_map_for_each(iter, &map) {
312             printf("Retrieved item: %d\n", *(int *)atf_map_iter_data(iter));
313             count++;
314         }
315         ATF_REQUIRE_EQ(count, size);
316         atf_map_fini(&map);
317     }
318 }
319 
320 ATF_TC(map_for_each_c);
321 ATF_TC_HEAD(map_for_each_c, tc)
322 {
323     atf_tc_set_md_var(tc, "descr", "Checks the atf_map_for_each_c macro");
324 }
325 ATF_TC_BODY(map_for_each_c, tc)
326 {
327     atf_map_t map;
328     atf_map_citer_t iter;
329     size_t count, i, size;
330     char keys[10][5];
331     int nums[10];
332 
333     printf("Iterating over empty map\n");
334     RE(atf_map_init(&map));
335     count = 0;
336     atf_map_for_each_c(iter, &map) {
337         count++;
338         printf("Item count is now %zd\n", count);
339     }
340     ATF_REQUIRE_EQ(count, 0);
341     atf_map_fini(&map);
342 
343     for (size = 0; size <= 10; size++) {
344         printf("Iterating over map of %zd elements\n", size);
345         RE(atf_map_init(&map));
346         for (i = 0; i < size; i++) {
347             nums[i] = i + 1;
348             snprintf(keys[i], sizeof(keys[i]), "%d", nums[i]);
349             RE(atf_map_insert(&map, keys[i], &nums[i], false));
350         }
351         count = 0;
352         atf_map_for_each_c(iter, &map) {
353             printf("Retrieved item: %d\n",
354                    *(const int *)atf_map_citer_data(iter));
355             count++;
356         }
357         ATF_REQUIRE_EQ(count, size);
358         atf_map_fini(&map);
359     }
360 }
361 
362 /*
363  * Other.
364  */
365 
366 ATF_TC(stable_keys);
367 ATF_TC_HEAD(stable_keys, tc)
368 {
369     atf_tc_set_md_var(tc, "descr", "Checks that the keys do not change "
370                       "even if their original values do");
371 }
372 ATF_TC_BODY(stable_keys, tc)
373 {
374     atf_map_t map;
375     atf_map_citer_t iter;
376     char key[] = "K1";
377 
378     RE(atf_map_init(&map));
379 
380     RE(atf_map_insert(&map, key, strdup("test-value"), true));
381     iter = atf_map_find_c(&map, "K1");
382     ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
383     iter = atf_map_find_c(&map, "K2");
384     ATF_REQUIRE(atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
385 
386     strcpy(key, "K2");
387     iter = atf_map_find_c(&map, "K1");
388     ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
389     iter = atf_map_find_c(&map, "K2");
390     ATF_REQUIRE(atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
391 
392     atf_map_fini(&map);
393 }
394 
395 /* ---------------------------------------------------------------------
396  * Main.
397  * --------------------------------------------------------------------- */
398 
399 ATF_TP_ADD_TCS(tp)
400 {
401     /* Constructors and destructors. */
402     ATF_TP_ADD_TC(tp, map_init);
403     ATF_TP_ADD_TC(tp, map_init_charpp_null);
404     ATF_TP_ADD_TC(tp, map_init_charpp_empty);
405     ATF_TP_ADD_TC(tp, map_init_charpp_some);
406     ATF_TP_ADD_TC(tp, map_init_charpp_short);
407 
408     /* Getters. */
409     ATF_TP_ADD_TC(tp, find);
410     ATF_TP_ADD_TC(tp, find_c);
411     ATF_TP_ADD_TC(tp, to_charpp_empty);
412     ATF_TP_ADD_TC(tp, to_charpp_some);
413 
414     /* Modifiers. */
415     ATF_TP_ADD_TC(tp, map_insert);
416 
417     /* Macros. */
418     ATF_TP_ADD_TC(tp, map_for_each);
419     ATF_TP_ADD_TC(tp, map_for_each_c);
420 
421     /* Other. */
422     ATF_TP_ADD_TC(tp, stable_keys);
423 
424     return atf_no_error();
425 }
426