Ejemplo n.º 1
0
ATF_TC_BODY(cleanup__mount_point__busy, tc)
{
    ATF_REQUIRE(mkdir("root", 0755) != -1);
    ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
    mount_tmpfs("root/dir1");

    pid_t pid = fork();
    ATF_REQUIRE(pid != -1);
    if (pid == 0) {
        if (chdir("root/dir1") == -1)
            abort();

        atf_utils_create_file("dont-delete-me", "%s", "");
        atf_utils_create_file("../../done", "%s", "");

        pause();
        exit(EXIT_SUCCESS);
    } else {
        fprintf(stderr, "Waiting for child to finish preparations\n");
        while (!atf_utils_file_exists("done")) {}
        fprintf(stderr, "Child done; cleaning up\n");

        ATF_REQUIRE(kyua_error_is_set(kyua_fs_cleanup("root")));
        ATF_REQUIRE(atf_utils_file_exists("root/dir1/dont-delete-me"));

        fprintf(stderr, "Killing child\n");
        ATF_REQUIRE(kill(pid, SIGKILL) != -1);
        int status;
        ATF_REQUIRE(waitpid(pid, &status, 0) != -1);

        ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
        ATF_REQUIRE(!lookup(".", "root", DT_DIR));
    }
}
Ejemplo n.º 2
0
/// Parses a single test case and writes it to the output.
///
/// This has to be called after the ident property has been read, and takes care
/// of reading the rest of the test case and printing the parsed result.
///
/// Be aware that this consumes the newline after the test case.  The caller
/// should not look for it.
///
/// \param [in,out] input File from which to read the header.
/// \param [in,out] output File to which to write the parsed test case.
/// \param [in,out] name The name of the test case.  This is a non-const pointer
///     and the input string is modified to simplify tokenization.
///
/// \return OK if the parsing succeeds; an error otherwise.
static kyua_error_t
parse_test_case(FILE* input, FILE* output, char* name)
{
    kyua_error_t error;
    char line[1024];  // It's ugly to have a limit, but it's easier this way.

    fprintf(output, "test_case{name=");
    print_quoted(name, output, true);

    error = kyua_error_ok();
    while (!kyua_error_is_set(error) &&
           fgets_no_newline(line, sizeof(line), input) != NULL &&
           strcmp(line, "") != 0) {
        char* key = NULL; char* value = NULL;
        error = parse_property(line, &key, &value);
        if (!kyua_error_is_set(error)) {
            const char* out_key = rewrite_property(key);
            if (out_key == rewrite_error) {
                error = kyua_generic_error_new("Unknown ATF property %s", key);
            } else if (out_key == NULL) {
                fprintf(output, ", ['custom.");
                print_quoted(key, output, false);
                fprintf(output, "']=");
                print_quoted(value, output, true);
            } else {
                fprintf(output, ", %s=", out_key);
                print_quoted(value, output, true);
            }
        }
    }

    fprintf(output, "}\n");

    return error;
}
Ejemplo n.º 3
0
Archivo: env.c Proyecto: namore/kyua
/// Sets a collection of configuration variables in the environment.
///
/// \param user_variables Set of configuration variables to pass to the test.
///     This is an array of strings of the form var=value and must have been
///     previously sanity-checked with kyua_env_check_configuration.
///
/// \return An error if there is a problem allocating memory.
///
/// \post The environment contains a new collection of TEST_ENV_* variables that
/// matches the input user_variables.
kyua_error_t
kyua_env_set_configuration(const char* const user_variables[])
{
    const char* const* iter;
    for (iter = user_variables; *iter != NULL; ++iter) {
        kyua_error_t error;

        char* var_value = strdup(*iter);
        if (var_value == NULL)
            return kyua_oom_error_new();

        char* value = strchr(var_value, '=');
        assert(value != NULL);  // Must have been validated.
        *value = '\0';
        value += 1;

        char* var;
        error = kyua_text_printf(&var, "TEST_ENV_%s", var_value);
        if (kyua_error_is_set(error)) {
            free(var_value);
            return error;
        }

        error = kyua_env_set(var, value);
        if (kyua_error_is_set(error)) {
            free(var_value);
            return error;
        }
    }
    return kyua_error_ok();
}
Ejemplo n.º 4
0
ATF_TC_BODY(fork_wait__core_size, tc)
{
    struct rlimit rl;
    rl.rlim_cur = 0;
    rl.rlim_max = RLIM_INFINITY;
    if (setrlimit(RLIMIT_CORE, &rl) == -1)
        atf_tc_skip("Failed to lower the core size limit");

    kyua_run_params_t run_params;
    kyua_run_params_init(&run_params);

    pid_t pid;
    kyua_error_t error = kyua_run_fork(&run_params, &pid);
    if (!kyua_error_is_set(error) && pid == 0)
        abort();

    ATF_REQUIRE(!kyua_error_is_set(error));
    int status; bool timed_out;
    error = kyua_run_wait(pid, &status, &timed_out);
    if (kyua_error_is_set(error))
        atf_tc_fail("wait failed; unexpected problem during exec?");

    ATF_REQUIRE(!timed_out);
    ATF_REQUIRE(WIFSIGNALED(status));
    ATF_REQUIRE_MSG(WCOREDUMP(status), "Core not dumped as expected");
}
Ejemplo n.º 5
0
/// Rewrites the test cases list from the input to the output.
///
/// \param [in,out] input Stream from which to read the test program's test
///     cases list.  The current location must be after the header and at the
///     first identifier (if any).
/// \param [out] output Stream to which to write the generic list.
///
/// \return An error object.
static kyua_error_t
parse_tests(FILE* input, FILE* output)
{
    char line[512];  // It's ugly to have a limit, but it's easier this way.

    if (fgets_no_newline(line, sizeof(line), input) == NULL) {
        return fgets_error(input, "Empty test cases list");
    }

    kyua_error_t error;

    do {
        char* key = NULL; char* value = NULL;
        error = parse_property(line, &key, &value);
        if (kyua_error_is_set(error))
            break;

        if (strcmp(key, "ident") == 0) {
            error = parse_test_case(input, output, value);
        } else {
            error = kyua_generic_error_new("Expected ident property, got %s",
                                           key);
        }
    } while (!kyua_error_is_set(error) &&
             fgets_no_newline(line, sizeof(line), input) != NULL);

    if (!kyua_error_is_set(error)) {
        if (ferror(input))
            error = kyua_libc_error_new(errno, "fgets failed");
        else
            assert(feof(input));
    }

    return error;
}
Ejemplo n.º 6
0
/// Body of a subprocess to execute GDB.
///
/// This should be called from the child created by a kyua_run_fork() call,
/// which means that we do not have to take care of isolating the process.
///
/// \pre The caller must have flushed stdout before spawning this process, to
///     prevent double-flushing and/or corruption of data.
///
/// \param program Path to the program being debugged.  Can be relative to
///     the given work directory.
/// \param core_name Path to the dumped core.  Use find_core() to deduce
///     a valid candidate.  Can be relative to the given work directory.
/// \param output Stream to which to send the output of GDB.
static void
run_gdb(const char* program, const char* core_name, FILE* output)
{
    // TODO(jmmv): Should be done by kyua_run_fork(), but doing so would change
    // the semantics of the ATF interface.  Need to evaluate this carefully.
    const kyua_error_t error = kyua_env_unset("TERM");
    if (kyua_error_is_set(error)) {
        kyua_error_warn(error, "Failed to unset TERM; GDB may misbehave");
        free(error);
    }

    (void)close(STDIN_FILENO);
#if defined(__minix) && !defined(NDEBUG)
    const int input_fd =
#endif /* defined(__minix) && !defined(NDEBUG) */
    open("/dev/null", O_RDONLY);
    assert(input_fd == STDIN_FILENO);

    const int output_fd = fileno(output);
    assert(output_fd != -1);  // We expect a file-backed stream.
    if (output_fd != STDOUT_FILENO) {
        fflush(stdout);
        (void)dup2(output_fd, STDOUT_FILENO);
    }
    if (output_fd != STDERR_FILENO) {
        fflush(stderr);
        (void)dup2(output_fd, STDERR_FILENO);
    }
    if (output_fd != STDOUT_FILENO && output_fd != STDERR_FILENO)
        fclose(output);

    const char* const gdb_args[] = {
        "gdb", "-batch", "-q", "-ex", "bt", program, core_name, NULL };
    kyua_run_exec(kyua_stacktrace_gdb, gdb_args);
}
Ejemplo n.º 7
0
/// Executes the cleanup of a test case.
///
/// \param test_program Path to the test program to execute.
/// \param test_case Name of the test case to run.
/// \param user_variables Set of configuration variables to pass to the test.
static void
exec_cleanup(const char* test_program, const char* test_case,
             const char* const user_variables[])
{
    char* name;
    kyua_error_t error = kyua_text_printf(&name, "%s:cleanup", test_case);
    if (kyua_error_is_set(error))
        kyua_error_err(EXIT_FAILURE, error,
                       "Failed to construct argument list");

    const size_t nargs =
        1 /* test_program */ +
        + 2 * count_variables(user_variables) /* -v name=value */
        + 1 /* test_case */ +
        1 /* NULL */;

    const char** args = malloc(sizeof(const char*) * nargs);
    if (args == NULL)
        kyua_error_err(EXIT_FAILURE, kyua_oom_error_new(),
                       "Failed to construct arguments list");

    size_t i = 0;
    args[i++] = test_program;
    const char* const* iter;
    for (iter = user_variables; *iter != NULL; ++iter) {
        args[i++] = "-v";
        args[i++] = *iter;
    }
    args[i++] = name;
    args[i++] = NULL;
    assert(i == nargs);

    kyua_run_exec(test_program, args);
}
Ejemplo n.º 8
0
/// Runs a single test cases of a test program.
///
/// \param test_program Path to the test program for which to list the test
///     cases.  Should be absolute.
/// \param test_case Name of the test case to run.
/// \param result_file Path to the file to which to write the result of the
///     test.  Should be absolute.
/// \param user_variables Array of name=value pairs that describe the user
///     configuration variables for the test case.
/// \param run_params Execution parameters to configure the test process.
/// \param [out] success Set to true if the test case reported a valid exit
///     condition (like "passed" or "skipped"); false otherwise.  This is
///     only updated if the method returns OK.
///
/// \return An error if the listing fails; OK otherwise.
static kyua_error_t
run_test_case(const char* test_program, const char* test_case,
              const char* result_file, const char* const user_variables[],
              const kyua_run_params_t* run_params, bool* success)
{
    kyua_error_t error;

    char* work_directory;
    error = kyua_run_work_directory_enter(WORKDIR_TEMPLATE,
                                          run_params->unprivileged_user,
                                          run_params->unprivileged_group,
                                          &work_directory);
    if (kyua_error_is_set(error))
        goto out;
    kyua_run_params_t real_run_params = *run_params;
    real_run_params.work_directory = work_directory;

    error = run_body(test_program, test_case, result_file, user_variables,
                     &real_run_params, success);
    if (has_cleanup(user_variables)) {
        error = run_cleanup(test_program, test_case, result_file,
                            user_variables, &real_run_params, *success,
                            success);
    }

    error = kyua_error_subsume(error,
        kyua_run_work_directory_leave(&work_directory));
out:
    return error;
}
Ejemplo n.º 9
0
ATF_TC_BODY(cleanup__subdir__empty, tc)
{
    ATF_REQUIRE(mkdir("root", 0755) != -1);
    ATF_REQUIRE(lookup(".", "root", DT_DIR));
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
    ATF_REQUIRE(!lookup(".", "root", DT_DIR));
}
Ejemplo n.º 10
0
ATF_TC_BODY(cleanup__file, tc)
{
    atf_utils_create_file("root", "%s", "");
    ATF_REQUIRE(lookup(".", "root", DT_REG));
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
    ATF_REQUIRE(!lookup(".", "root", DT_REG));
}
Ejemplo n.º 11
0
ATF_TC_BODY(vprintf__empty, tc)
{
    char* buffer;
    kyua_error_t error = call_vprintf(&buffer, "%s", "");
    ATF_REQUIRE(!kyua_error_is_set(error));
    ATF_REQUIRE_STREQ("", buffer);
}
Ejemplo n.º 12
0
ATF_TC_BODY(concat__two, tc)
{
    char* path;
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_concat(&path, "foo", "bar", NULL)));
    ATF_REQUIRE_STREQ("foo/bar", path);
    free(path);
}
Ejemplo n.º 13
0
ATF_TC_BODY(vprintf__some, tc)
{
    char* buffer;
    kyua_error_t error = call_vprintf(&buffer, "this is %d %s", 123, "foo");
    ATF_REQUIRE(!kyua_error_is_set(error));
    ATF_REQUIRE_STREQ("this is 123 foo", buffer);
    free(buffer);
}
Ejemplo n.º 14
0
ATF_TC_BODY(make_absolute__absolute, tc)
{
    char* absolute;
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_make_absolute(
                                       "/this/is/absolute", &absolute)));
    ATF_REQUIRE_STREQ("/this/is/absolute", absolute);
    free(absolute);
}
Ejemplo n.º 15
0
ATF_TC_BODY(fork_exec_wait__ok, tc)
{
    const char* const args[] = {"sh", "-c", "exit 42", NULL};
    int exitstatus = -1;  // Shut up GCC warning.
    const kyua_error_t error = exec_check("/bin/sh", args, &exitstatus);
    ATF_REQUIRE(!kyua_error_is_set(error));
    ATF_REQUIRE_EQ(42, exitstatus);
}
Ejemplo n.º 16
0
ATF_TC_BODY(concat__several, tc)
{
    char* path;
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_concat(&path, "/usr", ".", "bin",
                                   "ls", NULL)));
    ATF_REQUIRE_STREQ("/usr/./bin/ls", path);
    free(path);
}
Ejemplo n.º 17
0
/// Parses a results file written by an ATF test case.
///
/// \param input_name Path to the result file to parse.
/// \param [out] status Type of result.
/// \param [out] status_arg Optional integral argument to the status.
/// \param [out] reason Textual explanation of the result, if any.
/// \param reason_size Length of the reason output buffer.
///
/// \return An error if the input_name file has an invalid syntax; OK otherwise.
static kyua_error_t
read_atf_result(const char* input_name, enum atf_status* status,
                int* status_arg, char* const reason, const size_t reason_size)
{
    kyua_error_t error = kyua_error_ok();

    FILE* input = fopen(input_name, "r");
    if (input == NULL) {
        error = kyua_generic_error_new("Premature exit");
        goto out;
    }

    char line[1024];
    if (fgets(line, sizeof(line), input) == NULL) {
        if (ferror(input)) {
            error = kyua_libc_error_new(errno, "Failed to read result from "
                                        "file %s", input_name);
            goto out_input;
        } else {
            assert(feof(input));
            error = kyua_generic_error_new("Empty result file %s", input_name);
            goto out_input;
        }
    }

    if (!trim_newline(line)) {
        error = kyua_generic_error_new("Missing newline in result file");
        goto out_input;
    }

    char* reason_start = strstr(line, ": ");
    if (reason_start != NULL) {
        *reason_start = '\0';
        *(reason_start + 1) = '\0';
        reason_start += 2;
    }

    bool need_reason = false;  // Initialize to shut up gcc warning.
    error = parse_status(line, status, status_arg, &need_reason);
    if (kyua_error_is_set(error))
        goto out_input;

    if (need_reason) {
        error = read_reason(input, reason_start, reason, reason_size);
    } else {
        if (reason_start != NULL || !is_really_eof(input)) {
            error = kyua_generic_error_new("Found unexpected reason in passed "
                                           "test result");
            goto out_input;
        }
        reason[0] = '\0';
    }

out_input:
    fclose(input);
out:
    return error;
}
Ejemplo n.º 18
0
ATF_TC_BODY(cleanup__subdir__unprotect_symlink, tc)
{
    ATF_REQUIRE(mkdir("root", 0755) != -1);
    ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
    ATF_REQUIRE(symlink("/bin/ls", "root/dir1/ls") != -1);
    ATF_REQUIRE(chmod("root/dir1", 0555) != -1);
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
    ATF_REQUIRE(!lookup(".", "root", DT_DIR));
}
Ejemplo n.º 19
0
ATF_TC_BODY(cleanup__mount_point__simple, tc)
{
    ATF_REQUIRE(mkdir("root", 0755) != -1);
    ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
    atf_utils_create_file("root/zz", "%s", "");
    mount_tmpfs("root/dir1");
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
    ATF_REQUIRE(!lookup(".", "root", DT_DIR));
}
Ejemplo n.º 20
0
ATF_TC_BODY(sanitize__fail, tc)
{
    char* sane;
    kyua_error_t error = kyua_fs_sanitize("non-existent/path", &sane);
    ATF_REQUIRE(kyua_error_is_set(error));
    ATF_REQUIRE(kyua_error_is_type(error, "libc"));
    ATF_REQUIRE_EQ(ENOENT, kyua_libc_error_errno(error));
    kyua_error_free(error);
}
Ejemplo n.º 21
0
ATF_TC_BODY(current_path__enoent, tc)
{
    char* previous;
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_current_path(&previous)));

    ATF_REQUIRE(mkdir("root", 0755) != -1);
    ATF_REQUIRE(chdir("root") != -1);
    ATF_REQUIRE(rmdir("../root") != -1);
    char* cwd = (char*)0xdeadbeef;
    kyua_error_t error = kyua_fs_current_path(&cwd);
    ATF_REQUIRE(kyua_error_is_set(error));
    ATF_REQUIRE(kyua_error_is_type(error, "libc"));
    ATF_REQUIRE_EQ(ENOENT, kyua_libc_error_errno(error));
    ATF_REQUIRE_EQ((char*)0xdeadbeef, cwd);
    kyua_error_free(error);

    free(previous);
}
Ejemplo n.º 22
0
ATF_TC_BODY(fork_exec_wait__enoent, tc)
{
    const char* const args[] = {"foo", NULL};
    int unused_exitstatus;
    const kyua_error_t error = exec_check("./foo", args, &unused_exitstatus);
    ATF_REQUIRE(kyua_error_is_set(error));
    ATF_REQUIRE(kyua_error_is_type(error, "libc"));
    ATF_REQUIRE_EQ(ENOENT, kyua_libc_error_errno(error));
}
Ejemplo n.º 23
0
ATF_TC_BODY(cleanup__mount_point__links, tc)
{
    ATF_REQUIRE(mkdir("root", 0755) != -1);
    ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
    ATF_REQUIRE(mkdir("root/dir3", 0755) != -1);
    mount_tmpfs("root/dir1");
    ATF_REQUIRE(symlink("../dir3", "root/dir1/link") != -1);
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
    ATF_REQUIRE(!lookup(".", "root", DT_DIR));
}
Ejemplo n.º 24
0
ATF_TC_BODY(sanitize__ok, tc)
{
    ATF_REQUIRE(mkdir("a", 0755) != -1);
    ATF_REQUIRE(mkdir("a/bc", 0755) != -1);
    ATF_REQUIRE(mkdir("a/bc/12-34", 0755) != -1);

    char* sane;
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_sanitize(
                                       ".//a/bc///12-34", &sane)));

    char *expected;
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_make_absolute(
                                       "a/bc/12-34", &expected)));

    ATF_REQUIRE_STREQ(expected, sane);

    free(sane);
    free(expected);
}
Ejemplo n.º 25
0
ATF_TC_BODY(current_path__ok, tc)
{
    char* previous;
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_current_path(&previous)));

    ATF_REQUIRE(mkdir("root", 0755) != -1);
    ATF_REQUIRE(chdir("root") != -1);
    char* cwd;
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_current_path(&cwd)));

    char* exp_cwd;
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_concat(&exp_cwd, previous, "root",
                                   NULL)));
    ATF_REQUIRE_STREQ(exp_cwd, cwd);

    free(exp_cwd);
    free(cwd);
    free(previous);
}
Ejemplo n.º 26
0
/// Looks for a core file for the given program.
///
/// \param name The basename of the binary that generated the core.
/// \param directory The directory from which the program was run.  We expect to
///     find the core file in this directory.
/// \param dead_pid PID of the process that generated the core.  This is needed
///     in some platforms.
///
/// \return The path to the core file if found; otherwise none.
char*
kyua_stacktrace_find_core(const char* name, const char* directory,
                          const pid_t dead_pid)
{
    char* candidate = NULL;

    // TODO(jmmv): Other than checking all these defaults, in NetBSD we should
    // also inspect the value of the kern.defcorename sysctl(2) MIB and use that
    // as the first candidate.
    //
    // In Linux, the way to determine the name is by looking at
    // /proc/sys/kernel/core_{pattern,uses_pid} as described by core(5).
    // Unfortunately, there does not seem to be a standard API to parse these
    // files, which makes checking for core files quite difficult if the
    // defaults have been modified.

    // Default NetBSD naming scheme.
    if (candidate == NULL && MAXCOMLEN > 0) {
        char truncated[MAXCOMLEN + 1];
        candidate = try_core("%s/%s.core", directory,
                             slice(name, truncated, sizeof(truncated)));
    }

    // Common naming scheme without the MAXCOMLEN truncation.
    if (candidate == NULL)
        candidate = try_core("%s/%s.core", directory, name);

    // Common naming scheme found in Linux systems.
    if (candidate == NULL)
        candidate = try_core("%s/core.%d", directory, (int)dead_pid);

    // Default Mac OS X naming scheme.
    if (candidate == NULL)
        candidate = try_core("/cores/core.%d", (int)dead_pid);

    // Common naming scheme found in Linux systems.  Attempted last due to the
    // genericity of the core file name.
    if (candidate == NULL)
        candidate = try_core("%s/core", directory);

    if (candidate != NULL) {
        char* abs_candidate;
        kyua_error_t error = kyua_fs_make_absolute(candidate, &abs_candidate);
        if (kyua_error_is_set(error)) {
            kyua_error_free(error);
            return candidate;  // Return possibly-relative path as a best guess.
        } else {
            free(candidate);
            return abs_candidate;
        }
    } else {
        return candidate;
    }
}
Ejemplo n.º 27
0
/// Uses kyua_fork, kyua_exec and kyua_wait to execute a subprocess.
///
/// \param program Path to the program to run.
/// \param args Arguments to the program.
/// \param [out] exitstatus The exit status of the subprocess, if it exits
///     successfully without timing out nor receiving a signal.
///
/// \return Returns the error code of kyua_run_wait (which should have the
///     error representation of the exec call in the subprocess).
static kyua_error_t
exec_check(const char* program, const char* const* args, int* exitstatus)
{
    kyua_run_params_t run_params;
    kyua_run_params_init(&run_params);

    pid_t pid;
    kyua_error_t error = kyua_run_fork(&run_params, &pid);
    if (!kyua_error_is_set(error) && pid == 0)
        kyua_run_exec(program, args);
    ATF_REQUIRE(!kyua_error_is_set(error));
    int status; bool timed_out;
    error = kyua_run_wait(pid, &status, &timed_out);
    if (!kyua_error_is_set(error)) {
        ATF_REQUIRE(!timed_out);
        ATF_REQUIRE_MSG(WIFEXITED(status),
                        "Subprocess expected to exit successfully");
        *exitstatus = WEXITSTATUS(status);
    }
    return error;
}
Ejemplo n.º 28
0
ATF_TC_BODY(fork_exec_wait__eacces, tc)
{
    ATF_REQUIRE(mkdir("dir", 0000) != -1);

    const char* const args[] = {"foo", NULL};
    int unused_exitstatus;
    const kyua_error_t error = exec_check("./dir/foo", args,
                                          &unused_exitstatus);
    ATF_REQUIRE(kyua_error_is_set(error));
    ATF_REQUIRE(kyua_error_is_type(error, "libc"));
    ATF_REQUIRE_EQ(EACCES, kyua_libc_error_errno(error));
}
Ejemplo n.º 29
0
ATF_TC_BODY(fork_wait__timeout, tc)
{
    kyua_run_params_t run_params;
    kyua_run_params_init(&run_params);
    run_params.timeout_seconds = 1;

    pid_t pid;
    kyua_error_t error = kyua_run_fork(&run_params, &pid);
    if (!kyua_error_is_set(error) && pid == 0) {
        sigset_t mask;
        sigemptyset(&mask);
        for (;;)
            sigsuspend(&mask);
    }
    ATF_REQUIRE(!kyua_error_is_set(error));
    int status; bool timed_out;
    kyua_run_wait(pid, &status, &timed_out);
    ATF_REQUIRE(timed_out);
    ATF_REQUIRE(WIFSIGNALED(status));
    ATF_REQUIRE_EQ(SIGKILL, WTERMSIG(status));
}
Ejemplo n.º 30
0
ATF_TC_BODY(cleanup__subdir__unprotect_regular, tc)
{
    ATF_REQUIRE(mkdir("root", 0755) != -1);
    ATF_REQUIRE(mkdir("root/dir1", 0755) != -1);
    ATF_REQUIRE(mkdir("root/dir1/dir2", 0755) != -1);
    atf_utils_create_file("root/dir1/dir2/file", "%s", "");
    ATF_REQUIRE(chmod("root/dir1/dir2/file", 0000) != -1);
    ATF_REQUIRE(chmod("root/dir1/dir2", 0000) != -1);
    ATF_REQUIRE(chmod("root/dir1", 0000) != -1);
    ATF_REQUIRE(!kyua_error_is_set(kyua_fs_cleanup("root")));
    ATF_REQUIRE(!lookup(".", "root", DT_DIR));
}