Move testing framework out to its own library.
authorBrian Aker <brian@tangent.org>
Sat, 5 Mar 2011 20:39:12 +0000 (12:39 -0800)
committerBrian Aker <brian@tangent.org>
Sat, 5 Mar 2011 20:39:12 +0000 (12:39 -0800)
22 files changed:
.bzrignore
COPYING
Makefile.am
libtest/include.am [new file with mode: 0644]
libtest/server.c [new file with mode: 0644]
libtest/server.h [new file with mode: 0644]
libtest/test.c [new file with mode: 0644]
libtest/test.h [new file with mode: 0644]
tests/atomsmasher.c
tests/hash_plus.cc
tests/hashkit_functions.c
tests/include.am
tests/mem_functions.c
tests/mem_plus.cc
tests/mem_udp.c
tests/plus.cpp
tests/server.c [deleted file]
tests/server.h [deleted file]
tests/start.c
tests/test.c [deleted file]
tests/test.h [deleted file]
unittests/include.am

index 0ccaac97bb5290d11e4f8c2c64ab6afa1400c151..87578c4bc01c3468780834952bfb83eb0bd25a10 100644 (file)
@@ -186,3 +186,4 @@ tests/testplus
 tests/testudp
 unittests/unittests
 config/top.h
+libmemcached/generated_probes.h
diff --git a/COPYING b/COPYING
index c18e2ae877cecb45c572fb8d44cd1c8626dd5212..efbc4a88c99e88c412f0c496c7df948114e0c227 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -1,6 +1,7 @@
 Software License Agreement (BSD License)
 
-Copyright (c) 2007, TangentOrg (Brian Aker)
+Copyright (c) 2011, Data Differential (http://datadifferential.com/)
+Copyright (c) 2007-2010, TangentOrg (Brian Aker)
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
index 7b866d0c67b0f185c2e4481415309c516a9bb101..31585120cae1d8ff2ec87602823017247202e72e 100644 (file)
@@ -41,6 +41,7 @@ test-docs:
        (cd docs && $(MAKE) test-docs)
 include libmemcached/include.am
 include clients/include.am
+include libtest/include.am
 include libhashkit/include.am
 include unittests/include.am
 include tests/include.am
diff --git a/libtest/include.am b/libtest/include.am
new file mode 100644 (file)
index 0000000..d6d9b18
--- /dev/null
@@ -0,0 +1,20 @@
+# vim:ft=automake
+# Copyright (C) 2011 Data Differential (http://datadifferential.com/)
+# All rights reserved.
+#
+# Use and distribution licensed under the BSD license.  See
+# the COPYING file in the parent directory for full text.
+#
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+
+noinst_HEADERS+= \
+                libtest/server.h \
+                libtest/test.h
+
+noinst_LTLIBRARIES+= libtest/libserver.la
+libtest_libserver_la_SOURCES= libtest/server.c
+
+noinst_LTLIBRARIES+= libtest/libtest.la
+libtest_libtest_la_SOURCES= libtest/test.c
+
diff --git a/libtest/server.c b/libtest/server.c
new file mode 100644 (file)
index 0000000..4349a66
--- /dev/null
@@ -0,0 +1,246 @@
+/* LibMemcached
+ * Copyright (C) 2006-2009 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ *
+ * Summary:
+ *
+ */
+
+/*
+  Startup, and shutdown the memcached servers.
+*/
+
+#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT+10
+
+#define PID_FILE_BASE "/tmp/%ulibmemcached_memc.pid"
+
+#include "config.h"
+
+#include <assert.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <libmemcached/memcached.h>
+#include <libmemcached/util.h>
+
+#include <libtest/server.h>
+
+static struct timespec global_sleep_value= { .tv_sec= 0, .tv_nsec= 50000 };
+
+static void global_sleep(void)
+{
+#ifdef WIN32
+  sleep(1);
+#else
+  nanosleep(&global_sleep_value, NULL);
+#endif
+}
+
+static void kill_file(const char *file_buffer)
+{
+  FILE *fp= fopen(file_buffer, "r");
+
+  while ((fp= fopen(file_buffer, "r")))
+  {
+    char pid_buffer[1024];
+
+    if (fgets(pid_buffer, sizeof(pid_buffer), fp) != NULL)
+    {
+      pid_t pid= (pid_t)atoi(pid_buffer);
+      if (pid != 0)
+      {
+        if (kill(pid, SIGTERM) == -1)
+        {
+          remove(file_buffer); // If this happens we may be dealing with a dead server that left its pid file.
+        }
+        else
+        {
+          uint32_t counter= 3;
+          while ((kill(pid, 0) == 0) && --counter)
+          {
+            global_sleep();
+          }
+        }
+      }
+    }
+
+    global_sleep();
+
+    fclose(fp);
+  }
+}
+
+void server_startup(server_startup_st *construct)
+{
+  if ((construct->server_list= getenv("MEMCACHED_SERVERS")))
+  {
+    printf("servers %s\n", construct->server_list);
+    construct->servers= memcached_servers_parse(construct->server_list);
+    construct->server_list= NULL;
+    construct->count= 0;
+  }
+  else
+  {
+    {
+      char server_string_buffer[8096];
+      char *end_ptr;
+      end_ptr= server_string_buffer;
+
+      for (uint32_t x= 0; x < construct->count; x++)
+      {
+        int status;
+        in_port_t port;
+
+        {
+          char *var;
+          char variable_buffer[1024];
+
+          snprintf(variable_buffer, sizeof(variable_buffer), "LIBMEMCACHED_PORT_%u", x);
+
+          if ((var= getenv(variable_buffer)))
+          {
+            port= (in_port_t)atoi(var);
+          }
+          else
+          {
+            port= (in_port_t)(x + TEST_PORT_BASE);
+          }
+        }
+
+        char buffer[PATH_MAX];
+        snprintf(buffer, sizeof(buffer), PID_FILE_BASE, x);
+        kill_file(buffer);
+
+        if (x == 0)
+        {
+          snprintf(buffer, sizeof(buffer), "%s -d -u root -P "PID_FILE_BASE" -t 1 -p %u -U %u -m 128",
+                   MEMCACHED_BINARY, x, port, port);
+        }
+        else
+        {
+          snprintf(buffer, sizeof(buffer), "%s -d -u root -P "PID_FILE_BASE" -t 1 -p %u -U %u",
+                   MEMCACHED_BINARY, x, port, port);
+        }
+       if (libmemcached_util_ping("localhost", port, NULL))
+       {
+         fprintf(stderr, "Server on port %u already exists\n", port);
+       }
+       else
+       {
+         status= system(buffer);
+         fprintf(stderr, "STARTING SERVER: %s  status:%d\n", buffer, status);
+       }
+        int count;
+        size_t remaining_length= sizeof(server_string_buffer) - (size_t)(end_ptr -server_string_buffer);
+        count= snprintf(end_ptr, remaining_length,  "localhost:%u,", port);
+
+        if ((size_t)count >= remaining_length || count < 0)
+        {
+          fprintf(stderr, "server names grew to be larger then buffer allowed\n");
+          abort();
+        }
+        end_ptr+= count;
+      }
+      *end_ptr= 0;
+
+
+      int *pids= calloc(construct->count, sizeof(int));
+      for (uint32_t x= 0; x < construct->count; x++)
+      {
+        char buffer[PATH_MAX]; /* Nothing special for number */
+
+        snprintf(buffer, sizeof(buffer), PID_FILE_BASE, x);
+
+        uint32_t counter= 3000; // Absurd, just to catch run away process
+        while (pids[x] <= 0  && --counter)
+        {
+          FILE *file= fopen(buffer, "r");
+          if (file)
+          {
+            char pid_buffer[1024];
+            char *found= fgets(pid_buffer, sizeof(pid_buffer), file);
+
+            if (found)
+            {
+              pids[x]= atoi(pid_buffer);
+              fclose(file);
+
+              if (pids[x] > 0)
+                break;
+            }
+            fclose(file);
+          }
+          global_sleep();
+        }
+
+        bool was_started= false;
+        if (pids[x] > 0)
+        {
+          counter= 30;
+          while (--counter)
+          {
+            if (kill(pids[x], 0) == 0)
+            {
+              was_started= true;
+              break;
+            }
+            global_sleep();
+          }
+        }
+
+        if (was_started == false)
+        {
+          fprintf(stderr, "Failed to open buffer %s(%d)\n", buffer, pids[x]);
+          for (uint32_t y= 0; y < construct->count; y++)
+          {
+            if (pids[y] > 0)
+              kill(pids[y], SIGTERM);
+          }
+          abort();
+        }
+      }
+      free(pids);
+
+      construct->server_list= strdup(server_string_buffer);
+    }
+    printf("servers %s\n", construct->server_list);
+    construct->servers= memcached_servers_parse(construct->server_list);
+  }
+
+  assert(construct->servers);
+
+  srandom((unsigned int)time(NULL));
+
+  for (uint32_t x= 0; x < memcached_server_list_count(construct->servers); x++)
+  {
+    printf("\t%s : %d\n", memcached_server_name(&construct->servers[x]), memcached_server_port(&construct->servers[x]));
+    assert(construct->servers[x].fd == -1);
+    assert(construct->servers[x].cursor_active == 0);
+  }
+
+  printf("\n");
+}
+
+void server_shutdown(server_startup_st *construct)
+{
+  if (construct->server_list)
+  {
+    for (uint32_t x= 0; x < construct->count; x++)
+    {
+      char file_buffer[PATH_MAX]; /* Nothing special for number */
+      snprintf(file_buffer, sizeof(file_buffer), PID_FILE_BASE, x);
+      kill_file(file_buffer);
+    }
+
+    free(construct->server_list);
+  }
+}
diff --git a/libtest/server.h b/libtest/server.h
new file mode 100644 (file)
index 0000000..0aef86f
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006-2009 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ */
+
+/*
+  Server startup and shutdown functions.
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <libmemcached/memcached.h>
+
+typedef struct server_startup_st server_startup_st;
+
+struct server_startup_st
+{
+  uint8_t count;
+  uint8_t udp;
+  memcached_server_st *servers;
+  char *server_list;
+};
+
+void server_startup(server_startup_st *construct);
+void server_shutdown(server_startup_st *construct);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libtest/test.c b/libtest/test.c
new file mode 100644 (file)
index 0000000..009c4be
--- /dev/null
@@ -0,0 +1,371 @@
+/* uTest
+ * Copyright (C) 2006-2009 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ */
+
+/*
+  Sample test application.
+*/
+
+#include "config.h"
+
+#include <unistd.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdint.h>
+
+#include <libmemcached/memcached.h>
+
+#include <libtest/test.h>
+
+static void world_stats_print(world_stats_st *stats)
+{
+  fputc('\n', stderr);
+  fprintf(stderr, "Total Collections\t\t\t\t%u\n", stats->collection_total);
+  fprintf(stderr, "\tFailed Collections\t\t\t%u\n", stats->collection_failed);
+  fprintf(stderr, "\tSkipped Collections\t\t\t%u\n", stats->collection_skipped);
+  fprintf(stderr, "\tSucceeded Collections\t\t%u\n", stats->collection_success);
+  fputc('\n', stderr);
+  fprintf(stderr, "Total\t\t\t\t%u\n", stats->total);
+  fprintf(stderr, "\tFailed\t\t\t%u\n", stats->failed);
+  fprintf(stderr, "\tSkipped\t\t\t%u\n", stats->skipped);
+  fprintf(stderr, "\tSucceeded\t\t%u\n", stats->success);
+}
+
+long int timedif(struct timeval a, struct timeval b)
+{
+  long us, s;
+
+  us = (int)(a.tv_usec - b.tv_usec);
+  us /= 1000;
+  s = (int)(a.tv_sec - b.tv_sec);
+  s *= 1000;
+  return s + us;
+}
+
+const char *test_strerror(test_return_t code)
+{
+  switch (code) {
+  case TEST_SUCCESS:
+    return "ok";
+  case TEST_FAILURE:
+    return "failed";
+  case TEST_MEMORY_ALLOCATION_FAILURE:
+    return "memory allocation";
+  case TEST_SKIPPED:
+    return "skipped";
+  case TEST_MAXIMUM_RETURN:
+  default:
+    fprintf(stderr, "Unknown return value\n");
+    abort();
+  }
+}
+
+void create_core(void)
+{
+  if (getenv("LIBMEMCACHED_NO_COREDUMP") == NULL)
+  {
+    pid_t pid= fork();
+
+    if (pid == 0)
+    {
+      abort();
+    }
+    else
+    {
+      while (waitpid(pid, NULL, 0) != pid)
+      {
+        ;
+      }
+    }
+  }
+}
+
+
+static test_return_t _runner_default(test_callback_fn func, void *p)
+{
+  if (func)
+  {
+    return func(p);
+  }
+  else
+  {
+    return TEST_SUCCESS;
+  }
+}
+
+static world_runner_st defualt_runners= {
+  _runner_default,
+  _runner_default,
+  _runner_default
+};
+
+static test_return_t _default_callback(void *p)
+{
+  (void)p;
+
+  return TEST_SUCCESS;
+}
+
+static inline void set_default_fn(test_callback_fn *fn)
+{
+  if (*fn == NULL)
+  {
+    *fn= _default_callback;
+  }
+}
+
+static collection_st *init_world(world_st *world)
+{
+  if (! world->runner)
+  {
+    world->runner= &defualt_runners;
+  }
+
+  set_default_fn(&world->collection.startup);
+  set_default_fn(&world->collection.shutdown);
+
+  return world->collections;
+}
+
+
+int main(int argc, char *argv[])
+{
+  test_return_t return_code;
+  unsigned int x;
+  char *collection_to_run= NULL;
+  char *wildcard= NULL;
+  world_st world;
+  collection_st *collection;
+  collection_st *next;
+  void *world_ptr;
+
+  world_stats_st stats;
+
+#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
+  if (sasl_client_init(NULL) != SASL_OK)
+  {
+     fprintf(stderr, "Failed to initialize sasl library!\n");
+     return 1;
+  }
+#endif
+
+  memset(&stats, 0, sizeof(stats));
+  memset(&world, 0, sizeof(world));
+  get_world(&world);
+
+  collection= init_world(&world);
+
+  if (world.create)
+  {
+    test_return_t error;
+    world_ptr= world.create(&error);
+    if (error != TEST_SUCCESS)
+      exit(1);
+  }
+  else
+  {
+    world_ptr= NULL;
+  }
+
+  if (argc > 1)
+    collection_to_run= argv[1];
+
+  if (argc == 3)
+    wildcard= argv[2];
+
+  for (next= collection; next->name; next++)
+  {
+    test_return_t collection_rc= TEST_SUCCESS;
+    test_st *run;
+    bool failed= false;
+    bool skipped= false;
+
+    run= next->tests;
+    if (collection_to_run && fnmatch(collection_to_run, next->name, 0))
+      continue;
+
+    stats.collection_total++;
+
+    collection_rc= world.collection.startup(world_ptr);
+
+    if (collection_rc != TEST_SUCCESS)
+      goto skip_pre;
+
+    if (next->pre)
+    {
+      collection_rc= world.runner->pre(next->pre, world_ptr);
+    }
+
+skip_pre:
+    switch (collection_rc)
+    {
+      case TEST_SUCCESS:
+        fprintf(stderr, "\n%s\n\n", next->name);
+        break;
+      case TEST_FAILURE:
+        fprintf(stderr, "\n%s [ failed ]\n\n", next->name);
+        stats.collection_failed++;
+        goto cleanup;
+      case TEST_SKIPPED:
+        fprintf(stderr, "\n%s [ skipping ]\n\n", next->name);
+        stats.collection_skipped++;
+        goto cleanup;
+      case TEST_MEMORY_ALLOCATION_FAILURE:
+      case TEST_MAXIMUM_RETURN:
+      default:
+        assert(0);
+        break;
+    }
+
+
+    for (x= 0; run->name; run++)
+    {
+      struct timeval start_time, end_time;
+      long int load_time= 0;
+
+      if (wildcard && fnmatch(wildcard, run->name, 0))
+        continue;
+
+      fprintf(stderr, "Testing %s", run->name);
+
+      if (world.test.startup)
+      {
+        world.test.startup(world_ptr);
+      }
+
+      if (run->requires_flush && world.test.flush)
+      {
+        world.test.flush(world_ptr);
+      }
+
+      if (world.test.pre_run)
+      {
+        world.test.pre_run(world_ptr);
+      }
+
+
+      // Runner code
+      {
+#if 0
+        if (next->pre && world.runner->pre)
+        {
+          return_code= world.runner->pre(next->pre, world_ptr);
+
+          if (return_code != TEST_SUCCESS)
+          {
+            goto error;
+          }
+        }
+#endif
+
+        gettimeofday(&start_time, NULL);
+        return_code= world.runner->run(run->test_fn, world_ptr);
+        gettimeofday(&end_time, NULL);
+        load_time= timedif(end_time, start_time);
+
+#if 0
+        if (next->post && world.runner->post)
+        {
+          (void) world.runner->post(next->post, world_ptr);
+        }
+#endif
+      }
+
+      if (world.test.post_run)
+      {
+        world.test.post_run(world_ptr);
+      }
+
+      stats.total++;
+
+      fprintf(stderr, "\t\t\t\t\t");
+
+      switch (return_code)
+      {
+      case TEST_SUCCESS:
+        fprintf(stderr, "%ld.%03ld ", load_time / 1000, load_time % 1000);
+        stats.success++;
+        break;
+      case TEST_FAILURE:
+        stats.failed++;
+        failed= true;
+        break;
+      case TEST_SKIPPED:
+        stats.skipped++;
+        skipped= true;
+        break;
+      case TEST_MEMORY_ALLOCATION_FAILURE:
+        fprintf(stderr, "Exhausted memory, quitting\n");
+        abort();
+      case TEST_MAXIMUM_RETURN:
+      default:
+        assert(0); // Coding error.
+        break;
+      }
+
+      fprintf(stderr, "[ %s ]\n", test_strerror(return_code));
+
+      if (world.test.on_error)
+      {
+        test_return_t rc;
+        rc= world.test.on_error(return_code, world_ptr);
+
+        if (rc != TEST_SUCCESS)
+          break;
+      }
+    }
+
+    if (next->post && world.runner->post)
+    {
+      (void) world.runner->post(next->post, world_ptr);
+    }
+
+    if (! failed && ! skipped)
+    {
+      stats.collection_success++;
+    }
+cleanup:
+
+    world.collection.shutdown(world_ptr);
+  }
+
+  if (stats.collection_failed || stats.collection_skipped)
+  {
+    fprintf(stderr, "Some test failures and/or skipped test occurred.\n\n");
+  }
+  else
+  {
+    fprintf(stderr, "All tests completed successfully\n\n");
+  }
+
+  if (world.destroy)
+  {
+    test_return_t error;
+    error= world.destroy(world_ptr);
+
+    if (error != TEST_SUCCESS)
+    {
+      fprintf(stderr, "Failure during shutdown.\n");
+      stats.failed++; // We do this to make our exit code return 1
+    }
+  }
+
+  world_stats_print(&stats);
+
+#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
+  sasl_done();
+#endif
+
+  return stats.failed == 0 ? 0 : 1;
+}
diff --git a/libtest/test.h b/libtest/test.h
new file mode 100644 (file)
index 0000000..cc0fd78
--- /dev/null
@@ -0,0 +1,205 @@
+/* uTest
+ * Copyright (C) 2006-2009 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ */
+
+/*
+  Structures for generic tests.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#if !defined(__cplusplus)
+# include <stdbool.h>
+#endif
+
+typedef struct world_st world_st;
+typedef struct collection_st collection_st;
+typedef struct test_st test_st;
+
+typedef enum {
+  TEST_SUCCESS= 0, /* Backwards compatibility */
+  TEST_FAILURE,
+  TEST_MEMORY_ALLOCATION_FAILURE,
+  TEST_SKIPPED,
+  TEST_MAXIMUM_RETURN /* Always add new error code before */
+} test_return_t;
+
+typedef void *(*test_callback_create_fn)(test_return_t *error);
+typedef test_return_t (*test_callback_fn)(void *);
+typedef test_return_t (*test_callback_runner_fn)(test_callback_fn, void *);
+typedef test_return_t (*test_callback_error_fn)(test_return_t, void *);
+
+/* Help function for use with gettimeofday() */
+long int timedif(struct timeval a, struct timeval b);
+
+/**
+  A structure describing the test case.
+*/
+struct test_st {
+  const char *name;
+  bool requires_flush;
+  test_callback_fn test_fn;
+};
+
+
+/**
+  A structure which describes a collection of test cases.
+*/
+struct collection_st {
+  const char *name;
+  test_callback_fn pre;
+  test_callback_fn post;
+  test_st *tests;
+};
+
+
+/**
+  Structure which houses the actual callers for the test cases contained in
+  the collections.
+*/
+typedef struct {
+  test_callback_runner_fn pre;
+  test_callback_runner_fn run;
+  test_callback_runner_fn post;
+} world_runner_st;
+
+
+/**
+  world_st is the structure which is passed to the test implementation to be filled.
+  This must be implemented in order for the test framework to load the tests. We call
+  get_world() in order to fill this structure.
+*/
+
+struct world_st {
+  collection_st *collections;
+
+  /* These methods are called outside of any collection call. */
+  test_callback_create_fn create;
+  test_callback_fn destroy;
+
+  struct {
+    /* This is called a the beginning of any test run. */
+    test_callback_fn startup;
+
+    /* This called on a test if the test requires a flush call (the bool is from test_st) */
+    test_callback_fn flush;
+
+    /**
+      These are run before/after the test. If implemented. Their execution is not controlled
+      by the test.
+    */
+    test_callback_fn pre_run;
+    test_callback_fn post_run;
+
+    /**
+      If an error occurs during the test, this is called.
+    */
+    test_callback_error_fn on_error;
+  } test;
+
+  struct {
+    /* This is called a the beginning of any collection run. */
+    test_callback_fn startup;
+
+    /* This is called at the end of any collection run. */
+    test_callback_fn shutdown;
+  } collection;
+
+
+  /**
+    Runner represents the callers for the tests. If not implemented we will use
+    a set of default implementations.
+  */
+  world_runner_st *runner;
+};
+
+
+
+/**
+  @note world_stats_st is a simple structure for tracking test successes.
+*/
+typedef struct {
+  uint32_t collection_success;
+  uint32_t collection_skipped;
+  uint32_t collection_failed;
+  uint32_t collection_total;
+  uint32_t success;
+  uint32_t skipped;
+  uint32_t failed;
+  uint32_t total;
+} world_stats_st;
+
+/* How we make all of this work :) */
+void get_world(world_st *world);
+
+void create_core(void);
+
+/**
+  @note Friendly print function for errors.
+*/
+const char *test_strerror(test_return_t code);
+
+#define test_fail(A) \
+do \
+{ \
+  if (1) { \
+    fprintf(stderr, "\nFailed at %s:%d: %s\n", __FILE__, __LINE__, #A);\
+    create_core(); \
+    return TEST_FAILURE; \
+  } \
+} while (0)
+
+#define test_true(A) \
+do \
+{ \
+  if (! (A)) { \
+    fprintf(stderr, "\nAssertion failed at %s:%d: %s\n", __FILE__, __LINE__, #A);\
+    create_core(); \
+    return TEST_FAILURE; \
+  } \
+} while (0)
+
+#define test_true_got(A,B) \
+do \
+{ \
+  if (! (A)) { \
+    fprintf(stderr, "\nAssertion failed at %s:%d: \"%s\" received \"%s\"\n", __FILE__, __LINE__, #A, (B));\
+    create_core(); \
+    return TEST_FAILURE; \
+  } \
+} while (0)
+
+#define test_false(A) \
+do \
+{ \
+  if ((A)) { \
+    fprintf(stderr, "\nAssertion failed at %s:%d: %s\n", __FILE__, __LINE__, #A);\
+    create_core(); \
+    return TEST_FAILURE; \
+  } \
+} while (0)
+
+#define test_strcmp(A,B) \
+do \
+{ \
+  if (strcmp((A), (B))) \
+  { \
+    fprintf(stderr, "\n%s:%d: %s -> %s\n", __FILE__, __LINE__, (A), (B)); \
+    create_core(); \
+    return TEST_FAILURE; \
+  } \
+} while (0)
+
+#ifdef __cplusplus
+}
+#endif
index fac6986c424dd84149a569c3388173cd84fcc1d1..5b4bcbe241b7bb500deb1e8f2a9bcc1b2bf7fd75 100644 (file)
 #include <sys/stat.h>
 #include <unistd.h>
 #include <time.h>
-#include "server.h"
 #include "../clients/generator.h"
 #include "../clients/execute.h"
 
-#include "test.h"
+#include <libtest/server.h>
+#include <libtest/test.h>
 
 /* Number of items generated for tests */
 #define GLOBAL_COUNT 100000
index 1d0b9e83506ee4bc1911c5178b38ae76bd146af5..c148d3effd10528ac8cf427ef6bc4447a02df93d 100644 (file)
@@ -1,7 +1,8 @@
 /*
   C++ to libhashkit
 */
-#include "test.h"
+#include <libtest/test.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index deb5436a1570cf5961579aa48b704b7a02047801..0f2c42a99d050cd3c20954cb6d77cf6058274b03 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <libhashkit/hashkit.h>
 
-#include "test.h"
+#include <libtest/test.h>
 
 #include "hash_results.h"
 
index b90a5ef7d9f8559f33b833ecdf3bbe0697c7be02..f940caf88b3bb03e0edf57db232291a727d13fc9 100644 (file)
@@ -1,8 +1,17 @@
 # vim:ft=automake
+# Copyright (C) 2011 Data Differential
+# All rights reserved.
+#
+# Use and distribution licensed under the BSD license.  See
+# the COPYING file in the parent directory for full text.
+#
 # included from Top Level Makefile.am
 # All paths should be given relative to the root
 
-TESTS_LDADDS = libmemcached/libmemcached.la
+TESTS_LDADDS= \
+             libmemcached/libmemcached.la \
+             libtest/libserver.la \
+             libtest/libtest.la
 
 VALGRIND_COMMAND= $(LIBTOOL) --mode=execute valgrind --leak-check=yes --show-reachable=yes --track-fds=yes
 
@@ -22,9 +31,7 @@ noinst_HEADERS+= \
                 tests/hash_results.h \
                 tests/ketama_test_cases.h \
                 tests/ketama_test_cases_spy.h \
-                tests/libmemcached_world.h \
-                tests/server.h \
-                tests/test.h
+                tests/libmemcached_world.h
 
 noinst_PROGRAMS+= \
                  tests/atomsmasher \
@@ -36,55 +43,44 @@ noinst_PROGRAMS+= \
                  tests/testplus \
                  tests/testudp
 
-noinst_LTLIBRARIES+= tests/libserver.la
-tests_libserver_la_SOURCES= tests/server.c
-
-noinst_LTLIBRARIES+= tests/libtest.la
-tests_libtest_la_SOURCES= tests/test.c
-
 tests_testapp_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING)
 tests_testapp_SOURCES= tests/mem_functions.c
 tests_testapp_DEPENDENCIES= \
                            $(BUILT_SOURCES) \
                            clients/libgenexec.la \
-                           tests/libserver.la \
-                           tests/libtest.la \
                            libmemcached/libmemcachedinternal.la \
                            $(TESTS_LDADDS)
+
 tests_testapp_LDADD= clients/libgenexec.la \
-                    tests/libserver.la \
-                    tests/libtest.la \
                     libmemcached/libmemcachedinternal.la \
                     $(TESTS_LDADDS) $(LIBSASL)
 
 tests_testplus_SOURCES= tests/plus.cpp
 tests_testplus_CXXFLAGS = $(AM_CXXFLAGS) $(NO_EFF_CXX)
-tests_testplus_DEPENDENCIES= tests/libtest.la tests/libserver.la $(TESTS_LDADDS)
+tests_testplus_DEPENDENCIES= $(TESTS_LDADDS)
 tests_testplus_LDADD= $(tests_testplus_DEPENDENCIES) $(LIBSASL)
 
 tests_atomsmasher_SOURCES= tests/atomsmasher.c
 tests_atomsmasher_DEPENDENCIES= \
                                clients/libgenexec.la \
-                               tests/libserver.la \
-                               tests/libtest.la \
                                $(TESTS_LDADDS)
+
 tests_atomsmasher_LDADD= $(tests_atomsmasher_DEPENDENCIES) $(LIBSASL)
 
 tests_testudp_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING)
 tests_testudp_SOURCES= tests/mem_udp.c
 tests_testudp_DEPENDENCIES= \
                            clients/libgenexec.la \
-                           tests/libserver.la \
-                           tests/libtest.la \
                            $(TESTS_LDADDS)
+
 tests_testudp_LDADD= $(tests_testudp_DEPENDENCIES) $(LIBSASL)
 
 tests_startservers_SOURCES= tests/start.c
-tests_startservers_DEPENDENCIES= tests/libserver.la $(TESTS_LDADDS)
+tests_startservers_DEPENDENCIES= $(TESTS_LDADDS)
 tests_startservers_LDADD= $(tests_startservers_DEPENDENCIES) $(LIBSASL)
 
 tests_testhashkit_SOURCES = tests/hashkit_functions.c
-tests_testhashkit_DEPENDENCIES = tests/libtest.la libhashkit/libhashkit.la
+tests_testhashkit_DEPENDENCIES = libtest/libtest.la libhashkit/libhashkit.la
 tests_testhashkit_LDADD = $(tests_testhashkit_DEPENDENCIES) $(LIBSASL)
 
 tests_hashplus_SOURCES = tests/hash_plus.cc
@@ -94,7 +90,7 @@ tests_hashplus_LDADD = $(tests_testhashkit_DEPENDENCIES) $(LIBSASL)
 
 tests_memplus_SOURCES = tests/mem_plus.cc
 tests_memplus_CXXFLAGS = $(AM_CXXFLAGS) $(NO_EFF_CXX)
-tests_memplus_DEPENDENCIES = tests/libtest.la tests/libserver.la libmemcached/libmemcached.la
+tests_memplus_DEPENDENCIES = $(TESTS_LDADDS)
 tests_memplus_LDADD = $(tests_memplus_DEPENDENCIES) $(LIBSASL)
 
 test: check
index 871256cf371b8661153b3a77e3637ff2e97a35be..36c5717ec3166d2c6e14776de3a478c01396f6ae 100644 (file)
 
 #include "libmemcached/common.h"
 
-#include "server.h"
+#include <libtest/server.h>
+
 #include "clients/generator.h"
 #include "clients/execute.h"
 
 #define SMALL_STRING_LEN 1024
 
-#include "test.h"
+#include <libtest/test.h>
 
 
 #ifdef HAVE_LIBMEMCACHEDUTIL
index d62ae72312bb25fa662a4fe19aa182756a2e22e2..d9a76afb2f95ad3c7a510bf37f5f21ddc1fc4b76 100644 (file)
@@ -1,7 +1,8 @@
 /*
   C++ to libmemcit
 */
-#include "test.h"
+#include <libtest/test.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index 76aab981a3e21f90198bd83251ca47032154c001..01314dbdcd083bb56ab5f46fa85e238c4bed957c 100644 (file)
@@ -26,9 +26,8 @@
 #include <unistd.h>
 #include <time.h>
 
-#include "server.h"
-
-#include "test.h"
+#include <libtest/server.h>
+#include <libtest/test.h>
 
 #define SERVERS_TO_CREATE 5
 
index 0d588749c0404d3aa8ef90320c380aaeb94df0a2..c0c6bb9503713eb3271b4c86ae24dfd567be8285 100644 (file)
 #include <sys/stat.h>
 #include <unistd.h>
 #include <time.h>
-#include "server.h"
 
-#include "test.h"
+#include <libtest/server.h>
+
+#include <libtest/test.h>
 
 #include <string>
 #include <iostream>
diff --git a/tests/server.c b/tests/server.c
deleted file mode 100644 (file)
index 84f15de..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/* LibMemcached
- * Copyright (C) 2006-2009 Brian Aker
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- *
- * Summary:
- *
- */
-
-/*
-  Startup, and shutdown the memcached servers.
-*/
-
-#define TEST_PORT_BASE MEMCACHED_DEFAULT_PORT+10
-
-#define PID_FILE_BASE "/tmp/%ulibmemcached_memc.pid"
-
-#include "config.h"
-
-#include <assert.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <libmemcached/memcached.h>
-#include <libmemcached/util.h>
-
-#include "server.h"
-
-static struct timespec global_sleep_value= { .tv_sec= 0, .tv_nsec= 50000 };
-
-static void global_sleep(void)
-{
-#ifdef WIN32
-  sleep(1);
-#else
-  nanosleep(&global_sleep_value, NULL);
-#endif
-}
-
-static void kill_file(const char *file_buffer)
-{
-  FILE *fp= fopen(file_buffer, "r");
-
-  while ((fp= fopen(file_buffer, "r")))
-  {
-    char pid_buffer[1024];
-
-    if (fgets(pid_buffer, sizeof(pid_buffer), fp) != NULL)
-    {
-      pid_t pid= (pid_t)atoi(pid_buffer);
-      if (pid != 0)
-      {
-        if (kill(pid, SIGTERM) == -1)
-        {
-          remove(file_buffer); // If this happens we may be dealing with a dead server that left its pid file.
-        }
-        else
-        {
-          uint32_t counter= 3;
-          while ((kill(pid, 0) == 0) && --counter)
-          {
-            global_sleep();
-          }
-        }
-      }
-    }
-
-    global_sleep();
-
-    fclose(fp);
-  }
-}
-
-void server_startup(server_startup_st *construct)
-{
-  if ((construct->server_list= getenv("MEMCACHED_SERVERS")))
-  {
-    printf("servers %s\n", construct->server_list);
-    construct->servers= memcached_servers_parse(construct->server_list);
-    construct->server_list= NULL;
-    construct->count= 0;
-  }
-  else
-  {
-    {
-      char server_string_buffer[8096];
-      char *end_ptr;
-      end_ptr= server_string_buffer;
-
-      for (uint32_t x= 0; x < construct->count; x++)
-      {
-        int status;
-        in_port_t port;
-
-        {
-          char *var;
-          char variable_buffer[1024];
-
-          snprintf(variable_buffer, sizeof(variable_buffer), "LIBMEMCACHED_PORT_%u", x);
-
-          if ((var= getenv(variable_buffer)))
-          {
-            port= (in_port_t)atoi(var);
-          }
-          else
-          {
-            port= (in_port_t)(x + TEST_PORT_BASE);
-          }
-        }
-
-        char buffer[PATH_MAX];
-        snprintf(buffer, sizeof(buffer), PID_FILE_BASE, x);
-        kill_file(buffer);
-
-        if (x == 0)
-        {
-          snprintf(buffer, sizeof(buffer), "%s -d -u root -P "PID_FILE_BASE" -t 1 -p %u -U %u -m 128",
-                   MEMCACHED_BINARY, x, port, port);
-        }
-        else
-        {
-          snprintf(buffer, sizeof(buffer), "%s -d -u root -P "PID_FILE_BASE" -t 1 -p %u -U %u",
-                   MEMCACHED_BINARY, x, port, port);
-        }
-       if (libmemcached_util_ping("localhost", port, NULL))
-       {
-         fprintf(stderr, "Server on port %u already exists\n", port);
-       }
-       else
-       {
-         status= system(buffer);
-         fprintf(stderr, "STARTING SERVER: %s  status:%d\n", buffer, status);
-       }
-        int count;
-        size_t remaining_length= sizeof(server_string_buffer) - (size_t)(end_ptr -server_string_buffer);
-        count= snprintf(end_ptr, remaining_length,  "localhost:%u,", port);
-
-        if ((size_t)count >= remaining_length || count < 0)
-        {
-          fprintf(stderr, "server names grew to be larger then buffer allowed\n");
-          abort();
-        }
-        end_ptr+= count;
-      }
-      *end_ptr= 0;
-
-
-      int *pids= calloc(construct->count, sizeof(int));
-      for (uint32_t x= 0; x < construct->count; x++)
-      {
-        char buffer[PATH_MAX]; /* Nothing special for number */
-
-        snprintf(buffer, sizeof(buffer), PID_FILE_BASE, x);
-
-        uint32_t counter= 3000; // Absurd, just to catch run away process
-        while (pids[x] <= 0  && --counter)
-        {
-          FILE *file= fopen(buffer, "r");
-          if (file)
-          {
-            char pid_buffer[1024];
-            char *found= fgets(pid_buffer, sizeof(pid_buffer), file);
-
-            if (found)
-            {
-              pids[x]= atoi(pid_buffer);
-              fclose(file);
-
-              if (pids[x] > 0)
-                break;
-            }
-            fclose(file);
-          }
-          global_sleep();
-        }
-
-        bool was_started= false;
-        if (pids[x] > 0)
-        {
-          counter= 30;
-          while (--counter)
-          {
-            if (kill(pids[x], 0) == 0)
-            {
-              was_started= true;
-              break;
-            }
-            global_sleep();
-          }
-        }
-
-        if (was_started == false)
-        {
-          fprintf(stderr, "Failed to open buffer %s(%d)\n", buffer, pids[x]);
-          for (uint32_t y= 0; y < construct->count; y++)
-          {
-            if (pids[y] > 0)
-              kill(pids[y], SIGTERM);
-          }
-          abort();
-        }
-      }
-      free(pids);
-
-      construct->server_list= strdup(server_string_buffer);
-    }
-    printf("servers %s\n", construct->server_list);
-    construct->servers= memcached_servers_parse(construct->server_list);
-  }
-
-  assert(construct->servers);
-
-  srandom((unsigned int)time(NULL));
-
-  for (uint32_t x= 0; x < memcached_server_list_count(construct->servers); x++)
-  {
-    printf("\t%s : %d\n", memcached_server_name(&construct->servers[x]), memcached_server_port(&construct->servers[x]));
-    assert(construct->servers[x].fd == -1);
-    assert(construct->servers[x].cursor_active == 0);
-  }
-
-  printf("\n");
-}
-
-void server_shutdown(server_startup_st *construct)
-{
-  if (construct->server_list)
-  {
-    for (uint32_t x= 0; x < construct->count; x++)
-    {
-      char file_buffer[PATH_MAX]; /* Nothing special for number */
-      snprintf(file_buffer, sizeof(file_buffer), PID_FILE_BASE, x);
-      kill_file(file_buffer);
-    }
-
-    free(construct->server_list);
-  }
-}
diff --git a/tests/server.h b/tests/server.h
deleted file mode 100644 (file)
index 0aef86f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Brian Aker
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- */
-
-/*
-  Server startup and shutdown functions.
-*/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <libmemcached/memcached.h>
-
-typedef struct server_startup_st server_startup_st;
-
-struct server_startup_st
-{
-  uint8_t count;
-  uint8_t udp;
-  memcached_server_st *servers;
-  char *server_list;
-};
-
-void server_startup(server_startup_st *construct);
-void server_shutdown(server_startup_st *construct);
-
-#ifdef __cplusplus
-}
-#endif
index e3f2a64c874dd4a3df0e0984eeaf59eebc8e2a6f..ae9497f3a3a88a897c3670c106686e7118b6bf1a 100644 (file)
@@ -13,7 +13,7 @@
 
 #include <stdio.h>
 #include <string.h>
-#include "server.h"
+#include <libtest/server.h>
 
 int main(void)
 {
diff --git a/tests/test.c b/tests/test.c
deleted file mode 100644 (file)
index 348df72..0000000
+++ /dev/null
@@ -1,371 +0,0 @@
-/* uTest
- * Copyright (C) 2006-2009 Brian Aker
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- */
-
-/*
-  Sample test application.
-*/
-
-#include "config.h"
-
-#include <unistd.h>
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <time.h>
-#include <stdint.h>
-
-#include "libmemcached/memcached.h"
-
-#include "test.h"
-
-static void world_stats_print(world_stats_st *stats)
-{
-  fputc('\n', stderr);
-  fprintf(stderr, "Total Collections\t\t\t\t%u\n", stats->collection_total);
-  fprintf(stderr, "\tFailed Collections\t\t\t%u\n", stats->collection_failed);
-  fprintf(stderr, "\tSkipped Collections\t\t\t%u\n", stats->collection_skipped);
-  fprintf(stderr, "\tSucceeded Collections\t\t%u\n", stats->collection_success);
-  fputc('\n', stderr);
-  fprintf(stderr, "Total\t\t\t\t%u\n", stats->total);
-  fprintf(stderr, "\tFailed\t\t\t%u\n", stats->failed);
-  fprintf(stderr, "\tSkipped\t\t\t%u\n", stats->skipped);
-  fprintf(stderr, "\tSucceeded\t\t%u\n", stats->success);
-}
-
-long int timedif(struct timeval a, struct timeval b)
-{
-  long us, s;
-
-  us = (int)(a.tv_usec - b.tv_usec);
-  us /= 1000;
-  s = (int)(a.tv_sec - b.tv_sec);
-  s *= 1000;
-  return s + us;
-}
-
-const char *test_strerror(test_return_t code)
-{
-  switch (code) {
-  case TEST_SUCCESS:
-    return "ok";
-  case TEST_FAILURE:
-    return "failed";
-  case TEST_MEMORY_ALLOCATION_FAILURE:
-    return "memory allocation";
-  case TEST_SKIPPED:
-    return "skipped";
-  case TEST_MAXIMUM_RETURN:
-  default:
-    fprintf(stderr, "Unknown return value\n");
-    abort();
-  }
-}
-
-void create_core(void)
-{
-  if (getenv("LIBMEMCACHED_NO_COREDUMP") == NULL)
-  {
-    pid_t pid= fork();
-
-    if (pid == 0)
-    {
-      abort();
-    }
-    else
-    {
-      while (waitpid(pid, NULL, 0) != pid)
-      {
-        ;
-      }
-    }
-  }
-}
-
-
-static test_return_t _runner_default(test_callback_fn func, void *p)
-{
-  if (func)
-  {
-    return func(p);
-  }
-  else
-  {
-    return TEST_SUCCESS;
-  }
-}
-
-static world_runner_st defualt_runners= {
-  _runner_default,
-  _runner_default,
-  _runner_default
-};
-
-static test_return_t _default_callback(void *p)
-{
-  (void)p;
-
-  return TEST_SUCCESS;
-}
-
-static inline void set_default_fn(test_callback_fn *fn)
-{
-  if (*fn == NULL)
-  {
-    *fn= _default_callback;
-  }
-}
-
-static collection_st *init_world(world_st *world)
-{
-  if (! world->runner)
-  {
-    world->runner= &defualt_runners;
-  }
-
-  set_default_fn(&world->collection.startup);
-  set_default_fn(&world->collection.shutdown);
-
-  return world->collections;
-}
-
-
-int main(int argc, char *argv[])
-{
-  test_return_t return_code;
-  unsigned int x;
-  char *collection_to_run= NULL;
-  char *wildcard= NULL;
-  world_st world;
-  collection_st *collection;
-  collection_st *next;
-  void *world_ptr;
-
-  world_stats_st stats;
-
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
-  if (sasl_client_init(NULL) != SASL_OK)
-  {
-     fprintf(stderr, "Failed to initialize sasl library!\n");
-     return 1;
-  }
-#endif
-
-  memset(&stats, 0, sizeof(stats));
-  memset(&world, 0, sizeof(world));
-  get_world(&world);
-
-  collection= init_world(&world);
-
-  if (world.create)
-  {
-    test_return_t error;
-    world_ptr= world.create(&error);
-    if (error != TEST_SUCCESS)
-      exit(1);
-  }
-  else
-  {
-    world_ptr= NULL;
-  }
-
-  if (argc > 1)
-    collection_to_run= argv[1];
-
-  if (argc == 3)
-    wildcard= argv[2];
-
-  for (next= collection; next->name; next++)
-  {
-    test_return_t collection_rc= TEST_SUCCESS;
-    test_st *run;
-    bool failed= false;
-    bool skipped= false;
-
-    run= next->tests;
-    if (collection_to_run && fnmatch(collection_to_run, next->name, 0))
-      continue;
-
-    stats.collection_total++;
-
-    collection_rc= world.collection.startup(world_ptr);
-
-    if (collection_rc != TEST_SUCCESS)
-      goto skip_pre;
-
-    if (next->pre)
-    {
-      collection_rc= world.runner->pre(next->pre, world_ptr);
-    }
-
-skip_pre:
-    switch (collection_rc)
-    {
-      case TEST_SUCCESS:
-        fprintf(stderr, "\n%s\n\n", next->name);
-        break;
-      case TEST_FAILURE:
-        fprintf(stderr, "\n%s [ failed ]\n\n", next->name);
-        stats.collection_failed++;
-        goto cleanup;
-      case TEST_SKIPPED:
-        fprintf(stderr, "\n%s [ skipping ]\n\n", next->name);
-        stats.collection_skipped++;
-        goto cleanup;
-      case TEST_MEMORY_ALLOCATION_FAILURE:
-      case TEST_MAXIMUM_RETURN:
-      default:
-        assert(0);
-        break;
-    }
-
-
-    for (x= 0; run->name; run++)
-    {
-      struct timeval start_time, end_time;
-      long int load_time= 0;
-
-      if (wildcard && fnmatch(wildcard, run->name, 0))
-        continue;
-
-      fprintf(stderr, "Testing %s", run->name);
-
-      if (world.test.startup)
-      {
-        world.test.startup(world_ptr);
-      }
-
-      if (run->requires_flush && world.test.flush)
-      {
-        world.test.flush(world_ptr);
-      }
-
-      if (world.test.pre_run)
-      {
-        world.test.pre_run(world_ptr);
-      }
-
-
-      // Runner code
-      {
-#if 0
-        if (next->pre && world.runner->pre)
-        {
-          return_code= world.runner->pre(next->pre, world_ptr);
-
-          if (return_code != TEST_SUCCESS)
-          {
-            goto error;
-          }
-        }
-#endif
-
-        gettimeofday(&start_time, NULL);
-        return_code= world.runner->run(run->test_fn, world_ptr);
-        gettimeofday(&end_time, NULL);
-        load_time= timedif(end_time, start_time);
-
-#if 0
-        if (next->post && world.runner->post)
-        {
-          (void) world.runner->post(next->post, world_ptr);
-        }
-#endif
-      }
-
-      if (world.test.post_run)
-      {
-        world.test.post_run(world_ptr);
-      }
-
-      stats.total++;
-
-      fprintf(stderr, "\t\t\t\t\t");
-
-      switch (return_code)
-      {
-      case TEST_SUCCESS:
-        fprintf(stderr, "%ld.%03ld ", load_time / 1000, load_time % 1000);
-        stats.success++;
-        break;
-      case TEST_FAILURE:
-        stats.failed++;
-        failed= true;
-        break;
-      case TEST_SKIPPED:
-        stats.skipped++;
-        skipped= true;
-        break;
-      case TEST_MEMORY_ALLOCATION_FAILURE:
-        fprintf(stderr, "Exhausted memory, quitting\n");
-        abort();
-      case TEST_MAXIMUM_RETURN:
-      default:
-        assert(0); // Coding error.
-        break;
-      }
-
-      fprintf(stderr, "[ %s ]\n", test_strerror(return_code));
-
-      if (world.test.on_error)
-      {
-        test_return_t rc;
-        rc= world.test.on_error(return_code, world_ptr);
-
-        if (rc != TEST_SUCCESS)
-          break;
-      }
-    }
-
-    if (next->post && world.runner->post)
-    {
-      (void) world.runner->post(next->post, world_ptr);
-    }
-
-    if (! failed && ! skipped)
-    {
-      stats.collection_success++;
-    }
-cleanup:
-
-    world.collection.shutdown(world_ptr);
-  }
-
-  if (stats.collection_failed || stats.collection_skipped)
-  {
-    fprintf(stderr, "Some test failures and/or skipped test occurred.\n\n");
-  }
-  else
-  {
-    fprintf(stderr, "All tests completed successfully\n\n");
-  }
-
-  if (world.destroy)
-  {
-    test_return_t error;
-    error= world.destroy(world_ptr);
-
-    if (error != TEST_SUCCESS)
-    {
-      fprintf(stderr, "Failure during shutdown.\n");
-      stats.failed++; // We do this to make our exit code return 1
-    }
-  }
-
-  world_stats_print(&stats);
-
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
-  sasl_done();
-#endif
-
-  return stats.failed == 0 ? 0 : 1;
-}
diff --git a/tests/test.h b/tests/test.h
deleted file mode 100644 (file)
index cc0fd78..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/* uTest
- * Copyright (C) 2006-2009 Brian Aker
- * All rights reserved.
- *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
- */
-
-/*
-  Structures for generic tests.
-*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#if !defined(__cplusplus)
-# include <stdbool.h>
-#endif
-
-typedef struct world_st world_st;
-typedef struct collection_st collection_st;
-typedef struct test_st test_st;
-
-typedef enum {
-  TEST_SUCCESS= 0, /* Backwards compatibility */
-  TEST_FAILURE,
-  TEST_MEMORY_ALLOCATION_FAILURE,
-  TEST_SKIPPED,
-  TEST_MAXIMUM_RETURN /* Always add new error code before */
-} test_return_t;
-
-typedef void *(*test_callback_create_fn)(test_return_t *error);
-typedef test_return_t (*test_callback_fn)(void *);
-typedef test_return_t (*test_callback_runner_fn)(test_callback_fn, void *);
-typedef test_return_t (*test_callback_error_fn)(test_return_t, void *);
-
-/* Help function for use with gettimeofday() */
-long int timedif(struct timeval a, struct timeval b);
-
-/**
-  A structure describing the test case.
-*/
-struct test_st {
-  const char *name;
-  bool requires_flush;
-  test_callback_fn test_fn;
-};
-
-
-/**
-  A structure which describes a collection of test cases.
-*/
-struct collection_st {
-  const char *name;
-  test_callback_fn pre;
-  test_callback_fn post;
-  test_st *tests;
-};
-
-
-/**
-  Structure which houses the actual callers for the test cases contained in
-  the collections.
-*/
-typedef struct {
-  test_callback_runner_fn pre;
-  test_callback_runner_fn run;
-  test_callback_runner_fn post;
-} world_runner_st;
-
-
-/**
-  world_st is the structure which is passed to the test implementation to be filled.
-  This must be implemented in order for the test framework to load the tests. We call
-  get_world() in order to fill this structure.
-*/
-
-struct world_st {
-  collection_st *collections;
-
-  /* These methods are called outside of any collection call. */
-  test_callback_create_fn create;
-  test_callback_fn destroy;
-
-  struct {
-    /* This is called a the beginning of any test run. */
-    test_callback_fn startup;
-
-    /* This called on a test if the test requires a flush call (the bool is from test_st) */
-    test_callback_fn flush;
-
-    /**
-      These are run before/after the test. If implemented. Their execution is not controlled
-      by the test.
-    */
-    test_callback_fn pre_run;
-    test_callback_fn post_run;
-
-    /**
-      If an error occurs during the test, this is called.
-    */
-    test_callback_error_fn on_error;
-  } test;
-
-  struct {
-    /* This is called a the beginning of any collection run. */
-    test_callback_fn startup;
-
-    /* This is called at the end of any collection run. */
-    test_callback_fn shutdown;
-  } collection;
-
-
-  /**
-    Runner represents the callers for the tests. If not implemented we will use
-    a set of default implementations.
-  */
-  world_runner_st *runner;
-};
-
-
-
-/**
-  @note world_stats_st is a simple structure for tracking test successes.
-*/
-typedef struct {
-  uint32_t collection_success;
-  uint32_t collection_skipped;
-  uint32_t collection_failed;
-  uint32_t collection_total;
-  uint32_t success;
-  uint32_t skipped;
-  uint32_t failed;
-  uint32_t total;
-} world_stats_st;
-
-/* How we make all of this work :) */
-void get_world(world_st *world);
-
-void create_core(void);
-
-/**
-  @note Friendly print function for errors.
-*/
-const char *test_strerror(test_return_t code);
-
-#define test_fail(A) \
-do \
-{ \
-  if (1) { \
-    fprintf(stderr, "\nFailed at %s:%d: %s\n", __FILE__, __LINE__, #A);\
-    create_core(); \
-    return TEST_FAILURE; \
-  } \
-} while (0)
-
-#define test_true(A) \
-do \
-{ \
-  if (! (A)) { \
-    fprintf(stderr, "\nAssertion failed at %s:%d: %s\n", __FILE__, __LINE__, #A);\
-    create_core(); \
-    return TEST_FAILURE; \
-  } \
-} while (0)
-
-#define test_true_got(A,B) \
-do \
-{ \
-  if (! (A)) { \
-    fprintf(stderr, "\nAssertion failed at %s:%d: \"%s\" received \"%s\"\n", __FILE__, __LINE__, #A, (B));\
-    create_core(); \
-    return TEST_FAILURE; \
-  } \
-} while (0)
-
-#define test_false(A) \
-do \
-{ \
-  if ((A)) { \
-    fprintf(stderr, "\nAssertion failed at %s:%d: %s\n", __FILE__, __LINE__, #A);\
-    create_core(); \
-    return TEST_FAILURE; \
-  } \
-} while (0)
-
-#define test_strcmp(A,B) \
-do \
-{ \
-  if (strcmp((A), (B))) \
-  { \
-    fprintf(stderr, "\n%s:%d: %s -> %s\n", __FILE__, __LINE__, (A), (B)); \
-    create_core(); \
-    return TEST_FAILURE; \
-  } \
-} while (0)
-
-#ifdef __cplusplus
-}
-#endif
index c14434189a9f685eb6307ec887a5b06705961172..b7ca5d2653cdeec64925eb07dc75257ec8834dbe 100644 (file)
@@ -12,7 +12,7 @@ unittests_unittests_SOURCES= \
 
 unittests_unittests_CXXFLAGS= ${AM_CXXFLAGS} ${NO_WERROR} ${NO_EFF_CXX}
 unittests_unittests_LDADD= \
-                          tests/libserver.la \
+                          libtest/libserver.la \
                           libmemcached/libmemcachedinternal.la \
                           ${TESTS_LDADDS} ${LTLIBGTEST}
 # Shorthand