static void cleanup_tmpdir(const atf_fs_path_t *dir, const atf_fs_path_t *outfile, const atf_fs_path_t *errfile) { { atf_error_t err = atf_fs_unlink(outfile); if (atf_is_error(err)) { INV(atf_error_is(err, "libc") && atf_libc_error_code(err) == ENOENT); atf_error_free(err); } else INV(!atf_is_error(err)); } { atf_error_t err = atf_fs_unlink(errfile); if (atf_is_error(err)) { INV(atf_error_is(err, "libc") && atf_libc_error_code(err) == ENOENT); atf_error_free(err); } else INV(!atf_is_error(err)); } { atf_error_t err = atf_fs_rmdir(dir); INV(!atf_is_error(err)); } }
static atf_error_t run_tc(const atf_tp_t *tp, struct params *p, int *exitcode) { atf_error_t err; err = atf_no_error(); if (!atf_tp_has_tc(tp, p->m_tcname)) { err = usage_error("Unknown test case `%s'", p->m_tcname); goto out; } if (!atf_env_has("__RUNNING_INSIDE_ATF_RUN") || strcmp(atf_env_get( "__RUNNING_INSIDE_ATF_RUN"), "internal-yes-value") != 0) { print_warning("Running test cases outside of kyua(1) is unsupported"); print_warning("No isolation nor timeout control is being applied; you " "may get unexpected failures; see atf-test-case(4)"); } switch (p->m_tcpart) { case BODY: err = atf_tp_run(tp, p->m_tcname, atf_fs_path_cstring(&p->m_resfile)); if (atf_is_error(err)) { /* TODO: Handle error */ *exitcode = EXIT_FAILURE; atf_error_free(err); } else { *exitcode = EXIT_SUCCESS; } break; case CLEANUP: err = atf_tp_cleanup(tp, p->m_tcname); if (atf_is_error(err)) { /* TODO: Handle error */ *exitcode = EXIT_FAILURE; atf_error_free(err); } else { *exitcode = EXIT_SUCCESS; } break; default: UNREACHABLE; } INV(!atf_is_error(err)); out: return err; }
int atf_tp_main(int argc, char **argv, atf_error_t (*add_tcs_hook)(atf_tp_t *)) { atf_error_t err; int exitcode; progname = strrchr(argv[0], '/'); if (progname == NULL) progname = argv[0]; else progname++; /* Libtool workaround: if running from within the source tree (binaries * that are not installed yet), skip the "lt-" prefix added to files in * the ".libs" directory to show the real (not temporary) name. */ if (strncmp(progname, "lt-", 3) == 0) progname += 3; exitcode = EXIT_FAILURE; /* Silence GCC warning. */ err = controlled_main(argc, argv, add_tcs_hook, &exitcode); if (atf_is_error(err)) { print_error(err); atf_error_free(err); exitcode = EXIT_FAILURE; } return exitcode; }
ATF_TC_BODY(init_raw, tc) { const char *src = "String 1, String 2"; atf_dynstr_t str; RE(atf_dynstr_init_raw(&str, src, 0)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_raw(&str, src, 8)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_raw(&str, src + 10, 8)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_raw(&str, "String\0Lost", 11)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String") == 0); atf_dynstr_fini(&str); { atf_error_t err = atf_dynstr_init_raw(&str, "NULL", SIZE_MAX - 1); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "no_memory")); atf_error_free(err); } }
ATF_TC_BODY(no_memory_twice, tc) { { atf_error_t err = atf_no_memory_error(); ATF_REQUIRE(atf_error_is(err, "no_memory")); ATF_REQUIRE(atf_error_data(err) == NULL); atf_error_free(err); } { atf_error_t err = atf_no_memory_error(); ATF_REQUIRE(atf_error_is(err, "no_memory")); ATF_REQUIRE(atf_error_data(err) == NULL); atf_error_free(err); } }
ATF_TC_BODY(libc_new, tc) { atf_error_t err; err = atf_libc_error(ENOMEM, "Test message 1"); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOMEM); ATF_REQUIRE(strcmp(atf_libc_error_msg(err), "Test message 1") == 0); atf_error_free(err); err = atf_libc_error(EPERM, "%s message %d", "Test", 2); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE_EQ(atf_libc_error_code(err), EPERM); ATF_REQUIRE(strcmp(atf_libc_error_msg(err), "Test message 2") == 0); atf_error_free(err); }
static void do_child(void (*start)(void *), void *v, const stream_prepare_t *outsp, const stream_prepare_t *errsp) { atf_error_t err; err = child_connect(outsp, STDOUT_FILENO); if (atf_is_error(err)) goto out; err = child_connect(errsp, STDERR_FILENO); if (atf_is_error(err)) goto out; start(v); UNREACHABLE; out: if (atf_is_error(err)) { char buf[1024]; atf_error_format(err, buf, sizeof(buf)); fprintf(stderr, "Unhandled error: %s\n", buf); atf_error_free(err); exit(EXIT_FAILURE); } else exit(EXIT_SUCCESS); }
static atf_error_t run_tc(const atf_tp_t *tp, struct params *p, int *exitcode) { atf_error_t err; err = atf_no_error(); if (!atf_tp_has_tc(tp, p->m_tcname)) { err = usage_error("Unknown test case `%s'", p->m_tcname); goto out; } switch (p->m_tcpart) { case BODY: err = atf_tp_run(tp, p->m_tcname, atf_fs_path_cstring(&p->m_resfile)); if (atf_is_error(err)) { /* TODO: Handle error */ *exitcode = EXIT_FAILURE; atf_error_free(err); } else { *exitcode = EXIT_SUCCESS; } break; case CLEANUP: err = atf_tp_cleanup(tp, p->m_tcname); if (atf_is_error(err)) { /* TODO: Handle error */ *exitcode = EXIT_FAILURE; atf_error_free(err); } else { *exitcode = EXIT_SUCCESS; } break; default: UNREACHABLE; } INV(!atf_is_error(err)); out: return err; }
ATF_TC_BODY(error_new, tc) { atf_error_t err; int data; err = atf_error_new("test_error", NULL, 0, NULL); ATF_REQUIRE(atf_error_is(err, "test_error")); ATF_REQUIRE(!atf_error_is(err, "unknown_error")); ATF_REQUIRE(atf_error_data(err) == NULL); atf_error_free(err); data = 5; err = atf_error_new("test_data_error", &data, sizeof(data), NULL); ATF_REQUIRE(atf_error_is(err, "test_data_error")); ATF_REQUIRE(!atf_error_is(err, "unknown_error")); ATF_REQUIRE(atf_error_data(err) != NULL); ATF_REQUIRE_EQ(*((const int *)atf_error_data(err)), 5); atf_error_free(err); }
ATF_TC_BODY(no_memory_format, tc) { atf_error_t err; char buf[1024]; err = atf_no_memory_error(); atf_error_format(err, buf, sizeof(buf)); ATF_REQUIRE(strcmp(buf, "Not enough memory") == 0); atf_error_free(err); }
ATF_TC_BODY(format, tc) { atf_error_t err; char buf[1024]; printf("Testing default formatting function\n"); err = atf_error_new("test_error", NULL, 0, NULL); atf_error_format(err, buf, sizeof(buf)); printf("Error string is: %s\n", buf); ATF_REQUIRE(strcmp(buf, "Error 'test_error'") == 0); atf_error_free(err); printf("Testing custom formatting function\n"); err = atf_error_new("test_error", NULL, 0, test_format); atf_error_format(err, buf, sizeof(buf)); printf("Error string is: %s\n", buf); ATF_REQUIRE(strcmp(buf, "Test formatting function") == 0); atf_error_free(err); }
ATF_TC_BODY(is_error, tc) { atf_error_t err; err = atf_no_error(); ATF_REQUIRE(!atf_is_error(err)); err = atf_error_new("test_error", NULL, 0, NULL); ATF_REQUIRE(atf_is_error(err)); atf_error_free(err); }
ATF_TC_BODY(error_new_wo_memory, tc) { atf_error_t err; void *invalid; invalid = (void *)1; err = atf_error_new("test_error", invalid, SIZE_MAX, NULL); ATF_REQUIRE(atf_error_is(err, "no_memory")); ATF_REQUIRE(atf_error_data(err) == NULL); atf_error_free(err); }
ATF_TC_BODY(init_rep, tc) { const size_t maxlen = 8192; char buf[maxlen + 1]; size_t i; buf[0] = '\0'; for (i = 0; i < maxlen; i++) { atf_dynstr_t str; RE(atf_dynstr_init_rep(&str, i, 'a')); if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { fprintf(stderr, "Failed at iteration %zd\n", i); atf_tc_fail("Failed to construct dynstr by repeating %zd " "times the '%c' character", i, 'a'); } atf_dynstr_fini(&str); strcat(buf, "a"); } { atf_dynstr_t str; atf_error_t err; err = atf_dynstr_init_rep(&str, SIZE_MAX, 'a'); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "no_memory")); atf_error_free(err); err = atf_dynstr_init_rep(&str, SIZE_MAX - 1, 'a'); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "no_memory")); atf_error_free(err); } }
ATF_TC_BODY(libc_format, tc) { atf_error_t err; char buf[1024]; err = atf_libc_error(ENOMEM, "Test message 1"); atf_error_format(err, buf, sizeof(buf)); ATF_REQUIRE(strstr(buf, strerror(ENOMEM)) != NULL); ATF_REQUIRE(strstr(buf, "Test message 1") != NULL); atf_error_free(err); err = atf_libc_error(EPERM, "Test message 2"); atf_error_format(err, buf, sizeof(buf)); ATF_REQUIRE(strstr(buf, strerror(EPERM)) != NULL); ATF_REQUIRE(strstr(buf, "Test message 2") != NULL); atf_error_free(err); err = atf_libc_error(EPERM, "%s message %d", "Test", 3); atf_error_format(err, buf, sizeof(buf)); ATF_REQUIRE(strstr(buf, strerror(EPERM)) != NULL); ATF_REQUIRE(strstr(buf, "Test message 3") != NULL); atf_error_free(err); }
atf_error_t atf_fs_exists(const atf_fs_path_t *p, bool *b) { atf_error_t err; err = atf_fs_eaccess(p, atf_fs_access_f); if (atf_is_error(err)) { if (atf_error_is(err, "libc") && atf_libc_error_code(err) == ENOENT) { atf_error_free(err); err = atf_no_error(); *b = false; } } else *b = true; return err; }
ATF_TC_BODY(rmdir_enotempty, tc) { atf_fs_path_t p; atf_error_t err; RE(atf_fs_path_init_fmt(&p, "test-dir")); ATF_REQUIRE(mkdir("test-dir", 0755) != -1); ATF_REQUIRE(exists(&p)); create_file("test-dir/foo", 0644); err = atf_fs_rmdir(&p); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOTEMPTY); atf_error_free(err); atf_fs_path_fini(&p); }
ATF_TC_BODY(exec_umask, tc) { atf_check_result_t result; atf_fs_path_t process_helpers; const char *argv[3]; get_process_helpers_path(tc, false, &process_helpers); argv[0] = atf_fs_path_cstring(&process_helpers); argv[1] = "exit-success"; argv[2] = NULL; umask(0222); atf_error_t err = atf_check_exec_array(argv, &result); ATF_CHECK(atf_is_error(err)); ATF_CHECK(atf_error_is(err, "invalid_umask")); atf_error_free(err); atf_fs_path_fini(&process_helpers); }
ATF_TC_BODY(exists, tc) { atf_error_t err; atf_fs_path_t pdir, pfile; bool b; RE(atf_fs_path_init_fmt(&pdir, "dir")); RE(atf_fs_path_init_fmt(&pfile, "dir/file")); create_dir(atf_fs_path_cstring(&pdir), 0755); create_file(atf_fs_path_cstring(&pfile), 0644); printf("Checking existence of a directory\n"); RE(atf_fs_exists(&pdir, &b)); ATF_REQUIRE(b); printf("Checking existence of a file\n"); RE(atf_fs_exists(&pfile, &b)); ATF_REQUIRE(b); /* XXX: This should probably be a separate test case to let the user * be aware that some tests were skipped because privileges were not * correct. */ if (!atf_user_is_root()) { printf("Checking existence of a file inside a directory without " "permissions\n"); ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0000) != -1); err = atf_fs_exists(&pfile, &b); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0755) != -1); atf_error_free(err); } printf("Checking existence of a non-existent file\n"); ATF_REQUIRE(unlink(atf_fs_path_cstring(&pfile)) != -1); RE(atf_fs_exists(&pfile, &b)); ATF_REQUIRE(!b); atf_fs_path_fini(&pfile); atf_fs_path_fini(&pdir); }
ATF_TC_BODY(mkdtemp_err, tc) { atf_error_t err; atf_fs_path_t p; ATF_REQUIRE(mkdir("dir", 0555) != -1); RE(atf_fs_path_init_fmt(&p, "dir/testdir.XXXXXX")); err = atf_fs_mkdtemp(&p); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_CHECK_EQ(atf_libc_error_code(err), EACCES); atf_error_free(err); ATF_CHECK(!exists(&p)); ATF_CHECK(strcmp(atf_fs_path_cstring(&p), "dir/testdir.XXXXXX") == 0); atf_fs_path_fini(&p); }
static void do_umask_check(atf_error_t (*const mk_func)(atf_fs_path_t *), atf_fs_path_t *path, const mode_t test_mask, const char *str_mask, const char *exp_name) { char buf[1024]; int old_umask; atf_error_t err; printf("Creating temporary %s with umask %s\n", exp_name, str_mask); old_umask = umask(test_mask); err = mk_func(path); (void)umask(old_umask); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "invalid_umask")); atf_error_format(err, buf, sizeof(buf)); ATF_CHECK(strstr(buf, exp_name) != NULL); ATF_CHECK(strstr(buf, str_mask) != NULL); atf_error_free(err); }
ATF_TC_BODY(rmdir_eperm, tc) { atf_fs_path_t p; atf_error_t err; RE(atf_fs_path_init_fmt(&p, "test-dir/foo")); ATF_REQUIRE(mkdir("test-dir", 0755) != -1); ATF_REQUIRE(mkdir("test-dir/foo", 0755) != -1); ATF_REQUIRE(chmod("test-dir", 0555) != -1); ATF_REQUIRE(exists(&p)); err = atf_fs_rmdir(&p); if (atf_user_is_root()) { ATF_REQUIRE(!atf_is_error(err)); } else { ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE_EQ(atf_libc_error_code(err), EACCES); atf_error_free(err); } atf_fs_path_fini(&p); }
static void child_spawn_loop_and_wait_eintr (void *v) { atf_process_child_t child; atf_process_status_t status; struct sigaction sighup, old_sighup; #define RE_ABORT(expr) \ do { \ atf_error_t _aux_err = expr; \ if (atf_is_error(_aux_err)) { \ atf_error_free(_aux_err); \ abort(); \ } \ } while (0) { atf_process_stream_t outsb, errsb; RE_ABORT (atf_process_stream_init_capture (&outsb)); RE_ABORT (atf_process_stream_init_inherit (&errsb)); RE_ABORT (atf_process_fork (&child, child_loop, &outsb, &errsb, NULL)); atf_process_stream_fini (&outsb); atf_process_stream_fini (&errsb); } sighup.sa_handler = nop_signal; sigemptyset (&sighup.sa_mask); sighup.sa_flags = 0; if (sigaction (SIGHUP, &sighup, &old_sighup) == -1) abort (); printf ("waiting\n"); fflush (stdout); fprintf (stderr, "Child entering wait(2)\n"); atf_error_t err = atf_process_child_wait (&child, &status); fprintf (stderr, "Child's wait(2) terminated\n"); if (!atf_is_error (err)) { fprintf (stderr, "wait completed successfully (not interrupted)\n"); abort (); } if (!atf_error_is (err, "libc")) { fprintf (stderr, "wait did not raise libc_error\n"); abort (); } if (atf_libc_error_code (err) != EINTR) { fprintf (stderr, "libc_error is not EINTR\n"); abort (); } atf_error_free (err); sigaction (SIGHUP, &old_sighup, NULL); fprintf (stderr, "Child is killing subchild\n"); kill (atf_process_child_pid (&child), SIGTERM); RE_ABORT (atf_process_child_wait (&child, &status)); atf_process_status_fini (&status); #undef RE_ABORT exit (EXIT_SUCCESS); }
ATF_TC_BODY(eaccess, tc) { const int modes[] = { atf_fs_access_f, atf_fs_access_r, atf_fs_access_w, atf_fs_access_x, 0 }; const int *m; struct tests { mode_t fmode; int amode; int uerror; int rerror; } tests[] = { { 0000, atf_fs_access_r, EACCES, 0 }, { 0000, atf_fs_access_w, EACCES, 0 }, { 0000, atf_fs_access_x, EACCES, EACCES }, { 0001, atf_fs_access_r, EACCES, 0 }, { 0001, atf_fs_access_w, EACCES, 0 }, { 0001, atf_fs_access_x, EACCES, 0 }, { 0002, atf_fs_access_r, EACCES, 0 }, { 0002, atf_fs_access_w, EACCES, 0 }, { 0002, atf_fs_access_x, EACCES, EACCES }, { 0004, atf_fs_access_r, EACCES, 0 }, { 0004, atf_fs_access_w, EACCES, 0 }, { 0004, atf_fs_access_x, EACCES, EACCES }, { 0010, atf_fs_access_r, EACCES, 0 }, { 0010, atf_fs_access_w, EACCES, 0 }, { 0010, atf_fs_access_x, 0, 0 }, { 0020, atf_fs_access_r, EACCES, 0 }, { 0020, atf_fs_access_w, 0, 0 }, { 0020, atf_fs_access_x, EACCES, EACCES }, { 0040, atf_fs_access_r, 0, 0 }, { 0040, atf_fs_access_w, EACCES, 0 }, { 0040, atf_fs_access_x, EACCES, EACCES }, { 0100, atf_fs_access_r, EACCES, 0 }, { 0100, atf_fs_access_w, EACCES, 0 }, { 0100, atf_fs_access_x, 0, 0 }, { 0200, atf_fs_access_r, EACCES, 0 }, { 0200, atf_fs_access_w, 0, 0 }, { 0200, atf_fs_access_x, EACCES, EACCES }, { 0400, atf_fs_access_r, 0, 0 }, { 0400, atf_fs_access_w, EACCES, 0 }, { 0400, atf_fs_access_x, EACCES, EACCES }, { 0, 0, 0, 0 } }; struct tests *t; atf_fs_path_t p; atf_error_t err; RE(atf_fs_path_init_fmt(&p, "the-file")); printf("Non-existent file checks\n"); for (m = &modes[0]; *m != 0; m++) { err = atf_fs_eaccess(&p, *m); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOENT); atf_error_free(err); } create_file(atf_fs_path_cstring(&p), 0000); ATF_REQUIRE(chown(atf_fs_path_cstring(&p), geteuid(), getegid()) != -1); for (t = &tests[0]; t->amode != 0; t++) { const int experr = atf_user_is_root() ? t->rerror : t->uerror; printf("\n"); printf("File mode : %04o\n", (unsigned int)t->fmode); printf("Access mode : 0x%02x\n", t->amode); ATF_REQUIRE(chmod(atf_fs_path_cstring(&p), t->fmode) != -1); /* First, existence check. */ err = atf_fs_eaccess(&p, atf_fs_access_f); ATF_REQUIRE(!atf_is_error(err)); /* Now do the specific test case. */ printf("Expected error: %d\n", experr); err = atf_fs_eaccess(&p, t->amode); if (atf_is_error(err)) { if (atf_error_is(err, "libc")) printf("Error : %d\n", atf_libc_error_code(err)); else printf("Error : Non-libc error\n"); } else printf("Error : None\n"); if (experr == 0) { ATF_REQUIRE(!atf_is_error(err)); } else { ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE_EQ(atf_libc_error_code(err), experr); atf_error_free(err); } } atf_fs_path_fini(&p); }