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