From 7ba11a92a63df071ee3f848c980c8459dc184ebc Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Sun, 25 Mar 2012 18:08:09 -0700 Subject: [PATCH] Update --- libmemcached/io.cc | 1 - libtest/blobslap_worker.cc | 12 +--- libtest/cmdline.cc | 133 +++++++++++++++++++++++++++++------- libtest/cmdline.h | 8 +++ libtest/comparison.cc | 34 ++++++++- libtest/comparison.hpp | 7 ++ libtest/framework.cc | 8 ++- libtest/gearmand.cc | 12 +--- libtest/memcached.cc | 45 ++++++------ libtest/run.gdb | 1 - libtest/runner.h | 13 ++++ libtest/server.cc | 76 ++++++++------------- libtest/server.h | 9 ++- libtest/server_container.cc | 13 ++++ libtest/server_container.h | 2 + libtest/signal.cc | 2 +- libtest/test.cc | 36 ++++++++-- tests/libmemcached_world.h | 85 ++++++++++++----------- 18 files changed, 327 insertions(+), 170 deletions(-) diff --git a/libmemcached/io.cc b/libmemcached/io.cc index 049c436d..d7c13199 100644 --- a/libmemcached/io.cc +++ b/libmemcached/io.cc @@ -206,7 +206,6 @@ static memcached_return_t io_wait(memcached_server_write_instance_st ptr, size_t loop_max= 5; while (--loop_max) // While loop is for ERESTART or EINTR { - int error= poll(&fds, 1, ptr->root->poll_timeout); switch (error) { diff --git a/libtest/blobslap_worker.cc b/libtest/blobslap_worker.cc index caddbdd7..f3419620 100644 --- a/libtest/blobslap_worker.cc +++ b/libtest/blobslap_worker.cc @@ -49,7 +49,7 @@ class BlobslapWorker : public Server private: public: BlobslapWorker(in_port_t port_arg) : - Server("localhost", port_arg) + Server("localhost", port_arg, "benchmark/blobslap_worker", true) { set_pid_file(); } @@ -118,16 +118,6 @@ public: return "blobslap_worker"; }; - const char *executable() - { - return "benchmark/blobslap_worker"; - } - - const char *daemon_file_option() - { - return "--daemon"; - } - bool has_port_option() const { return true; diff --git a/libtest/cmdline.cc b/libtest/cmdline.cc index e774113a..1a13342b 100644 --- a/libtest/cmdline.cc +++ b/libtest/cmdline.cc @@ -30,6 +30,7 @@ using namespace libtest; #include #include #include +#include #include #include #include @@ -239,19 +240,71 @@ Application::error_t Application::run(const char *args[]) return Application::SUCCESS; } -Application::error_t Application::wait() +bool Application::check() const { - if (_pid == -1) + Error << "Testing " << _exectuble; + if (kill(_pid, 0) == 0) { - Error << "wait() got an invalid pid_t"; - return Application::INVALID; + return true; } + return false; +} + +void Application::murder() +{ + slurp(); + kill(_pid, SIGTERM); +} + +// false means that no data was returned +bool Application::slurp() +{ + struct pollfd fds[2]; + fds[0].fd= stdout_fd.fd()[0]; + fds[0].events= POLLIN; + fds[0].revents= 0; + fds[1].fd= stderr_fd.fd()[0]; + fds[1].events= POLLIN; + fds[1].revents= 0; + + int active_fd; + if ((active_fd= poll(fds, 2, 400)) == -1) + { + int error; + switch ((error= errno)) + { +#ifdef TARGET_OS_LINUX + case ERESTART: +#endif + case EINTR: + break; + + case EFAULT: + case ENOMEM: + fatal_message(strerror(error)); + break; + + case EINVAL: + fatal_message("RLIMIT_NOFILE exceeded, or if OSX the timeout value was invalid"); + break; + + default: + fatal_message(strerror(error)); + break; + } + } + + if (active_fd == 0) + { + return false; + } + + if (fds[0].revents == POLLIN) { ssize_t read_length; char buffer[1024]= { 0 }; - bool bail= false; - while (((read_length= ::read(stdout_fd.fd()[0], buffer, sizeof(buffer))) != 0) or bail) + while ((read_length= ::read(stdout_fd.fd()[0], buffer, sizeof(buffer)))) { if (read_length == -1) { @@ -262,8 +315,10 @@ Application::error_t Application::wait() default: Error << strerror(errno); - bail= true; + break; } + + break; } _stdout_buffer.reserve(read_length +1); for (size_t x= 0; x < read_length; x++) @@ -274,11 +329,11 @@ Application::error_t Application::wait() } } + if (fds[1].revents == POLLIN) { ssize_t read_length; char buffer[1024]= { 0 }; - bool bail= false; - while (((read_length= ::read(stderr_fd.fd()[0], buffer, sizeof(buffer))) != 0) or bail) + while ((read_length= ::read(stderr_fd.fd()[0], buffer, sizeof(buffer)))) { if (read_length == -1) { @@ -289,8 +344,10 @@ Application::error_t Application::wait() default: Error << strerror(errno); - bail= true; + break; } + + break; } _stderr_buffer.reserve(read_length +1); for (size_t x= 0; x < read_length; x++) @@ -301,13 +358,30 @@ Application::error_t Application::wait() } } + return true; +} + +Application::error_t Application::wait() +{ + fatal_assert(_pid != -1); + + slurp(); + error_t exit_code= FAILURE; { int status= 0; pid_t waited_pid; if ((waited_pid= waitpid(_pid, &status, 0)) == -1) { - Error << "Error occured while waitpid(" << strerror(errno) << ") on pid " << int(_pid); + switch (errno) + { + case ECHILD: + exit_code= Application::SUCCESS; + break; + + default: + Error << "Error occured while waitpid(" << strerror(errno) << ") on pid " << int(_pid); + } } else { @@ -329,6 +403,13 @@ Application::error_t Application::wait() return exit_code; } +void Application::add_long_option(const std::string& name, const std::string& option_value) +{ + std::string arg(name); + arg+= option_value; + _options.push_back(std::make_pair(arg, std::string())); +} + void Application::add_option(const std::string& arg) { _options.push_back(std::make_pair(arg, std::string())); @@ -347,12 +428,27 @@ Application::Pipe::Pipe() _open[1]= false; } +void Application::Pipe::nonblock() +{ + int ret; + if ((ret= fcntl(_fd[0], F_GETFL, 0)) == -1) + { + Error << "fcntl(F_GETFL) " << strerror(errno); + throw strerror(errno); + } + + if ((ret= fcntl(_fd[0], F_SETFL, ret | O_NONBLOCK)) == -1) + { + Error << "fcntl(F_SETFL) " << strerror(errno); + throw strerror(errno); + } +} + void Application::Pipe::reset() { close(READ); close(WRITE); - int ret; if (pipe(_fd) == -1) { throw strerror(errno); @@ -360,18 +456,9 @@ void Application::Pipe::reset() _open[0]= true; _open[1]= true; + if (0) { - if ((ret= fcntl(_fd[0], F_GETFL, 0)) == -1) - { - Error << "fcntl(F_GETFL) " << strerror(errno); - throw strerror(errno); - } - - if ((ret= fcntl(_fd[0], F_SETFL, ret | O_NONBLOCK)) == -1) - { - Error << "fcntl(F_SETFL) " << strerror(errno); - throw strerror(errno); - } + nonblock(); } } diff --git a/libtest/cmdline.h b/libtest/cmdline.h index f6da62be..0f069925 100644 --- a/libtest/cmdline.h +++ b/libtest/cmdline.h @@ -58,6 +58,8 @@ public: posix_spawn_file_actions_t& file_actions, const int newfildes); + void nonblock(); + private: int _fd[2]; bool _open[2]; @@ -70,6 +72,7 @@ public: void add_option(const std::string&); void add_option(const std::string&, const std::string&); + void add_long_option(const std::string& option_name, const std::string& option_value); error_t run(const char *args[]= NULL); error_t wait(); @@ -100,6 +103,11 @@ public: _use_valgrind= arg; } + bool check() const; + + bool slurp(); + void murder(); + void use_gdb(bool arg= true) { _use_gdb= arg; diff --git a/libtest/comparison.cc b/libtest/comparison.cc index 121df252..a4c3736d 100644 --- a/libtest/comparison.cc +++ b/libtest/comparison.cc @@ -24,14 +24,44 @@ namespace libtest { -bool _in_valgrind(const char*, int, const char*) +bool valgrind_is_caller(void) { if (bool(getenv("TESTS_ENVIRONMENT")) and strstr(getenv("TESTS_ENVIRONMENT"), "valgrind")) { return true; } - return TEST_SUCCESS; + return false; +} + +bool gdb_is_caller(void) +{ + if (bool(getenv("TESTS_ENVIRONMENT")) and strstr(getenv("TESTS_ENVIRONMENT"), "gdb")) + { + return true; + } + + return false; +} + +bool helgrind_is_caller(void) +{ + if (bool(getenv("TESTS_ENVIRONMENT")) and strstr(getenv("TESTS_ENVIRONMENT"), "helgrind")) + { + return true; + } + + return false; +} + +bool _in_valgrind(const char*, int, const char*) +{ + if (valgrind_is_caller()) + { + return true; + } + + return false; } } // namespace libtest diff --git a/libtest/comparison.hpp b/libtest/comparison.hpp index 98ea1c8b..4c809982 100644 --- a/libtest/comparison.hpp +++ b/libtest/comparison.hpp @@ -34,6 +34,13 @@ namespace libtest { +LIBTEST_API +bool gdb_is_caller(void); + +LIBTEST_API +bool valgrind_is_caller(void); + +LIBTEST_API bool _in_valgrind(const char *file, int line, const char *func); template diff --git a/libtest/framework.cc b/libtest/framework.cc index a9730a0e..96918664 100644 --- a/libtest/framework.cc +++ b/libtest/framework.cc @@ -120,7 +120,13 @@ test_return_t Framework::Item::startup(void* arg) libtest::Runner *Framework::runner() { - return _runner ? _runner : &defualt_runners; + if (_runner == NULL) + { + _runner= &defualt_runners; + } + _runner->set_servers(_servers); + + return _runner; } void* Framework::create(test_return_t& arg) diff --git a/libtest/gearmand.cc b/libtest/gearmand.cc index 85307fcf..1cb52079 100644 --- a/libtest/gearmand.cc +++ b/libtest/gearmand.cc @@ -90,7 +90,7 @@ class Gearmand : public libtest::Server private: public: Gearmand(const std::string& host_arg, in_port_t port_arg) : - libtest::Server(host_arg, port_arg) + libtest::Server(host_arg, port_arg, GEARMAND_BINARY, true) { set_pid_file(); } @@ -160,16 +160,6 @@ public: return "gearmand"; }; - const char *executable() - { - return GEARMAND_BINARY; - } - - const char *daemon_file_option() - { - return "--daemon"; - } - void log_file_option(Application& app, const std::string& arg) { if (arg.empty() == false) diff --git a/libtest/memcached.cc b/libtest/memcached.cc index ce523a7a..e7c16395 100644 --- a/libtest/memcached.cc +++ b/libtest/memcached.cc @@ -50,6 +50,18 @@ using namespace libtest; using namespace libtest; +namespace { + bool is_memcached_libtool() + { + if (MEMCACHED_BINARY and strcmp(MEMCACHED_BINARY, "memcached/memcached") == 0) + { + return true; + } + + return false; + } +} + class Memcached : public libtest::Server { std::string _username; @@ -61,13 +73,15 @@ public: const bool is_socket_arg, const std::string& username_arg, const std::string& password_arg) : - libtest::Server(host_arg, port_arg, is_socket_arg), + libtest::Server(host_arg, port_arg, + MEMCACHED_BINARY, is_memcached_libtool(), is_socket_arg), _username(username_arg), _password(password_arg) { } Memcached(const std::string& host_arg, const in_port_t port_arg, const bool is_socket_arg) : - libtest::Server(host_arg, port_arg, is_socket_arg) + libtest::Server(host_arg, port_arg, + MEMCACHED_BINARY, is_memcached_libtool(), is_socket_arg) { set_pid_file(); } @@ -168,12 +182,7 @@ public: bool is_libtool() { - if (MEMCACHED_BINARY and strcmp(MEMCACHED_BINARY, "memcached/memcached") == 0) - { - return true; - } - - return false; + return is_memcached_libtool(); } virtual void pid_file_option(Application& app, const std::string& arg) @@ -189,11 +198,6 @@ public: return "-s "; } - const char *daemon_file_option() - { - return "-d"; - } - virtual void port_option(Application& app, in_port_t arg) { char buffer[30]; @@ -237,8 +241,8 @@ class MemcachedLight : public libtest::Server { public: - MemcachedLight(const std::string& host_arg, const in_port_t port_arg): - libtest::Server(host_arg, port_arg) + MemcachedLight(const std::string& host_arg, const in_port_t port_arg) : + libtest::Server(host_arg, port_arg, MEMCACHED_LIGHT_BINARY, true) { set_pid_file(); } @@ -309,11 +313,6 @@ public: return MEMCACHED_LIGHT_BINARY; } - const char *daemon_file_option() - { - return "--daemon"; - } - virtual void port_option(Application& app, in_port_t arg) { char buffer[1024]; @@ -411,9 +410,9 @@ public: bool ping() { // Memcached is slow to start, so we need to do this - if (not pid_file().empty()) + if (pid_file().empty() == false) { - if (not wait_for_pidfile()) + if (wait_for_pidfile() == false) { Error << "Pidfile was not found:" << pid_file(); return -1; @@ -432,7 +431,7 @@ public: ret= libmemcached_util_ping2(hostname().c_str(), port(), username().c_str(), password().c_str(), &rc); } - if (memcached_failed(rc) or not ret) + if (memcached_failed(rc) or ret == false) { Error << "libmemcached_util_ping2(" << hostname() << ", " << port() << ", " << username() << ", " << password() << ") error: " << memcached_strerror(NULL, rc); } diff --git a/libtest/run.gdb b/libtest/run.gdb index 86b5fe07..c38beb27 100644 --- a/libtest/run.gdb +++ b/libtest/run.gdb @@ -3,4 +3,3 @@ set logging overwrite on set environment LIBTEST_IN_GDB=1 run thread apply all bt -quit diff --git a/libtest/runner.h b/libtest/runner.h index 217e2697..ea42c260 100644 --- a/libtest/runner.h +++ b/libtest/runner.h @@ -37,7 +37,20 @@ public: Runner(); + void set_servers(libtest::server_startup_st& arg) + { + _servers= &arg; + } + + bool check() + { + return _servers ? _servers->check() : true; + } + virtual ~Runner() { } + +private: + libtest::server_startup_st* _servers; }; } // namespace Runner diff --git a/libtest/server.cc b/libtest/server.cc index 7591e8bf..55713d45 100644 --- a/libtest/server.cc +++ b/libtest/server.cc @@ -76,12 +76,15 @@ std::ostream& operator<<(std::ostream& output, const Server &arg) #define MAGIC_MEMORY 123570 -Server::Server(const std::string& host_arg, const in_port_t port_arg, bool is_socket_arg) : +Server::Server(const std::string& host_arg, const in_port_t port_arg, + const std::string& executable, const bool _is_libtool, + bool is_socket_arg) : _magic(MAGIC_MEMORY), _is_socket(is_socket_arg), _pid(-1), _port(port_arg), - _hostname(host_arg) + _hostname(host_arg), + _app(executable, _is_libtool) { } @@ -91,6 +94,18 @@ Server::~Server() { Error << "Unable to kill:" << *this; } + + Application::error_t ret; + if (Application::SUCCESS != (ret= _app.wait())) + { + Error << "Application::wait() " << _running << " " << ret << ": " << _app.stderr_result(); + } +} + +bool Server::check() +{ + _app.slurp(); + return _app.check(); } bool Server::validate() @@ -147,41 +162,29 @@ bool Server::start() fatal_message("has_pid() failed, programer error"); } - Application app(executable(), is_libtool()); - - if (is_debug()) + // This needs more work. +#if 0 + if (gdb_is_caller()) { - app.use_gdb(); - } - else if (getenv("TESTS_ENVIRONMENT")) - { - if (strstr(getenv("TESTS_ENVIRONMENT"), "gdb")) - { - app.use_gdb(); - } + _app.use_gdb(); } +#endif - if (args(app) == false) + if (args(_app) == false) { Error << "Could not build command()"; return false; } Application::error_t ret; - if (Application::SUCCESS != (ret= app.run())) + if (Application::SUCCESS != (ret= _app.run())) { Error << "Application::run() " << ret; return false; } - _running= app.print(); - - if (Application::SUCCESS != (ret= app.wait())) - { - Error << "Application::wait() " << _running << " " << ret; - return false; - } + _running= _app.print(); - if (is_valgrind()) + if (valgrind_is_caller()) { dream(5, 50000); } @@ -198,11 +201,11 @@ bool Server::start() } } + uint32_t this_wait; bool pinged= false; { uint32_t timeout= 20; // This number should be high enough for valgrind startup (which is slow) uint32_t waited; - uint32_t this_wait; uint32_t retry; for (waited= 0, retry= 1; ; retry++, waited+= this_wait) @@ -230,7 +233,9 @@ bool Server::start() { fatal_message("Failed to kill off server after startup occurred, when pinging failed"); } - Error << "Failed to ping() server started, having pid_file. exec:" << _running; + Error << "Failed to ping(), waited:" << this_wait + << " server started, having pid_file. exec:" << _running + << " error:" << _app.stderr_result(); } else { @@ -367,12 +372,6 @@ bool Server::args(Application& app) pid_file_option(app, pid_file()); } - assert(daemon_file_option()); - if (daemon_file_option() and not is_valgrind() and not is_helgrind()) - { - app.add_option(daemon_file_option()); - } - if (has_socket_file_option()) { if (set_socket_file() == false) @@ -403,21 +402,6 @@ bool Server::args(Application& app) return true; } -bool Server::is_debug() const -{ - return bool(getenv("LIBTEST_MANUAL_GDB")); -} - -bool Server::is_valgrind() const -{ - return bool(getenv("LIBTEST_MANUAL_VALGRIND")); -} - -bool Server::is_helgrind() const -{ - return bool(getenv("LIBTEST_MANUAL_HELGRIND")); -} - bool Server::kill(pid_t pid_arg) { if (check_pid(pid_arg) and kill_pid(pid_arg)) // If we kill it, reset diff --git a/libtest/server.h b/libtest/server.h index 1b6841d5..c9700e95 100644 --- a/libtest/server.h +++ b/libtest/server.h @@ -55,13 +55,13 @@ protected: std::string _extra_args; public: - Server(const std::string& hostname, const in_port_t port_arg, const bool is_socket_arg= false); + Server(const std::string& hostname, const in_port_t port_arg, + const std::string& executable, const bool _is_libtool, + const bool is_socket_arg= false); virtual ~Server(); virtual const char *name()= 0; - virtual const char *executable()= 0; - virtual const char *daemon_file_option()= 0; virtual bool is_libtool()= 0; virtual bool has_socket_file_option() const @@ -224,6 +224,8 @@ public: return _running; } + bool check(); + std::string log_and_pid(); bool kill(pid_t pid_arg); @@ -235,6 +237,7 @@ public: protected: bool set_pid_file(); Options _options; + Application _app; private: bool is_helgrind() const; diff --git a/libtest/server_container.cc b/libtest/server_container.cc index 579f901c..1b5229cc 100644 --- a/libtest/server_container.cc +++ b/libtest/server_container.cc @@ -102,6 +102,19 @@ void server_startup_st::shutdown_and_remove() servers.clear(); } +bool server_startup_st::check() const +{ + for (std::vector::const_iterator iter= servers.begin(); iter != servers.end(); iter++) + { + if ((*iter)->check() == false) + { + return false; + } + } + + return true; +} + void server_startup_st::shutdown() { for (std::vector::iterator iter= servers.begin(); iter != servers.end(); iter++) diff --git a/libtest/server_container.h b/libtest/server_container.h index 29ecb97d..bb2a4ea5 100644 --- a/libtest/server_container.h +++ b/libtest/server_container.h @@ -111,6 +111,8 @@ public: void shutdown(); bool shutdown(uint32_t number_of_host); + bool check() const; + void push_server(Server *); Server *pop_server(); }; diff --git a/libtest/signal.cc b/libtest/signal.cc index bc9da4bc..266a7c4a 100644 --- a/libtest/signal.cc +++ b/libtest/signal.cc @@ -160,7 +160,7 @@ SignalThread::SignalThread() : { pthread_mutex_init(&shutdown_mutex, NULL); sigemptyset(&set); - if (not getenv("LIBTEST_IN_GDB")) + if (bool(getenv("LIBTEST_IN_GDB")) == false) { sigaddset(&set, SIGABRT); sigaddset(&set, SIGQUIT); diff --git a/libtest/test.cc b/libtest/test.cc index cafc48d4..3e5713c9 100644 --- a/libtest/test.cc +++ b/libtest/test.cc @@ -77,6 +77,7 @@ static long int timedif(struct timeval a, struct timeval b) int main(int argc, char *argv[]) { bool opt_repeat= false; + bool opt_quiet= false; std::string collection_to_run; // Options parsing @@ -84,14 +85,17 @@ int main(int argc, char *argv[]) enum long_option_t { OPT_LIBYATL_VERSION, OPT_LIBYATL_MATCH_COLLECTION, + OPT_LIBYATL_QUIET, OPT_LIBYATL_REPEAT }; static struct option long_options[]= { - {"repeat", no_argument, NULL, OPT_LIBYATL_REPEAT}, - {"collection", required_argument, NULL, OPT_LIBYATL_MATCH_COLLECTION}, - {0, 0, 0, 0} + { "version", no_argument, NULL, OPT_LIBYATL_VERSION }, + { "quiet", no_argument, NULL, OPT_LIBYATL_QUIET }, + { "repeat", no_argument, NULL, OPT_LIBYATL_REPEAT }, + { "collection", required_argument, NULL, OPT_LIBYATL_MATCH_COLLECTION }, + { 0, 0, 0, 0 } }; int option_index= 0; @@ -108,6 +112,10 @@ int main(int argc, char *argv[]) case OPT_LIBYATL_VERSION: break; + case OPT_LIBYATL_QUIET: + opt_quiet= true; + break; + case OPT_LIBYATL_REPEAT: opt_repeat= true; break; @@ -129,11 +137,27 @@ int main(int argc, char *argv[]) srandom((unsigned int)time(NULL)); - if (getenv("LIBTEST_QUIET") and strcmp(getenv("LIBTEST_QUIET"), "0") == 0) + int repeat; + if (bool(getenv("YATL_REPEAT")) and (repeat= atoi(getenv("YATL_REPEAT")))) { - close(STDOUT_FILENO); + opt_repeat= true; + } + + if ((getenv("YATL_QUIET") and strcmp(getenv("YATL_QUIET"), "0") == 0) or opt_quiet) + { + opt_quiet= true; } else if (getenv("JENKINS_URL")) + { + if (getenv("YATL_QUIET") and strcmp(getenv("YATL_QUIET"), "1") == 0) + { } + else + { + opt_quiet= true; + } + } + + if (opt_quiet) { close(STDOUT_FILENO); } @@ -173,7 +197,7 @@ int main(int argc, char *argv[]) fatal_assert(sigignore(SIGPIPE) == 0); libtest::SignalThread signal; - if (not signal.setup()) + if (signal.setup() == false) { Error << "Failed to setup signals"; return EXIT_FAILURE; diff --git a/tests/libmemcached_world.h b/tests/libmemcached_world.h index 18137986..aef39bbf 100644 --- a/tests/libmemcached_world.h +++ b/tests/libmemcached_world.h @@ -208,63 +208,66 @@ static bool world_destroy(void *object) typedef test_return_t (*libmemcached_test_callback_fn)(memcached_st *); -static test_return_t _runner_default(libmemcached_test_callback_fn func, libmemcached_test_container_st *container) -{ - if (func) +class LibmemcachedRunner : public libtest::Runner { +public: + test_return_t run(test_callback_fn* func, void *object) { - test_true(container); - test_true(container->memc); - test_return_t ret; - try { - ret= func(container->memc); - } - catch (std::exception& e) - { - libtest::Error << e.what(); - return TEST_FAILURE; - } - - return ret; + return _runner_default(libmemcached_test_callback_fn(func), (libmemcached_test_container_st*)object); } - return TEST_SUCCESS; -} - -static test_return_t _pre_runner_default(libmemcached_test_callback_fn func, libmemcached_test_container_st *container) -{ - if (func) + test_return_t pre(test_callback_fn* func, void *object) { - return func(container->parent); + return _pre_runner_default(libmemcached_test_callback_fn(func), (libmemcached_test_container_st*)object); } - return TEST_SUCCESS; -} - -static test_return_t _post_runner_default(libmemcached_test_callback_fn func, libmemcached_test_container_st *container) -{ - if (func) + test_return_t post(test_callback_fn* func, void *object) { - return func(container->parent); + return _post_runner_default(libmemcached_test_callback_fn(func), (libmemcached_test_container_st*)object); } - return TEST_SUCCESS; -} - -class LibmemcachedRunner : public libtest::Runner { -public: - test_return_t run(test_callback_fn* func, void *object) +private: + test_return_t _runner_default(libmemcached_test_callback_fn func, libmemcached_test_container_st *container) { - return _runner_default(libmemcached_test_callback_fn(func), (libmemcached_test_container_st*)object); + test_compare(true, check()); + + if (func) + { + test_true(container); + test_true(container->memc); + test_return_t ret; + try { + ret= func(container->memc); + } + catch (std::exception& e) + { + libtest::Error << e.what(); + return TEST_FAILURE; + } + + return ret; + } + + return TEST_SUCCESS; } - test_return_t pre(test_callback_fn* func, void *object) + test_return_t _pre_runner_default(libmemcached_test_callback_fn func, libmemcached_test_container_st *container) { - return _pre_runner_default(libmemcached_test_callback_fn(func), (libmemcached_test_container_st*)object); + if (func) + { + return func(container->parent); + } + + return TEST_SUCCESS; } - test_return_t post(test_callback_fn* func, void *object) + test_return_t _post_runner_default(libmemcached_test_callback_fn func, libmemcached_test_container_st *container) { - return _post_runner_default(libmemcached_test_callback_fn(func), (libmemcached_test_container_st*)object); + if (func) + { + return func(container->parent); + } + + return TEST_SUCCESS; } }; -- 2.30.2