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