tests/testudp
unittests/unittests
config/top.h
+libmemcached/generated_probes.h
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
(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
--- /dev/null
+# 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
+
--- /dev/null
+/* 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);
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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
#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
/*
C++ to libhashkit
*/
-#include "test.h"
+#include <libtest/test.h>
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libhashkit/hashkit.h>
-#include "test.h"
+#include <libtest/test.h>
#include "hash_results.h"
# 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
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 \
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
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
#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
/*
C++ to libmemcit
*/
-#include "test.h"
+#include <libtest/test.h>
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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
#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>
+++ /dev/null
-/* 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);
- }
-}
+++ /dev/null
-/*
- * 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
#include <stdio.h>
#include <string.h>
-#include "server.h"
+#include <libtest/server.h>
int main(void)
{
+++ /dev/null
-/* 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;
-}
+++ /dev/null
-/* 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
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