示例#1
0
文件: atf_main.c 项目: Bhudipta/minix
/// 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);
}
示例#2
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);
}
示例#3
0
文件: atf_main.c 项目: Bhudipta/minix
/// Executes the body 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 result_file Path to the ATF result file to be created.
/// \param user_variables Set of configuration variables to pass to the test.
static void
exec_body(const char* test_program, const char* test_case,
          const char* result_file, const char* const user_variables[])
{
    const size_t nargs =
        1 /* test_program */ +
        2 /* -r result_file */
        + 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;
    args[i++] = "-r";
    args[i++] = result_file;
    const char* const* iter;
    for (iter = user_variables; *iter != NULL; ++iter) {
        args[i++] = "-v";
        args[i++] = *iter;
    }
    args[i++] = test_case;
    args[i++] = NULL;
    assert(i == nargs);

    kyua_run_exec(test_program, args);
}
示例#4
0
文件: atf_main.c 项目: Bhudipta/minix
/// Executes the test program in list mode.
///
/// \param test_program Path to the test program to execute; should be absolute.
/// \param stdout_fds Pipe to write the output of the test program to.
static void
run_list(const char* test_program, const int stdout_fds[2])
{
    (void)close(stdout_fds[0]);

    if (stdout_fds[1] != STDOUT_FILENO) {
        if (dup2(stdout_fds[1], STDOUT_FILENO) == -1)
            err(EXIT_FAILURE, "dup2 failed");
        (void)close(stdout_fds[1]);
    }

    if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1)
        err(EXIT_FAILURE, "dup2 failed");

    const char* const program_args[] = { test_program, "-l", NULL };
    kyua_run_exec(test_program, program_args);
}
示例#5
0
文件: run_test.c 项目: s5unty/kyua
/// 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;
}