{
free(pairs[x].key);
if (pairs[x].value)
+ {
free(pairs[x].value);
+ }
}
free(pairs);
using namespace libtest;
-static test_return_t _default_callback(void*)
-{
- return TEST_SUCCESS;
-}
-
Framework::Framework() :
collections(NULL),
_create(NULL),
_destroy(NULL),
- collection_startup(_default_callback),
- collection_shutdown(_default_callback),
- _on_error(NULL),
_runner(NULL),
_socket(false),
_creators_ptr(NULL)
delete _runner;
}
-test_return_t Framework::Item::flush(void* arg, test_st* run)
-{
- if (run->requires_flush and _flush)
- {
- return _flush(arg);
- }
-
- return TEST_SUCCESS;
-}
-
-test_return_t Framework::on_error(const test_return_t rc, void* arg)
-{
- if (_on_error and test_failed(_on_error(rc, arg)))
- {
- return TEST_FAILURE;
- }
-
- return TEST_SUCCESS;
-}
-
-test_return_t Framework::startup(void* arg)
-{
- if (collection_startup)
- {
- return collection_startup(arg);
- }
-
- return TEST_SUCCESS;
-}
-
-test_return_t Framework::Item::startup(void* arg)
-{
- if (_startup)
- {
- return _startup(arg);
- }
-
- return TEST_SUCCESS;
-}
-
libtest::Runner *Framework::runner()
{
if (_runner == NULL)
test_callback_create_fn *_create;
test_callback_destroy_fn *_destroy;
- /* This is called a the beginning of any collection run. */
- test_callback_fn *collection_startup;
-
- /* This is called a the end of any collection run. */
- test_callback_fn *collection_shutdown;
-
- void set_collection_shutdown(test_callback_error_fn *arg)
- {
- _on_error= arg;
- }
-
public:
void* create(test_return_t& arg);
- test_return_t startup(void*);
-
- test_return_t shutdown(void* arg)
- {
- if (collection_shutdown)
- {
- return collection_shutdown(arg);
- }
-
- return TEST_SUCCESS;
- }
-
- /**
- These are run before/after the test. If implemented. Their execution is not controlled
- by the test.
- */
- class Item {
- public:
- /* This is called a the beginning of any run. */
- test_callback_fn *_startup;
-
- test_return_t startup(void*);
-
- /*
- This called on a test if the test requires a flush call (the bool is
- from test_st)
- */
- test_callback_fn *_flush;
-
- public:
-
- Item() :
- _startup(NULL),
- _flush(NULL)
- { }
-
- void set_startup(test_callback_fn *arg)
- {
- _startup= arg;
- }
-
- void set_collection(test_callback_fn *arg)
- {
- _flush= arg;
- }
-
- void set_flush(test_callback_fn *arg)
- {
- _flush= arg;
- }
-
- test_return_t flush(void* arg, test_st* run);
-
- } item;
-
/**
If an error occurs during the test, this is called.
*/
#include <cassert>
#include <cstdlib>
#include <cstring>
+#include <ctime>
+#include <fnmatch.h>
+#include <iostream>
+#include <memory>
+#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
-#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
-#include <ctime>
-#include <fnmatch.h>
-#include <iostream>
#include <signal.h>
return s + us;
}
+static test_return_t runner_code(Framework* frame,
+ test_st* run,
+ void* creators_ptr,
+ long int& load_time)
+{ // Runner Code
+
+ struct timeval start_time, end_time;
+
+ gettimeofday(&start_time, NULL);
+ assert(frame->runner());
+ assert(run->test_fn);
+
+ test_return_t return_code;
+ try
+ {
+ return_code= frame->runner()->run(run->test_fn, creators_ptr);
+ }
+ // Special case where check for the testing of the exception
+ // system.
+ catch (libtest::fatal &e)
+ {
+ if (fatal::is_disabled())
+ {
+ fatal::increment_disabled_counter();
+ return_code= TEST_SUCCESS;
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ gettimeofday(&end_time, NULL);
+ load_time= timedif(end_time, start_time);
+
+ return return_code;
+}
+
#include <getopt.h>
#include <unistd.h>
int exit_code;
- try {
- do {
+ try
+ {
+ do
+ {
exit_code= EXIT_SUCCESS;
- Framework world;
+ std::auto_ptr<Framework> frame(new Framework);
fatal_assert(sigignore(SIGPIPE) == 0);
Stats stats;
- get_world(&world);
+ get_world(frame.get());
test_return_t error;
- void *creators_ptr= world.create(error);
+ void *creators_ptr= frame->create(error);
switch (error)
{
wildcard= argv[2];
}
- for (collection_st *next= world.collections; next and next->name and (not signal.is_shutdown()); next++)
+ for (collection_st *next= frame->collections; next and next->name and (not signal.is_shutdown()); next++)
{
- bool failed= false;
- bool skipped= false;
-
if (collection_to_run.empty() == false and fnmatch(collection_to_run.c_str(), next->name, 0))
{
continue;
stats.collection_total++;
- test_return_t collection_rc= world.startup(creators_ptr);
-
- if (collection_rc == TEST_SUCCESS and next->pre)
- {
- collection_rc= world.runner()->pre(next->pre, creators_ptr);
- }
-
- switch (collection_rc)
- {
- case TEST_SUCCESS:
- break;
-
- case TEST_FAILURE:
- Out << next->name << " [ failed ]";
- failed= true;
- signal.set_shutdown(SHUTDOWN_GRACEFUL);
- goto cleanup;
-
- case TEST_SKIPPED:
- Out << next->name << " [ skipping ]";
- skipped= true;
- goto cleanup;
-
- default:
- fatal_message("invalid return code");
- }
-
- Out << "Collection: " << next->name;
-
- for (test_st *run= next->tests; run->name; run++)
+ bool failed= false;
+ bool skipped= false;
+ test_return_t collection_rc;
+ if (test_success(collection_rc= frame->runner()->pre(next->pre, creators_ptr)))
{
- struct timeval start_time, end_time;
- long int load_time= 0;
+ Out << "Collection: " << next->name;
- if (wildcard && fnmatch(wildcard, run->name, 0))
+ for (test_st *run= next->tests; run->name; run++)
{
- continue;
- }
+ long int load_time= 0;
- test_return_t return_code;
- try {
- if (test_success(return_code= world.item.startup(creators_ptr)))
+ if (wildcard && fnmatch(wildcard, run->name, 0))
{
- if (run->requires_flush)
- {
- return_code= world.runner()->flush(creators_ptr);
- }
+ continue;
+ }
- if (test_success(return_code))
+ test_return_t return_code;
+ try
+ {
+ if (run->requires_flush)
{
- { // Runner Code
- gettimeofday(&start_time, NULL);
- assert(world.runner());
- assert(run->test_fn);
- try
- {
- return_code= world.runner()->run(run->test_fn, creators_ptr);
- }
- // Special case where check for the testing of the exception
- // system.
- catch (libtest::fatal &e)
- {
- if (fatal::is_disabled())
- {
- fatal::increment_disabled_counter();
- return_code= TEST_SUCCESS;
- }
- else
- {
- throw;
- }
- }
-
- gettimeofday(&end_time, NULL);
- load_time= timedif(end_time, start_time);
+ if (test_failed(frame->runner()->flush(creators_ptr)))
+ {
+ Error << "frame->runner()->flush(creators_ptr)";
+ continue;
}
}
- else if (return_code == TEST_SKIPPED)
+
+ return_code= runner_code(frame.get(), run, creators_ptr, load_time);
+
+ if (return_code == TEST_SKIPPED)
{ }
else if (return_code == TEST_FAILURE)
{
- Error << " item.flush(failure)";
+#if 0
+ Error << " frame->runner()->run(failure)";
signal.set_shutdown(SHUTDOWN_GRACEFUL);
+#endif
}
+
}
- else if (return_code == TEST_SKIPPED)
- { }
- else if (return_code == TEST_FAILURE)
+ catch (libtest::fatal &e)
{
- Error << " item.startup(failure)";
- signal.set_shutdown(SHUTDOWN_GRACEFUL);
+ Error << "Fatal exception was thrown: " << e.what();
+ return_code= TEST_FAILURE;
+ throw;
+ }
+ catch (std::exception &e)
+ {
+ Error << "Exception was thrown: " << e.what();
+ return_code= TEST_FAILURE;
+ throw;
+ }
+ catch (...)
+ {
+ Error << "Unknown exception occurred";
+ return_code= TEST_FAILURE;
+ throw;
}
- }
-
- catch (libtest::fatal &e)
- {
- Error << "Fatal exception was thrown: " << e.what();
- return_code= TEST_FAILURE;
- }
- catch (std::exception &e)
- {
- Error << "Exception was thrown: " << e.what();
- return_code= TEST_FAILURE;
- }
- catch (...)
- {
- Error << "Unknown exception occurred";
- return_code= TEST_FAILURE;
- }
- stats.total++;
+ stats.total++;
- switch (return_code)
- {
- case TEST_SUCCESS:
- Out << "\tTesting " << run->name << "\t\t\t\t\t" << load_time / 1000 << "." << load_time % 1000 << "[ " << test_strerror(return_code) << " ]";
- stats.success++;
- break;
-
- case TEST_FAILURE:
- stats.failed++;
- failed= true;
- Out << "\tTesting " << run->name << "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
- break;
-
- case TEST_SKIPPED:
- stats.skipped++;
- skipped= true;
- Out << "\tTesting " << run->name << "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
- break;
-
- default:
- fatal_message("invalid return code");
+ switch (return_code)
+ {
+ case TEST_SUCCESS:
+ Out << "\tTesting " << run->name << "\t\t\t\t\t" << load_time / 1000 << "." << load_time % 1000 << "[ " << test_strerror(return_code) << " ]";
+ stats.success++;
+ break;
+
+ case TEST_FAILURE:
+ stats.failed++;
+ failed= true;
+ Out << "\tTesting " << run->name << "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
+ break;
+
+ case TEST_SKIPPED:
+ stats.skipped++;
+ skipped= true;
+ Out << "\tTesting " << run->name << "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
+ break;
+
+ default:
+ fatal_message("invalid return code");
+ }
+#if 0
+ @TODO add code here to allow for a collection to define a method to reset to allow tests to continue.
+#endif
}
- if (test_failed(world.on_error(return_code, creators_ptr)))
- {
- Error << "Failed while running on_error()";
- signal.set_shutdown(SHUTDOWN_GRACEFUL);
- break;
- }
+ (void) frame->runner()->post(next->post, creators_ptr);
+ }
+ else if (collection_rc == TEST_FAILURE)
+ {
+ Out << next->name << " [ failed ]";
+ failed= true;
+#if 0
+ signal.set_shutdown(SHUTDOWN_GRACEFUL);
+#endif
+ }
+ else if (collection_rc == TEST_SKIPPED)
+ {
+ Out << next->name << " [ skipping ]";
+ skipped= true;
}
- (void) world.runner()->post(next->post, creators_ptr);
-
-cleanup:
if (failed == false and skipped == false)
{
stats.collection_success++;
stats.collection_skipped++;
}
- world.shutdown(creators_ptr);
Outn();
}
- if (not signal.is_shutdown())
+ if (signal.is_shutdown() == false)
{
signal.set_shutdown(SHUTDOWN_GRACEFUL);
}
{
Out << "Some tests were skipped.";
}
- else if (stats.collection_success and stats.collection_failed == 0)
+ else if (stats.collection_success and (stats.collection_failed == 0))
{
Out << "All tests completed successfully.";
}
world->_create= (test_callback_create_fn*)world_create;
world->_destroy= (test_callback_destroy_fn*)world_destroy;
- world->item._startup= (test_callback_fn*)world_test_startup;
- world->_on_error= (test_callback_error_fn*)world_on_error;
-
- world->collection_startup= (test_callback_fn*)world_container_startup;
- world->collection_shutdown= (test_callback_fn*)world_container_shutdown;
-
world->set_runner(new LibmemcachedRunner);
global_framework= world;
noinst_HEADERS+= tests/libmemcached_world.h
noinst_HEADERS+= tests/libmemcached_world_socket.h
noinst_HEADERS+= tests/runner.h
+noinst_HEADERS+= tests/libmemcached_test_container.h
# Cycle should always run first
tests_cycle_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING)
world->_create= (test_callback_create_fn*)world_create;
world->_destroy= (test_callback_destroy_fn*)world_destroy;
- world->item._startup= (test_callback_fn*)world_test_startup;
- world->_on_error= (test_callback_error_fn*)world_on_error;
-
- world->collection_startup= (test_callback_fn*)world_container_startup;
- world->collection_shutdown= (test_callback_fn*)world_container_shutdown;
-
world->set_runner(new LibmemcachedRunner);
world->set_socket();
};
test_st replication_tests[]= {
+ {"validate replication setup", true, (test_callback_fn*)check_replication_sanity_TEST },
{"set", true, (test_callback_fn*)replication_set_test },
{"get", false, (test_callback_fn*)replication_get_test },
{"mget", false, (test_callback_fn*)replication_mget_test },
world->_create= (test_callback_create_fn*)world_create;
world->_destroy= (test_callback_destroy_fn*)world_destroy;
- world->item._startup= (test_callback_fn*)world_test_startup;
- world->_on_error= (test_callback_error_fn*)world_on_error;
-
- world->collection_startup= (test_callback_fn*)world_container_startup;
- world->collection_shutdown= (test_callback_fn*)world_container_shutdown;
-
world->set_runner(new LibmemcachedRunner);
}
world->_create= (test_callback_create_fn*)world_create;
world->_destroy= (test_callback_destroy_fn*)world_destroy;
- world->item._startup= (test_callback_fn*)world_test_startup;
- world->_on_error= (test_callback_error_fn*)world_on_error;
-
- world->collection_startup= (test_callback_fn*)world_container_startup;
- world->collection_shutdown= (test_callback_fn*)world_container_shutdown;
-
world->set_runner(new LibmemcachedRunner);
}
}
#define REGRESSION_BINARY_VS_BLOCK_COUNT 20480
-static pairs_st *global_pairs;
+static pairs_st *global_pairs= NULL;
test_return_t key_setup(memcached_st *memc)
{
test_return_t key_teardown(memcached_st *)
{
pairs_free(global_pairs);
+ global_pairs= NULL;
return TEST_SUCCESS;
}
/* First add all of the items.. */
for (ptrdiff_t x= 0; x < REGRESSION_BINARY_VS_BLOCK_COUNT; ++x)
{
- char blob[1024] = {0};
-
- memcached_return_t rc= memcached_add_by_key(memc, "bob", 3, global_pairs[x].key, global_pairs[x].key_length, blob, sizeof(blob), 0, 0);
+ libtest::vchar_t blob;
+ libtest::vchar::make(blob, 1024);
+
+ memcached_return_t rc= memcached_add_by_key(memc,
+ test_literal_param("bob"),
+ global_pairs[x].key, global_pairs[x].key_length,
+ &blob[0], blob.size(),
+ time_t(0), uint32_t(0));
test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE, memcached_strerror(NULL, rc));
}
world->_create= world_create;
world->_destroy= world_destroy;
- world->item._startup= reinterpret_cast<test_callback_fn*>(world_test_startup);
- world->_on_error= reinterpret_cast<test_callback_error_fn*>(world_on_error);
-
- world->collection_startup= reinterpret_cast<test_callback_fn*>(world_container_startup);
- world->collection_shutdown= reinterpret_cast<test_callback_fn*>(world_container_shutdown);
-
world->set_runner(new LibmemcachedRunner);
}
#include <tests/replication.h>
#include <tests/debug.h>
+#include "tests/libmemcached-1.0/setup_and_teardowns.h"
+
+test_return_t check_replication_sanity_TEST(memcached_st *memc)
+{
+ test_true(memc);
+ test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
+
+ /*
+ * Make sure that we store the item on all servers
+ * (master + replicas == number of servers)
+ */
+ test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS), uint64_t(memcached_server_count(memc) - 1));
+
+ return TEST_SUCCESS;
+}
+
test_return_t replication_set_test(memcached_st *memc)
{
memcached_return_t rc;
uint32_t flags;
char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
&len, &flags, &rc);
- test_true(rc == MEMCACHED_SUCCESS);
- test_true(val != NULL);
+ test_compare(MEMCACHED_SUCCESS, rc);
+ test_true(val);
free(val);
}
{
hits++;
}
- test_true(hits == 4);
+ test_compare(4, hits);
memcached_result_free(&result_obj);
}
world->_create= (test_callback_create_fn*)world_create;
world->_destroy= (test_callback_destroy_fn*)world_destroy;
- world->item._startup= (test_callback_fn*)world_test_startup;
- world->_on_error= (test_callback_error_fn*)world_on_error;
-
- world->collection_startup= (test_callback_fn*)world_container_startup;
- world->collection_shutdown= (test_callback_fn*)world_container_shutdown;
-
world->set_runner(new LibmemcachedRunner);
world->set_sasl("memcached", "memcached");
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached Client and Server
+ *
+ * Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#pragma once
+
+/* The structure we use for the test system */
+struct libmemcached_test_container_st
+{
+private:
+ memcached_st *_parent;
+
+public:
+ libtest::server_startup_st& construct;
+
+ libmemcached_test_container_st(libtest::server_startup_st &construct_arg) :
+ _parent(NULL),
+ construct(construct_arg)
+ { }
+
+ memcached_st* parent()
+ {
+ return _parent;
+ }
+
+ void parent(memcached_st* arg)
+ {
+ reset();
+ _parent= arg;
+ }
+
+ void reset()
+ {
+ if (_parent)
+ {
+ memcached_free(_parent);
+ _parent= NULL;
+ }
+ }
+
+ ~libmemcached_test_container_st()
+ {
+ reset();
+ }
+};
+
+
#pragma once
-/* The structure we use for the test system */
-struct libmemcached_test_container_st
-{
- libtest::server_startup_st& construct;
- memcached_st *parent;
- memcached_st *memc;
-
- libmemcached_test_container_st(libtest::server_startup_st &construct_arg) :
- construct(construct_arg),
- parent(NULL),
- memc(NULL)
- { }
-};
+#include "tests/libmemcached_test_container.h"
static void *world_create(libtest::server_startup_st& servers, test_return_t& error)
{
return global_container;
}
-static test_return_t world_container_startup(libmemcached_test_container_st *container)
-{
- char buffer[BUFSIZ];
-
- test_compare_got(MEMCACHED_SUCCESS,
- libmemcached_check_configuration(container->construct.option_string().c_str(), container->construct.option_string().size(),
- buffer, sizeof(buffer)),
- container->construct.option_string().c_str());
-
- test_null(container->parent);
- container->parent= memcached(container->construct.option_string().c_str(), container->construct.option_string().size());
- test_true(container->parent);
- test_compare(MEMCACHED_SUCCESS, memcached_version(container->parent));
-
- if (container->construct.sasl())
- {
- if (memcached_failed(memcached_behavior_set(container->parent, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1)))
- {
- memcached_free(container->parent);
- return TEST_FAILURE;
- }
-
- if (memcached_failed(memcached_set_sasl_auth_data(container->parent, container->construct.username().c_str(), container->construct.password().c_str())))
- {
- memcached_free(container->parent);
- return TEST_FAILURE;
- }
- }
-
- return TEST_SUCCESS;
-}
-
-static test_return_t world_container_shutdown(libmemcached_test_container_st *container)
-{
- memcached_free(container->parent);
- container->parent= NULL;
-
- return TEST_SUCCESS;
-}
-
-static test_return_t world_test_startup(libmemcached_test_container_st *container)
-{
- test_true(container);
- test_null(container->memc);
- test_true(container->parent);
- container->memc= memcached_clone(NULL, container->parent);
- test_true(container->memc);
-
- return TEST_SUCCESS;
-}
-
-static test_return_t world_on_error(test_return_t , libmemcached_test_container_st *container)
-{
- test_true(container->memc);
- memcached_free(container->memc);
- container->memc= NULL;
-
- return TEST_SUCCESS;
-}
-
static bool world_destroy(void *object)
{
libmemcached_test_container_st *container= (libmemcached_test_container_st *)object;
#include <cassert>
-/* The structure we use for the test system */
-struct libmemcached_test_container_st
-{
- libtest::server_startup_st& construct;
- memcached_st *parent;
- memcached_st *memc;
-
- libmemcached_test_container_st(libtest::server_startup_st &construct_arg) :
- construct(construct_arg),
- parent(NULL),
- memc(NULL)
- { }
-};
+#include "tests/libmemcached_test_container.h"
static void *world_create(libtest::server_startup_st& servers, test_return_t& error)
{
return global_container;
}
-static test_return_t world_container_startup(libmemcached_test_container_st *container)
-{
- char buffer[BUFSIZ];
-
- test_compare_got(MEMCACHED_SUCCESS,
- libmemcached_check_configuration(container->construct.option_string().c_str(), container->construct.option_string().size(),
- buffer, sizeof(buffer)),
- container->construct.option_string().c_str());
-
- test_null(container->parent);
- container->parent= memcached(container->construct.option_string().c_str(), container->construct.option_string().size());
- test_true(container->parent);
- test_compare(MEMCACHED_SUCCESS, memcached_version(container->parent));
-
- if (container->construct.sasl())
- {
- if (memcached_failed(memcached_behavior_set(container->parent, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1)))
- {
- memcached_free(container->parent);
- return TEST_FAILURE;
- }
-
- if (memcached_failed(memcached_set_sasl_auth_data(container->parent, container->construct.username().c_str(), container->construct.password().c_str())))
- {
- memcached_free(container->parent);
- return TEST_FAILURE;
- }
- }
-
- return TEST_SUCCESS;
-}
-
-static test_return_t world_container_shutdown(libmemcached_test_container_st *container)
-{
- memcached_free(container->parent);
- container->parent= NULL;
-
- return TEST_SUCCESS;
-}
-
-static test_return_t world_test_startup(libmemcached_test_container_st *container)
-{
- test_true(container);
- test_null(container->memc);
- test_true(container->parent);
- container->memc= memcached_clone(NULL, container->parent);
- test_true(container->memc);
-
- return TEST_SUCCESS;
-}
-
-static test_return_t world_on_error(test_return_t , libmemcached_test_container_st *container)
-{
- test_true(container->memc);
- memcached_free(container->memc);
- container->memc= NULL;
-
- return TEST_SUCCESS;
-}
-
static bool world_destroy(void *object)
{
libmemcached_test_container_st *container= (libmemcached_test_container_st *)object;
world->_create= (test_callback_create_fn*)world_create;
world->_destroy= (test_callback_destroy_fn*)world_destroy;
- world->item._startup= (test_callback_fn*)world_test_startup;
- world->_on_error= (test_callback_error_fn*)world_on_error;
-
- world->collection_startup= (test_callback_fn*)world_container_startup;
- world->collection_shutdown= (test_callback_fn*)world_container_shutdown;
-
world->set_runner(new LibmemcachedRunner);
}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Gearmand client and server library.
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+class Memc {
+public:
+ Memc()
+ {
+ _memc= memcached_create(NULL);
+
+ if (_memc == NULL)
+ {
+ throw "memcached_create() failed";
+ }
+ }
+
+ Memc(memcached_st* arg)
+ {
+ _memc= memcached_clone(NULL, arg);
+
+ if (_memc == NULL)
+ {
+ throw "memcached_clone() failed";
+ }
+ }
+
+ memcached_st* operator&() const
+ {
+ return _memc;
+ }
+
+ memcached_st* operator->() const
+ {
+ return _memc;
+ }
+
+ ~Memc()
+ {
+ memcached_free(_memc);
+ }
+
+private:
+ memcached_st *_memc;
+
+};
test_return_t replication_randomize_mget_fail_test(memcached_st *memc);
test_return_t replication_miss_test(memcached_st *memc);
+
+test_return_t check_replication_sanity_TEST(memcached_st*);
#pragma once
#include "tests/libmemcached-1.0/generate.h"
+#include "tests/memc.h"
class LibmemcachedRunner : public libtest::Runner {
public:
test_return_t flush(libmemcached_test_container_st *container)
{
- test_true(container->memc);
- memcached_flush(container->memc, 0);
- memcached_quit(container->memc);
+ Memc memc(container->parent());
+ memcached_flush(&memc, 0);
+ memcached_quit(&memc);
return TEST_SUCCESS;
}
private:
test_return_t _runner_default(libmemcached_test_callback_fn func, libmemcached_test_container_st *container)
{
+ test_true(container);
+ test_true(container->parent());
+ Memc memc(container->parent());
+
test_compare(true, check());
+ test_return_t ret= TEST_SUCCESS;
if (func)
{
test_true(container);
- test_true(container->memc);
- test_return_t ret;
try {
- ret= func(container->memc);
+ ret= func(&memc);
}
catch (std::exception& e)
{
libtest::Error << e.what();
- return TEST_FAILURE;
+ ret= TEST_FAILURE;
}
-
- return ret;
}
- return TEST_SUCCESS;
+ return ret;
}
test_return_t _pre_runner_default(libmemcached_test_callback_fn func, libmemcached_test_container_st *container)
{
+ container->reset();
+ {
+ char buffer[BUFSIZ];
+
+ test_compare_got(MEMCACHED_SUCCESS,
+ libmemcached_check_configuration(container->construct.option_string().c_str(), container->construct.option_string().size(),
+ buffer, sizeof(buffer)),
+ container->construct.option_string().c_str());
+
+ test_null(container->parent());
+ container->parent(memcached(container->construct.option_string().c_str(), container->construct.option_string().size()));
+ test_true(container->parent());
+ test_compare(MEMCACHED_SUCCESS, memcached_version(container->parent()));
+
+ if (container->construct.sasl())
+ {
+ if (memcached_failed(memcached_behavior_set(container->parent(), MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1)))
+ {
+ container->reset();
+ return TEST_FAILURE;
+ }
+
+ if (memcached_failed(memcached_set_sasl_auth_data(container->parent(), container->construct.username().c_str(), container->construct.password().c_str())))
+ {
+ container->reset();
+ return TEST_FAILURE;
+ }
+ }
+ }
+
test_compare(true, check());
if (func)
{
- return func(container->parent);
+ return func(container->parent());
}
return TEST_SUCCESS;
test_compare(true, check());
cleanup_pairs(NULL);
+ test_return_t rc= TEST_SUCCESS;
if (func)
{
- return func(container->parent);
+ rc= func(container->parent());
}
+ container->reset();
- return TEST_SUCCESS;
+ return rc;
}
};