Beispiel #1
0
atf_error_t
atf_fs_mkstemp(atf_fs_path_t *p, int *fdout)
{
    atf_error_t err;
    char *buf;
    int fd;

    if (!check_umask(S_IRWXU, S_IRWXU)) {
        err = invalid_umask_error(p, atf_fs_stat_reg_type, current_umask());
        goto out;
    }

    err = copy_contents(p, &buf);
    if (atf_is_error(err))
        goto out;

    err = do_mkstemp(buf, &fd);
    if (atf_is_error(err))
        goto out_buf;

    replace_contents(p, buf);
    *fdout = fd;

    INV(!atf_is_error(err));
out_buf:
    free(buf);
out:
    return err;
}
Beispiel #2
0
atf_error_t
atf_fs_mkdtemp(atf_fs_path_t *p)
{
    atf_error_t err;
    char *buf = NULL;

    if (!check_umask(S_IRWXU, S_IRWXU)) {
        err = invalid_umask_error(p, atf_fs_stat_dir_type, current_umask());
        goto out;
    }

    err = copy_contents(p, &buf);
    if (atf_is_error(err))
        goto out;

    err = do_mkdtemp(buf);
    if (atf_is_error(err))
        goto out_buf;

    replace_contents(p, buf);

    INV(!atf_is_error(err));
out_buf:
    free(buf);
out:
    return err;
}
Beispiel #3
0
static
atf_error_t
params_init(struct params *p, const char *argv0)
{
    atf_error_t err;

    p->m_do_list = false;
    p->m_tcname = NULL;
    p->m_tcpart = BODY;

    err = argv0_to_dir(argv0, &p->m_srcdir);
    if (atf_is_error(err))
        return err;

    err = atf_fs_path_init_fmt(&p->m_resfile, "/dev/stdout");
    if (atf_is_error(err)) {
        atf_fs_path_fini(&p->m_srcdir);
        return err;
    }

    err = atf_map_init(&p->m_config);
    if (atf_is_error(err)) {
        atf_fs_path_fini(&p->m_resfile);
        atf_fs_path_fini(&p->m_srcdir);
        return err;
    }

    return err;
}
Beispiel #4
0
atf_error_t
atf_process_fork(atf_process_child_t *c,
                 void (*start)(void *),
                 const atf_process_stream_t *outsb,
                 const atf_process_stream_t *errsb,
                 void *v)
{
    atf_error_t err;
    atf_process_stream_t inherit_outsb, inherit_errsb;
    const atf_process_stream_t *real_outsb, *real_errsb;

    real_outsb = NULL;  /* Shut up GCC warning. */
    err = init_stream_w_default(outsb, &inherit_outsb, &real_outsb);
    if (atf_is_error(err))
        goto out;

    real_errsb = NULL;  /* Shut up GCC warning. */
    err = init_stream_w_default(errsb, &inherit_errsb, &real_errsb);
    if (atf_is_error(err))
        goto out_out;

    err = fork_with_streams(c, start, real_outsb, real_errsb, v);

    if (errsb == NULL)
        atf_process_stream_fini(&inherit_errsb);
out_out:
    if (outsb == NULL)
        atf_process_stream_fini(&inherit_outsb);
out:
    return err;
}
Beispiel #5
0
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));
    }
}
Beispiel #6
0
static
atf_error_t
normalize_ap(atf_dynstr_t *d, const char *p, va_list ap)
{
    char *str;
    atf_error_t err;
    va_list ap2;

    err = atf_dynstr_init(d);
    if (atf_is_error(err))
        goto out;

    va_copy(ap2, ap);
    err = atf_text_format_ap(&str, p, ap2);
    va_end(ap2);
    if (atf_is_error(err))
        atf_dynstr_fini(d);
    else {
        err = normalize(d, str);
        free(str);
    }

out:
    return err;
}
Beispiel #7
0
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);
}
Beispiel #8
0
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;
}
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);
}
Beispiel #10
0
static
atf_error_t
fork_with_streams(atf_process_child_t *c,
                  void (*start)(void *),
                  const atf_process_stream_t *outsb,
                  const atf_process_stream_t *errsb,
                  void *v)
{
    atf_error_t err;
    stream_prepare_t outsp;
    stream_prepare_t errsp;
    pid_t pid;

    err = stream_prepare_init(&outsp, outsb);
    if (atf_is_error(err))
        goto out;

    err = stream_prepare_init(&errsp, errsb);
    if (atf_is_error(err))
        goto err_outpipe;

    pid = fork();
    if (pid == -1) {
        err = atf_libc_error(errno, "Failed to fork");
        goto err_errpipe;
    }

    if (pid == 0) {
        do_child(start, v, &outsp, &errsp);
        UNREACHABLE;
        abort();
        err = atf_no_error();
    } else {
        err = do_parent(c, pid, &outsp, &errsp);
        if (atf_is_error(err))
            goto err_errpipe;
    }

    goto out;

err_errpipe:
    stream_prepare_fini(&errsp);
err_outpipe:
    stream_prepare_fini(&outsp);

out:
    return err;
}
Beispiel #11
0
static
atf_error_t
controlled_main(int argc, char **argv,
                atf_error_t (*add_tcs_hook)(atf_tp_t *),
                int *exitcode)
{
    atf_error_t err;
    struct params p;
    atf_tp_t tp;
    char **raw_config;

    err = process_params(argc, argv, &p);
    if (atf_is_error(err))
        goto out;

    err = handle_srcdir(&p);
    if (atf_is_error(err))
        goto out_p;

    raw_config = atf_map_to_charpp(&p.m_config);
    if (raw_config == NULL) {
        err = atf_no_memory_error();
        goto out_p;
    }
    err = atf_tp_init(&tp, (const char* const*)raw_config);
    atf_utils_free_charpp(raw_config);
    if (atf_is_error(err))
        goto out_p;

    err = add_tcs_hook(&tp);
    if (atf_is_error(err))
        goto out_tp;

    if (p.m_do_list) {
        list_tcs(&tp);
        INV(!atf_is_error(err));
        *exitcode = EXIT_SUCCESS;
    } else {
        err = run_tc(&tp, &p, exitcode);
    }

out_tp:
    atf_tp_fini(&tp);
out_p:
    params_fini(&p);
out:
    return err;
}
Beispiel #12
0
impl::stream_redirect_path::stream_redirect_path(const fs::path& p)
{
    atf_error_t err = atf_process_stream_init_redirect_path(&m_sb, p.c_path());
    if (atf_is_error(err))
        throw_atf_error(err);
    m_inited = true;
}
Beispiel #13
0
impl::stream_capture::stream_capture(void)
{
    atf_error_t err = atf_process_stream_init_capture(&m_sb);
    if (atf_is_error(err))
        throw_atf_error(err);
    m_inited = true;
}
Beispiel #14
0
impl::stream_redirect_fd::stream_redirect_fd(const int fd)
{
    atf_error_t err = atf_process_stream_init_redirect_fd(&m_sb, fd);
    if (atf_is_error(err))
        throw_atf_error(err);
    m_inited = true;
}
ATF_TC_BODY(no_error, tc)
{
    atf_error_t err;

    err = atf_no_error();
    ATF_REQUIRE(!atf_is_error(err));
}
Beispiel #16
0
impl::stream_connect::stream_connect(const int src_fd, const int tgt_fd)
{
    atf_error_t err = atf_process_stream_init_connect(&m_sb, src_fd, tgt_fd);
    if (atf_is_error(err))
        throw_atf_error(err);
    m_inited = true;
}
Beispiel #17
0
void
impl::set(const std::string& name, const std::string& val)
{
    atf_error_t err = atf_env_set(name.c_str(), val.c_str());
    if (atf_is_error(err))
        throw_atf_error(err);
}
Beispiel #18
0
atf_error_t
atf_env_set(const char *name, const char *val)
{
    atf_error_t err;

#if defined(HAVE_SETENV)
    if (setenv(name, val, 1) == -1)
        err = atf_libc_error(errno, "Cannot set environment variable "
                             "'%s' to '%s'", name, val);
    else
        err = atf_no_error();
#elif defined(HAVE_PUTENV)
    char *buf;

    err = atf_text_format(&buf, "%s=%s", name, val);
    if (!atf_is_error(err)) {
        if (putenv(buf) == -1)
            err = atf_libc_error(errno, "Cannot set environment variable "
                                 "'%s' to '%s'", name, val);
        free(buf);
    }
#else
#   error "Don't know how to set an environment variable."
#endif

    return err;
}
Beispiel #19
0
static
atf_error_t
normalize(atf_dynstr_t *d, char *p)
{
    const char *ptr;
    char *last;
    atf_error_t err;
    bool first;

    PRE(strlen(p) > 0);
    PRE(atf_dynstr_length(d) == 0);

    if (p[0] == '/')
        err = atf_dynstr_append_fmt(d, "/");
    else
        err = atf_no_error();

    first = true;
    last = NULL; /* Silence GCC warning. */
    ptr = strtok_r(p, "/", &last);
    while (!atf_is_error(err) && ptr != NULL) {
        if (strlen(ptr) > 0) {
            err = atf_dynstr_append_fmt(d, "%s%s", first ? "" : "/", ptr);
            first = false;
        }

        ptr = strtok_r(NULL, "/", &last);
    }

    return err;
}
Beispiel #20
0
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;
}
Beispiel #21
0
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);
    }
}
Beispiel #22
0
void
impl::unset(const std::string& name)
{
    atf_error_t err = atf_env_unset(name.c_str());
    if (atf_is_error(err))
        throw_atf_error(err);
}
Beispiel #23
0
impl::stream_inherit::stream_inherit(void)
{
    atf_error_t err = atf_process_stream_init_inherit(&m_sb);
    if (atf_is_error(err))
        throw_atf_error(err);
    m_inited = true;
}
Beispiel #24
0
atf_error_t
atf_text_for_each_word(const char *instr, const char *sep,
                       atf_error_t (*func)(const char *, void *),
                       void *data)
{
    atf_error_t err;
    char *str, *str2, *last;

    str = strdup(instr);
    if (str == NULL) {
        err = atf_no_memory_error();
        goto out;
    }

    err = atf_no_error();
    str2 = strtok_r(str, sep, &last);
    while (str2 != NULL && !atf_is_error(err)) {
        err = func(str2, data);
        str2 = strtok_r(NULL, sep, &last);
    }

    free(str);
out:
    return err;
}
Beispiel #25
0
/** Searches for a regexp in a file.
 *
 * \param regex The regexp to look for.
 * \param file The file in which to look for the expression.
 * \param ... Positional parameters to the regex.
 *
 * \return True if there is a match; false otherwise. */
bool
atf_utils_grep_file(const char *regex, const char *file, ...)
{
    int fd;
    va_list ap;
    atf_dynstr_t formatted;
    atf_error_t error;

    va_start(ap, file);
    error = atf_dynstr_init_ap(&formatted, regex, ap);
    va_end(ap);
    ATF_REQUIRE(!atf_is_error(error));

    ATF_REQUIRE((fd = open(file, O_RDONLY)) != -1);
    bool found = false;
    char *line = NULL;
    while (!found && (line = atf_utils_readline(fd)) != NULL) {
        found = grep_string(atf_dynstr_cstring(&formatted), line);
        free(line);
    }
    close(fd);

    atf_dynstr_fini(&formatted);

    return found;
}
Beispiel #26
0
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;
}
Beispiel #27
0
atf_error_t
atf_text_split(const char *str, const char *delim, atf_list_t *words)
{
    atf_error_t err;
    const char *end;
    const char *iter;

    err = atf_list_init(words);
    if (atf_is_error(err))
        goto err;

    end = str + strlen(str);
    INV(*end == '\0');
    iter = str;
    while (iter < end) {
        const char *ptr;

        INV(iter != NULL);
        ptr = strstr(iter, delim);
        if (ptr == NULL)
            ptr = end;

        INV(ptr >= iter);
        if (ptr > iter) {
            atf_dynstr_t word;

            err = atf_dynstr_init_raw(&word, iter, ptr - iter);
            if (atf_is_error(err))
                goto err_list;

            err = atf_list_append(words, atf_dynstr_fini_disown(&word), true);
            if (atf_is_error(err))
                goto err_list;
        }

        iter = ptr + strlen(delim);
    }

    INV(!atf_is_error(err));
    return err;

err_list:
    atf_list_fini(words);
err:
    return err;
}
Beispiel #28
0
static
atf_error_t
srcdir_strip_libtool(atf_fs_path_t *srcdir)
{
    atf_error_t err;
    atf_fs_path_t parent;

    err = atf_fs_path_branch_path(srcdir, &parent);
    if (atf_is_error(err))
        goto out;

    atf_fs_path_fini(srcdir);
    *srcdir = parent;

    INV(!atf_is_error(err));
out:
    return err;
}
Beispiel #29
0
atf_error_t
atf_fs_path_to_absolute(const atf_fs_path_t *p, atf_fs_path_t *pa)
{
    atf_error_t err;

    PRE(!atf_fs_path_is_absolute(p));

    err = atf_fs_getcwd(pa);
    if (atf_is_error(err))
        goto out;

    err = atf_fs_path_append_path(pa, p);
    if (atf_is_error(err))
        atf_fs_path_fini(pa);

out:
    return err;
}
Beispiel #30
0
static
atf_error_t
mkstemp_discard_fd(atf_fs_path_t *p)
{
    int fd;
    atf_error_t err = atf_fs_mkstemp(p, &fd);
    if (!atf_is_error(err))
        close(fd);
    return err;
}