src/test/fifo.c
author Tero Marttila <terom@fixme.fi>
Mon, 04 May 2009 20:55:04 +0300
branchnew-transport
changeset 168 a58ad50911fc
permissions -rw-r--r--
refactor test.c into tests/*
#include "test.h"
#include "../fifo.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

struct test_fifo_ctx {
    /** Path to the fifo */
    const char *path;

    /** The write end */
    int fd;

    /** callback invoked? */
    bool on_read;

    /** Still running? */
    bool run;
};

/**
 * Open the FIFO and write the test string to it
 */
static void test_fifo_open_write (struct test_fifo_ctx *ctx)
{
    // ...raw, for writing
    if ((ctx->fd = open(ctx->path, O_WRONLY)) < 0)
        FATAL_PERROR("open");

    // write something into it
    if (write(ctx->fd, "test", 4) != 4)
        FATAL_PERROR("write");
 
}

static void test_fifo_close (struct test_fifo_ctx *ctx)
{
    close(ctx->fd);
    ctx->fd = -1;
}

static void test_fifo_on_read (transport_t *fifo, void *arg)
{
    int ret;
    char buf[16];
    struct test_fifo_ctx *ctx = arg;
    error_t err;

    // read it back out
    log_info("test fifo_read");
    if ((ret = transport_read(fifo, buf, 16, &err)) < 0)
        assert_success(-ret);

    assert(ret == 4);
    assert_strncmp(buf, "test", 4);
 
    if (ctx->on_read) {
        test_fifo_close(ctx);
        ctx->run = false;
        return;
    }
   
    // re-open the fifo
    log_info("test fifo-re-open");
    test_fifo_close(ctx);
    test_fifo_open_write(ctx);

    ctx->on_read = true;
}

static struct transport_callbacks test_fifo_callbacks = {
    .on_read = test_fifo_on_read,
};

void test_fifo (void)
{
    transport_t *fifo;
    struct error_info err;
    struct test_fifo_ctx _ctx, *ctx = &_ctx; memset(ctx, 0, sizeof(*ctx));
    struct transport_info info = { &test_fifo_callbacks, ctx, TRANSPORT_READ };

    // XXX: requires that this be run in a suitable CWD
    ctx->path = "test.fifo";

    // create the fifo
    if ((mkfifo(ctx->path, 0600) < 0) && (errno != EEXIST))
        FATAL_PERROR("mkfifo");

    // open it
    log_info("test fifo_open_read");
    assert_success(fifo_open_read(&info, &fifo, _test_ctx.ev_base, ctx->path, &err));
    
    // put some data into it
    test_fifo_open_write(ctx);
   
    // run the event loop
    log_debug("running the event loop...");
    ctx->run = true;

    while (ctx->run)
        assert(event_base_loop(_test_ctx.ev_base, EVLOOP_ONCE) == 0);

    // check
    assert(ctx->fd < 0);
    
    // cleanup
    transport_destroy(fifo);
}