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