1123474Swpaul/* Copyright (c) 2008 The NetBSD Foundation, Inc. 2123474Swpaul * All rights reserved. 3123474Swpaul * 4123474Swpaul * Redistribution and use in source and binary forms, with or without 5123474Swpaul * modification, are permitted provided that the following conditions 6123474Swpaul * are met: 7123474Swpaul * 1. Redistributions of source code must retain the above copyright 8123474Swpaul * notice, this list of conditions and the following disclaimer. 9123474Swpaul * 2. Redistributions in binary form must reproduce the above copyright 10123474Swpaul * notice, this list of conditions and the following disclaimer in the 11123474Swpaul * documentation and/or other materials provided with the distribution. 12123474Swpaul * 13123474Swpaul * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 14123474Swpaul * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 15123474Swpaul * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16123474Swpaul * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17123474Swpaul * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 18123474Swpaul * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19123474Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 20123474Swpaul * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21123474Swpaul * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 22123474Swpaul * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23123474Swpaul * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 24123474Swpaul * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 25123474Swpaul 26123474Swpaul#include "atf-c/detail/map.h" 27123474Swpaul 28123474Swpaul#include <stdio.h> 29123474Swpaul#include <string.h> 30123474Swpaul 31123474Swpaul#include <atf-c.h> 32123474Swpaul 33123474Swpaul#include "atf-c/detail/test_helpers.h" 34123474Swpaul#include "atf-c/utils.h" 35123474Swpaul 36123474Swpaul/* --------------------------------------------------------------------- 37123474Swpaul * Tests for the "atf_map" type. 38123474Swpaul * --------------------------------------------------------------------- */ 39123474Swpaul 40123474Swpaul/* 41123474Swpaul * Constructors and destructors. 42123474Swpaul */ 43123474Swpaul 44123474SwpaulATF_TC(map_init); 45123474SwpaulATF_TC_HEAD(map_init, tc) 46123474Swpaul{ 47123474Swpaul atf_tc_set_md_var(tc, "descr", "Checks the atf_map_init function"); 48124135Swpaul} 49123474SwpaulATF_TC_BODY(map_init, tc) 50123474Swpaul{ 51123474Swpaul atf_map_t map; 52123474Swpaul 53123474Swpaul RE(atf_map_init(&map)); 54123474Swpaul ATF_REQUIRE_EQ(atf_map_size(&map), 0); 55123474Swpaul atf_map_fini(&map); 56124060Swpaul} 57124060Swpaul 58123474SwpaulATF_TC_WITHOUT_HEAD(map_init_charpp_null); 59123474SwpaulATF_TC_BODY(map_init_charpp_null, tc) 60123474Swpaul{ 61123474Swpaul atf_map_t map; 62123474Swpaul 63123474Swpaul RE(atf_map_init_charpp(&map, NULL)); 64123695Swpaul ATF_REQUIRE_EQ(atf_map_size(&map), 0); 65123695Swpaul atf_map_fini(&map); 66123695Swpaul} 67123474Swpaul 68123474SwpaulATF_TC_WITHOUT_HEAD(map_init_charpp_empty); 69123474SwpaulATF_TC_BODY(map_init_charpp_empty, tc) 70123474Swpaul{ 71123474Swpaul const char *const array[] = { NULL }; 72123474Swpaul atf_map_t map; 73123474Swpaul 74123474Swpaul RE(atf_map_init_charpp(&map, array)); 75123474Swpaul ATF_REQUIRE_EQ(atf_map_size(&map), 0); 76123474Swpaul atf_map_fini(&map); 77123474Swpaul} 78123474Swpaul 79123474SwpaulATF_TC_WITHOUT_HEAD(map_init_charpp_some); 80123474SwpaulATF_TC_BODY(map_init_charpp_some, tc) 81123474Swpaul{ 82123474Swpaul const char *const array[] = { "K1", "V1", "K2", "V2", NULL }; 83123474Swpaul atf_map_t map; 84123474Swpaul atf_map_citer_t iter; 85123535Swpaul 86123474Swpaul RE(atf_map_init_charpp(&map, array)); 87124100Swpaul ATF_REQUIRE_EQ(atf_map_size(&map), 2); 88123474Swpaul 89124060Swpaul iter = atf_map_find_c(&map, "K1"); 90124060Swpaul ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map))); 91123474Swpaul ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K1") == 0); 92123474Swpaul ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V1") == 0); 93123474Swpaul 94123474Swpaul iter = atf_map_find_c(&map, "K2"); 95123474Swpaul ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map))); 96123474Swpaul ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K2") == 0); 97123474Swpaul ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V2") == 0); 98123474Swpaul 99123474Swpaul atf_map_fini(&map); 100124060Swpaul} 101124060Swpaul 102124060SwpaulATF_TC_WITHOUT_HEAD(map_init_charpp_short); 103124060SwpaulATF_TC_BODY(map_init_charpp_short, tc) 104124122Swpaul{ 105124122Swpaul const char *const array[] = { "K1", "V1", "K2", NULL }; 106124122Swpaul atf_map_t map; 107124122Swpaul 108124122Swpaul atf_error_t err = atf_map_init_charpp(&map, array); 109124060Swpaul ATF_REQUIRE(atf_is_error(err)); 110124060Swpaul ATF_REQUIRE(atf_error_is(err, "libc")); 111124060Swpaul} 112124060Swpaul 113124060Swpaul/* 114124060Swpaul * Getters. 115124060Swpaul */ 116124060Swpaul 117124060SwpaulATF_TC(find); 118124122SwpaulATF_TC_HEAD(find, tc) 119124122Swpaul{ 120124122Swpaul atf_tc_set_md_var(tc, "descr", "Checks the atf_map_find function"); 121124122Swpaul} 122124122SwpaulATF_TC_BODY(find, tc) 123124060Swpaul{ 124124060Swpaul atf_map_t map; 125124060Swpaul char val1[] = "V1"; 126124060Swpaul char val2[] = "V2"; 127124060Swpaul atf_map_iter_t iter; 128124060Swpaul 129124060Swpaul RE(atf_map_init(&map)); 130124060Swpaul RE(atf_map_insert(&map, "K1", val1, false)); 131124060Swpaul RE(atf_map_insert(&map, "K2", val2, false)); 132123474Swpaul 133123474Swpaul iter = atf_map_find(&map, "K0"); 134123474Swpaul ATF_REQUIRE(atf_equal_map_iter_map_iter(iter, atf_map_end(&map))); 135123474Swpaul 136123474Swpaul iter = atf_map_find(&map, "K1"); 137123474Swpaul ATF_REQUIRE(!atf_equal_map_iter_map_iter(iter, atf_map_end(&map))); 138124100Swpaul ATF_REQUIRE(strcmp(atf_map_iter_key(iter), "K1") == 0); 139124100Swpaul ATF_REQUIRE(strcmp(atf_map_iter_data(iter), "V1") == 0); 140124100Swpaul strcpy(atf_map_iter_data(iter), "Z1"); 141124100Swpaul 142124100Swpaul iter = atf_map_find(&map, "K1"); 143124100Swpaul ATF_REQUIRE(!atf_equal_map_iter_map_iter(iter, atf_map_end(&map))); 144124100Swpaul ATF_REQUIRE(strcmp(atf_map_iter_key(iter), "K1") == 0); 145123474Swpaul ATF_REQUIRE(strcmp(atf_map_iter_data(iter), "Z1") == 0); 146123474Swpaul 147123474Swpaul iter = atf_map_find(&map, "K2"); 148123474Swpaul ATF_REQUIRE(!atf_equal_map_iter_map_iter(iter, atf_map_end(&map))); 149123474Swpaul ATF_REQUIRE(strcmp(atf_map_iter_key(iter), "K2") == 0); 150123474Swpaul ATF_REQUIRE(strcmp(atf_map_iter_data(iter), "V2") == 0); 151124060Swpaul 152124060Swpaul atf_map_fini(&map); 153124060Swpaul} 154124060Swpaul 155123474SwpaulATF_TC(find_c); 156123474SwpaulATF_TC_HEAD(find_c, tc) 157123474Swpaul{ 158123474Swpaul atf_tc_set_md_var(tc, "descr", "Checks the atf_map_find_c function"); 159123474Swpaul} 160123474SwpaulATF_TC_BODY(find_c, tc) 161123474Swpaul{ 162124060Swpaul atf_map_t map; 163124060Swpaul char val1[] = "V1"; 164124060Swpaul char val2[] = "V2"; 165124060Swpaul atf_map_citer_t iter; 166123474Swpaul 167123474Swpaul RE(atf_map_init(&map)); 168123474Swpaul RE(atf_map_insert(&map, "K1", val1, false)); 169123474Swpaul RE(atf_map_insert(&map, "K2", val2, false)); 170123474Swpaul 171123474Swpaul iter = atf_map_find_c(&map, "K0"); 172123474Swpaul ATF_REQUIRE(atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map))); 173123474Swpaul 174123695Swpaul iter = atf_map_find_c(&map, "K1"); 175123695Swpaul ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map))); 176123695Swpaul ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K1") == 0); 177123695Swpaul ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V1") == 0); 178123695Swpaul 179123474Swpaul iter = atf_map_find_c(&map, "K2"); 180123474Swpaul ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map))); 181123474Swpaul ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K2") == 0); 182123474Swpaul ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V2") == 0); 183123535Swpaul 184123535Swpaul atf_map_fini(&map); 185123535Swpaul} 186123535Swpaul 187123695SwpaulATF_TC_WITHOUT_HEAD(to_charpp_empty); 188123695SwpaulATF_TC_BODY(to_charpp_empty, tc) 189123695Swpaul{ 190123695Swpaul atf_map_t map; 191123695Swpaul char **array; 192123535Swpaul 193123535Swpaul RE(atf_map_init(&map)); 194123535Swpaul ATF_REQUIRE((array = atf_map_to_charpp(&map)) != NULL); 195123535Swpaul atf_map_fini(&map); 196123474Swpaul 197123474Swpaul ATF_CHECK_EQ(NULL, array[0]); 198123474Swpaul atf_utils_free_charpp(array); 199123474Swpaul} 200123474Swpaul 201124060SwpaulATF_TC_WITHOUT_HEAD(to_charpp_some); 202124060SwpaulATF_TC_BODY(to_charpp_some, tc) 203124060Swpaul{ 204124060Swpaul atf_map_t map; 205123474Swpaul char **array; 206123474Swpaul 207123474Swpaul char s1[] = "one"; 208123474Swpaul char s2[] = "two"; 209123474Swpaul char s3[] = "three"; 210123474Swpaul 211123474Swpaul RE(atf_map_init(&map)); 212123474Swpaul RE(atf_map_insert(&map, "K1", s1, false)); 213123474Swpaul RE(atf_map_insert(&map, "K2", s2, false)); 214123474Swpaul RE(atf_map_insert(&map, "K3", s3, false)); 215123474Swpaul ATF_REQUIRE((array = atf_map_to_charpp(&map)) != NULL); 216123474Swpaul atf_map_fini(&map); 217123474Swpaul 218123474Swpaul ATF_CHECK_STREQ("K1", array[0]); 219123474Swpaul ATF_CHECK_STREQ("one", array[1]); 220123474Swpaul ATF_CHECK_STREQ("K2", array[2]); 221123474Swpaul ATF_CHECK_STREQ("two", array[3]); 222123474Swpaul ATF_CHECK_STREQ("K3", array[4]); 223123474Swpaul ATF_CHECK_STREQ("three", array[5]); 224123474Swpaul ATF_CHECK_EQ(NULL, array[6]); 225123474Swpaul atf_utils_free_charpp(array); 226124060Swpaul} 227124060Swpaul 228123474Swpaul/* 229123474Swpaul * Modifiers. 230123474Swpaul */ 231123474Swpaul 232123474SwpaulATF_TC(map_insert); 233123474SwpaulATF_TC_HEAD(map_insert, tc) 234123474Swpaul{ 235124060Swpaul atf_tc_set_md_var(tc, "descr", "Checks the atf_map_insert function"); 236124060Swpaul} 237123474SwpaulATF_TC_BODY(map_insert, tc) 238123474Swpaul{ 239123474Swpaul atf_map_t map; 240123474Swpaul char buf[] = "1st test string"; 241123474Swpaul char buf2[] = "2nd test string"; 242123474Swpaul const char *ptr; 243123474Swpaul atf_map_citer_t iter; 244124060Swpaul 245124060Swpaul RE(atf_map_init(&map)); 246123474Swpaul 247123474Swpaul printf("Inserting some values\n"); 248123474Swpaul ATF_REQUIRE_EQ(atf_map_size(&map), 0); 249123474Swpaul RE(atf_map_insert(&map, "K1", buf, false)); 250123474Swpaul ATF_REQUIRE_EQ(atf_map_size(&map), 1); 251123474Swpaul RE(atf_map_insert(&map, "K2", buf, false)); 252123474Swpaul ATF_REQUIRE_EQ(atf_map_size(&map), 2); 253123474Swpaul RE(atf_map_insert(&map, "K3", buf, false)); 254123474Swpaul ATF_REQUIRE_EQ(atf_map_size(&map), 3); 255123474Swpaul 256123474Swpaul printf("Replacing a value\n"); 257123474Swpaul iter = atf_map_find_c(&map, "K3"); 258123474Swpaul ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map))); 259123474Swpaul ptr = atf_map_citer_data(iter); 260123474Swpaul ATF_REQUIRE_EQ(ptr, buf); 261123474Swpaul RE(atf_map_insert(&map, "K3", buf2, false)); 262123474Swpaul ATF_REQUIRE_EQ(atf_map_size(&map), 3); 263123474Swpaul iter = atf_map_find_c(&map, "K3"); 264123474Swpaul ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map))); 265123474Swpaul ptr = atf_map_citer_data(iter); 266123474Swpaul ATF_REQUIRE_EQ(ptr, buf2); 267123474Swpaul 268123474Swpaul atf_map_fini(&map); 269123474Swpaul} 270123474Swpaul 271123474Swpaul/* 272123474Swpaul * Macros. 273123474Swpaul */ 274123474Swpaul 275123474SwpaulATF_TC(map_for_each); 276123474SwpaulATF_TC_HEAD(map_for_each, tc) 277123474Swpaul{ 278123474Swpaul atf_tc_set_md_var(tc, "descr", "Checks the atf_map_for_each macro"); 279123474Swpaul} 280123474SwpaulATF_TC_BODY(map_for_each, tc) 281123620Swpaul{ 282123620Swpaul atf_map_t map; 283123620Swpaul atf_map_iter_t iter; 284123620Swpaul size_t count, i, size; 285123474Swpaul char keys[10][5]; 286123474Swpaul int nums[10]; 287123474Swpaul 288123474Swpaul printf("Iterating over empty map\n"); 289123474Swpaul RE(atf_map_init(&map)); 290123474Swpaul count = 0; 291123474Swpaul atf_map_for_each(iter, &map) { 292123474Swpaul count++; 293123474Swpaul printf("Item count is now %zd\n", count); 294123474Swpaul } 295123474Swpaul ATF_REQUIRE_EQ(count, 0); 296123474Swpaul atf_map_fini(&map); 297123474Swpaul 298123474Swpaul for (size = 0; size <= 10; size++) { 299123474Swpaul printf("Iterating over map of %zd elements\n", size); 300123474Swpaul RE(atf_map_init(&map)); 301123474Swpaul for (i = 0; i < size; i++) { 302123474Swpaul nums[i] = i + 1; 303123474Swpaul snprintf(keys[i], sizeof(keys[i]), "%d", nums[i]); 304123474Swpaul RE(atf_map_insert(&map, keys[i], &nums[i], false)); 305123474Swpaul } 306123474Swpaul count = 0; 307123474Swpaul atf_map_for_each(iter, &map) { 308123474Swpaul printf("Retrieved item: %d\n", *(int *)atf_map_iter_data(iter)); 309123474Swpaul count++; 310123474Swpaul } 311123474Swpaul ATF_REQUIRE_EQ(count, size); 312123474Swpaul atf_map_fini(&map); 313123474Swpaul } 314123474Swpaul} 315123474Swpaul 316123474SwpaulATF_TC(map_for_each_c); 317123474SwpaulATF_TC_HEAD(map_for_each_c, tc) 318123474Swpaul{ 319123474Swpaul atf_tc_set_md_var(tc, "descr", "Checks the atf_map_for_each_c macro"); 320123474Swpaul} 321123474SwpaulATF_TC_BODY(map_for_each_c, tc) 322123474Swpaul{ 323123474Swpaul atf_map_t map; 324123474Swpaul atf_map_citer_t iter; 325123474Swpaul size_t count, i, size; 326123474Swpaul char keys[10][5]; 327123474Swpaul int nums[10]; 328123474Swpaul 329123474Swpaul printf("Iterating over empty map\n"); 330123474Swpaul RE(atf_map_init(&map)); 331123474Swpaul count = 0; 332123474Swpaul atf_map_for_each_c(iter, &map) { 333123474Swpaul count++; 334123474Swpaul printf("Item count is now %zd\n", count); 335123474Swpaul } 336123474Swpaul ATF_REQUIRE_EQ(count, 0); 337123474Swpaul atf_map_fini(&map); 338123474Swpaul 339123474Swpaul for (size = 0; size <= 10; size++) { 340123474Swpaul printf("Iterating over map of %zd elements\n", size); 341123474Swpaul RE(atf_map_init(&map)); 342123474Swpaul for (i = 0; i < size; i++) { 343123474Swpaul nums[i] = i + 1; 344123474Swpaul snprintf(keys[i], sizeof(keys[i]), "%d", nums[i]); 345123474Swpaul RE(atf_map_insert(&map, keys[i], &nums[i], false)); 346123474Swpaul } 347123474Swpaul count = 0; 348123474Swpaul atf_map_for_each_c(iter, &map) { 349123474Swpaul printf("Retrieved item: %d\n", 350123474Swpaul *(const int *)atf_map_citer_data(iter)); 351123474Swpaul count++; 352123474Swpaul } 353123474Swpaul ATF_REQUIRE_EQ(count, size); 354123474Swpaul atf_map_fini(&map); 355123474Swpaul } 356123474Swpaul} 357123474Swpaul 358123474Swpaul/* 359123474Swpaul * Other. 360123474Swpaul */ 361123474Swpaul 362123474SwpaulATF_TC(stable_keys); 363123474SwpaulATF_TC_HEAD(stable_keys, tc) 364123474Swpaul{ 365123474Swpaul atf_tc_set_md_var(tc, "descr", "Checks that the keys do not change " 366123474Swpaul "even if their original values do"); 367123474Swpaul} 368123474SwpaulATF_TC_BODY(stable_keys, tc) 369123474Swpaul{ 370123474Swpaul atf_map_t map; 371123474Swpaul atf_map_citer_t iter; 372123474Swpaul char key[] = "K1"; 373123474Swpaul 374123474Swpaul RE(atf_map_init(&map)); 375123474Swpaul 376123474Swpaul RE(atf_map_insert(&map, key, strdup("test-value"), true)); 377123474Swpaul iter = atf_map_find_c(&map, "K1"); 378123474Swpaul ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map))); 379123474Swpaul iter = atf_map_find_c(&map, "K2"); 380123474Swpaul ATF_REQUIRE(atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map))); 381123474Swpaul 382123474Swpaul strcpy(key, "K2"); 383123474Swpaul iter = atf_map_find_c(&map, "K1"); 384123826Swpaul ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map))); 385123826Swpaul iter = atf_map_find_c(&map, "K2"); 386123474Swpaul ATF_REQUIRE(atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map))); 387123474Swpaul 388123474Swpaul atf_map_fini(&map); 389123474Swpaul} 390123535Swpaul 391123474Swpaul/* --------------------------------------------------------------------- 392123474Swpaul * Main. 393123826Swpaul * --------------------------------------------------------------------- */ 394123474Swpaul 395123474SwpaulATF_TP_ADD_TCS(tp) 396123826Swpaul{ 397123535Swpaul /* Constructors and destructors. */ 398123535Swpaul ATF_TP_ADD_TC(tp, map_init); 399123826Swpaul ATF_TP_ADD_TC(tp, map_init_charpp_null); 400123535Swpaul ATF_TP_ADD_TC(tp, map_init_charpp_empty); 401123535Swpaul ATF_TP_ADD_TC(tp, map_init_charpp_some); 402123826Swpaul ATF_TP_ADD_TC(tp, map_init_charpp_short); 403123535Swpaul 404123536Swpaul /* Getters. */ 405123826Swpaul ATF_TP_ADD_TC(tp, find); 406123474Swpaul ATF_TP_ADD_TC(tp, find_c); 407123474Swpaul ATF_TP_ADD_TC(tp, to_charpp_empty); 408123858Swpaul ATF_TP_ADD_TC(tp, to_charpp_some); 409123826Swpaul 410123858Swpaul /* Modifiers. */ 411123474Swpaul ATF_TP_ADD_TC(tp, map_insert); 412123474Swpaul 413123474Swpaul /* Macros. */ 414123848Swpaul ATF_TP_ADD_TC(tp, map_for_each); 415123848Swpaul ATF_TP_ADD_TC(tp, map_for_each_c); 416123848Swpaul 417123848Swpaul /* Other. */ 418123848Swpaul ATF_TP_ADD_TC(tp, stable_keys); 419123848Swpaul 420123848Swpaul return atf_no_error(); 421123848Swpaul} 422123848Swpaul