Exemple #1
0
SXE_RETURN
sxe_hex_to_bytes(unsigned char * bytes, const char * hex, unsigned hex_length)
{
    SXE_RETURN result = SXE_RETURN_ERROR_INTERNAL;
    unsigned   i;
    char       character;
    unsigned   nibble_high;
    unsigned   nibble_low;

    SXEA1((hex_length % 1) == 0, "sxe_hex_to_bytes: hex string length %u is odd", hex_length);
    SXEE6("(bytes=%p,hex='%.*s',hex_length=%u)", bytes, hex_length, hex, hex_length);

    for (i = 0; i < hex_length; i++) {
        if (((nibble_high = hex_character_to_nibble[(unsigned)(character = hex[  i])]) == NA)
         || ((nibble_low  = hex_character_to_nibble[(unsigned)(character = hex[++i])]) == NA))
        {
            SXEL3(isprint(character) ? "%s%c'" : "%s\\x%02x'", "sxe_hex_to_bytes: Unexpected hex character '", hex[i]);
            goto SXE_EARLY_OUT;
        }

        bytes[(i - 1) / 2] = (nibble_high << 4) | nibble_low;
    }

    result = SXE_RETURN_OK;

SXE_EARLY_OUT:
    SXER6("return result=%s", sxe_return_to_string(result));
    return result;
}
Exemple #2
0
/**
 * Allocate and contruct a hash
 *
 * @param name          = Name of the hash, used in diagnostics
 * @param element_count = Maximum number of elements in the hash
 * @param element_size  = Size of each element in the hash in bytes
 * @param key_offset    = Offset of start of key from start of element in bytes
 * @param key_size      = Size of the key in bytes
 * @param options       = SXE_HASH_OPTION_UNLOCKED  | SXE_HASH_OPTION_LOCKED       (single threaded  or use locking)
 *                      + SXE_HASH_OPTION_PREHASHED | SXE_HASH_OPTION_LOOKUP3_HASH (key is prehashed or use lookup3)
 *
 * @return A pointer to an array of hash elements
 */
void *
sxe_hash_new_plus(const char * name, unsigned element_count, unsigned element_size, unsigned key_offset, unsigned key_size,
                  unsigned options)
{
    SXE_HASH * hash;
    unsigned   size;

    SXEE6("sxe_hash_new_plus(name=%s,element_count=%u,element_size=%u,key_offset=%u,key_size=%u,options=%u)", name, element_count,
           element_size, key_offset, key_size, options);
    size = sizeof(SXE_HASH) + sxe_pool_size(element_count, element_size, element_count + SXE_HASH_BUCKETS_RESERVED);
    SXEA1((hash = malloc(size)) != NULL, "Unable to allocate %u bytes of memory for hash %s", size, name);
    SXEL6("Base address of hash %s = %p", name, hash);

    /* Note: hash + 1 == pool base */
    hash->pool   = sxe_pool_construct(hash + 1, name, element_count, element_size, element_count + SXE_HASH_BUCKETS_RESERVED,
                                      options & SXE_HASH_OPTION_LOCKED ? SXE_POOL_OPTION_LOCKED : 0);
    hash->count      = element_count;
    hash->size       = element_size;
    hash->key_offset = key_offset;
    hash->key_size   = key_size;
    hash->options    = options;
    hash->hash_key   = options & SXE_HASH_OPTION_LOOKUP3_HASH ? lookup3_hash : sxe_prehashed_key_hash;

    SXER6("return array=%p", hash->pool);
    return hash->pool;
}
Exemple #3
0
static void
test_event_timeout(SXE_POOL_TCP * pool, void * info)
{
    SXEE6("%s(pool=%s, info=%p)", __func__, SXE_POOL_TCP_GET_NAME(pool), info);
    SXE_UNUSED_ARGUMENT(pool);
    SXE_UNUSED_ARGUMENT(info);
    SXEA1(0, "test_event_timeout should never be called in this test");
    SXER6("return");
}
static void
test_case(const char * tapname, const char * request, unsigned count)
{
    SXE  * client;
    tap_ev event;

    tap_test_case_name(tapname);

    SXEA1((client = test_new_tcp(NULL, "0.0.0.0", 0, client_connect, client_read, client_close)) != NULL,
            "Failed to allocate client SXE");
    SXEA1(sxe_connect(client, "127.0.0.1", SXE_LOCAL_PORT(listener)) == SXE_RETURN_OK, "Failed to connect to HTTPD");

#ifdef _WIN32
    usleep(10000);    /* Copied from test-errors.c and which is a TODO item */
#endif

    is_eq(test_tap_ev_queue_identifier_wait(q_client, TEST_WAIT, &event), "client_connect", "Got a client connected event");
    is(tap_ev_arg(event, "this"), client, "It's the client");
    is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_connect", "Got a server connected event");

    test_sxe_send(client, request, strlen(request), client_sent, "client_sent", q_client, TEST_WAIT, &event);

    if (count == 2) {
        is_eq(test_tap_ev_queue_identifier_wait(q_httpd , TEST_WAIT, &event), "h_header", "HTTPD: header event (a)"         );
        is_strncmp(tap_ev_arg(event, "key"  ), "Good"   , SXE_LITERAL_LENGTH( "Good"   ), "HTTPD: header was 'Good'"        );
        is_strncmp(tap_ev_arg(event, "value"), "Header" , SXE_LITERAL_LENGTH( "Header" ), "HTTPD: header value was 'Header'");

        is_eq(test_tap_ev_queue_identifier_wait(q_httpd , TEST_WAIT, &event), "h_header", "HTTPD: header event (b)"         );
        is_strncmp(tap_ev_arg(event, "key"  ), "Another", SXE_LITERAL_LENGTH( "Another"), "HTTPD: header was 'Another'"     );
        is_strncmp(tap_ev_arg(event, "value"), "Foo"    , SXE_LITERAL_LENGTH( "Foo"    ), "HTTPD: header value was 'Foo'"   );
    }

    is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_respond", "HTTPD: respond event");

    sxe_close(client);
    is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_close", "HTTPD: close event");
}
SXE_RETURN
sxe_mkpath(const char * path)
{
    SXE_RETURN  result = SXE_RETURN_ERROR_INTERNAL;
    char        command[PATH_MAX + sizeof(MKDIR_COMMAND) + 1];
    struct stat filestat;
#ifdef _WIN32
    unsigned    command_length;
    unsigned    i;
#endif

    SXEA1(snprintf(command, sizeof(command), MKDIR_COMMAND " %s", path) >= 0, "Failed to format 'mkdir' command");

#ifdef _WIN32
    /* Remove slash termination (tossers at MS don't implement stat correctly)
     */
    command_length = strlen(command) - 1;

    if (command[command_length] == '/') {
        command[command_length] = '\0'; /* Coverage Exclusion - todo: win32 coverage */
    }

    for (i = command_length - 1; i >= sizeof(MKDIR_COMMAND); i--) {
        if (command[i] == '/') {
            command[i] = '\\';
        }
    }
#endif

    SXEL6("sxe_mkpath(): command '%s'", command, &command[sizeof(MKDIR_COMMAND)]);

    if (stat(&command[sizeof(MKDIR_COMMAND)], &filestat) >= 0) {
        SXEL6("sxe_mkpath(): '%s' already exists", path);
        result = SXE_RETURN_OK; /* COVERAGE EXCLUSION - harmless, and only happens on windows */
        goto SXE_EARLY_OUT;     /* COVERAGE EXCLUSION - harmless, and only happens on windows */
    }

    if (system(command) == 0) {
        result = SXE_RETURN_OK;
    }
SXE_EARLY_OUT:
    return result;
}
Exemple #6
0
int
main(int argc, char ** argv)
{
    int             fd;
    double          start_time;
    unsigned        count = 0;                   /* e.g. master=0, slaves=1, 2, 3, etc */
    char          * unique_memmap_path_and_file; /* e.g. /tmp/test-sxe-pool-mmap-pid-1234.bin */
    char            unique_memmap_path_and_file_master_buffer[PATH_MAX];
    unsigned        unique_memmap_path_and_file_master_buffer_used;
    unsigned        id;
    unsigned      * pool;
    unsigned      * shared;
    size_t          size;
    SXE_MMAP        memmap;
    int             child[TEST_CLIENT_INSTANCES];
    SXE_POOL_WALKER walker;

    putenv(SXE_CAST_NOCONST(char *, "SXE_LOG_LEVEL_LIBSXE_LIB_SXE_POOL=5"));    /* Set to 5 to suppress sxe-pool debug logging since this is kind of a stress test */
    putenv(SXE_CAST_NOCONST(char *, "SXE_LOG_LEVEL_LIBSXE_LIB_SXE_LIST=5"));    /* Set to 5 to suppress sxe-list debug logging since this is kind of a stress test */

    if (argc > 1) {
        count                       = atoi(argv[1]);
        unique_memmap_path_and_file =      argv[2] ;

        SXEL1("Instance %2u unique memmap path and file: %s", count, unique_memmap_path_and_file);
        sxe_mmap_open(&memmap, unique_memmap_path_and_file);
        shared  = SXE_CAST(unsigned *, SXE_MMAP_ADDR(&memmap));
        pool    = sxe_pool_from_base(shared);
        SXEL6("Instance %2u mapped to shared pool // base=%p, pool=%p", count, shared, pool);

        do {
            usleep(10000 * count);
            id = sxe_pool_set_oldest_element_state(pool, TEST_STATE_FREE, TEST_STATE_CLIENT_TAKE);
            SXEA1(id != SXE_POOL_LOCK_NOT_TAKEN, "Got SXE_POOL_LOCK_NOT_TAKEN");;
        } while (id == SXE_POOL_NO_INDEX);

        SXEL6("Instance %2u got pool element %u", count, id);
        pool[id] = count;
        sxe_pool_set_indexed_element_state(pool, id, TEST_STATE_CLIENT_TAKE, TEST_STATE_CLIENT_DONE);
        sxe_mmap_close(&memmap);
        SXEL6("Instance %2u exiting", count);
        return 0;
    }
Exemple #7
0
SXE_RETURN
sha1_to_hex(SOPHOS_SHA1 * sha1, char * sha1_in_hex, unsigned sha1_in_hex_length)
{
    SXE_RETURN result = SXE_RETURN_OK;

    SXEE6("(sha1=%08x%08x%08x%08x%08x,sha1_in_hex='%p',sha1_in_hex_length='%u'",
           sha1->word[4], sha1->word[3], sha1->word[2], sha1->word[1], sha1->word[0],
           sha1_in_hex, sha1_in_hex_length);
    SXEA1(sha1_in_hex_length == (SHA1_IN_HEX_LENGTH + 1), "Incorrect length of char * for sha1_to_hex(): '%u'", sha1_in_hex_length);

    snprintf(sha1_in_hex     , 9, "%08x", htonl(sha1->word[0]));
    snprintf(sha1_in_hex +  8, 9, "%08x", htonl(sha1->word[1]));
    snprintf(sha1_in_hex + 16, 9, "%08x", htonl(sha1->word[2]));
    snprintf(sha1_in_hex + 24, 9, "%08x", htonl(sha1->word[3]));
    snprintf(sha1_in_hex + 32, 9, "%08x", htonl(sha1->word[4]));
    SXEL6("sha1_in_hex: '%.*s'", SXE_CAST(int, SHA1_IN_HEX_LENGTH), sha1_in_hex);

    SXER6("return %s", sxe_return_to_string(result));
    return result;
}
int
main(void)
{

#if !TEST_DIRWATCH
/* TODO: Implement sxe_dirwatch() on Windows */
/* TODO: Implement sxe_dirwatch() on Apple */
/* TODO: Implement sxe_dirwatch() on FreeBSD */
#else

    char tempdir1[] = "tmp-XXXXXX";
    char tempdir2[] = "tmp-XXXXXX";
    char tempdir3[] = "tmp-XXXXXX";
    SXE_DIRWATCH dirwatch1;
    SXE_DIRWATCH dirwatch2;
    SXE_DIRWATCH dirwatch3;
    char fname[PATH_MAX];
    tap_ev ev;

    plan_tests(28);

    sxe_register(1, 0);
    sxe_init();

    /* We need to make a new temporary directory, because *everything* appears
     * to change willy-nilly during the build. The current directory has a
     * file that always changes. The /tmp directory always seems to have
     * spurious changes in it. */
    SXEA1(mkdtemp(tempdir1), "Failed to create tempdir: %s", strerror(errno));
    SXEA1(mkdtemp(tempdir2), "Failed to create tempdir: %s", strerror(errno));
    SXEA1(mkdtemp(tempdir3), "Failed to create tempdir: %s", strerror(errno));

    sxe_dirwatch_init();
    sxe_dirwatch_init(); /* for coverage */
    sxe_dirwatch_add(&dirwatch1, tempdir1, SXE_DIRWATCH_CREATED|SXE_DIRWATCH_MODIFIED|SXE_DIRWATCH_DELETED, test_dirwatch_event, (void *)1);
    sxe_dirwatch_add(&dirwatch2, tempdir2, SXE_DIRWATCH_MODIFIED, test_dirwatch_event, (void *)2);
    sxe_dirwatch_add(&dirwatch3, tempdir3, SXE_DIRWATCH_DELETED, test_dirwatch_event, (void *)3);
    sxe_dirwatch_start();

    /* tempdir1: create, modify, delete */
    {
        char rname[PATH_MAX];
        int fd;

        snprintf(rname, sizeof rname, "%s/renamed", tempdir1);
        snprintf(fname, sizeof fname, "%s/created", tempdir1);

        fd = open(fname, O_CREAT|O_RDWR, S_IRWXU);
        write(fd, "Hello", 5);
        rename(fname, rname);
        unlink(rname);

        is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event",  "Got a dirwatch event");
        is_eq(tap_ev_arg(ev, "chfile"), "created",                                 "Got filename %s", fname);
        is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_CREATED,                        "Got flags=SXE_DIRWATCH_CREATED");
        is(tap_ev_arg(ev, "user_data"), 1,                                         "Got user_data=1 (%s)", tempdir1);

        is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event",  "Got a dirwatch event");
        is_eq(tap_ev_arg(ev, "chfile"), "created",                                 "Got filename %s", fname);
        is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_MODIFIED,                       "Got flags=SXE_DIRWATCH_MODIFIED");
        is(tap_ev_arg(ev, "user_data"), 1,                                         "Got user_data=1 (%s)", tempdir1);

        is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event",  "Got a dirwatch event");
        is_eq(tap_ev_arg(ev, "chfile"), "created",                                 "Got filename %s", fname);
        is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_DELETED,                        "Got flags=SXE_DIRWATCH_DELETED");
        is(tap_ev_arg(ev, "user_data"), 1,                                         "Got user_data=1 (%s)", tempdir1);

        is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event",  "Got a dirwatch event");
        is_eq(tap_ev_arg(ev, "chfile"), "renamed",                                 "Got filename %s", rname);
        is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_CREATED,                        "Got flags=SXE_DIRWATCH_CREATED");
        is(tap_ev_arg(ev, "user_data"), 1,                                         "Got user_data=1 (%s)", tempdir1);

        is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event",  "Got a dirwatch event");
        is_eq(tap_ev_arg(ev, "chfile"), "renamed",                                 "Got filename %s", rname);
        is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_DELETED,                        "Got flags=SXE_DIRWATCH_DELETED");
        is(tap_ev_arg(ev, "user_data"), 1,                                         "Got user_data=1 (%s)", tempdir1);
    }

    /* tempdir2: modified */
    {
        const char *rel;
        int fd;

        snprintf(fname, sizeof fname, "%s/file.XXXXXX", tempdir2);
        SXEA1((rel = strchr(fname, '/')), "Didn't find '/' in %s", fname);
        rel++;

        fd = mkstemp(fname);
        write(fd, "Hello", 5);
        unlink(fname);

        is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event",  "Got a dirwatch event");
        is_eq(tap_ev_arg(ev, "chfile"), rel,                                       "Got filename %s", fname);
        is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_MODIFIED,                       "Got flags=SXE_DIRWATCH_MODIFIED");
        is(tap_ev_arg(ev, "user_data"), 2,                                         "Got user_data=2 (%s)", tempdir2);
    }

    /* tempdir3: deleted */
    {
        const char *rel;
        int fd;

        snprintf(fname, sizeof fname, "%s/file.XXXXXX", tempdir3);
        SXEA1((rel = strchr(fname, '/')), "Didn't find '/' in %s", fname);
        rel++;

        fd = mkstemp(fname);
        unlink(fname);

        is_eq(test_tap_ev_identifier_wait(TEST_WAIT, &ev), "test_dirwatch_event",  "Got a dirwatch event");
        is_eq(tap_ev_arg(ev, "chfile"), rel,                                       "Got filename %s", fname);
        is(tap_ev_arg(ev, "chflags"), SXE_DIRWATCH_DELETED,                        "Got flags=SXE_DIRWATCH_DELETED");
        is(tap_ev_arg(ev, "user_data"), 3,                                         "Got user_data=3 (%s)", tempdir3);
    }

    rmdir(tempdir1);
    rmdir(tempdir2);
    rmdir(tempdir3);

    sxe_dirwatch_stop();

#endif
    return exit_status();
}
int
main(void)
{
    SXE_HTTPD_REQUEST      * request[TEST_BUFFER_COUNT];
    SXE                    * client[TEST_BUFFER_COUNT];
    tap_ev                   ev;
    SXE                    * listener;
    char                   * send_buffer;
    int                      i;

    SXEA1(send_buffer = malloc(TEST_SEND_BYTES), "Failed to allocate %u KB", TEST_SEND_BYTES);

    for (i = 0; i < TEST_SEND_BYTES; i++) {
        send_buffer[i] = 'A';
    }

    tap_plan(33, TAP_FLAG_ON_FAILURE_EXIT, NULL);
    test_sxe_register_and_init(TEST_BUFFER_COUNT * 2 + 1);

    sxe_httpd_construct(&httpd, TEST_BUFFER_COUNT + 1, TEST_BUFFER_COUNT, TEST_BUFFER_SIZE, 0);
    SXE_HTTPD_SET_HANDLER(&httpd, respond, h_respond);

    SXEA1((listener = test_httpd_listen(&httpd, "0.0.0.0", 0)) != NULL,                         "sxe_httpd_listen failed");

    tap_test_case_name("connecting 10 clients");
    for (i = 0; i < TEST_BUFFER_COUNT; i++) {
        SXEA1((client[i] = test_new_tcp(NULL, "0.0.0.0", 0, client_connect, client_read, NULL)) != NULL, "sxe_new_tcp failed");
        sxe_connect(client[i], "127.0.0.1", SXE_LOCAL_PORT(listener));

#define TEST_GET "GET / HTTP/1.1\r\n\r\n"

        is_eq(test_tap_ev_queue_identifier_wait(q_client, TEST_WAIT, &ev), "client_connect",      "client[%d] connected to HTTPD", i);
        TEST_SXE_SEND_LITERAL(client[i], TEST_GET, client_sent, q_client, TEST_WAIT, &ev);

        is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &ev),            "h_respond", "HTTPD[%d] respond event", i);
        request[i] = SXE_CAST_NOCONST(SXE_HTTPD_REQUEST *, tap_ev_arg(ev, "request"));
    }

    tap_test_case_name("response_copy_body_data() runs out");
    {
        SXE_RETURN ret = SXE_RETURN_OK;

        sxe_httpd_response_start(request[0], 200, "OK");

        /* When we copy body data, we try to immediately send each buffer. If
         * it succeeds, we may not actually run out of buffers, because as the
         * buffers are depleted they are freed again. Eventually, though,
         * we'll fill the kernel's TCP output buffers.
         */
        for (i = 0; i < TEST_SEND_COUNT && ret == SXE_RETURN_OK; i++) {
            ret = sxe_httpd_response_copy_body_data(request[0], send_buffer, TEST_SEND_BYTES);
        }
        is(ret, SXE_RETURN_NO_UNUSED_ELEMENTS, "HTTPD: response ran out of buffers after sending %d bytes %d times", TEST_SEND_BYTES, i);

        /* NOTE: you get an assertion if you call sxe_httpd_response_end() after
         * we've run out of buffers, because the last valid buffer has been send,
         * and no other buffers are available, so request->out_buffer == NULL. Not
         * sure what to do in this case... I guess we could queue a zero-length
         * buffer? Although we're out of buffers...
         */
#if NOT_SURE_WHAT_TO_DO_HERE
        sxe_httpd_response_end(request[0], h_sent, NULL);
#endif
    }

    tap_test_case_name("response_start() runs out of buffers");
    {
        is(sxe_httpd_response_start(request[1], 200, "OK"), SXE_RETURN_NO_UNUSED_ELEMENTS, "response_start() ran out of buffers");
        sxe_httpd_close(request[1]);
        sxe_close(client[1]);
    }

    tap_test_case_name("response_simple() runs out of buffers during response_start()");
    {
        is(sxe_httpd_response_simple(request[2], NULL, NULL, 200, "OK", "", NULL), SXE_RETURN_NO_UNUSED_ELEMENTS, "response_simple() ran out of buffers");
        sxe_httpd_close(request[2]);
        sxe_close(client[2]);
    }

    /* TODO: because there are as many buffers as there are clients, we should
     * be able to test all combinations of places where we can run out of
     * buffers. We just need to ensure that all clients now call
     * response_start(), so that all have a buffer allocated. Then we can do
     * things like call sxe_httpd_response_header() with enough headers to
     * fill up the buffer and grab another one, which will fail because there
     * are no more buffers free... as long as the send does not complete
     * immediately. Perhaps it's worth mocking send() so that it always
     * returns a blocking answer?
     */

    sxe_httpd_close(request[0]);
    sxe_close(client[0]);

    return exit_status();
}
Exemple #10
0
int
main(void)
{
    SXE_HTTPD    httpd;
    SXE        * client;
    SXE        * client2;
    SXE        * server;
    SXE        * server2;
    tap_ev       event;

    plan_tests(14);

    test_sxe_register_and_init(1000);

    sxe_httpd_construct(&httpd, 2, 10, 512, 0);
    SXE_HTTPD_SET_HANDLER(&httpd, connect, h_connect);
    SXE_HTTPD_SET_HANDLER(&httpd, request, h_request);
    SXE_HTTPD_SET_HANDLER(&httpd, close,   h_close);
    ok((listener = test_httpd_listen(&httpd, "0.0.0.0", 0)) != NULL,                              "HTTPD listening");

    /* Starts two connections, then make a new connection, the oldest will be reaped by the server */
    tap_test_case_name("reap connections");

    /* 1st connection */
    SXEA1((client = test_new_tcp(NULL, "0.0.0.0", 0, client_connect, client_read, client_close)) != NULL,
           "Failed to allocate client SXE");
    SXEA1(sxe_connect(client, "127.0.0.1", SXE_LOCAL_PORT(listener)) == SXE_RETURN_OK,          "Failed to connect to HTTPD");
    is_eq(test_tap_ev_queue_identifier_wait(q_client, TEST_WAIT, &event), "client_connect", "Got 1st client connected event");
    is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_connect",     "Got 1st server connect event");
    server = SXE_CAST(SXE *, tap_ev_arg(event, "this"));

    /* 1st client: send a complete request line */
    TEST_SXE_SEND_LITERAL(client, "GET /good HTTP/1.1\r\n", client_sent, q_client, TEST_WAIT, &event);

    /* Waiting for 1st client request state "stable" on "STATE_HEADER" to make
     * sure there is no more state updates on this request object, then the following
     * usleep will guarantee the 1st connection is older than the 2nd one.
     */
    is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_request",     "Got 1st server request event");
    is(tap_ev_arg(event, "this"), server,                                                        "It's the 1st server");
    usleep(300000);

    /* 2nd connection, reaping happens, the 1st one got reaped */
    SXEA1((client2 = test_new_tcp(NULL, "0.0.0.0", 0, client_connect, client_read, client_close)) != NULL,
           "Failed to allocate client SXE");
    SXEA1(sxe_connect(client2, "127.0.0.1", SXE_LOCAL_PORT(listener)) == SXE_RETURN_OK,         "Failed to connect to HTTPD");

    is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_connect",     "Got 2nd server connect event");
    server2 = SXE_CAST(SXE *, tap_ev_arg(event, "this"));
    is_eq(test_tap_ev_queue_identifier_wait(q_httpd, TEST_WAIT, &event), "h_close",       "Got a server close event");
    is(tap_ev_arg(event, "this"), server,                                                        "It's the 1st server");

    /* Pull these two arguments off in any order */
    test_process_all_libev_events();
    ok((event = tap_ev_queue_shift_next(q_client, "client_connect")) != NULL, "Got 2nd client connected event");
    ok((event = tap_ev_queue_shift_next(q_client, "client_close")) != NULL, "Got a client close event");
    is(tap_ev_arg(event, "this"), client,                                                        "It's the 1st client");

    is(tap_ev_queue_length(q_httpd),                                         0,                "No server events lurking");
    is(tap_ev_queue_length(q_client),                                         0,                "No client events lurking");

    sxe_close(listener);
    return exit_status();
}