1 /* $Id: t_ppath.c,v 1.1 2011/08/25 19:09:46 dyoung 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.1 2011/08/25 19:09:46 dyoung 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