1 /* $NetBSD: fs_test.c,v 1.3 2014/12/10 04:38:03 christos Exp $ */ 2 3 /* 4 * Automated Testing Framework (atf) 5 * 6 * Copyright (c) 2007 The NetBSD Foundation, Inc. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 19 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 25 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 29 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/types.h> 33 #include <sys/stat.h> 34 35 #include <errno.h> 36 #include <fcntl.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <unistd.h> 41 42 #include <atf-c.h> 43 44 #include "fs.h" 45 #include "test_helpers.h" 46 #include "user.h" 47 48 /* --------------------------------------------------------------------- 49 * Auxiliary functions. 50 * --------------------------------------------------------------------- */ 51 52 static 53 void 54 create_dir(const char *p, int mode) 55 { 56 int ret; 57 58 ret = mkdir(p, mode); 59 if (ret == -1) 60 atf_tc_fail("Could not create helper directory %s", p); 61 } 62 63 static 64 void 65 create_file(const char *p, int mode) 66 { 67 int fd; 68 69 fd = open(p, O_CREAT | O_WRONLY | O_TRUNC, mode); 70 if (fd == -1) 71 atf_tc_fail("Could not create helper file %s", p); 72 close(fd); 73 } 74 75 static 76 bool 77 exists(const atf_fs_path_t *p) 78 { 79 return access(atf_fs_path_cstring(p), F_OK) == 0; 80 } 81 82 static 83 atf_error_t 84 mkstemp_discard_fd(atf_fs_path_t *p) 85 { 86 int fd; 87 atf_error_t err = atf_fs_mkstemp(p, &fd); 88 if (!atf_is_error(err)) 89 close(fd); 90 return err; 91 } 92 93 /* --------------------------------------------------------------------- 94 * Test cases for the "atf_fs_path" type. 95 * --------------------------------------------------------------------- */ 96 97 ATF_TC(path_normalize); 98 ATF_TC_HEAD(path_normalize, tc) 99 { 100 atf_tc_set_md_var(tc, "descr", "Tests the path's normalization"); 101 } 102 ATF_TC_BODY(path_normalize, tc) 103 { 104 struct test { 105 const char *in; 106 const char *out; 107 } tests[] = { 108 { ".", ".", }, 109 { "..", "..", }, 110 111 { "/", "/", }, 112 { "//", "/", }, /* NO_CHECK_STYLE */ 113 { "///", "/", }, /* NO_CHECK_STYLE */ 114 115 { "foo", "foo", }, 116 { "foo/", "foo", }, 117 { "foo/bar", "foo/bar", }, 118 { "foo/bar/", "foo/bar", }, 119 120 { "/foo", "/foo", }, 121 { "/foo/bar", "/foo/bar", }, 122 { "/foo/bar/", "/foo/bar", }, 123 124 { "///foo", "/foo", }, /* NO_CHECK_STYLE */ 125 { "///foo///bar", "/foo/bar", }, /* NO_CHECK_STYLE */ 126 { "///foo///bar///", "/foo/bar", }, /* NO_CHECK_STYLE */ 127 128 { NULL, NULL } 129 }; 130 struct test *t; 131 132 for (t = &tests[0]; t->in != NULL; t++) { 133 atf_fs_path_t p; 134 135 printf("Input : >%s<\n", t->in); 136 printf("Expected output: >%s<\n", t->out); 137 138 RE(atf_fs_path_init_fmt(&p, "%s", t->in)); 139 printf("Output : >%s<\n", atf_fs_path_cstring(&p)); 140 ATF_REQUIRE(strcmp(atf_fs_path_cstring(&p), t->out) == 0); 141 atf_fs_path_fini(&p); 142 143 printf("\n"); 144 } 145 } 146 147 ATF_TC(path_copy); 148 ATF_TC_HEAD(path_copy, tc) 149 { 150 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_copy constructor"); 151 } 152 ATF_TC_BODY(path_copy, tc) 153 { 154 atf_fs_path_t str, str2; 155 156 RE(atf_fs_path_init_fmt(&str, "foo")); 157 RE(atf_fs_path_copy(&str2, &str)); 158 159 ATF_REQUIRE(atf_equal_fs_path_fs_path(&str, &str2)); 160 161 RE(atf_fs_path_append_fmt(&str2, "bar")); 162 163 ATF_REQUIRE(!atf_equal_fs_path_fs_path(&str, &str2)); 164 165 atf_fs_path_fini(&str2); 166 atf_fs_path_fini(&str); 167 } 168 169 ATF_TC(path_is_absolute); 170 ATF_TC_HEAD(path_is_absolute, tc) 171 { 172 atf_tc_set_md_var(tc, "descr", "Tests the path::is_absolute function"); 173 } 174 ATF_TC_BODY(path_is_absolute, tc) 175 { 176 struct test { 177 const char *in; 178 bool abs; 179 } tests[] = { 180 { "/", true }, 181 { "////", true }, /* NO_CHECK_STYLE */ 182 { "////a", true }, /* NO_CHECK_STYLE */ 183 { "//a//", true }, /* NO_CHECK_STYLE */ 184 { "a////", false }, /* NO_CHECK_STYLE */ 185 { "../foo", false }, 186 { NULL, false }, 187 }; 188 struct test *t; 189 190 for (t = &tests[0]; t->in != NULL; t++) { 191 atf_fs_path_t p; 192 193 printf("Input : %s\n", t->in); 194 printf("Expected result: %s\n", t->abs ? "true" : "false"); 195 196 RE(atf_fs_path_init_fmt(&p, "%s", t->in)); 197 printf("Result : %s\n", 198 atf_fs_path_is_absolute(&p) ? "true" : "false"); 199 if (t->abs) 200 ATF_REQUIRE(atf_fs_path_is_absolute(&p)); 201 else 202 ATF_REQUIRE(!atf_fs_path_is_absolute(&p)); 203 atf_fs_path_fini(&p); 204 205 printf("\n"); 206 } 207 } 208 209 ATF_TC(path_is_root); 210 ATF_TC_HEAD(path_is_root, tc) 211 { 212 atf_tc_set_md_var(tc, "descr", "Tests the path::is_root function"); 213 } 214 ATF_TC_BODY(path_is_root, tc) 215 { 216 struct test { 217 const char *in; 218 bool root; 219 } tests[] = { 220 { "/", true }, 221 { "////", true }, /* NO_CHECK_STYLE */ 222 { "////a", false }, /* NO_CHECK_STYLE */ 223 { "//a//", false }, /* NO_CHECK_STYLE */ 224 { "a////", false }, /* NO_CHECK_STYLE */ 225 { "../foo", false }, 226 { NULL, false }, 227 }; 228 struct test *t; 229 230 for (t = &tests[0]; t->in != NULL; t++) { 231 atf_fs_path_t p; 232 233 printf("Input : %s\n", t->in); 234 printf("Expected result: %s\n", t->root ? "true" : "false"); 235 236 RE(atf_fs_path_init_fmt(&p, "%s", t->in)); 237 printf("Result : %s\n", 238 atf_fs_path_is_root(&p) ? "true" : "false"); 239 if (t->root) 240 ATF_REQUIRE(atf_fs_path_is_root(&p)); 241 else 242 ATF_REQUIRE(!atf_fs_path_is_root(&p)); 243 atf_fs_path_fini(&p); 244 245 printf("\n"); 246 } 247 } 248 249 ATF_TC(path_branch_path); 250 ATF_TC_HEAD(path_branch_path, tc) 251 { 252 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_branch_path " 253 "function"); 254 } 255 ATF_TC_BODY(path_branch_path, tc) 256 { 257 struct test { 258 const char *in; 259 const char *branch; 260 } tests[] = { 261 { ".", "." }, 262 { "foo", "." }, 263 { "foo/bar", "foo" }, 264 { "/foo", "/" }, 265 { "/foo/bar", "/foo" }, 266 { NULL, NULL }, 267 }; 268 struct test *t; 269 270 for (t = &tests[0]; t->in != NULL; t++) { 271 atf_fs_path_t p, bp; 272 273 printf("Input : %s\n", t->in); 274 printf("Expected output: %s\n", t->branch); 275 276 RE(atf_fs_path_init_fmt(&p, "%s", t->in)); 277 RE(atf_fs_path_branch_path(&p, &bp)); 278 printf("Output : %s\n", atf_fs_path_cstring(&bp)); 279 ATF_REQUIRE(strcmp(atf_fs_path_cstring(&bp), t->branch) == 0); 280 atf_fs_path_fini(&bp); 281 atf_fs_path_fini(&p); 282 283 printf("\n"); 284 } 285 } 286 287 ATF_TC(path_leaf_name); 288 ATF_TC_HEAD(path_leaf_name, tc) 289 { 290 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_leaf_name " 291 "function"); 292 } 293 ATF_TC_BODY(path_leaf_name, tc) 294 { 295 struct test { 296 const char *in; 297 const char *leaf; 298 } tests[] = { 299 { ".", "." }, 300 { "foo", "foo" }, 301 { "foo/bar", "bar" }, 302 { "/foo", "foo" }, 303 { "/foo/bar", "bar" }, 304 { NULL, NULL }, 305 }; 306 struct test *t; 307 308 for (t = &tests[0]; t->in != NULL; t++) { 309 atf_fs_path_t p; 310 atf_dynstr_t ln; 311 312 printf("Input : %s\n", t->in); 313 printf("Expected output: %s\n", t->leaf); 314 315 RE(atf_fs_path_init_fmt(&p, "%s", t->in)); 316 RE(atf_fs_path_leaf_name(&p, &ln)); 317 printf("Output : %s\n", atf_dynstr_cstring(&ln)); 318 ATF_REQUIRE(atf_equal_dynstr_cstring(&ln, t->leaf)); 319 atf_dynstr_fini(&ln); 320 atf_fs_path_fini(&p); 321 322 printf("\n"); 323 } 324 } 325 326 ATF_TC(path_append); 327 ATF_TC_HEAD(path_append, tc) 328 { 329 atf_tc_set_md_var(tc, "descr", "Tests the concatenation of multiple " 330 "paths"); 331 } 332 ATF_TC_BODY(path_append, tc) 333 { 334 struct test { 335 const char *in; 336 const char *ap; 337 const char *out; 338 } tests[] = { 339 { "foo", "bar", "foo/bar" }, 340 { "foo/", "/bar", "foo/bar" }, 341 { "foo/", "/bar/baz", "foo/bar/baz" }, 342 { "foo/", "///bar///baz", "foo/bar/baz" }, /* NO_CHECK_STYLE */ 343 344 { NULL, NULL, NULL } 345 }; 346 struct test *t; 347 348 for (t = &tests[0]; t->in != NULL; t++) { 349 atf_fs_path_t p; 350 351 printf("Input : >%s<\n", t->in); 352 printf("Append : >%s<\n", t->ap); 353 printf("Expected output: >%s<\n", t->out); 354 355 RE(atf_fs_path_init_fmt(&p, "%s", t->in)); 356 357 RE(atf_fs_path_append_fmt(&p, "%s", t->ap)); 358 359 printf("Output : >%s<\n", atf_fs_path_cstring(&p)); 360 ATF_REQUIRE(strcmp(atf_fs_path_cstring(&p), t->out) == 0); 361 362 atf_fs_path_fini(&p); 363 364 printf("\n"); 365 } 366 } 367 368 ATF_TC(path_to_absolute); 369 ATF_TC_HEAD(path_to_absolute, tc) 370 { 371 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_to_absolute " 372 "function"); 373 } 374 ATF_TC_BODY(path_to_absolute, tc) 375 { 376 const char *names[] = { ".", "dir", NULL }; 377 const char **n; 378 379 ATF_REQUIRE(mkdir("dir", 0755) != -1); 380 381 for (n = names; *n != NULL; n++) { 382 atf_fs_path_t p, p2; 383 atf_fs_stat_t st1, st2; 384 385 RE(atf_fs_path_init_fmt(&p, "%s", *n)); 386 RE(atf_fs_stat_init(&st1, &p)); 387 printf("Relative path: %s\n", atf_fs_path_cstring(&p)); 388 389 RE(atf_fs_path_to_absolute(&p, &p2)); 390 printf("Absolute path: %s\n", atf_fs_path_cstring(&p2)); 391 392 ATF_REQUIRE(atf_fs_path_is_absolute(&p2)); 393 RE(atf_fs_stat_init(&st2, &p2)); 394 395 ATF_REQUIRE_EQ(atf_fs_stat_get_device(&st1), 396 atf_fs_stat_get_device(&st2)); 397 ATF_REQUIRE_EQ(atf_fs_stat_get_inode(&st1), 398 atf_fs_stat_get_inode(&st2)); 399 400 atf_fs_stat_fini(&st2); 401 atf_fs_stat_fini(&st1); 402 atf_fs_path_fini(&p2); 403 atf_fs_path_fini(&p); 404 405 printf("\n"); 406 } 407 } 408 409 ATF_TC(path_equal); 410 ATF_TC_HEAD(path_equal, tc) 411 { 412 atf_tc_set_md_var(tc, "descr", "Tests the equality operators for paths"); 413 } 414 ATF_TC_BODY(path_equal, tc) 415 { 416 atf_fs_path_t p1, p2; 417 418 RE(atf_fs_path_init_fmt(&p1, "foo")); 419 420 RE(atf_fs_path_init_fmt(&p2, "foo")); 421 ATF_REQUIRE(atf_equal_fs_path_fs_path(&p1, &p2)); 422 atf_fs_path_fini(&p2); 423 424 RE(atf_fs_path_init_fmt(&p2, "bar")); 425 ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2)); 426 atf_fs_path_fini(&p2); 427 428 atf_fs_path_fini(&p1); 429 } 430 431 /* --------------------------------------------------------------------- 432 * Test cases for the "atf_fs_stat" type. 433 * --------------------------------------------------------------------- */ 434 435 ATF_TC(stat_mode); 436 ATF_TC_HEAD(stat_mode, tc) 437 { 438 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_get_mode function " 439 "and, indirectly, the constructor"); 440 } 441 ATF_TC_BODY(stat_mode, tc) 442 { 443 atf_fs_path_t p; 444 atf_fs_stat_t st; 445 446 create_file("f1", 0400); 447 create_file("f2", 0644); 448 449 RE(atf_fs_path_init_fmt(&p, "f1")); 450 RE(atf_fs_stat_init(&st, &p)); 451 ATF_CHECK_EQ(0400, atf_fs_stat_get_mode(&st)); 452 atf_fs_stat_fini(&st); 453 atf_fs_path_fini(&p); 454 455 RE(atf_fs_path_init_fmt(&p, "f2")); 456 RE(atf_fs_stat_init(&st, &p)); 457 ATF_CHECK_EQ(0644, atf_fs_stat_get_mode(&st)); 458 atf_fs_stat_fini(&st); 459 atf_fs_path_fini(&p); 460 } 461 462 ATF_TC(stat_type); 463 ATF_TC_HEAD(stat_type, tc) 464 { 465 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_get_type function " 466 "and, indirectly, the constructor"); 467 } 468 ATF_TC_BODY(stat_type, tc) 469 { 470 atf_fs_path_t p; 471 atf_fs_stat_t st; 472 473 create_dir("dir", 0755); 474 create_file("reg", 0644); 475 476 RE(atf_fs_path_init_fmt(&p, "dir")); 477 RE(atf_fs_stat_init(&st, &p)); 478 ATF_REQUIRE_EQ(atf_fs_stat_get_type(&st), atf_fs_stat_dir_type); 479 atf_fs_stat_fini(&st); 480 atf_fs_path_fini(&p); 481 482 RE(atf_fs_path_init_fmt(&p, "reg")); 483 RE(atf_fs_stat_init(&st, &p)); 484 ATF_REQUIRE_EQ(atf_fs_stat_get_type(&st), atf_fs_stat_reg_type); 485 atf_fs_stat_fini(&st); 486 atf_fs_path_fini(&p); 487 } 488 489 ATF_TC(stat_perms); 490 ATF_TC_HEAD(stat_perms, tc) 491 { 492 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_is_* functions"); 493 } 494 ATF_TC_BODY(stat_perms, tc) 495 { 496 atf_fs_path_t p; 497 atf_fs_stat_t st; 498 499 create_file("reg", 0); 500 501 RE(atf_fs_path_init_fmt(&p, "reg")); 502 503 #define perms(ur, uw, ux, gr, gw, gx, othr, othw, othx) \ 504 { \ 505 RE(atf_fs_stat_init(&st, &p)); \ 506 ATF_REQUIRE(atf_fs_stat_is_owner_readable(&st) == ur); \ 507 ATF_REQUIRE(atf_fs_stat_is_owner_writable(&st) == uw); \ 508 ATF_REQUIRE(atf_fs_stat_is_owner_executable(&st) == ux); \ 509 ATF_REQUIRE(atf_fs_stat_is_group_readable(&st) == gr); \ 510 ATF_REQUIRE(atf_fs_stat_is_group_writable(&st) == gw); \ 511 ATF_REQUIRE(atf_fs_stat_is_group_executable(&st) == gx); \ 512 ATF_REQUIRE(atf_fs_stat_is_other_readable(&st) == othr); \ 513 ATF_REQUIRE(atf_fs_stat_is_other_writable(&st) == othw); \ 514 ATF_REQUIRE(atf_fs_stat_is_other_executable(&st) == othx); \ 515 atf_fs_stat_fini(&st); \ 516 } 517 518 chmod("reg", 0000); 519 perms(false, false, false, false, false, false, false, false, false); 520 521 chmod("reg", 0001); 522 perms(false, false, false, false, false, false, false, false, true); 523 524 chmod("reg", 0010); 525 perms(false, false, false, false, false, true, false, false, false); 526 527 chmod("reg", 0100); 528 perms(false, false, true, false, false, false, false, false, false); 529 530 chmod("reg", 0002); 531 perms(false, false, false, false, false, false, false, true, false); 532 533 chmod("reg", 0020); 534 perms(false, false, false, false, true, false, false, false, false); 535 536 chmod("reg", 0200); 537 perms(false, true, false, false, false, false, false, false, false); 538 539 chmod("reg", 0004); 540 perms(false, false, false, false, false, false, true, false, false); 541 542 chmod("reg", 0040); 543 perms(false, false, false, true, false, false, false, false, false); 544 545 chmod("reg", 0400); 546 perms(true, false, false, false, false, false, false, false, false); 547 548 chmod("reg", 0644); 549 perms(true, true, false, true, false, false, true, false, false); 550 551 chmod("reg", 0755); 552 perms(true, true, true, true, false, true, true, false, true); 553 554 chmod("reg", 0777); 555 perms(true, true, true, true, true, true, true, true, true); 556 557 #undef perms 558 559 atf_fs_path_fini(&p); 560 } 561 562 /* --------------------------------------------------------------------- 563 * Test cases for the free functions. 564 * --------------------------------------------------------------------- */ 565 566 ATF_TC(exists); 567 ATF_TC_HEAD(exists, tc) 568 { 569 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_exists function"); 570 } 571 ATF_TC_BODY(exists, tc) 572 { 573 atf_error_t err; 574 atf_fs_path_t pdir, pfile; 575 bool b; 576 577 RE(atf_fs_path_init_fmt(&pdir, "dir")); 578 RE(atf_fs_path_init_fmt(&pfile, "dir/file")); 579 580 create_dir(atf_fs_path_cstring(&pdir), 0755); 581 create_file(atf_fs_path_cstring(&pfile), 0644); 582 583 printf("Checking existence of a directory\n"); 584 RE(atf_fs_exists(&pdir, &b)); 585 ATF_REQUIRE(b); 586 587 printf("Checking existence of a file\n"); 588 RE(atf_fs_exists(&pfile, &b)); 589 ATF_REQUIRE(b); 590 591 /* XXX: This should probably be a separate test case to let the user 592 * be aware that some tests were skipped because privileges were not 593 * correct. */ 594 if (!atf_user_is_root()) { 595 printf("Checking existence of a file inside a directory without " 596 "permissions\n"); 597 ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0000) != -1); 598 err = atf_fs_exists(&pfile, &b); 599 ATF_REQUIRE(atf_is_error(err)); 600 ATF_REQUIRE(atf_error_is(err, "libc")); 601 ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0755) != -1); 602 atf_error_free(err); 603 } 604 605 printf("Checking existence of a non-existent file\n"); 606 ATF_REQUIRE(unlink(atf_fs_path_cstring(&pfile)) != -1); 607 RE(atf_fs_exists(&pfile, &b)); 608 ATF_REQUIRE(!b); 609 610 atf_fs_path_fini(&pfile); 611 atf_fs_path_fini(&pdir); 612 } 613 614 ATF_TC(eaccess); 615 ATF_TC_HEAD(eaccess, tc) 616 { 617 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_eaccess function"); 618 } 619 ATF_TC_BODY(eaccess, tc) 620 { 621 const int modes[] = { atf_fs_access_f, atf_fs_access_r, atf_fs_access_w, 622 atf_fs_access_x, 0 }; 623 const int *m; 624 struct tests { 625 mode_t fmode; 626 int amode; 627 int uerror; 628 int rerror; 629 } tests[] = { 630 { 0000, atf_fs_access_r, EACCES, 0 }, 631 { 0000, atf_fs_access_w, EACCES, 0 }, 632 { 0000, atf_fs_access_x, EACCES, EACCES }, 633 634 { 0001, atf_fs_access_r, EACCES, 0 }, 635 { 0001, atf_fs_access_w, EACCES, 0 }, 636 { 0001, atf_fs_access_x, EACCES, 0 }, 637 { 0002, atf_fs_access_r, EACCES, 0 }, 638 { 0002, atf_fs_access_w, EACCES, 0 }, 639 { 0002, atf_fs_access_x, EACCES, EACCES }, 640 { 0004, atf_fs_access_r, EACCES, 0 }, 641 { 0004, atf_fs_access_w, EACCES, 0 }, 642 { 0004, atf_fs_access_x, EACCES, EACCES }, 643 644 { 0010, atf_fs_access_r, EACCES, 0 }, 645 { 0010, atf_fs_access_w, EACCES, 0 }, 646 { 0010, atf_fs_access_x, 0, 0 }, 647 { 0020, atf_fs_access_r, EACCES, 0 }, 648 { 0020, atf_fs_access_w, 0, 0 }, 649 { 0020, atf_fs_access_x, EACCES, EACCES }, 650 { 0040, atf_fs_access_r, 0, 0 }, 651 { 0040, atf_fs_access_w, EACCES, 0 }, 652 { 0040, atf_fs_access_x, EACCES, EACCES }, 653 654 { 0100, atf_fs_access_r, EACCES, 0 }, 655 { 0100, atf_fs_access_w, EACCES, 0 }, 656 { 0100, atf_fs_access_x, 0, 0 }, 657 { 0200, atf_fs_access_r, EACCES, 0 }, 658 { 0200, atf_fs_access_w, 0, 0 }, 659 { 0200, atf_fs_access_x, EACCES, EACCES }, 660 { 0400, atf_fs_access_r, 0, 0 }, 661 { 0400, atf_fs_access_w, EACCES, 0 }, 662 { 0400, atf_fs_access_x, EACCES, EACCES }, 663 664 { 0, 0, 0, 0 } 665 }; 666 struct tests *t; 667 atf_fs_path_t p; 668 atf_error_t err; 669 670 RE(atf_fs_path_init_fmt(&p, "the-file")); 671 672 printf("Non-existent file checks\n"); 673 for (m = &modes[0]; *m != 0; m++) { 674 err = atf_fs_eaccess(&p, *m); 675 ATF_REQUIRE(atf_is_error(err)); 676 ATF_REQUIRE(atf_error_is(err, "libc")); 677 ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOENT); 678 atf_error_free(err); 679 } 680 681 create_file(atf_fs_path_cstring(&p), 0000); 682 ATF_REQUIRE(chown(atf_fs_path_cstring(&p), geteuid(), getegid()) != -1); 683 684 for (t = &tests[0]; t->amode != 0; t++) { 685 const int experr = atf_user_is_root() ? t->rerror : t->uerror; 686 687 printf("\n"); 688 printf("File mode : %04o\n", (unsigned int)t->fmode); 689 printf("Access mode : 0x%02x\n", t->amode); 690 691 ATF_REQUIRE(chmod(atf_fs_path_cstring(&p), t->fmode) != -1); 692 693 /* First, existence check. */ 694 err = atf_fs_eaccess(&p, atf_fs_access_f); 695 ATF_REQUIRE(!atf_is_error(err)); 696 697 /* Now do the specific test case. */ 698 printf("Expected error: %d\n", experr); 699 err = atf_fs_eaccess(&p, t->amode); 700 if (atf_is_error(err)) { 701 if (atf_error_is(err, "libc")) 702 printf("Error : %d\n", atf_libc_error_code(err)); 703 else 704 printf("Error : Non-libc error\n"); 705 } else 706 printf("Error : None\n"); 707 if (experr == 0) { 708 ATF_REQUIRE(!atf_is_error(err)); 709 } else { 710 ATF_REQUIRE(atf_is_error(err)); 711 ATF_REQUIRE(atf_error_is(err, "libc")); 712 ATF_REQUIRE_EQ(atf_libc_error_code(err), experr); 713 atf_error_free(err); 714 } 715 } 716 717 atf_fs_path_fini(&p); 718 } 719 720 ATF_TC(getcwd); 721 ATF_TC_HEAD(getcwd, tc) 722 { 723 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_getcwd function"); 724 } 725 ATF_TC_BODY(getcwd, tc) 726 { 727 atf_fs_path_t cwd1, cwd2; 728 729 create_dir ("root", 0755); 730 731 RE(atf_fs_getcwd(&cwd1)); 732 ATF_REQUIRE(chdir("root") != -1); 733 RE(atf_fs_getcwd(&cwd2)); 734 735 RE(atf_fs_path_append_fmt(&cwd1, "root")); 736 737 ATF_REQUIRE(atf_equal_fs_path_fs_path(&cwd1, &cwd2)); 738 739 atf_fs_path_fini(&cwd2); 740 atf_fs_path_fini(&cwd1); 741 } 742 743 ATF_TC(rmdir_empty); 744 ATF_TC_HEAD(rmdir_empty, tc) 745 { 746 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function"); 747 } 748 ATF_TC_BODY(rmdir_empty, tc) 749 { 750 atf_fs_path_t p; 751 752 RE(atf_fs_path_init_fmt(&p, "test-dir")); 753 754 ATF_REQUIRE(mkdir("test-dir", 0755) != -1); 755 ATF_REQUIRE(exists(&p)); 756 RE(atf_fs_rmdir(&p)); 757 ATF_REQUIRE(!exists(&p)); 758 759 atf_fs_path_fini(&p); 760 } 761 762 ATF_TC(rmdir_enotempty); 763 ATF_TC_HEAD(rmdir_enotempty, tc) 764 { 765 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function"); 766 } 767 ATF_TC_BODY(rmdir_enotempty, tc) 768 { 769 atf_fs_path_t p; 770 atf_error_t err; 771 772 RE(atf_fs_path_init_fmt(&p, "test-dir")); 773 774 ATF_REQUIRE(mkdir("test-dir", 0755) != -1); 775 ATF_REQUIRE(exists(&p)); 776 create_file("test-dir/foo", 0644); 777 778 err = atf_fs_rmdir(&p); 779 ATF_REQUIRE(atf_is_error(err)); 780 ATF_REQUIRE(atf_error_is(err, "libc")); 781 ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOTEMPTY); 782 atf_error_free(err); 783 784 atf_fs_path_fini(&p); 785 } 786 787 ATF_TC(rmdir_eperm); 788 ATF_TC_HEAD(rmdir_eperm, tc) 789 { 790 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function"); 791 } 792 ATF_TC_BODY(rmdir_eperm, tc) 793 { 794 atf_fs_path_t p; 795 atf_error_t err; 796 797 RE(atf_fs_path_init_fmt(&p, "test-dir/foo")); 798 799 ATF_REQUIRE(mkdir("test-dir", 0755) != -1); 800 ATF_REQUIRE(mkdir("test-dir/foo", 0755) != -1); 801 ATF_REQUIRE(chmod("test-dir", 0555) != -1); 802 ATF_REQUIRE(exists(&p)); 803 804 err = atf_fs_rmdir(&p); 805 if (atf_user_is_root()) { 806 ATF_REQUIRE(!atf_is_error(err)); 807 } else { 808 ATF_REQUIRE(atf_is_error(err)); 809 ATF_REQUIRE(atf_error_is(err, "libc")); 810 ATF_REQUIRE_EQ(atf_libc_error_code(err), EACCES); 811 atf_error_free(err); 812 } 813 814 atf_fs_path_fini(&p); 815 } 816 817 ATF_TC(mkdtemp_ok); 818 ATF_TC_HEAD(mkdtemp_ok, tc) 819 { 820 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function, " 821 "successful execution"); 822 } 823 ATF_TC_BODY(mkdtemp_ok, tc) 824 { 825 atf_fs_path_t p1, p2; 826 atf_fs_stat_t s1, s2; 827 828 RE(atf_fs_path_init_fmt(&p1, "testdir.XXXXXX")); 829 RE(atf_fs_path_init_fmt(&p2, "testdir.XXXXXX")); 830 RE(atf_fs_mkdtemp(&p1)); 831 RE(atf_fs_mkdtemp(&p2)); 832 ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2)); 833 ATF_REQUIRE(exists(&p1)); 834 ATF_REQUIRE(exists(&p2)); 835 836 RE(atf_fs_stat_init(&s1, &p1)); 837 ATF_REQUIRE_EQ(atf_fs_stat_get_type(&s1), atf_fs_stat_dir_type); 838 ATF_REQUIRE( atf_fs_stat_is_owner_readable(&s1)); 839 ATF_REQUIRE( atf_fs_stat_is_owner_writable(&s1)); 840 ATF_REQUIRE( atf_fs_stat_is_owner_executable(&s1)); 841 ATF_REQUIRE(!atf_fs_stat_is_group_readable(&s1)); 842 ATF_REQUIRE(!atf_fs_stat_is_group_writable(&s1)); 843 ATF_REQUIRE(!atf_fs_stat_is_group_executable(&s1)); 844 ATF_REQUIRE(!atf_fs_stat_is_other_readable(&s1)); 845 ATF_REQUIRE(!atf_fs_stat_is_other_writable(&s1)); 846 ATF_REQUIRE(!atf_fs_stat_is_other_executable(&s1)); 847 848 RE(atf_fs_stat_init(&s2, &p2)); 849 ATF_REQUIRE_EQ(atf_fs_stat_get_type(&s2), atf_fs_stat_dir_type); 850 ATF_REQUIRE( atf_fs_stat_is_owner_readable(&s2)); 851 ATF_REQUIRE( atf_fs_stat_is_owner_writable(&s2)); 852 ATF_REQUIRE( atf_fs_stat_is_owner_executable(&s2)); 853 ATF_REQUIRE(!atf_fs_stat_is_group_readable(&s2)); 854 ATF_REQUIRE(!atf_fs_stat_is_group_writable(&s2)); 855 ATF_REQUIRE(!atf_fs_stat_is_group_executable(&s2)); 856 ATF_REQUIRE(!atf_fs_stat_is_other_readable(&s2)); 857 ATF_REQUIRE(!atf_fs_stat_is_other_writable(&s2)); 858 ATF_REQUIRE(!atf_fs_stat_is_other_executable(&s2)); 859 860 atf_fs_stat_fini(&s2); 861 atf_fs_stat_fini(&s1); 862 atf_fs_path_fini(&p2); 863 atf_fs_path_fini(&p1); 864 } 865 866 ATF_TC(mkdtemp_err); 867 ATF_TC_HEAD(mkdtemp_err, tc) 868 { 869 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function, " 870 "error conditions"); 871 atf_tc_set_md_var(tc, "require.user", "unprivileged"); 872 } 873 ATF_TC_BODY(mkdtemp_err, tc) 874 { 875 atf_error_t err; 876 atf_fs_path_t p; 877 878 ATF_REQUIRE(mkdir("dir", 0555) != -1); 879 880 RE(atf_fs_path_init_fmt(&p, "dir/testdir.XXXXXX")); 881 882 err = atf_fs_mkdtemp(&p); 883 ATF_REQUIRE(atf_is_error(err)); 884 ATF_REQUIRE(atf_error_is(err, "libc")); 885 ATF_CHECK_EQ(atf_libc_error_code(err), EACCES); 886 atf_error_free(err); 887 888 ATF_CHECK(!exists(&p)); 889 ATF_CHECK(strcmp(atf_fs_path_cstring(&p), "dir/testdir.XXXXXX") == 0); 890 891 atf_fs_path_fini(&p); 892 } 893 894 static 895 void 896 do_umask_check(atf_error_t (*const mk_func)(atf_fs_path_t *), 897 atf_fs_path_t *path, const mode_t test_mask, 898 const char *str_mask, const char *exp_name) 899 { 900 char buf[1024]; 901 int old_umask; 902 atf_error_t err; 903 904 printf("Creating temporary %s with umask %s\n", exp_name, str_mask); 905 906 old_umask = umask(test_mask); 907 err = mk_func(path); 908 (void)umask(old_umask); 909 910 ATF_REQUIRE(atf_is_error(err)); 911 ATF_REQUIRE(atf_error_is(err, "invalid_umask")); 912 atf_error_format(err, buf, sizeof(buf)); 913 ATF_CHECK(strstr(buf, exp_name) != NULL); 914 ATF_CHECK(strstr(buf, str_mask) != NULL); 915 atf_error_free(err); 916 } 917 918 ATF_TC(mkdtemp_umask); 919 ATF_TC_HEAD(mkdtemp_umask, tc) 920 { 921 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function " 922 "causing an error due to a too strict umask"); 923 } 924 ATF_TC_BODY(mkdtemp_umask, tc) 925 { 926 atf_fs_path_t p; 927 928 RE(atf_fs_path_init_fmt(&p, "testdir.XXXXXX")); 929 930 do_umask_check(atf_fs_mkdtemp, &p, 00100, "00100", "directory"); 931 do_umask_check(atf_fs_mkdtemp, &p, 00200, "00200", "directory"); 932 do_umask_check(atf_fs_mkdtemp, &p, 00400, "00400", "directory"); 933 do_umask_check(atf_fs_mkdtemp, &p, 00500, "00500", "directory"); 934 do_umask_check(atf_fs_mkdtemp, &p, 00600, "00600", "directory"); 935 936 atf_fs_path_fini(&p); 937 } 938 939 ATF_TC(mkstemp_ok); 940 ATF_TC_HEAD(mkstemp_ok, tc) 941 { 942 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function, " 943 "successful execution"); 944 } 945 ATF_TC_BODY(mkstemp_ok, tc) 946 { 947 int fd1, fd2; 948 atf_fs_path_t p1, p2; 949 atf_fs_stat_t s1, s2; 950 951 RE(atf_fs_path_init_fmt(&p1, "testfile.XXXXXX")); 952 RE(atf_fs_path_init_fmt(&p2, "testfile.XXXXXX")); 953 fd1 = fd2 = -1; 954 RE(atf_fs_mkstemp(&p1, &fd1)); 955 RE(atf_fs_mkstemp(&p2, &fd2)); 956 ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2)); 957 ATF_REQUIRE(exists(&p1)); 958 ATF_REQUIRE(exists(&p2)); 959 960 ATF_CHECK(fd1 != -1); 961 ATF_CHECK(fd2 != -1); 962 ATF_CHECK(write(fd1, "foo", 3) == 3); 963 ATF_CHECK(write(fd2, "bar", 3) == 3); 964 close(fd1); 965 close(fd2); 966 967 RE(atf_fs_stat_init(&s1, &p1)); 968 ATF_CHECK_EQ(atf_fs_stat_get_type(&s1), atf_fs_stat_reg_type); 969 ATF_CHECK( atf_fs_stat_is_owner_readable(&s1)); 970 ATF_CHECK( atf_fs_stat_is_owner_writable(&s1)); 971 ATF_CHECK(!atf_fs_stat_is_owner_executable(&s1)); 972 ATF_CHECK(!atf_fs_stat_is_group_readable(&s1)); 973 ATF_CHECK(!atf_fs_stat_is_group_writable(&s1)); 974 ATF_CHECK(!atf_fs_stat_is_group_executable(&s1)); 975 ATF_CHECK(!atf_fs_stat_is_other_readable(&s1)); 976 ATF_CHECK(!atf_fs_stat_is_other_writable(&s1)); 977 ATF_CHECK(!atf_fs_stat_is_other_executable(&s1)); 978 979 RE(atf_fs_stat_init(&s2, &p2)); 980 ATF_CHECK_EQ(atf_fs_stat_get_type(&s2), atf_fs_stat_reg_type); 981 ATF_CHECK( atf_fs_stat_is_owner_readable(&s2)); 982 ATF_CHECK( atf_fs_stat_is_owner_writable(&s2)); 983 ATF_CHECK(!atf_fs_stat_is_owner_executable(&s2)); 984 ATF_CHECK(!atf_fs_stat_is_group_readable(&s2)); 985 ATF_CHECK(!atf_fs_stat_is_group_writable(&s2)); 986 ATF_CHECK(!atf_fs_stat_is_group_executable(&s2)); 987 ATF_CHECK(!atf_fs_stat_is_other_readable(&s2)); 988 ATF_CHECK(!atf_fs_stat_is_other_writable(&s2)); 989 ATF_CHECK(!atf_fs_stat_is_other_executable(&s2)); 990 991 atf_fs_stat_fini(&s2); 992 atf_fs_stat_fini(&s1); 993 atf_fs_path_fini(&p2); 994 atf_fs_path_fini(&p1); 995 } 996 997 ATF_TC(mkstemp_err); 998 ATF_TC_HEAD(mkstemp_err, tc) 999 { 1000 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function, " 1001 "error conditions"); 1002 atf_tc_set_md_var(tc, "require.user", "unprivileged"); 1003 } 1004 ATF_TC_BODY(mkstemp_err, tc) 1005 { 1006 int fd; 1007 atf_error_t err; 1008 atf_fs_path_t p; 1009 1010 ATF_REQUIRE(mkdir("dir", 0555) != -1); 1011 1012 RE(atf_fs_path_init_fmt(&p, "dir/testfile.XXXXXX")); 1013 fd = 1234; 1014 1015 err = atf_fs_mkstemp(&p, &fd); 1016 ATF_REQUIRE(atf_is_error(err)); 1017 ATF_REQUIRE(atf_error_is(err, "libc")); 1018 ATF_CHECK_EQ(atf_libc_error_code(err), EACCES); 1019 atf_error_free(err); 1020 1021 ATF_CHECK(!exists(&p)); 1022 ATF_CHECK(strcmp(atf_fs_path_cstring(&p), "dir/testfile.XXXXXX") == 0); 1023 ATF_CHECK_EQ(fd, 1234); 1024 1025 atf_fs_path_fini(&p); 1026 } 1027 1028 ATF_TC(mkstemp_umask); 1029 ATF_TC_HEAD(mkstemp_umask, tc) 1030 { 1031 atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function " 1032 "causing an error due to a too strict umask"); 1033 } 1034 ATF_TC_BODY(mkstemp_umask, tc) 1035 { 1036 atf_fs_path_t p; 1037 1038 RE(atf_fs_path_init_fmt(&p, "testfile.XXXXXX")); 1039 1040 do_umask_check(mkstemp_discard_fd, &p, 00100, "00100", "regular file"); 1041 do_umask_check(mkstemp_discard_fd, &p, 00200, "00200", "regular file"); 1042 do_umask_check(mkstemp_discard_fd, &p, 00400, "00400", "regular file"); 1043 1044 atf_fs_path_fini(&p); 1045 } 1046 1047 /* --------------------------------------------------------------------- 1048 * Main. 1049 * --------------------------------------------------------------------- */ 1050 1051 ATF_TP_ADD_TCS(tp) 1052 { 1053 /* Add the tests for the "atf_fs_path" type. */ 1054 ATF_TP_ADD_TC(tp, path_normalize); 1055 ATF_TP_ADD_TC(tp, path_copy); 1056 ATF_TP_ADD_TC(tp, path_is_absolute); 1057 ATF_TP_ADD_TC(tp, path_is_root); 1058 ATF_TP_ADD_TC(tp, path_branch_path); 1059 ATF_TP_ADD_TC(tp, path_leaf_name); 1060 ATF_TP_ADD_TC(tp, path_append); 1061 ATF_TP_ADD_TC(tp, path_to_absolute); 1062 ATF_TP_ADD_TC(tp, path_equal); 1063 1064 /* Add the tests for the "atf_fs_stat" type. */ 1065 ATF_TP_ADD_TC(tp, stat_mode); 1066 ATF_TP_ADD_TC(tp, stat_type); 1067 ATF_TP_ADD_TC(tp, stat_perms); 1068 1069 /* Add the tests for the free functions. */ 1070 ATF_TP_ADD_TC(tp, eaccess); 1071 ATF_TP_ADD_TC(tp, exists); 1072 ATF_TP_ADD_TC(tp, getcwd); 1073 ATF_TP_ADD_TC(tp, rmdir_empty); 1074 ATF_TP_ADD_TC(tp, rmdir_enotempty); 1075 ATF_TP_ADD_TC(tp, rmdir_eperm); 1076 ATF_TP_ADD_TC(tp, mkdtemp_ok); 1077 ATF_TP_ADD_TC(tp, mkdtemp_err); 1078 ATF_TP_ADD_TC(tp, mkdtemp_umask); 1079 ATF_TP_ADD_TC(tp, mkstemp_ok); 1080 ATF_TP_ADD_TC(tp, mkstemp_err); 1081 ATF_TP_ADD_TC(tp, mkstemp_umask); 1082 1083 return atf_no_error(); 1084 } 1085