Home | History | Annotate | Line # | Download | only in libppath
t_ppath.c revision 1.2
      1 /* $Id: t_ppath.c,v 1.2 2020/05/14 08:34:18 msaitoh Exp $ */
      2 
      3 /* Copyright (c) 2010 David Young.  All rights reserved. */
      4 
      5 #include <sys/cdefs.h>
      6 __RCSID("$Id: t_ppath.c,v 1.2 2020/05/14 08:34:18 msaitoh Exp $");
      7 
      8 #include <assert.h>
      9 #include <atf-c.h>
     10 #include <errno.h>
     11 #include <stdlib.h>
     12 #include <string.h>
     13 
     14 #include <ppath/ppath.h>
     15 #include "personnel.h"
     16 
     17 void test_ppath_extant_inc(void);
     18 void test_ppath_extant_dec(void);
     19 void test_ppath_component_extant_inc(void);
     20 void test_ppath_component_extant_dec(void);
     21 
     22 __strong_alias(ppath_extant_inc, test_ppath_extant_inc);
     23 __strong_alias(ppath_extant_dec, test_ppath_extant_dec);
     24 __strong_alias(ppath_component_extant_inc, test_ppath_component_extant_inc);
     25 __strong_alias(ppath_component_extant_dec, test_ppath_component_extant_dec);
     26 
     27 static uint64_t nppath = 0, nppath_component = 0;
     28 
     29 static bool
     30 dictionary_equals(prop_dictionary_t ld, prop_dictionary_t rd)
     31 {
     32 	bool eq;
     33 	char *lt, *rt;
     34 
     35 	lt = prop_dictionary_externalize(ld);
     36 	rt = prop_dictionary_externalize(rd);
     37 
     38 	assert(lt != NULL && rt != NULL);
     39 
     40 	eq = (strcmp(lt, rt) == 0);
     41 
     42 	free(lt);
     43 	free(rt);
     44 
     45 	return eq;
     46 }
     47 
     48 static void
     49 assert_no_ppath_extant(void)
     50 {
     51 	ATF_CHECK_EQ(nppath, 0);
     52 }
     53 
     54 static void
     55 assert_no_ppath_component_extant(void)
     56 {
     57 	ATF_CHECK_EQ(nppath_component, 0);
     58 }
     59 
     60 void
     61 test_ppath_extant_inc(void)
     62 {
     63 	if (++nppath == 0)
     64 		atf_tc_fail("count of extant paths overflowed");
     65 }
     66 
     67 void
     68 test_ppath_extant_dec(void)
     69 {
     70 	if (nppath-- == 0)
     71 		atf_tc_fail("count of extant path underflowed");
     72 }
     73 
     74 void
     75 test_ppath_component_extant_inc(void)
     76 {
     77 	if (++nppath_component == 0)
     78 		atf_tc_fail("count of extant path components overflowed");
     79 }
     80 
     81 void
     82 test_ppath_component_extant_dec(void)
     83 {
     84 	if (nppath_component-- == 0)
     85 		atf_tc_fail("count of extant path components underflowed");
     86 }
     87 
     88 ATF_TC(push_until_full);
     89 
     90 ATF_TC_HEAD(push_until_full, tc)
     91 {
     92 	atf_tc_set_md_var(tc, "descr", "check ppath_push() returns error "
     93 	    "after ppath_t reaches maximum length");
     94 }
     95 
     96 ATF_TC_BODY(push_until_full, tc)
     97 {
     98 	ppath_t *p, *rp;
     99 	ppath_component_t *pc;
    100 	int i;
    101 
    102 	assert_no_ppath_extant();
    103 	assert_no_ppath_component_extant();
    104 
    105 	if ((p = ppath_create()) == NULL)
    106 		atf_tc_fail("ppath_create failed");
    107 
    108 	if ((pc = ppath_idx(0)) == NULL)
    109 		atf_tc_fail("ppath_idx failed");
    110 
    111 	for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
    112 		rp = ppath_push(p, pc);
    113 		ATF_CHECK_EQ(rp, p);
    114 	}
    115 
    116 	rp = ppath_push(p, pc);
    117 	ATF_CHECK_EQ(rp, NULL);
    118 
    119 	rp = ppath_push(p, pc);
    120 	ATF_CHECK_EQ(rp, NULL);
    121 
    122 	ppath_component_release(pc);
    123 	ppath_release(p);
    124 
    125 	assert_no_ppath_extant();
    126 	assert_no_ppath_component_extant();
    127 }
    128 
    129 ATF_TC(pop_until_empty);
    130 ATF_TC_HEAD(pop_until_empty, tc)
    131 {
    132 	atf_tc_set_md_var(tc, "descr", "check ppath_pop() returns error "
    133 	    "after ppath_t is empty");
    134 }
    135 
    136 ATF_TC_BODY(pop_until_empty, tc)
    137 {
    138 	ppath_t *p, *rp;
    139 	ppath_component_t *pc, *rpc;
    140 	int i;
    141 
    142 	assert_no_ppath_extant();
    143 	assert_no_ppath_component_extant();
    144 
    145 	if ((p = ppath_create()) == NULL)
    146 		atf_tc_fail("ppath_create failed");
    147 
    148 	if ((pc = ppath_idx(0)) == NULL)
    149 		atf_tc_fail("ppath_idx failed");
    150 
    151 	for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
    152 		rp = ppath_push(p, pc);
    153 		ATF_CHECK_EQ(rp, p);
    154 	}
    155 
    156 	for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
    157 		rp = ppath_pop(p, &rpc);
    158 		ATF_CHECK_EQ(rp, p);
    159 		ATF_CHECK_EQ(rpc, pc);
    160 		ppath_component_release(rpc);
    161 	}
    162 
    163 	rp = ppath_pop(p, &rpc);
    164 	ATF_CHECK_EQ(rp, NULL);
    165 	rp = ppath_pop(p, &rpc);
    166 	ATF_CHECK_EQ(rp, NULL);
    167 
    168 	ppath_component_release(pc);
    169 	ppath_release(p);
    170 
    171 	assert_no_ppath_extant();
    172 	assert_no_ppath_component_extant();
    173 }
    174 
    175 ATF_TC(length);
    176 
    177 ATF_TC_HEAD(length, tc)
    178 {
    179 	atf_tc_set_md_var(tc, "descr", "check that ppath_push() "
    180 	    "and ppath_pop() affect ppath_length() correctly");
    181 }
    182 
    183 ATF_TC_BODY(length, tc)
    184 {
    185 	ppath_t *p, *rp;
    186 	ppath_component_t *pc;
    187 	unsigned int i, len;
    188 
    189 	assert_no_ppath_extant();
    190 	assert_no_ppath_component_extant();
    191 
    192 	if ((p = ppath_create()) == NULL)
    193 		atf_tc_fail("ppath_create failed");
    194 
    195 	if ((pc = ppath_idx(0)) == NULL)
    196 		atf_tc_fail("ppath_idx failed");
    197 
    198 	for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
    199 		len = ppath_length(p);
    200 		ATF_CHECK_EQ(len, i);
    201 		rp = ppath_push(p, pc);
    202 		ATF_CHECK_EQ(rp, p);
    203 	}
    204 
    205 	for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
    206 		len = ppath_length(p);
    207 		ATF_CHECK_EQ(len, PPATH_MAX_COMPONENTS - i);
    208 		rp = ppath_pop(p, NULL);
    209 		ATF_CHECK_EQ(rp, p);
    210 	}
    211 	ppath_component_release(pc);
    212 	ppath_release(p);
    213 
    214 	assert_no_ppath_extant();
    215 	assert_no_ppath_component_extant();
    216 }
    217 
    218 ATF_TC(component_at);
    219 
    220 ATF_TC_HEAD(component_at, tc)
    221 {
    222 	atf_tc_set_md_var(tc, "descr", "check that ppath_component_at() "
    223 	    "returns the expected component");
    224 }
    225 
    226 ATF_TC_BODY(component_at, tc)
    227 {
    228 	ppath_t *p, *rp;
    229 	ppath_component_t *pc;
    230 	unsigned int i;
    231 
    232 	assert_no_ppath_extant();
    233 	assert_no_ppath_component_extant();
    234 
    235 	if ((p = ppath_create()) == NULL)
    236 		atf_tc_fail("ppath_create failed");
    237 
    238 	for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
    239 		if ((pc = ppath_idx(i)) == NULL)
    240 			atf_tc_fail("ppath_idx failed");
    241 		rp = ppath_push(p, pc);
    242 		ppath_component_release(pc);
    243 		ATF_CHECK_EQ(rp, p);
    244 	}
    245 
    246 	for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
    247 		pc = ppath_component_at(p, i);
    248 		ATF_CHECK_EQ(ppath_component_idx(pc), (int)i);
    249 		ppath_component_release(pc);
    250 	}
    251 	ppath_release(p);
    252 
    253 	assert_no_ppath_extant();
    254 	assert_no_ppath_component_extant();
    255 }
    256 
    257 ATF_TC(get_idx_key);
    258 
    259 ATF_TC_HEAD(get_idx_key, tc)
    260 {
    261 	atf_tc_set_md_var(tc, "descr", "check that ppath_component_idx() "
    262 	    "and ppath_component_key() return -1 and NULL, respectively, if "
    263 	    "the component is a key or an index, respectively.");
    264 }
    265 
    266 ATF_TC_BODY(get_idx_key, tc)
    267 {
    268 	ppath_component_t *idx, *key;
    269 
    270 	assert_no_ppath_extant();
    271 	assert_no_ppath_component_extant();
    272 
    273 	if ((idx = ppath_idx(0)) == NULL)
    274 		atf_tc_fail("ppath_idx failed");
    275 	if ((key = ppath_key("key")) == NULL)
    276 		atf_tc_fail("ppath_idx failed");
    277 
    278 	ATF_CHECK_EQ(ppath_component_key(idx), NULL);
    279 	ATF_CHECK_EQ(ppath_component_idx(key), -1);
    280 
    281 	ppath_component_release(idx);
    282 	ppath_component_release(key);
    283 
    284 	assert_no_ppath_extant();
    285 	assert_no_ppath_component_extant();
    286 }
    287 
    288 ATF_TC(ppath_copy);
    289 
    290 ATF_TC_HEAD(ppath_copy, tc)
    291 {
    292 	atf_tc_set_md_var(tc, "descr", "check that ppath_copy() "
    293 	    "creates an exact replica of a path, and that no "
    294 	    "resources are leaked.");
    295 }
    296 
    297 ATF_TC_BODY(ppath_copy, tc)
    298 {
    299 	ppath_component_t *pc, *cpc;
    300 	ppath_t *p, *cp, *rp;
    301 	unsigned int i;
    302 
    303 	assert_no_ppath_extant();
    304 	assert_no_ppath_component_extant();
    305 
    306 	if ((p = ppath_create()) == NULL)
    307 		atf_tc_fail("ppath_create failed");
    308 
    309 	for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
    310 		if ((pc = ppath_idx(i)) == NULL)
    311 			atf_tc_fail("ppath_idx failed");
    312 		rp = ppath_push(p, pc);
    313 		ppath_component_release(pc);
    314 		ATF_CHECK_EQ(rp, p);
    315 	}
    316 
    317 	if ((cp = ppath_copy(p)) == NULL)
    318 		atf_tc_fail("ppath_copy failed");
    319 
    320 	for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
    321 		pc = ppath_component_at(p, i);
    322 		cpc = ppath_component_at(cp, i);
    323 		ATF_CHECK_EQ(pc, cpc);
    324 		ppath_component_release(pc);
    325 		ppath_component_release(cpc);
    326 	}
    327 
    328 	ppath_release(cp);
    329 	ppath_release(p);
    330 
    331 	assert_no_ppath_extant();
    332 	assert_no_ppath_component_extant();
    333 }
    334 
    335 ATF_TC(replace);
    336 
    337 ATF_TC_HEAD(replace, tc)
    338 {
    339 	atf_tc_set_md_var(tc, "descr", "check that ppath_replace_idx() "
    340 	    "and ppath_replace_key() produce the paths we expect without "
    341 	    "leaking resources.");
    342 }
    343 
    344 ATF_TC_BODY(replace, tc)
    345 {
    346 	ppath_component_t *pc;
    347 	ppath_t *p, *cp, *rp;
    348 	unsigned int i;
    349 
    350 	assert_no_ppath_extant();
    351 	assert_no_ppath_component_extant();
    352 
    353 	if ((p = ppath_create()) == NULL)
    354 		atf_tc_fail("ppath_create failed");
    355 
    356 	/* index replacement fails on an empty path */
    357 	rp = ppath_replace_idx(p, 0);
    358 	ATF_CHECK_EQ(rp, NULL);
    359 
    360 	/* key replacement fails on an empty path */
    361 	rp = ppath_replace_key(p, "key");
    362 	ATF_CHECK_EQ(rp, NULL);
    363 
    364 	for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
    365 		if ((pc = ppath_idx(i)) == NULL)
    366 			atf_tc_fail("ppath_idx failed");
    367 		rp = ppath_push(p, pc);
    368 		ppath_component_release(pc);
    369 		ATF_CHECK_EQ(rp, p);
    370 	}
    371 
    372 	if ((cp = ppath_copy(p)) == NULL)
    373 		atf_tc_fail("ppath_copy failed");
    374 
    375 	rp = ppath_pop(cp, NULL);
    376 	ATF_CHECK_EQ(rp, cp);
    377 	rp = ppath_push_key(cp, "key");
    378 	ATF_CHECK_EQ(rp, cp);
    379 
    380 	ppath_replace_idx(p, 0);
    381 
    382 	if ((pc = ppath_component_at(p, PPATH_MAX_COMPONENTS - 1)) == NULL)
    383 		atf_tc_fail("ppath_idx failed");
    384 	ATF_CHECK_EQ(ppath_component_idx(pc), 0);
    385 	ppath_component_release(pc);
    386 
    387 	for (i = 0; i < PPATH_MAX_COMPONENTS - 1; i++) {
    388 		if ((pc = ppath_component_at(p, i)) == NULL)
    389 			atf_tc_fail("ppath_idx failed");
    390 		ATF_CHECK_EQ(ppath_component_idx(pc), (int)i);
    391 		ppath_component_release(pc);
    392 	}
    393 
    394 	for (i = 0; i < PPATH_MAX_COMPONENTS - 1; i++) {
    395 		if ((pc = ppath_component_at(cp, i)) == NULL)
    396 			atf_tc_fail("ppath_idx failed");
    397 		ATF_CHECK_EQ(ppath_component_idx(pc), (int)i);
    398 		ppath_component_release(pc);
    399 	}
    400 
    401 	if ((pc = ppath_component_at(cp, PPATH_MAX_COMPONENTS - 1)) == NULL)
    402 		atf_tc_fail("ppath_idx failed");
    403 	if (ppath_component_key(pc) == NULL ||
    404 	    strcmp(ppath_component_key(pc), "key") != 0)
    405 		atf_tc_fail("last path component expected to be \"key\"");
    406 	ppath_component_release(pc);
    407 	ppath_release(p);
    408 	ppath_release(cp);
    409 
    410 	assert_no_ppath_extant();
    411 	assert_no_ppath_component_extant();
    412 }
    413 
    414 ATF_TC(copyset_object_twice_success);
    415 
    416 ATF_TC_HEAD(copyset_object_twice_success, tc)
    417 {
    418 	atf_tc_set_md_var(tc, "descr",
    419 	    "check that after back-to-back ppath_copyset_object() calls, "
    420 	    "changing the \"u.s. citizen\" property and the first property "
    421 	    "in \"children\" in the \"John Doe\" record in the "
    422 	    "\"personnel\" property list, the properties are changed "
    423 	    "in the new dictionary and unchanged in the old dictionary");
    424 }
    425 
    426 ATF_TC_BODY(copyset_object_twice_success, tc)
    427 {
    428 	const char *s;
    429 	char *oext, *next;
    430 	int rc;
    431 	bool v = false;
    432 	prop_dictionary_t d, od;
    433 	prop_object_t nd = NULL, ond;
    434 	prop_object_t r, or;
    435 	ppath_t *p, *p2, *p3;
    436 
    437 	assert_no_ppath_extant();
    438 	assert_no_ppath_component_extant();
    439 
    440 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
    441 		atf_tc_fail("prop_dictionary_internalize failed");
    442 	od = prop_dictionary_copy(d);
    443 
    444 	if (!dictionary_equals(od, d)) {
    445 		oext = prop_dictionary_externalize(od);
    446 		next = prop_dictionary_externalize(d);
    447 		atf_tc_fail("dictionaries are unequal from the outset, argh! "
    448 		    "original\n%s\nnew\n%s", oext, next);
    449 		free(oext);
    450 		free(next);
    451 	}
    452 
    453 	if ((p = ppath_create()) == NULL || (p2 = ppath_create()) == NULL ||
    454 	    (p3 = ppath_create()) == NULL)
    455 		atf_tc_fail("ppath_create failed");
    456 
    457 	if (ppath_push_key(p, "John Doe") == NULL)
    458 		atf_tc_fail("ppath_push_key failed");
    459 	if (ppath_push_key(p, "u.s. citizen") == NULL)
    460 		atf_tc_fail("ppath_push_key failed");
    461 
    462 	if (ppath_push_key(p2, "John Doe") == NULL)
    463 		atf_tc_fail("ppath_push_key failed");
    464 	if (ppath_push_key(p2, "children") == NULL)
    465 		atf_tc_fail("ppath_push_key failed");
    466 	if (ppath_push_idx(p2, 0) == NULL)
    467 		atf_tc_fail("ppath_push_idx failed");
    468 
    469 	if (ppath_push_key(p3, "John Doe") == NULL)
    470 		atf_tc_fail("ppath_push_key failed");
    471 
    472 	v = false;
    473 	rc = ppath_get_bool(d, p, &v);
    474 	ATF_CHECK_EQ(rc, 0);
    475 	ATF_CHECK_EQ(v, true);
    476 
    477 	s = "";
    478 	rc = ppath_get_string(d, p2, &s);
    479 	ATF_CHECK_EQ(rc, 0);
    480 	ATF_CHECK_STREQ(s, "Jane Doe");
    481 
    482 	rc = ppath_copyset_bool(d, &nd, p, false);
    483 	ATF_CHECK_EQ(rc, 0);
    484 
    485 	rc = ppath_get_object(nd, p3, &r);
    486 	ATF_CHECK_EQ(rc, 0);
    487 
    488 	ond = nd;
    489 
    490 	rc = ppath_copyset_string(d, &nd, p2, "Martha Doe");
    491 	ATF_CHECK_EQ(rc, 0);
    492 
    493 	ATF_CHECK_EQ(nd, ond);
    494 
    495 	rc = ppath_get_object(nd, p3, &or);
    496 	ATF_CHECK_EQ(rc, 0);
    497 
    498 	ATF_CHECK_EQ(r, or);
    499 
    500 	v = true;
    501 	rc = ppath_get_bool(nd, p, &v);
    502 	ATF_CHECK_EQ(rc, 0);
    503 	ATF_CHECK_EQ(v, false);
    504 
    505 	s = "";
    506 	rc = ppath_get_string(nd, p2, &s);
    507 	ATF_CHECK_EQ(rc, 0);
    508 	ATF_CHECK_STREQ(s, "Martha Doe");
    509 
    510 	if (!dictionary_equals(od, d)) {
    511 		oext = prop_dictionary_externalize(od);
    512 		next = prop_dictionary_externalize(d);
    513 		atf_tc_fail("copydel modified original dictionary, "
    514 		    "original\n%s\nnew\n%s", oext, next);
    515 		free(oext);
    516 		free(next);
    517 	}
    518 
    519 	if (dictionary_equals(od, nd)) {
    520 		oext = prop_dictionary_externalize(od);
    521 		next = prop_dictionary_externalize(nd);
    522 		atf_tc_fail("copydel made no change to the new "
    523 		    "dictionary, original\n%s\nnew\n%s", oext, next);
    524 		free(oext);
    525 		free(next);
    526 	}
    527 
    528 	rc = ppath_set_bool(od, p, false);
    529 	ATF_CHECK_EQ(rc, 0);
    530 
    531 	rc = ppath_set_string(od, p2, "Martha Doe");
    532 	ATF_CHECK_EQ(rc, 0);
    533 
    534 	if (!dictionary_equals(od, nd)) {
    535 		oext = prop_dictionary_externalize(od);
    536 		next = prop_dictionary_externalize(nd);
    537 		atf_tc_fail("copydel made an out-of-bounds change to the new "
    538 		    "dictionary, original\n%s\nnew\n%s", oext, next);
    539 		free(oext);
    540 		free(next);
    541 	}
    542 
    543 	ppath_release(p);
    544 	ppath_release(p2);
    545 	ppath_release(p3);
    546 	prop_object_release(d);
    547 	prop_object_release(od);
    548 	prop_object_release(nd);
    549 	assert_no_ppath_extant();
    550 	assert_no_ppath_component_extant();
    551 }
    552 
    553 ATF_TC(copydel_object_twice_success);
    554 
    555 ATF_TC_HEAD(copydel_object_twice_success, tc)
    556 {
    557 	atf_tc_set_md_var(tc, "descr",
    558 	    "check that after back-to-back ppath_copydel_object() calls, "
    559 	    "removing the \"u.s. citizen\" property and the first property "
    560 	    "in \"children\" from the \"John Doe\" record in the "
    561 	    "\"personnel\" property list, the properties are missing "
    562 	    "from the new dictionary and unchanged in the old dictionary");
    563 }
    564 
    565 ATF_TC_BODY(copydel_object_twice_success, tc)
    566 {
    567 	const char *s;
    568 	char *oext, *next;
    569 	int rc;
    570 	bool v = false;
    571 	prop_dictionary_t d, od;
    572 	prop_object_t nd = NULL, ond;
    573 	prop_object_t r, or;
    574 	ppath_t *p, *p2, *p3;
    575 
    576 	assert_no_ppath_extant();
    577 	assert_no_ppath_component_extant();
    578 
    579 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
    580 		atf_tc_fail("prop_dictionary_internalize failed");
    581 	od = prop_dictionary_copy(d);
    582 
    583 	if (!dictionary_equals(od, d)) {
    584 		oext = prop_dictionary_externalize(od);
    585 		next = prop_dictionary_externalize(d);
    586 		atf_tc_fail("dictionaries are unequal from the outset, argh! "
    587 		    "original\n%s\nnew\n%s", oext, next);
    588 		free(oext);
    589 		free(next);
    590 	}
    591 
    592 	if ((p = ppath_create()) == NULL || (p2 = ppath_create()) == NULL ||
    593 	    (p3 = ppath_create()) == NULL)
    594 		atf_tc_fail("ppath_create failed");
    595 
    596 	if (ppath_push_key(p, "John Doe") == NULL)
    597 		atf_tc_fail("ppath_push_key failed");
    598 	if (ppath_push_key(p, "u.s. citizen") == NULL)
    599 		atf_tc_fail("ppath_push_key failed");
    600 
    601 	if (ppath_push_key(p2, "John Doe") == NULL)
    602 		atf_tc_fail("ppath_push_key failed");
    603 	if (ppath_push_key(p2, "children") == NULL)
    604 		atf_tc_fail("ppath_push_key failed");
    605 	if (ppath_push_idx(p2, 0) == NULL)
    606 		atf_tc_fail("ppath_push_idx failed");
    607 
    608 	if (ppath_push_key(p3, "John Doe") == NULL)
    609 		atf_tc_fail("ppath_push_key failed");
    610 
    611 	v = false;
    612 	rc = ppath_get_bool(d, p, &v);
    613 	ATF_CHECK_EQ(rc, 0);
    614 	ATF_CHECK_EQ(v, true);
    615 
    616 	s = "";
    617 	rc = ppath_get_string(d, p2, &s);
    618 	ATF_CHECK_EQ(rc, 0);
    619 	ATF_CHECK_STREQ(s, "Jane Doe");
    620 
    621 	rc = ppath_copydel_bool(d, &nd, p);
    622 	ATF_CHECK_EQ(rc, 0);
    623 
    624 	ond = nd;
    625 
    626 	rc = ppath_get_object(nd, p3, &r);
    627 	ATF_CHECK_EQ(rc, 0);
    628 
    629 	rc = ppath_copydel_string(d, &nd, p2);
    630 	ATF_CHECK_EQ(rc, 0);
    631 
    632 	ATF_CHECK_EQ(nd, ond);
    633 
    634 	rc = ppath_get_object(nd, p3, &or);
    635 	ATF_CHECK_EQ(rc, 0);
    636 
    637 	ATF_CHECK_EQ(r, or);
    638 
    639 	v = true;
    640 	rc = ppath_get_bool(nd, p, &v);
    641 	ATF_CHECK_EQ(rc, ENOENT);
    642 	ATF_CHECK_EQ(v, true);
    643 
    644 	if (!dictionary_equals(od, d)) {
    645 		oext = prop_dictionary_externalize(od);
    646 		next = prop_dictionary_externalize(d);
    647 		atf_tc_fail("copydel modified original dictionary, "
    648 		    "original\n%s\nnew\n%s", oext, next);
    649 		free(oext);
    650 		free(next);
    651 	}
    652 
    653 	if (dictionary_equals(od, nd)) {
    654 		oext = prop_dictionary_externalize(od);
    655 		next = prop_dictionary_externalize(nd);
    656 		atf_tc_fail("copydel made no change to the new "
    657 		    "dictionary, original\n%s\nnew\n%s", oext, next);
    658 		free(oext);
    659 		free(next);
    660 	}
    661 
    662 	rc = ppath_delete_bool(od, p);
    663 	ATF_CHECK_EQ(rc, 0);
    664 
    665 	rc = ppath_delete_string(od, p2);
    666 	ATF_CHECK_EQ(rc, 0);
    667 
    668 	if (!dictionary_equals(od, nd)) {
    669 		oext = prop_dictionary_externalize(od);
    670 		next = prop_dictionary_externalize(nd);
    671 		atf_tc_fail("copydel made an out-of-bounds change to the new "
    672 		    "dictionary, original\n%s\nnew\n%s", oext, next);
    673 		free(oext);
    674 		free(next);
    675 	}
    676 
    677 	ppath_release(p);
    678 	ppath_release(p2);
    679 	ppath_release(p3);
    680 	prop_object_release(d);
    681 	prop_object_release(od);
    682 	prop_object_release(nd);
    683 	assert_no_ppath_extant();
    684 	assert_no_ppath_component_extant();
    685 }
    686 
    687 ATF_TC(copydel_bool_success);
    688 
    689 ATF_TC_HEAD(copydel_bool_success, tc)
    690 {
    691 	atf_tc_set_md_var(tc, "descr", "check ppath_copydel_bool() deletes "
    692 	    "the \"u.s. citizen\" property in the \"John Doe\" record in the "
    693 	    "\"personnel\" property list and verifies the value is missing "
    694 	    "from the new dictionary and unchanged in the old dictionary");
    695 }
    696 
    697 ATF_TC_BODY(copydel_bool_success, tc)
    698 {
    699 	char *oext, *next;
    700 	int rc;
    701 	bool v = false;
    702 	prop_dictionary_t d, od;
    703 	prop_object_t nd = NULL;
    704 	ppath_t *p;
    705 
    706 	assert_no_ppath_extant();
    707 	assert_no_ppath_component_extant();
    708 
    709 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
    710 		atf_tc_fail("prop_dictionary_internalize failed");
    711 	od = prop_dictionary_copy(d);
    712 
    713 	if (!dictionary_equals(od, d)) {
    714 		oext = prop_dictionary_externalize(od);
    715 		next = prop_dictionary_externalize(d);
    716 		atf_tc_fail("dictionaries are unequal from the outset, argh! "
    717 		    "original\n%s\nnew\n%s", oext, next);
    718 		free(oext);
    719 		free(next);
    720 	}
    721 
    722 	if ((p = ppath_create()) == NULL)
    723 		atf_tc_fail("ppath_create failed");
    724 
    725 	if (ppath_push_key(p, "John Doe") == NULL)
    726 		atf_tc_fail("ppath_push_key failed");
    727 	if (ppath_push_key(p, "u.s. citizen") == NULL)
    728 		atf_tc_fail("ppath_push_key failed");
    729 
    730 	v = false;
    731 	rc = ppath_get_bool(d, p, &v);
    732 	ATF_CHECK_EQ(rc, 0);
    733 	ATF_CHECK_EQ(v, true);
    734 
    735 	rc = ppath_copydel_bool(d, &nd, p);
    736 	ATF_CHECK_EQ(rc, 0);
    737 
    738 	v = true;
    739 	rc = ppath_get_bool(nd, p, &v);
    740 	ATF_CHECK_EQ(rc, ENOENT);
    741 	ATF_CHECK_EQ(v, true);
    742 
    743 	if (!dictionary_equals(od, d)) {
    744 		oext = prop_dictionary_externalize(od);
    745 		next = prop_dictionary_externalize(d);
    746 		atf_tc_fail("copydel modified original dictionary, "
    747 		    "original\n%s\nnew\n%s", oext, next);
    748 		free(oext);
    749 		free(next);
    750 	}
    751 
    752 	if (dictionary_equals(od, nd)) {
    753 		oext = prop_dictionary_externalize(od);
    754 		next = prop_dictionary_externalize(nd);
    755 		atf_tc_fail("copydel made no change to the new "
    756 		    "dictionary, original\n%s\nnew\n%s", oext, next);
    757 		free(oext);
    758 		free(next);
    759 	}
    760 
    761 	rc = ppath_delete_bool(od, p);
    762 	ATF_CHECK_EQ(rc, 0);
    763 
    764 	if (!dictionary_equals(od, nd)) {
    765 		oext = prop_dictionary_externalize(od);
    766 		next = prop_dictionary_externalize(nd);
    767 		atf_tc_fail("copydel made an out-of-bounds change to the new "
    768 		    "dictionary, original\n%s\nnew\n%s", oext, next);
    769 		free(oext);
    770 		free(next);
    771 	}
    772 
    773 	ppath_release(p);
    774 	prop_object_release(d);
    775 	prop_object_release(od);
    776 	prop_object_release(nd);
    777 	assert_no_ppath_extant();
    778 	assert_no_ppath_component_extant();
    779 }
    780 
    781 ATF_TC(copyset_bool_success);
    782 
    783 ATF_TC_HEAD(copyset_bool_success, tc)
    784 {
    785 	atf_tc_set_md_var(tc, "descr", "check ppath_copyset_bool() sets "
    786 	    "the \"u.s. citizen\" property in the \"John Doe\" record in the "
    787 	    "\"personnel\" property list to false and verifies the new value "
    788 	    "in the new dictionary and that the old dictionary is unchanged");
    789 }
    790 
    791 ATF_TC_BODY(copyset_bool_success, tc)
    792 {
    793 	char *oext, *next;
    794 	int rc;
    795 	bool v = false;
    796 	prop_dictionary_t d, od;
    797 	prop_object_t nd = NULL;
    798 	ppath_t *p;
    799 
    800 	assert_no_ppath_extant();
    801 	assert_no_ppath_component_extant();
    802 
    803 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
    804 		atf_tc_fail("prop_dictionary_internalize failed");
    805 	od = prop_dictionary_copy(d);
    806 
    807 	if (!dictionary_equals(od, d)) {
    808 		oext = prop_dictionary_externalize(od);
    809 		next = prop_dictionary_externalize(d);
    810 		atf_tc_fail("dictionaries are unequal from the outset, argh! "
    811 		    "original\n%s\nnew\n%s", oext, next);
    812 		free(oext);
    813 		free(next);
    814 	}
    815 
    816 	if ((p = ppath_create()) == NULL)
    817 		atf_tc_fail("ppath_create failed");
    818 
    819 	if (ppath_push_key(p, "John Doe") == NULL)
    820 		atf_tc_fail("ppath_push_key failed");
    821 	if (ppath_push_key(p, "u.s. citizen") == NULL)
    822 		atf_tc_fail("ppath_push_key failed");
    823 
    824 	v = false;
    825 	rc = ppath_get_bool(d, p, &v);
    826 	ATF_CHECK_EQ(rc, 0);
    827 	ATF_CHECK_EQ(v, true);
    828 
    829 	rc = ppath_copyset_bool(d, &nd, p, false);
    830 	ATF_CHECK_EQ(rc, 0);
    831 
    832 	v = true;
    833 	rc = ppath_get_bool(nd, p, &v);
    834 	ATF_CHECK_EQ(rc, 0);
    835 	ATF_CHECK_EQ(v, false);
    836 
    837 	if (!dictionary_equals(od, d)) {
    838 		oext = prop_dictionary_externalize(od);
    839 		next = prop_dictionary_externalize(d);
    840 		atf_tc_fail("copyset modified original dictionary, "
    841 		    "original\n%s\nnew\n%s", oext, next);
    842 		free(oext);
    843 		free(next);
    844 	}
    845 
    846 	if (dictionary_equals(od, nd)) {
    847 		oext = prop_dictionary_externalize(od);
    848 		next = prop_dictionary_externalize(nd);
    849 		atf_tc_fail("copyset made no change to the new "
    850 		    "dictionary, original\n%s\nnew\n%s", oext, next);
    851 		free(oext);
    852 		free(next);
    853 	}
    854 
    855 	rc = ppath_set_bool(nd, p, true);
    856 	ATF_CHECK_EQ(rc, 0);
    857 
    858 	if (!dictionary_equals(od, nd)) {
    859 		oext = prop_dictionary_externalize(od);
    860 		next = prop_dictionary_externalize(nd);
    861 		atf_tc_fail("copyset made an out-of-bounds change to the new "
    862 		    "dictionary, original\n%s\nnew\n%s", oext, next);
    863 		free(oext);
    864 		free(next);
    865 	}
    866 
    867 	ppath_release(p);
    868 	prop_object_release(d);
    869 	prop_object_release(od);
    870 	prop_object_release(nd);
    871 	assert_no_ppath_extant();
    872 	assert_no_ppath_component_extant();
    873 }
    874 
    875 ATF_TC(set_bool_eftype);
    876 
    877 ATF_TC_HEAD(set_bool_eftype, tc)
    878 {
    879 	atf_tc_set_md_var(tc, "descr", "check ppath_set_bool() does not "
    880 	    "overwrite with a bool "
    881 	    "the \"job title\" property in the \"John Doe\" record in "
    882 	    "the "
    883 	    "\"personnel\" property list");
    884 }
    885 
    886 ATF_TC_BODY(set_bool_eftype, tc)
    887 {
    888 	int rc;
    889 	bool v = false;
    890 	prop_dictionary_t d;
    891 	ppath_t *p;
    892 
    893 	assert_no_ppath_extant();
    894 	assert_no_ppath_component_extant();
    895 
    896 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
    897 		atf_tc_fail("prop_dictionary_internalize failed");
    898 
    899 	if ((p = ppath_create()) == NULL)
    900 		atf_tc_fail("ppath_create failed");
    901 
    902 	if (ppath_push_key(p, "John Doe") == NULL)
    903 		atf_tc_fail("ppath_push_key failed");
    904 	if (ppath_push_key(p, "job title") == NULL)
    905 		atf_tc_fail("ppath_push_key failed");
    906 
    907 	v = false;
    908 	rc = ppath_get_bool(d, p, &v);
    909 	ATF_CHECK_EQ(rc, EFTYPE);
    910 	ATF_CHECK_EQ(v, false);
    911 
    912 	rc = ppath_set_bool(d, p, false);
    913 	ATF_CHECK_EQ(rc, EFTYPE);
    914 
    915 	v = true;
    916 	rc = ppath_get_bool(d, p, &v);
    917 	ATF_CHECK_EQ(rc, EFTYPE);
    918 	ATF_CHECK_EQ(v, true);
    919 
    920 	ppath_release(p);
    921 	prop_object_release(d);
    922 	assert_no_ppath_extant();
    923 	assert_no_ppath_component_extant();
    924 }
    925 
    926 ATF_TC(set_bool_enoent);
    927 
    928 ATF_TC_HEAD(set_bool_enoent, tc)
    929 {
    930 	atf_tc_set_md_var(tc, "descr", "check ppath_set_bool() does not create "
    931 	    "the \"russian citizen\" property in the \"John Doe\" record in "
    932 	    "the "
    933 	    "\"personnel\" property list");
    934 }
    935 
    936 ATF_TC_BODY(set_bool_enoent, tc)
    937 {
    938 	int rc;
    939 	bool v = false;
    940 	prop_dictionary_t d;
    941 	ppath_t *p;
    942 
    943 	assert_no_ppath_extant();
    944 	assert_no_ppath_component_extant();
    945 
    946 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
    947 		atf_tc_fail("prop_dictionary_internalize failed");
    948 
    949 	if ((p = ppath_create()) == NULL)
    950 		atf_tc_fail("ppath_create failed");
    951 
    952 	if (ppath_push_key(p, "John Doe") == NULL)
    953 		atf_tc_fail("ppath_push_key failed");
    954 	if (ppath_push_key(p, "russian citizen") == NULL)
    955 		atf_tc_fail("ppath_push_key failed");
    956 
    957 	v = false;
    958 	rc = ppath_get_bool(d, p, &v);
    959 	ATF_CHECK_EQ(rc, ENOENT);
    960 	ATF_CHECK_EQ(v, false);
    961 
    962 	rc = ppath_set_bool(d, p, false);
    963 	ATF_CHECK_EQ(rc, ENOENT);
    964 
    965 	v = true;
    966 	rc = ppath_get_bool(d, p, &v);
    967 	ATF_CHECK_EQ(rc, ENOENT);
    968 	ATF_CHECK_EQ(v, true);
    969 
    970 	ppath_release(p);
    971 	prop_object_release(d);
    972 	assert_no_ppath_extant();
    973 	assert_no_ppath_component_extant();
    974 }
    975 
    976 ATF_TC(create_bool_eexist);
    977 
    978 ATF_TC_HEAD(create_bool_eexist, tc)
    979 {
    980 	atf_tc_set_md_var(tc, "descr", "check ppath_create_bool() returns "
    981 	    "EEXIST because the \"u.s. citizen\" property in the "
    982 	    "\"John Doe\" record in the \"personnel\" property list "
    983 	    "already exists");
    984 }
    985 
    986 ATF_TC_BODY(create_bool_eexist, tc)
    987 {
    988 	int rc;
    989 	bool v = false;
    990 	prop_dictionary_t d;
    991 	ppath_t *p;
    992 
    993 	assert_no_ppath_extant();
    994 	assert_no_ppath_component_extant();
    995 
    996 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
    997 		atf_tc_fail("prop_dictionary_internalize failed");
    998 
    999 	if ((p = ppath_create()) == NULL)
   1000 		atf_tc_fail("ppath_create failed");
   1001 
   1002 	if (ppath_push_key(p, "John Doe") == NULL)
   1003 		atf_tc_fail("ppath_push_key failed");
   1004 	if (ppath_push_key(p, "u.s. citizen") == NULL)
   1005 		atf_tc_fail("ppath_push_key failed");
   1006 
   1007 	v = false;
   1008 	rc = ppath_get_bool(d, p, &v);
   1009 	ATF_CHECK_EQ(rc, 0);
   1010 	ATF_CHECK_EQ(v, true);
   1011 
   1012 	rc = ppath_create_bool(d, p, false);
   1013 	ATF_CHECK_EQ(rc, EEXIST);
   1014 
   1015 	v = false;
   1016 	rc = ppath_get_bool(d, p, &v);
   1017 	ATF_CHECK_EQ(rc, 0);
   1018 	ATF_CHECK_EQ(v, true);
   1019 
   1020 	ppath_release(p);
   1021 	prop_object_release(d);
   1022 	assert_no_ppath_extant();
   1023 	assert_no_ppath_component_extant();
   1024 }
   1025 
   1026 ATF_TC(create_bool_success);
   1027 
   1028 ATF_TC_HEAD(create_bool_success, tc)
   1029 {
   1030 	atf_tc_set_md_var(tc, "descr", "check ppath_create_bool() creates "
   1031 	    "the \"russian citizen\" property in the \"John Doe\" record in "
   1032 	    "the \"personnel\" property list and sets it to false");
   1033 }
   1034 
   1035 ATF_TC_BODY(create_bool_success, tc)
   1036 {
   1037 	int rc;
   1038 	bool v = false;
   1039 	prop_dictionary_t d;
   1040 	ppath_t *p;
   1041 
   1042 	assert_no_ppath_extant();
   1043 	assert_no_ppath_component_extant();
   1044 
   1045 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
   1046 		atf_tc_fail("prop_dictionary_internalize failed");
   1047 
   1048 	if ((p = ppath_create()) == NULL)
   1049 		atf_tc_fail("ppath_create failed");
   1050 
   1051 	if (ppath_push_key(p, "John Doe") == NULL)
   1052 		atf_tc_fail("ppath_push_key failed");
   1053 	if (ppath_push_key(p, "russian citizen") == NULL)
   1054 		atf_tc_fail("ppath_push_key failed");
   1055 
   1056 	v = false;
   1057 	rc = ppath_get_bool(d, p, &v);
   1058 	ATF_CHECK_EQ(rc, ENOENT);
   1059 	ATF_CHECK_EQ(v, false);
   1060 
   1061 	rc = ppath_create_bool(d, p, false);
   1062 	ATF_CHECK_EQ(rc, 0);
   1063 
   1064 	v = true;
   1065 	rc = ppath_get_bool(d, p, &v);
   1066 	ATF_CHECK_EQ(rc, 0);
   1067 	ATF_CHECK_EQ(v, false);
   1068 
   1069 	ppath_release(p);
   1070 	prop_object_release(d);
   1071 	assert_no_ppath_extant();
   1072 	assert_no_ppath_component_extant();
   1073 }
   1074 
   1075 ATF_TC(set_bool_success);
   1076 
   1077 ATF_TC_HEAD(set_bool_success, tc)
   1078 {
   1079 	atf_tc_set_md_var(tc, "descr", "check ppath_set_bool() sets "
   1080 	    "the \"u.s. citizen\" property in the \"John Doe\" record in the "
   1081 	    "\"personnel\" property list to false and verifies the new value");
   1082 }
   1083 
   1084 ATF_TC_BODY(set_bool_success, tc)
   1085 {
   1086 	int rc;
   1087 	bool v = false;
   1088 	prop_dictionary_t d;
   1089 	ppath_t *p;
   1090 
   1091 	assert_no_ppath_extant();
   1092 	assert_no_ppath_component_extant();
   1093 
   1094 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
   1095 		atf_tc_fail("prop_dictionary_internalize failed");
   1096 
   1097 	if ((p = ppath_create()) == NULL)
   1098 		atf_tc_fail("ppath_create failed");
   1099 
   1100 	if (ppath_push_key(p, "John Doe") == NULL)
   1101 		atf_tc_fail("ppath_push_key failed");
   1102 	if (ppath_push_key(p, "u.s. citizen") == NULL)
   1103 		atf_tc_fail("ppath_push_key failed");
   1104 
   1105 	v = false;
   1106 	rc = ppath_get_bool(d, p, &v);
   1107 	ATF_CHECK_EQ(rc, 0);
   1108 	ATF_CHECK_EQ(v, true);
   1109 
   1110 	rc = ppath_set_bool(d, p, v);
   1111 	ATF_CHECK_EQ(rc, 0);
   1112 
   1113 	v = true;
   1114 	rc = ppath_get_bool(d, p, &v);
   1115 	ATF_CHECK_EQ(rc, 0);
   1116 	ATF_CHECK_EQ(v, true);
   1117 
   1118 	ppath_release(p);
   1119 	prop_object_release(d);
   1120 	assert_no_ppath_extant();
   1121 	assert_no_ppath_component_extant();
   1122 }
   1123 
   1124 ATF_TC(get_bool_success);
   1125 
   1126 ATF_TC_HEAD(get_bool_success, tc)
   1127 {
   1128 	atf_tc_set_md_var(tc, "descr", "check ppath_get_bool() fetches "
   1129 	    "the \"u.s. citizen\" property from the \"John Doe\" record in the "
   1130 	    "\"personnel\" property list, and compares it with the expected "
   1131 	    "value, true");
   1132 }
   1133 
   1134 ATF_TC_BODY(get_bool_success, tc)
   1135 {
   1136 	int rc;
   1137 	bool v = false;
   1138 	prop_dictionary_t d;
   1139 	ppath_t *p;
   1140 
   1141 	assert_no_ppath_extant();
   1142 	assert_no_ppath_component_extant();
   1143 
   1144 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
   1145 		atf_tc_fail("prop_dictionary_internalize failed");
   1146 
   1147 	if ((p = ppath_create()) == NULL)
   1148 		atf_tc_fail("ppath_create failed");
   1149 
   1150 	if (ppath_push_key(p, "John Doe") == NULL)
   1151 		atf_tc_fail("ppath_push_key failed");
   1152 	if (ppath_push_key(p, "u.s. citizen") == NULL)
   1153 		atf_tc_fail("ppath_push_key failed");
   1154 
   1155 	rc = ppath_get_bool(d, p, &v);
   1156 	ATF_CHECK_EQ(rc, 0);
   1157 	ATF_CHECK_EQ(v, true);
   1158 
   1159 	ppath_release(p);
   1160 	prop_object_release(d);
   1161 	assert_no_ppath_extant();
   1162 	assert_no_ppath_component_extant();
   1163 }
   1164 
   1165 ATF_TC(delete_bool_success);
   1166 
   1167 ATF_TC_HEAD(delete_bool_success, tc)
   1168 {
   1169 	atf_tc_set_md_var(tc, "descr", "check ppath_delete_bool() succeeds "
   1170 	    "for the path (\"John Doe\", \"u.s. citizen\") in the "
   1171 	    "\"personnel\" property list");
   1172 }
   1173 
   1174 ATF_TC_BODY(delete_bool_success, tc)
   1175 {
   1176 	int rc;
   1177 	prop_dictionary_t d;
   1178 	ppath_t *p;
   1179 
   1180 	assert_no_ppath_extant();
   1181 	assert_no_ppath_component_extant();
   1182 
   1183 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
   1184 		atf_tc_fail("prop_dictionary_internalize failed");
   1185 
   1186 	if ((p = ppath_create()) == NULL)
   1187 		atf_tc_fail("ppath_create failed");
   1188 
   1189 	if (ppath_push_key(p, "John Doe") == NULL)
   1190 		atf_tc_fail("ppath_push_key failed");
   1191 	if (ppath_push_key(p, "u.s. citizen") == NULL)
   1192 		atf_tc_fail("ppath_push_key failed");
   1193 
   1194 	rc = ppath_delete_bool(d, p);
   1195 	ATF_CHECK_EQ(rc, 0);
   1196 
   1197 	rc = ppath_get_bool(d, p, NULL);
   1198 	ATF_CHECK_EQ(rc, ENOENT);
   1199 
   1200 	ppath_release(p);
   1201 	prop_object_release(d);
   1202 	assert_no_ppath_extant();
   1203 	assert_no_ppath_component_extant();
   1204 }
   1205 
   1206 ATF_TC(delete_bool_eftype);
   1207 
   1208 ATF_TC_HEAD(delete_bool_eftype, tc)
   1209 {
   1210 	atf_tc_set_md_var(tc, "descr", "check ppath_delete_bool() returns "
   1211 	    "EFTYPE for the path (\"John Doe\", \"job title\") in the "
   1212 	    "\"personnel\" property list and does not delete the path");
   1213 }
   1214 
   1215 ATF_TC_BODY(delete_bool_eftype, tc)
   1216 {
   1217 	int rc;
   1218 	prop_dictionary_t d;
   1219 	ppath_t *p;
   1220 
   1221 	assert_no_ppath_extant();
   1222 	assert_no_ppath_component_extant();
   1223 
   1224 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
   1225 		atf_tc_fail("prop_dictionary_internalize failed");
   1226 
   1227 	if ((p = ppath_create()) == NULL)
   1228 		atf_tc_fail("ppath_create failed");
   1229 
   1230 	if (ppath_push_key(p, "John Doe") == NULL)
   1231 		atf_tc_fail("ppath_push_key failed");
   1232 	if (ppath_push_key(p, "job title") == NULL)
   1233 		atf_tc_fail("ppath_push_key failed");
   1234 
   1235 	rc = ppath_delete_bool(d, p);
   1236 	ATF_CHECK_EQ(rc, EFTYPE);
   1237 
   1238 	rc = ppath_get_object(d, p, NULL);
   1239 	ATF_CHECK_EQ(rc, 0);
   1240 
   1241 	ppath_release(p);
   1242 	prop_object_release(d);
   1243 	assert_no_ppath_extant();
   1244 	assert_no_ppath_component_extant();
   1245 }
   1246 
   1247 ATF_TC(delete_bool_enoent);
   1248 
   1249 ATF_TC_HEAD(delete_bool_enoent, tc)
   1250 {
   1251 	atf_tc_set_md_var(tc, "descr", "check ppath_delete_bool() returns "
   1252 	    "ENOENT for the path (\"John Doe\", \"citizen\") in the "
   1253 	    "\"personnel\" property list");
   1254 }
   1255 
   1256 ATF_TC_BODY(delete_bool_enoent, tc)
   1257 {
   1258 	int rc;
   1259 	prop_dictionary_t d;
   1260 	ppath_t *p;
   1261 
   1262 	assert_no_ppath_extant();
   1263 	assert_no_ppath_component_extant();
   1264 
   1265 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
   1266 		atf_tc_fail("prop_dictionary_internalize failed");
   1267 
   1268 	if ((p = ppath_create()) == NULL)
   1269 		atf_tc_fail("ppath_create failed");
   1270 
   1271 	if (ppath_push_key(p, "John Doe") == NULL)
   1272 		atf_tc_fail("ppath_push_key failed");
   1273 	if (ppath_push_key(p, "citizen") == NULL)
   1274 		atf_tc_fail("ppath_push_key failed");
   1275 
   1276 	rc = ppath_delete_bool(d, p);
   1277 	ATF_CHECK_EQ(rc, ENOENT);
   1278 
   1279 	ppath_release(p);
   1280 	prop_object_release(d);
   1281 	assert_no_ppath_extant();
   1282 	assert_no_ppath_component_extant();
   1283 }
   1284 
   1285 ATF_TC(get_bool_enoent);
   1286 
   1287 ATF_TC_HEAD(get_bool_enoent, tc)
   1288 {
   1289 	atf_tc_set_md_var(tc, "descr", "check ppath_get_bool() returns "
   1290 	    "ENOENT for the path (\"John Doe\", \"citizen\") in the "
   1291 	    "\"personnel\" property list, and the bool * argument is "
   1292 	    "unchanged");
   1293 }
   1294 
   1295 ATF_TC_BODY(get_bool_enoent, tc)
   1296 {
   1297 	int rc;
   1298 	bool v;
   1299 	prop_dictionary_t d;
   1300 	ppath_t *p;
   1301 
   1302 	assert_no_ppath_extant();
   1303 	assert_no_ppath_component_extant();
   1304 
   1305 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
   1306 		atf_tc_fail("prop_dictionary_internalize failed");
   1307 
   1308 	if ((p = ppath_create()) == NULL)
   1309 		atf_tc_fail("ppath_create failed");
   1310 
   1311 	if (ppath_push_key(p, "John Doe") == NULL)
   1312 		atf_tc_fail("ppath_push_key failed");
   1313 	if (ppath_push_key(p, "citizen") == NULL)
   1314 		atf_tc_fail("ppath_push_key failed");
   1315 
   1316 	v = true;
   1317 	rc = ppath_get_bool(d, p, &v);
   1318 	ATF_CHECK_EQ(rc, ENOENT);
   1319 	ATF_CHECK_EQ(v, true);
   1320 
   1321 	v = false;
   1322 	rc = ppath_get_bool(d, p, &v);
   1323 	ATF_CHECK_EQ(rc, ENOENT);
   1324 	ATF_CHECK_EQ(v, false);
   1325 
   1326 	ppath_release(p);
   1327 	prop_object_release(d);
   1328 	assert_no_ppath_extant();
   1329 	assert_no_ppath_component_extant();
   1330 }
   1331 
   1332 ATF_TC(get_bool_eftype);
   1333 
   1334 ATF_TC_HEAD(get_bool_eftype, tc)
   1335 {
   1336 	atf_tc_set_md_var(tc, "descr", "check ppath_get_bool() returns "
   1337 	    "EFTYPE for the path (\"John Doe\", \"job title\") in the "
   1338 	    "\"personnel\" property list, and the bool * argument is "
   1339 	    "unchanged");
   1340 }
   1341 
   1342 ATF_TC_BODY(get_bool_eftype, tc)
   1343 {
   1344 	int rc;
   1345 	bool v;
   1346 	prop_dictionary_t d;
   1347 	ppath_t *p;
   1348 
   1349 	assert_no_ppath_extant();
   1350 	assert_no_ppath_component_extant();
   1351 
   1352 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
   1353 		atf_tc_fail("prop_dictionary_internalize failed");
   1354 
   1355 	if ((p = ppath_create()) == NULL)
   1356 		atf_tc_fail("ppath_create failed");
   1357 
   1358 	if (ppath_push_key(p, "John Doe") == NULL)
   1359 		atf_tc_fail("ppath_push_key failed");
   1360 	if (ppath_push_key(p, "job title") == NULL)
   1361 		atf_tc_fail("ppath_push_key failed");
   1362 
   1363 	v = true;
   1364 	rc = ppath_get_bool(d, p, &v);
   1365 	ATF_CHECK_EQ(rc, EFTYPE);
   1366 	ATF_CHECK_EQ(v, true);
   1367 
   1368 	v = false;
   1369 	rc = ppath_get_bool(d, p, &v);
   1370 	ATF_CHECK_EQ(rc, EFTYPE);
   1371 	ATF_CHECK_EQ(v, false);
   1372 
   1373 	ppath_release(p);
   1374 	prop_object_release(d);
   1375 	assert_no_ppath_extant();
   1376 	assert_no_ppath_component_extant();
   1377 }
   1378 
   1379 ATF_TC(get_string_eftype);
   1380 
   1381 ATF_TC_HEAD(get_string_eftype, tc)
   1382 {
   1383 	atf_tc_set_md_var(tc, "descr", "check ppath_get_string() returns "
   1384 	    "EFTYPE for the path (\"John Doe\", \"u.s. citizen\") in the "
   1385 	    "\"personnel\" property list, and the const char ** argument is "
   1386 	    "unchanged");
   1387 }
   1388 
   1389 ATF_TC_BODY(get_string_eftype, tc)
   1390 {
   1391 	int rc;
   1392 	const char *v;
   1393 	prop_dictionary_t d;
   1394 	ppath_t *p;
   1395 
   1396 	assert_no_ppath_extant();
   1397 	assert_no_ppath_component_extant();
   1398 
   1399 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
   1400 		atf_tc_fail("prop_dictionary_internalize failed");
   1401 
   1402 	if ((p = ppath_create()) == NULL)
   1403 		atf_tc_fail("ppath_create failed");
   1404 
   1405 	if (ppath_push_key(p, "John Doe") == NULL)
   1406 		atf_tc_fail("ppath_push_key failed");
   1407 	if (ppath_push_key(p, "u.s. citizen") == NULL)
   1408 		atf_tc_fail("ppath_push_key failed");
   1409 
   1410 	v = NULL;
   1411 	rc = ppath_get_string(d, p, &v);
   1412 	ATF_CHECK_EQ(rc, EFTYPE);
   1413 	ATF_CHECK_EQ(v, NULL);
   1414 
   1415 	v = "xyz";
   1416 	rc = ppath_get_string(d, p, &v);
   1417 	ATF_CHECK_EQ(rc, EFTYPE);
   1418 	ATF_CHECK_STREQ(v, "xyz");
   1419 
   1420 	ppath_release(p);
   1421 	prop_object_release(d);
   1422 	assert_no_ppath_extant();
   1423 	assert_no_ppath_component_extant();
   1424 }
   1425 
   1426 ATF_TC(get_string_enoent);
   1427 
   1428 ATF_TC_HEAD(get_string_enoent, tc)
   1429 {
   1430 	atf_tc_set_md_var(tc, "descr", "check ppath_get_string() returns "
   1431 	    "ENOENT for the path (\"John Doe\", \"title\") in the "
   1432 	    "\"personnel\" property list, and the const char ** argument is "
   1433 	    "unchanged");
   1434 }
   1435 
   1436 ATF_TC_BODY(get_string_enoent, tc)
   1437 {
   1438 	int rc;
   1439 	const char *v;
   1440 	prop_dictionary_t d;
   1441 	ppath_t *p;
   1442 
   1443 	assert_no_ppath_extant();
   1444 	assert_no_ppath_component_extant();
   1445 
   1446 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
   1447 		atf_tc_fail("prop_dictionary_internalize failed");
   1448 
   1449 	if ((p = ppath_create()) == NULL)
   1450 		atf_tc_fail("ppath_create failed");
   1451 
   1452 	if (ppath_push_key(p, "John Doe") == NULL)
   1453 		atf_tc_fail("ppath_push_key failed");
   1454 	if (ppath_push_key(p, "title") == NULL)
   1455 		atf_tc_fail("ppath_push_key failed");
   1456 
   1457 	v = NULL;
   1458 	rc = ppath_get_string(d, p, &v);
   1459 	ATF_CHECK_EQ(rc, ENOENT);
   1460 	ATF_CHECK_EQ(v, NULL);
   1461 
   1462 	v = "xyz";
   1463 	rc = ppath_get_string(d, p, &v);
   1464 	ATF_CHECK_EQ(rc, ENOENT);
   1465 	ATF_CHECK_STREQ(v, "xyz");
   1466 
   1467 	ppath_release(p);
   1468 	prop_object_release(d);
   1469 	assert_no_ppath_extant();
   1470 	assert_no_ppath_component_extant();
   1471 }
   1472 
   1473 ATF_TC(get_string_success);
   1474 
   1475 ATF_TC_HEAD(get_string_success, tc)
   1476 {
   1477 	atf_tc_set_md_var(tc, "descr", "check ppath_get_string() fetches "
   1478 	    "the \"job title\" property from the \"John Doe\" record in the "
   1479 	    "\"personnel\" property list and compares it with the expected "
   1480 	    "value, \"computer programmer\"");
   1481 }
   1482 
   1483 ATF_TC_BODY(get_string_success, tc)
   1484 {
   1485 	int rc;
   1486 	const char *v = NULL;
   1487 	prop_dictionary_t d;
   1488 	ppath_t *p;
   1489 
   1490 	assert_no_ppath_extant();
   1491 	assert_no_ppath_component_extant();
   1492 
   1493 	if ((d = prop_dictionary_internalize(personnel)) == NULL)
   1494 		atf_tc_fail("prop_dictionary_internalize failed");
   1495 
   1496 	if ((p = ppath_create()) == NULL)
   1497 		atf_tc_fail("ppath_create failed");
   1498 
   1499 	if (ppath_push_key(p, "John Doe") == NULL)
   1500 		atf_tc_fail("ppath_push_key failed");
   1501 	if (ppath_push_key(p, "job title") == NULL)
   1502 		atf_tc_fail("ppath_push_key failed");
   1503 
   1504 	rc = ppath_get_string(d, p, &v);
   1505 	ATF_CHECK_EQ(rc, 0);
   1506 	ATF_CHECK_STREQ(v, "computer programmer");
   1507 
   1508 	ppath_release(p);
   1509 	prop_object_release(d);
   1510 	assert_no_ppath_extant();
   1511 	assert_no_ppath_component_extant();
   1512 }
   1513 
   1514 ATF_TP_ADD_TCS(tp)
   1515 {
   1516 
   1517 	ATF_TP_ADD_TC(tp, push_until_full);
   1518 	ATF_TP_ADD_TC(tp, pop_until_empty);
   1519 	ATF_TP_ADD_TC(tp, length);
   1520 	ATF_TP_ADD_TC(tp, component_at);
   1521 	ATF_TP_ADD_TC(tp, get_idx_key);
   1522 	ATF_TP_ADD_TC(tp, ppath_copy);
   1523 	ATF_TP_ADD_TC(tp, replace);
   1524 
   1525 	ATF_TP_ADD_TC(tp, delete_bool_eftype);
   1526 	ATF_TP_ADD_TC(tp, delete_bool_enoent);
   1527 	ATF_TP_ADD_TC(tp, delete_bool_success);
   1528 
   1529 	ATF_TP_ADD_TC(tp, get_bool_eftype);
   1530 	ATF_TP_ADD_TC(tp, get_bool_enoent);
   1531 	ATF_TP_ADD_TC(tp, get_bool_success);
   1532 
   1533 	ATF_TP_ADD_TC(tp, copydel_bool_success);
   1534 	ATF_TP_ADD_TC(tp, copydel_object_twice_success);
   1535 	ATF_TP_ADD_TC(tp, copyset_object_twice_success);
   1536 	ATF_TP_ADD_TC(tp, copyset_bool_success);
   1537 	ATF_TP_ADD_TC(tp, create_bool_eexist);
   1538 	ATF_TP_ADD_TC(tp, create_bool_success);
   1539 	ATF_TP_ADD_TC(tp, set_bool_enoent);
   1540 	ATF_TP_ADD_TC(tp, set_bool_eftype);
   1541 	ATF_TP_ADD_TC(tp, set_bool_success);
   1542 
   1543 	ATF_TP_ADD_TC(tp, get_string_eftype);
   1544 	ATF_TP_ADD_TC(tp, get_string_enoent);
   1545 	ATF_TP_ADD_TC(tp, get_string_success);
   1546 
   1547 	return atf_no_error();
   1548 }
   1549