/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "testutil.h"
#include "apr.h"
#include "apu.h"
#include "apr_general.h"
#include "apr_strings.h"
#include "apr_hash.h"
#include "apr_memcache.h"
#include "apr_network_io.h"
#include "apr_thread_proc.h"
#include "apr_signal.h"
#include "testmemcache.h"

#if APR_HAVE_STDLIB_H
#include <stdlib.h>             /* for exit() */
#endif
#if APR_HAVE_PROCESS_H
#include <process.h>            /* for getpid() */
#endif

#define HOST "localhost"
#define PORT 11211

/* the total number of items to use for set/get testing */
#define TDATA_SIZE 3000

/* some smaller subset of TDATA_SIZE used for multiget testing */
#define TDATA_SET 100

/* our custom hash function just returns this all the time */
#define HASH_FUNC_RESULT 510

/* all keys will be prefixed with this */
const char prefix[] = "testmemcache";

/* text for values we store */
const char txt[] =
"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis at"
"lacus in ligula hendrerit consectetuer. Vestibulum tristique odio"
"iaculis leo. In massa arcu, ultricies a, laoreet nec, hendrerit non,"
"neque. Nulla sagittis sapien ac risus. Morbi ligula dolor, vestibulum"
"nec, viverra id, placerat dapibus, arcu. Curabitur egestas feugiat"
"tellus. Donec dignissim. Nunc ante. Curabitur id lorem. In mollis"
"tortor sit amet eros auctor dapibus. Proin nulla sem, tristique in,"
"convallis id, iaculis feugiat cras amet.";

/*
 * this datatype is for our custom server determination function. this might
 * be useful if you don't want to rely on simply hashing keys to determine
 * where a key belongs, but instead want to write something fancy, or use some
 * other kind of configuration data, i.e. a hash plus some data about a
 * namespace, or whatever. see my_server_func, and test_memcache_user_funcs
 * for the examples.
 */
typedef struct {
  const char *someval;
  apr_uint32_t which_server;
} my_hash_server_baton;


/* this could do something fancy and return some hash result.
 * for simplicity, just return the same value, so we can test it later on.
 * if you wanted to use some external hashing library or functions for
 * consistent hashing, for example, this would be a good place to do it.
 */
static apr_uint32_t my_hash_func(void *baton, const char *data,
                                 apr_size_t data_len)
{

  return HASH_FUNC_RESULT;
}

/*
 * a fancy function to determine which server to use given some kind of data
 * and a hash value. this example actually ignores the hash value itself
 * and pulls some number from the *baton, which is a struct that has some
 * kind of meaningful stuff in it.
 */
static apr_memcache_server_t *my_server_func(void *baton,
                                             apr_memcache_t *mc,
                                             const apr_uint32_t hash)
{
  apr_memcache_server_t *ms = NULL;
  my_hash_server_baton *mhsb = (my_hash_server_baton *)baton;

  if(mc->ntotal == 0) {
    return NULL;
  }

  if(mc->ntotal < mhsb->which_server) {
    return NULL;
  }

  ms = mc->live_servers[mhsb->which_server - 1];

  return ms;
}

apr_uint16_t firsttime = 0;
static int randval(apr_uint32_t high)
{
    apr_uint32_t i = 0;
    double d = 0;

    if (firsttime == 0) {
        srand((unsigned) (getpid()));
        firsttime = 1;
    }

    d = (double) rand() / ((double) RAND_MAX + 1);
    i = (int) (d * (high - 0 + 1));

    return i > 0 ? i : 1;
}

/* use apr_socket stuff to see if there is in fact a memcached server
 * running on PORT.
 */
static apr_status_t check_mc(void)
{
    apr_pool_t *pool = p;
    apr_status_t rv;
    apr_socket_t *sock = NULL;
    apr_sockaddr_t *sa;
    struct iovec vec[2];
    apr_size_t written;
    char buf[128];
    apr_size_t len;

    rv = apr_socket_create(&sock, APR_INET, SOCK_STREAM, 0, pool);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = apr_sockaddr_info_get(&sa, HOST, APR_INET, PORT, 0, pool);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = apr_socket_timeout_set(sock, 1 * APR_USEC_PER_SEC);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = apr_socket_connect(sock, sa);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    rv = apr_socket_timeout_set(sock, -1);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    vec[0].iov_base = "version";
    vec[0].iov_len = sizeof("version") - 1;

    vec[1].iov_base = "\r\n";
    vec[1].iov_len = sizeof("\r\n") - 1;

    rv = apr_socket_sendv(sock, vec, 2, &written);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    len = sizeof(buf);
    rv = apr_socket_recv(sock, buf, &len);
    if (rv != APR_SUCCESS) {
        return rv;
    }

    if (strncmp(buf, "VERSION", sizeof("VERSION") - 1) != 0) {
        rv = APR_EGENERAL;
    }

    apr_socket_close(sock);
    return rv;
}

static int has_memcache_server(void)
{
    static int has_memcache_server_state = -1;

    if (has_memcache_server_state < 0) {
        apr_status_t rv;

        /* check for a running memcached on the typical port before
         * trying to run the tests. succeed if we don't find one.
         */
        rv = check_mc();
        if (rv == APR_SUCCESS) {
            has_memcache_server_state = 1;
        }
        else {
            has_memcache_server_state = 0;
            abts_log_message("Error %d occurred attempting to reach memcached "
                             "on %s:%d.  Skipping apr_memcache tests...",
                             rv, HOST, PORT);
        }
    }

    return has_memcache_server_state;
}
/*
 * general test to make sure we can create the memcache struct and add
 * some servers, but not more than we tell it we can add
 */

static void test_memcache_create(abts_case * tc, void *data)
{
  apr_pool_t *pool = p;
  apr_status_t rv;
  apr_memcache_t *memcache;
  apr_memcache_server_t *server, *s;
  apr_uint32_t max_servers = 10;
  apr_uint32_t i;
  apr_uint32_t hash;

  if (!has_memcache_server()) {
      ABTS_SKIP(tc, data, "Memcache server not found.");
      return;
  }

  rv = apr_memcache_create(pool, max_servers, 0, &memcache);
  ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

  for (i = 1; i <= max_servers; i++) {
    apr_port_t port;

    port = PORT + i;
    rv =
      apr_memcache_server_create(pool, HOST, PORT + i, 0, 1, 1,
                                 apr_time_from_sec(60), &server);
    ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

    rv = apr_memcache_add_server(memcache, server);
    ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

    s = apr_memcache_find_server(memcache, HOST, port);
    ABTS_PTR_EQUAL(tc, server, s);

    rv = apr_memcache_disable_server(memcache, s);
    ABTS_ASSERT(tc, "server disable failed", rv == APR_SUCCESS);

    rv = apr_memcache_enable_server(memcache, s);
    ABTS_ASSERT(tc, "server enable failed", rv == APR_SUCCESS);

    hash = apr_memcache_hash(memcache, prefix, strlen(prefix));
    ABTS_ASSERT(tc, "hash failed", hash > 0);

    s = apr_memcache_find_server_hash(memcache, hash);
    ABTS_PTR_NOTNULL(tc, s);
  }

  rv = apr_memcache_server_create(pool, HOST, PORT, 0, 1, 1,
                                  apr_time_from_sec(60), &server);
  ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

  rv = apr_memcache_add_server(memcache, server);
  ABTS_ASSERT(tc, "server add should have failed", rv != APR_SUCCESS);

}

/* install our own custom hashing and server selection routines. */

static int create_test_hash(apr_pool_t *p, apr_hash_t *h)
{
  int i;

  for (i = 0; i < TDATA_SIZE; i++) {
    char *k, *v;

    k = apr_pstrcat(p, prefix, apr_itoa(p, i), NULL);
    v = apr_pstrndup(p, txt, randval((apr_uint32_t)strlen(txt)));

    apr_hash_set(h, k, APR_HASH_KEY_STRING, v);
  }

  return i;
}

static void test_memcache_user_funcs(abts_case * tc, void *data)
{
  apr_pool_t *pool = p;
  apr_status_t rv;
  apr_memcache_t *memcache;
  apr_memcache_server_t *found;
  apr_uint32_t max_servers = 10;
  apr_uint32_t hres;
  apr_uint32_t i;
  my_hash_server_baton *baton =
    apr_pcalloc(pool, sizeof(my_hash_server_baton));

  if (!has_memcache_server()) {
      ABTS_SKIP(tc, data, "Memcache server not found.");
      return;
  }

  rv = apr_memcache_create(pool, max_servers, 0, &memcache);
  ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

  /* as noted above, install our custom hash function, and call
   * apr_memcache_hash. the return value should be our predefined number,
   * and our function just ignores the other args, for simplicity.
   */
  memcache->hash_func = my_hash_func;

  hres = apr_memcache_hash(memcache, "whatever", sizeof("whatever") - 1);
  ABTS_INT_EQUAL(tc, HASH_FUNC_RESULT, hres);

  /* add some servers */
  for(i = 1; i <= 10; i++) {
    apr_memcache_server_t *ms;

    rv = apr_memcache_server_create(pool, HOST, i, 0, 1, 1,
                                    apr_time_from_sec(60), &ms);
    ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

    rv = apr_memcache_add_server(memcache, ms);
    ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);
  }

  /*
   * set 'which_server' in our server_baton to find the third server
   * which should have the same port.
   */
  baton->which_server = 3;
  memcache->server_func = my_server_func;
  memcache->server_baton = baton;
  found = apr_memcache_find_server_hash(memcache, 0);
  ABTS_ASSERT(tc, "wrong server found", found->port == baton->which_server);
}

/* test non data related commands like stats and version */
static void test_memcache_meta(abts_case * tc, void *data)
{
    apr_pool_t *pool = p;
    apr_memcache_t *memcache;
    apr_memcache_server_t *server;
    apr_memcache_stats_t *stats;
    char *result;
    apr_status_t rv;

    if (!has_memcache_server()) {
        ABTS_SKIP(tc, data, "Memcache server not found.");
        return;
    }

    rv = apr_memcache_create(pool, 1, 0, &memcache);
    ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

    rv = apr_memcache_server_create(pool, HOST, PORT, 0, 1, 1,
                                    apr_time_from_sec(60), &server);
    ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

    rv = apr_memcache_add_server(memcache, server);
    ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

    apr_memcache_version(server, pool, &result);
    ABTS_PTR_NOTNULL(tc, result);

    apr_memcache_stats(server, p, &stats);
    ABTS_PTR_NOTNULL(tc, stats);

    ABTS_STR_NEQUAL(tc, stats->version, result, 5);

    /*
     * no way to know exactly what will be in most of these, so
     * just make sure there is something.
     */

    ABTS_ASSERT(tc, "pid", stats->pid >= 0);
    ABTS_ASSERT(tc, "time", stats->time >= 0);
    /* ABTS_ASSERT(tc, "pointer_size", stats->pointer_size >= 0); */
    ABTS_ASSERT(tc, "rusage_user", stats->rusage_user >= 0);
    ABTS_ASSERT(tc, "rusage_system", stats->rusage_system >= 0);

    ABTS_ASSERT(tc, "curr_items", stats->curr_items >= 0);
    ABTS_ASSERT(tc, "total_items", stats->total_items >= 0);
    ABTS_ASSERT(tc, "bytes", stats->bytes >= 0);

    ABTS_ASSERT(tc, "curr_connections", stats->curr_connections >= 0);
    ABTS_ASSERT(tc, "total_connections", stats->total_connections >= 0);
    ABTS_ASSERT(tc, "connection_structures",
                stats->connection_structures >= 0);

    ABTS_ASSERT(tc, "cmd_get", stats->cmd_get >= 0);
    ABTS_ASSERT(tc, "cmd_set", stats->cmd_set >= 0);
    ABTS_ASSERT(tc, "get_hits", stats->get_hits >= 0);
    ABTS_ASSERT(tc, "get_misses", stats->get_misses >= 0);

    /* ABTS_ASSERT(tc, "evictions", stats->evictions >= 0); */

    ABTS_ASSERT(tc, "bytes_read", stats->bytes_read >= 0);
    ABTS_ASSERT(tc, "bytes_written", stats->bytes_written >= 0);
    ABTS_ASSERT(tc, "limit_maxbytes", stats->limit_maxbytes >= 0);

    /* ABTS_ASSERT(tc, "threads", stats->threads >= 0); */
}

/* test add and replace calls */

static void test_memcache_addreplace(abts_case * tc, void *data)
{
 apr_pool_t *pool = p;
 apr_status_t rv;
 apr_memcache_t *memcache;
 apr_memcache_server_t *server;
 apr_hash_t *tdata;
 apr_hash_index_t *hi;
 char *result;
 apr_size_t len;

  if (!has_memcache_server()) {
      ABTS_SKIP(tc, data, "Memcache server not found.");
      return;
  }

  rv = apr_memcache_create(pool, 1, 0, &memcache);
  ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

  rv = apr_memcache_server_create(pool, HOST, PORT, 0, 1, 1,
                                  apr_time_from_sec(60), &server);
  ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

  rv = apr_memcache_add_server(memcache, server);
  ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

  tdata = apr_hash_make(p);
  create_test_hash(pool, tdata);

  for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) {
    const void *k;
    void *v;
    const char *key;

    apr_hash_this(hi, &k, NULL, &v);
    key = k;

    /* doesn't exist yet, fail */
    rv = apr_memcache_replace(memcache, key, v, strlen(v) - 1, 0, 27);
    ABTS_ASSERT(tc, "replace should have failed", rv != APR_SUCCESS);

    /* doesn't exist yet, succeed */
    rv = apr_memcache_add(memcache, key, v, strlen(v), 0, 27);
    ABTS_ASSERT(tc, "add failed", rv == APR_SUCCESS);

    /* exists now, succeed */
    rv = apr_memcache_replace(memcache, key, "new", sizeof("new") - 1, 0, 27);
    ABTS_ASSERT(tc, "replace failed", rv == APR_SUCCESS);

    /* make sure its different */
    rv = apr_memcache_getp(memcache, pool, key, &result, &len, NULL);
    ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS);
    ABTS_STR_NEQUAL(tc, result, "new", 3);

    /* exists now, fail */
    rv = apr_memcache_add(memcache, key, v, strlen(v), 0, 27);
    ABTS_ASSERT(tc, "add should have failed", rv != APR_SUCCESS);

    /* clean up */
    rv = apr_memcache_delete(memcache, key, 0);
    ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS);
  }
}

/* basic tests of the increment and decrement commands */
static void test_memcache_incrdecr(abts_case * tc, void *data)
{
 apr_pool_t *pool = p;
 apr_status_t rv;
 apr_memcache_t *memcache;
 apr_memcache_server_t *server;
 apr_uint32_t new;
 char *result;
 apr_size_t len;
 apr_uint32_t i;

  if (!has_memcache_server()) {
      ABTS_SKIP(tc, data, "Memcache server not found.");
      return;
  }

  rv = apr_memcache_create(pool, 1, 0, &memcache);
  ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

  rv = apr_memcache_server_create(pool, HOST, PORT, 0, 1, 1,
                                  apr_time_from_sec(60), &server);
  ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

  rv = apr_memcache_add_server(memcache, server);
  ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

  rv = apr_memcache_set(memcache, prefix, "271", sizeof("271") - 1, 0, 27);
  ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS);

  for( i = 1; i <= TDATA_SIZE; i++) {
    apr_uint32_t expect;

    rv = apr_memcache_getp(memcache, pool, prefix, &result, &len, NULL);
    ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS);

    expect = i + atoi(result);

    rv = apr_memcache_incr(memcache, prefix, i, &new);
    ABTS_ASSERT(tc, "incr failed", rv == APR_SUCCESS);

    ABTS_INT_EQUAL(tc, expect, new);

    rv = apr_memcache_decr(memcache, prefix, i, &new);
    ABTS_ASSERT(tc, "decr failed", rv == APR_SUCCESS);
    ABTS_INT_EQUAL(tc, atoi(result), new);

  }

  rv = apr_memcache_getp(memcache, pool, prefix, &result, &len, NULL);
  ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS);

  ABTS_INT_EQUAL(tc, 271, atoi(result));

  rv = apr_memcache_delete(memcache, prefix, 0);
  ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS);
}

/* test the multiget functionality */
static void test_memcache_multiget(abts_case * tc, void *data)
{
  apr_pool_t *pool = p;
  apr_pool_t *tmppool;
  apr_status_t rv;
  apr_memcache_t *memcache;
  apr_memcache_server_t *server;
  apr_hash_t *tdata, *values;
  apr_hash_index_t *hi;
  apr_uint32_t i;

  if (!has_memcache_server()) {
      ABTS_SKIP(tc, data, "Memcache server not found.");
      return;
  }

  rv = apr_memcache_create(pool, 1, 0, &memcache);
  ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

  rv = apr_memcache_server_create(pool, HOST, PORT, 0, 1, 1,
                                  apr_time_from_sec(60), &server);
  ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

  rv = apr_memcache_add_server(memcache, server);
  ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

  values = apr_hash_make(p);
  tdata = apr_hash_make(p);

  create_test_hash(pool, tdata);

  for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) {
    const void *k;
    void *v;
    const char *key;

    apr_hash_this(hi, &k, NULL, &v);
    key = k;

    rv = apr_memcache_set(memcache, key, v, strlen(v), 0, 27);
    ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS);
  }

  apr_pool_create(&tmppool, pool);
  for (i = 0; i < TDATA_SET; i++)
    apr_memcache_add_multget_key(pool,
                                 apr_pstrcat(pool, prefix,
                                             apr_itoa(pool, i), NULL),
                                 &values);

  rv = apr_memcache_multgetp(memcache,
                             tmppool,
                             pool,
                             values);

  ABTS_ASSERT(tc, "multgetp failed", rv == APR_SUCCESS);
  ABTS_ASSERT(tc, "multgetp returned too few results",
              apr_hash_count(values) == TDATA_SET);

  for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) {
    const void *k;
    const char *key;

    apr_hash_this(hi, &k, NULL, NULL);
    key = k;

    rv = apr_memcache_delete(memcache, key, 0);
    ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS);
  }

}

/* test setting and getting */

static void test_memcache_setget(abts_case * tc, void *data)
{
    apr_pool_t *pool = p;
    apr_status_t rv;
    apr_memcache_t *memcache;
    apr_memcache_server_t *server;
    apr_hash_t *tdata;
    apr_hash_index_t *hi;
    char *result;
    apr_size_t len;

    if (!has_memcache_server()) {
        ABTS_SKIP(tc, data, "Memcache server not found.");
        return;
    }

    rv = apr_memcache_create(pool, 1, 0, &memcache);
    ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

    rv = apr_memcache_server_create(pool, HOST, PORT, 0, 1, 1,
                                    apr_time_from_sec(60), &server);
    ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

    rv = apr_memcache_add_server(memcache, server);
    ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

    tdata = apr_hash_make(pool);

    create_test_hash(pool, tdata);

    for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) {
        const void *k;
        void *v;
        const char *key;

        apr_hash_this(hi, &k, NULL, &v);
        key = k;

        rv = apr_memcache_set(memcache, key, v, strlen(v), 0, 27);
        ABTS_ASSERT(tc, "set failed", rv == APR_SUCCESS);
        rv = apr_memcache_getp(memcache, pool, key, &result, &len, NULL);
        ABTS_ASSERT(tc, "get failed", rv == APR_SUCCESS);
    }

    rv = apr_memcache_getp(memcache, pool, "nothere3423", &result, &len, NULL);

    ABTS_ASSERT(tc, "get should have failed", rv != APR_SUCCESS);

    for (hi = apr_hash_first(p, tdata); hi; hi = apr_hash_next(hi)) {
        const void *k;
        const char *key;

        apr_hash_this(hi, &k, NULL, NULL);
        key = k;

        rv = apr_memcache_delete(memcache, key, 0);
        ABTS_ASSERT(tc, "delete failed", rv == APR_SUCCESS);
    }
}

static void test_connection_validation(abts_case *tc, void *data)
{
    apr_status_t rv;
    apr_memcache_t *memcache;
    apr_memcache_server_t *memserver;
    char *result;
    apr_procattr_t *procattr;
    apr_proc_t proc;
    const char *args[2];
    int exitcode;
    apr_exit_why_e why;
#ifdef SIGPIPE
    /*
     * If SIGPIPE is present ignore it as we will write to a closed socket.
     * Otherwise we would be terminated by the default handler for SIGPIPE.
     */
    apr_sigfunc_t *old_action;

    old_action = apr_signal(SIGPIPE, SIG_IGN);
#endif

    rv = apr_procattr_create(&procattr, p);
    ABTS_ASSERT(tc, "Couldn't create procattr", rv == APR_SUCCESS);

    rv = apr_procattr_io_set(procattr, APR_NO_PIPE, APR_NO_PIPE,
            APR_NO_PIPE);
    ABTS_ASSERT(tc, "Couldn't set io in procattr", rv == APR_SUCCESS);

    rv = apr_procattr_error_check_set(procattr, 1);
    ABTS_ASSERT(tc, "Couldn't set error check in procattr", rv == APR_SUCCESS);

    rv = apr_procattr_cmdtype_set(procattr, APR_PROGRAM_ENV);
    ABTS_ASSERT(tc, "Couldn't set copy environment", rv == APR_SUCCESS);

    args[0] = "memcachedmock" EXTENSION;
    args[1] = NULL;
    rv = apr_proc_create(&proc, TESTBINPATH "memcachedmock" EXTENSION, args, NULL,
                         procattr, p);
    ABTS_ASSERT(tc, "Couldn't launch program", rv == APR_SUCCESS);

    /* Wait for the mock memcached to start */
    apr_sleep(apr_time_from_sec(2));

    rv = apr_memcache_create(p, 1, 0, &memcache);
    ABTS_ASSERT(tc, "memcache create failed", rv == APR_SUCCESS);

    rv = apr_memcache_server_create(p, MOCK_HOST, MOCK_PORT, 0, 1, 1,
                                    apr_time_from_sec(60), &memserver);
    ABTS_ASSERT(tc, "server create failed", rv == APR_SUCCESS);

    rv = apr_memcache_add_server(memcache, memserver);
    ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);

    rv = apr_memcache_version(memserver, p, &result);
    ABTS_ASSERT(tc, "Couldn't get initial version", rv == APR_SUCCESS);

    /* Wait for the mock memcached to shutdown the socket */
    apr_sleep(apr_time_from_sec(1));

    rv = apr_memcache_version(memserver, p, &result);
    ABTS_ASSERT(tc, "Couldn't get version after connection shutdown", rv == APR_SUCCESS);

#ifdef SIGPIPE
    /* Restore old SIGPIPE handler */
    apr_signal(SIGPIPE, old_action);
#endif

    apr_proc_wait(&proc, &exitcode, &why, APR_WAIT);
}

abts_suite *testmemcache(abts_suite * suite)
{
    suite = ADD_SUITE(suite);
    abts_run_test(suite, test_memcache_create, NULL);
    abts_run_test(suite, test_memcache_user_funcs, NULL);
    abts_run_test(suite, test_memcache_meta, NULL);
    abts_run_test(suite, test_memcache_setget, NULL);
    abts_run_test(suite, test_memcache_multiget, NULL);
    abts_run_test(suite, test_memcache_addreplace, NULL);
    abts_run_test(suite, test_memcache_incrdecr, NULL);
    abts_run_test(suite, test_connection_validation, NULL);

    return suite;
}
