if (!val)
{
if (verbose)
+ {
fprintf(stderr, "\n%s:%d: %s", file, line, expression);
+ }
if (do_core)
+ {
abort();
+ }
return TEST_FAIL;
}
size_t num_bytes= len - offset;
ssize_t nw= timeout_io_op(sock, POLLOUT, (void*)(ptr + offset), num_bytes);
if (nw == -1)
+ {
verify(get_socket_errno() == EINTR || get_socket_errno() == EAGAIN);
+ }
else
+ {
offset+= (size_t)nw;
+ }
+
} while (offset < len);
return TEST_PASS;
static enum test_return resend_packet(command *cmd)
{
size_t length= sizeof (protocol_binary_request_no_extras) +
- ntohl(cmd->plain.message.header.request.bodylen);
+ ntohl(cmd->plain.message.header.request.bodylen);
execute(retry_write(cmd, length));
return TEST_PASS;
fprintf(stderr, "Errno: %d %s\n", get_socket_errno(), strerror(errno));
verify(get_socket_errno() == EINTR || get_socket_errno() == EAGAIN);
break;
+
case 0:
return TEST_FAIL;
+
default:
offset+= (size_t)nr;
}
for (int ii= 0; ii < 10; ii++)
{
if (ii == 0)
+ {
execute(send_packet(&cmd));
+ }
else
+ {
execute(resend_packet(&cmd));
+ }
if (cc == PROTOCOL_BINARY_CMD_SET)
{
for (int ii= 0; ii < 10; ii++)
{
if (ii == 0)
+ {
execute(send_packet(&cmd));
+ }
else
+ {
execute(resend_packet(&cmd));
+ }
if (cc == PROTOCOL_BINARY_CMD_REPLACE || ii == 0)
{
uint16_t expected_result;
if (ii == 0)
+ {
expected_result=PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
+ }
else
+ {
expected_result=PROTOCOL_BINARY_RESPONSE_SUCCESS;
+ }
execute(send_binary_noop());
execute(recv_packet(&rsp));
execute(binary_set_item(key, key));
}
else
+ {
execute(test_binary_noop());
+ }
}
/* verify that replace with CAS value works! */
const char *value;
if (cc == PROTOCOL_BINARY_CMD_APPEND || cc == PROTOCOL_BINARY_CMD_APPENDQ)
+ {
value="hello";
+ }
else
+ {
value=" world";
+ }
execute(binary_set_item(key, value));
if (cc == PROTOCOL_BINARY_CMD_APPEND || cc == PROTOCOL_BINARY_CMD_APPENDQ)
+ {
value=" world";
+ }
else
+ {
value="hello";
+ }
raw_command(&cmd, cc, key, strlen(key), value, strlen(value));
execute(send_packet(&cmd));
verify(validate_response_header(&rsp, cc, PROTOCOL_BINARY_RESPONSE_SUCCESS));
}
else
+ {
execute(test_binary_noop());
+ }
raw_command(&cmd, PROTOCOL_BINARY_CMD_GET, key, strlen(key), NULL, 0);
execute(send_packet(&cmd));
execute(send_string(buffer));
if (!noreply)
+ {
execute(receive_response("STORED\r\n"));
+ }
return test_ascii_version();
}
execute(send_string(buffer));
if (!noreply)
+ {
execute(receive_response("STORED\r\n"));
+ }
execute(send_string(buffer));
if (!noreply)
+ {
execute(receive_response("NOT_STORED\r\n"));
+ }
return test_ascii_version();
}
char buffer[1024];
size_t datasize= 0;
if (value != NULL)
+ {
datasize= strlen(value);
+ }
verify(datasize < sizeof(buffer));
snprintf(buffer, sizeof(buffer), "get %s\r\n", key);
execute(send_string(buffer));
if (exist)
+ {
execute(ascii_get_value(key, value));
+ }
execute(retry_read(buffer, 5));
verify(memcmp(buffer, "END\r\n", 5) == 0);
char buffer[1024];
size_t datasize= 0;
if (value != NULL)
+ {
datasize= strlen(value);
+ }
verify(datasize < sizeof(buffer));
snprintf(buffer, sizeof(buffer), "gets %s\r\n", key);
execute(send_string(buffer));
if (noreply)
+ {
execute(test_ascii_version());
+ }
else
+ {
execute(receive_response("NOT_STORED\r\n"));
+ }
execute(ascii_set_item(key, "value"));
execute(ascii_get_item(key, "value", true));
execute(send_string(buffer));
if (noreply)
+ {
execute(test_ascii_version());
+ }
else
+ {
execute(receive_response("STORED\r\n"));
+ }
/* reexecute the same command should fail due to illegal cas */
execute(send_string(buffer));
if (noreply)
+ {
execute(test_ascii_version());
+ }
else
+ {
execute(receive_response("EXISTS\r\n"));
+ }
return test_ascii_version();
}
};
for (uint32_t x= 0; x < nkeys; ++x)
+ {
execute(ascii_set_item(keys[x], "value"));
+ }
/* Ask for a key that doesn't exist as well */
execute(send_string("get test_ascii_mget1 test_ascii_mget2 test_ascii_mget3 "
}
for (uint32_t x= 0; x < nkeys; ++x)
+ {
free(returned[x]);
+ }
return TEST_PASS;
}
execute(send_string(cmd));
if (noreply)
+ {
execute(test_ascii_version());
+ }
else
{
char buffer[80];
/* verify that it doesn't wrap */
execute(send_string(cmd));
if (noreply)
+ {
execute(test_ascii_version());
+ }
else
{
char buffer[80];
execute(ascii_set_item(key, value));
if (append)
+ {
value=" world";
+ }
else
+ {
value="hello";
+ }
char cmd[400];
snprintf(cmd, sizeof(cmd), "%s %s 0 0 %u%s\r\n%s\r\n",
execute(send_string(cmd));
if (noreply)
+ {
execute(test_ascii_version());
+ }
else
+ {
execute(receive_response("STORED\r\n"));
+ }
execute(ascii_get_item(key, "hello world", true));
execute(send_string(cmd));
if (noreply)
+ {
execute(test_ascii_version());
+ }
else
+ {
execute(receive_response("NOT_STORED\r\n"));
+ }
return TEST_PASS;
}
"\t-a\tOnly test the ascii protocol\n"
"\t-b\tOnly test the binary protocol\n",
argv[0]);
- return EXIT_FAILURE;
+ return EXIT_SUCCESS;
}
}
for (int ii= 0; testcases[ii].description != NULL; ++ii)
{
if (testname != NULL && strcmp(testcases[ii].description, testname) != 0)
- continue;
+ {
+ continue;
+ }
if ((testcases[ii].description[0] == 'a' && (tests.ascii) == 0) ||
(testcases[ii].description[0] == 'b' && (tests.binary) == 0))
continue;
}
if (strncmp(buffer, "quit", 4) == 0)
- exit(0);
+ {
+ exit(EXIT_SUCCESS);
+ }
}
fprintf(stdout, "%-40s", testcases[ii].description);
closesocket(sock);
if ((sock= connect_server(hostname, port)) == INVALID_SOCKET)
{
- fprintf(stderr, "Failed to connect to <%s:%s>: %s\n",
- hostname, port, strerror(get_socket_errno()));
+ fprintf(stderr, "Failed to connect to <%s:%s>: %s\n", hostname, port, strerror(get_socket_errno()));
fprintf(stderr, "%d of %d tests failed\n", failed, total);
return EXIT_FAILURE;
}
closesocket(sock);
if (failed == 0)
+ {
fprintf(stdout, "All tests passed\n");
+ }
else
+ {
fprintf(stderr, "%d of %d tests failed\n", failed, total);
+ }
- return (failed == 0) ? 0 : 1;
+ return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
memcached_return_t rc;
memcached_server_st *servers;
- int return_code= 0;
+ int return_code= EXIT_SUCCESS;
options_parse(argc, argv);
initialize_sockets();
char *temp;
if ((temp= getenv("MEMCACHED_SERVERS")))
+ {
opt_servers= strdup(temp);
+ }
else
{
- fprintf(stderr, "No Servers provided\n");
- exit(1);
+ std::cerr << "No servers provied" << std::endl;
+ exit(EXIT_FAILURE);
}
}
if (opt_displayflag)
{
if (opt_verbose)
- printf("key: %s\nflags: ", argv[optind]);
- printf("%x\n", flags);
+ {
+ std::cout << "key: " << argv[optind] << std::endl << "flags: " << flags << std::endl;
+ }
}
else
{
if (opt_verbose)
{
- printf("key: %s\nflags: %x\nlength: %lu\nvalue: ",
- argv[optind], flags, (unsigned long)string_length);
+ std::cout << "key: " << argv[optind] << std::endl << "flags: " << flags << "length: " << string_length << std::endl << "value: ";
}
if (opt_file)
{
- FILE *fp;
- size_t written;
-
- fp= fopen(opt_file, "w");
- if (!fp)
+ FILE *fp= fopen(opt_file, "w");
+ if (fp == NULL)
{
perror("fopen");
- return_code= -1;
+ return_code= EXIT_FAILURE;
break;
}
- written= fwrite(string, 1, string_length, fp);
+ size_t written= fwrite(string, 1, string_length, fp);
if (written != string_length)
{
- fprintf(stderr, "error writing file (written %lu, should be %lu)\n", (unsigned long)written, (unsigned long)string_length);
- return_code= -1;
+ std::cerr << "error writing file to file " << opt_file << " wrote " << written << ", should have written" << string_length << std::endl;
+ return_code= EXIT_FAILURE;
break;
}
if (fclose(fp))
{
- fprintf(stderr, "error closing file\n");
- return_code= -1;
+ std::cerr << "error closing " << opt_file << std::endl;
+ return_code= EXIT_FAILURE;
break;
}
}
else
{
- printf("%.*s\n", (int)string_length, string);
+ std::cout.write(string, string_length);
+ std::cout << std::endl;
}
free(string);
}
}
else if (rc != MEMCACHED_NOTFOUND)
{
- fprintf(stderr, "memcat: %s: memcache error %s",
- argv[optind], memcached_strerror(memc, rc));
+ std::cerr << "error on " << argv[optind] << "(" << memcached_strerror(memc, rc) << ")";
if (memcached_last_error_errno(memc))
{
- fprintf(stderr, " system error %s", strerror(memcached_last_error_errno(memc)));
+ std::cerr << " system error (" << strerror(memcached_last_error_errno(memc)) << ")" << std::endl;
}
- fprintf(stderr, "\n");
+ std::cerr << std::endl;
- return_code= -1;
+ return_code= EXIT_FAILURE;
break;
}
else // Unknown Issue
{
- fprintf(stderr, "memcat: %s not found\n", argv[optind]);
- return_code= -1;
+ std::cerr << "error on " << argv[optind] << "("<< memcached_strerror(NULL, rc) << ")" << std::endl;
+ return_code= EXIT_FAILURE;
}
optind++;
}
memcached_free(memc);
if (opt_servers)
+ {
free(opt_servers);
+ }
if (opt_hash)
+ {
free(opt_hash);
+ }
return return_code;
}
*/
#include "config.h"
-#include <inttypes.h>
+#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <cstring>
+#include <climits>
+
#include <getopt.h>
#include <iostream>
#include <unistd.h>
/* Prototypes */
void options_parse(int argc, char *argv[]);
-static int opt_verbose= 0;
-
int main(int argc, char *argv[])
{
options_parse(argc, argv);
- if (argc != 2)
+ if (argc < 2)
{
return EXIT_FAILURE;
}
- unsigned long value= strtoul(argv[1], (char **) NULL, 10);
-
- if (value < MEMCACHED_MAXIMUM_RETURN)
+ while (optind < argc)
{
- std::cout << memcached_strerror(NULL, (memcached_return_t)value) << std::endl;
- }
- else
- {
- std::cerr << memcached_strerror(NULL, MEMCACHED_MAXIMUM_RETURN) << std::endl;
- return EXIT_FAILURE;
+ errno= 0;
+ char *nptr;
+ unsigned long value= strtoul(argv[optind], &nptr, 10);
+
+ if ((nptr == argv[optind] and value == 0) or
+ (value == ULONG_MAX and errno == ERANGE) or
+ (value == 0 and errno == EINVAL))
+ {
+ std::cerr << "strtoul() was unable to parse given value" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if (value < MEMCACHED_MAXIMUM_RETURN)
+ {
+ std::cout << memcached_strerror(NULL, (memcached_return_t)value) << std::endl;
+ }
+ else
+ {
+ std::cerr << memcached_strerror(NULL, MEMCACHED_MAXIMUM_RETURN) << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ optind++;
}
return EXIT_SUCCESS;
{
{(OPTIONSTRING)"version", no_argument, NULL, OPT_VERSION},
{(OPTIONSTRING)"help", no_argument, NULL, OPT_HELP},
- {(OPTIONSTRING)"quiet", no_argument, NULL, OPT_QUIET},
- {(OPTIONSTRING)"verbose", no_argument, &opt_verbose, OPT_VERBOSE},
- {(OPTIONSTRING)"debug", no_argument, &opt_verbose, OPT_DEBUG},
{0, 0, 0, 0},
};
case 0:
break;
- case OPT_VERBOSE: /* --verbose or -v */
- opt_verbose = OPT_VERBOSE;
- break;
-
- case OPT_DEBUG: /* --debug or -d */
- opt_verbose = OPT_DEBUG;
- break;
-
case OPT_VERSION: /* --version or -V */
opt_version= true;
break;
opt_help= true;
break;
- case OPT_QUIET:
- close_stdio();
- break;
-
case '?':
/* getopt_long already printed an error message. */
exit(EXIT_FAILURE);
default:
- abort();
+ exit(EXIT_FAILURE);
}
}
[1],
[Define to true if you want to use functions from atomic.h])])])
+AC_DEFINE([HAVE_LIBDRIZZLE], [0], [Support for libdrizzle])
+AC_DEFINE([HAVE_DRIZZLED_BINARY], [0], [Support for DrizzleD])
+AC_DEFINE([GEARMAND_BLOBSLAP_WORKER], [0], [Support for Gearman Blobslap worker])
+AC_DEFINE([HAVE_LIBPQ], [0], [Support for Postgres])
+AC_DEFINE([HAVE_LIBCURL], [0], [Support for libcurl])
+
AC_CHECK_HEADERS_ONCE(winsock2.h poll.h sys/wait.h fnmatch.h)
AM_CONDITIONAL(BUILD_POLL, test "x$ac_cv_header_poll_h" = "xno")
AM_CONDITIONAL(BUILD_WIN32_WRAPPERS, test "x$ac_cv_header_winsock2_h" = "xyes")
bool has_gearmand_binary()
{
#if defined(HAVE_GEARMAND_BINARY) && HAVE_GEARMAND_BINARY
- if (access(GEARMAND_BINARY,R_OK|X_OK) == 0)
+ std::stringstream arg_buffer;
+
+ if (getenv("PWD"))
+ {
+ arg_buffer << getenv("PWD");
+ arg_buffer << "/";
+ }
+ arg_buffer << GEARMAND_BINARY;
+
+ if (access(arg_buffer.str().c_str() ,R_OK|X_OK) == 0)
{
return true;
}
const char *executable()
{
- return GEARMAND_BLOBSLAP_WORKER;
+ return "benchmark/blobslap_worker";
}
const char *pid_file_option()
using namespace libtest;
#include <cstdlib>
-#include <string>
+#include <cstring>
+#include <fcntl.h>
+#include <memory>
+#include <spawn.h>
#include <sstream>
+#include <string>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+extern "C" {
+ static int exited_successfully(int status)
+ {
+ if (status == 0)
+ {
+ return EXIT_SUCCESS;
+ }
+
+ if (WIFEXITED(status) == true)
+ {
+ return WEXITSTATUS(status);
+ }
+ else if (WIFSIGNALED(status) == true)
+ {
+ return WTERMSIG(status);
+ }
+
+ return EXIT_FAILURE;
+ }
+}
+
+namespace {
+
+ std::string print_argv(char * * & built_argv, const size_t& argc, const pid_t& pid)
+ {
+ std::stringstream arg_buffer;
+
+ for (size_t x= 0; x < argc; x++)
+ {
+ arg_buffer << built_argv[x] << " ";
+ }
+
+ return arg_buffer.str();
+ }
+
+}
namespace libtest {
-bool exec_cmdline(const std::string& executable, const char *args[])
+Application::Application(const std::string& arg, const bool _use_libtool_arg) :
+ _use_libtool(_use_libtool_arg),
+ _argc(0),
+ _exectuble(arg),
+ built_argv(NULL),
+ _pid(-1)
+ {
+ if (_use_libtool)
+ {
+ if (libtool() == NULL)
+ {
+ throw "libtool requested, but know libtool was found";
+ }
+ }
+
+ if (_use_libtool and getenv("PWD"))
+ {
+ _exectuble_with_path+= getenv("PWD");
+ _exectuble_with_path+= "/";
+ }
+ _exectuble_with_path+= _exectuble;
+ }
+
+Application::~Application()
+{
+ delete_argv();
+}
+
+Application::error_t Application::run(const char *args[])
{
- std::stringstream arg_buffer;
+ stdin_fd.reset();
+ stdout_fd.reset();
+ stderr_fd.reset();
+ _stdout_buffer.clear();
+ _stderr_buffer.clear();
- arg_buffer << libtool();
+ posix_spawn_file_actions_t file_actions;
+ posix_spawn_file_actions_init(&file_actions);
- if (getenv("PWD"))
+ stdin_fd.dup_for_spawn(Application::Pipe::READ, file_actions, STDIN_FILENO);
+ stdout_fd.dup_for_spawn(Application::Pipe::WRITE, file_actions, STDOUT_FILENO);
+ stderr_fd.dup_for_spawn(Application::Pipe::WRITE, file_actions, STDERR_FILENO);
+
+ create_argv(args);
+
+ int spawn_ret;
+ if (_use_libtool)
{
- arg_buffer << getenv("PWD");
- arg_buffer << "/";
+ spawn_ret= posix_spawn(&_pid, built_argv[0], &file_actions, NULL, built_argv, NULL);
}
+ else
+ {
+ spawn_ret= posix_spawnp(&_pid, built_argv[0], &file_actions, NULL, built_argv, NULL);
+ }
+
+ posix_spawn_file_actions_destroy(&file_actions);
- arg_buffer << executable;
- for (const char **ptr= args; *ptr; ++ptr)
+ stdin_fd.close(Application::Pipe::READ);
+ stdout_fd.close(Application::Pipe::WRITE);
+ stderr_fd.close(Application::Pipe::WRITE);
+
+ if (spawn_ret)
{
- arg_buffer << " " << *ptr;
+ Error << print();
+ return Application::INVALID;
}
+ return Application::SUCCESS;
+}
+
+Application::error_t Application::wait()
+{
+ if (_pid == -1)
+ {
+ Error << "wait() got an invalid pid_t";
+ return Application::INVALID;
+ }
+
+ {
+ 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)
+ {
+ if (read_length == -1)
+ {
+ switch(errno)
+ {
+ case EAGAIN:
+ continue;
+
+ default:
+ Error << strerror(errno);
+ bail= true;
+ }
+ }
+ _stdout_buffer.reserve(read_length +1);
+ for (size_t x= 0; x < read_length; x++)
+ {
+ _stdout_buffer.push_back(buffer[x]);
+ }
+ // @todo Suck up all output code here
+ }
+ }
+
+ {
+ 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)
+ {
+ if (read_length == -1)
+ {
+ switch(errno)
+ {
+ case EAGAIN:
+ continue;
+
+ default:
+ Error << strerror(errno);
+ bail= true;
+ }
+ }
+ _stderr_buffer.reserve(read_length +1);
+ for (size_t x= 0; x < read_length; x++)
+ {
+ _stderr_buffer.push_back(buffer[x]);
+ }
+ // @todo Suck up all errput code here
+ }
+ }
+
+ 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);
+ }
+ else
+ {
+ assert(waited_pid == _pid);
+ exit_code= error_t(exited_successfully(status));
+ }
+ }
+
+ if (exit_code == Application::INVALID)
+ {
#if 0
- arg_buffer << " > /dev/null 2>&1";
+ Error << print_argv(built_argv, _argc, _pid);
#endif
+ }
+
+ return exit_code;
+}
+
+void Application::add_option(const std::string& arg)
+{
+ _options.push_back(std::make_pair(arg, std::string()));
+}
+
+void Application::add_option(const std::string& name, const std::string& value)
+{
+ _options.push_back(std::make_pair(name, value));
+}
+
+Application::Pipe::Pipe()
+{
+ _fd[0]= -1;
+ _fd[1]= -1;
+ _open[0]= false;
+ _open[1]= false;
+}
+
+void Application::Pipe::reset()
+{
+ close(READ);
+ close(WRITE);
+
+ int ret;
+ if ((ret= pipe(_fd)) < 0)
+ {
+ throw strerror(ret);
+ }
+ _open[0]= true;
+ _open[1]= true;
+
+ {
+ ret= fcntl(_fd[0], F_GETFL, 0);
+ if (ret == -1)
+ {
+ Error << "fcntl(F_GETFL) " << strerror(ret);
+ throw strerror(ret);
+ }
+
+ ret= fcntl(_fd[0], F_SETFL, ret | O_NONBLOCK);
+ if (ret == -1)
+ {
+ Error << "fcntl(F_SETFL) " << strerror(ret);
+ throw strerror(ret);
+ }
+ }
+}
+
+Application::Pipe::~Pipe()
+{
+ close(READ);
+ close(WRITE);
+}
+
+void Application::Pipe::dup_for_spawn(const close_t& arg, posix_spawn_file_actions_t& file_actions, const int newfildes)
+{
+ int type= int(arg);
+
+ int ret;
+ if ((ret= posix_spawn_file_actions_adddup2(&file_actions, _fd[type], newfildes )) < 0)
+ {
+ Error << "posix_spawn_file_actions_adddup2(" << strerror(ret) << ")";
+ throw strerror(ret);
+ }
+
+ if ((ret= posix_spawn_file_actions_addclose(&file_actions, _fd[type])) < 0)
+ {
+ Error << "posix_spawn_file_actions_adddup2(" << strerror(ret) << ")";
+ throw strerror(ret);
+ }
+}
+
+void Application::Pipe::close(const close_t& arg)
+{
+ int type= int(arg);
+
+ if (_open[type])
+ {
+ int ret;
+ if ((ret= ::close(_fd[type])) < 0)
+ {
+ Error << "close(" << strerror(ret) << ")";
+ }
+ _open[type]= false;
+ }
+}
+
+void Application::create_argv(const char *args[])
+{
+ _argc= 2 +_use_libtool ? 2 : 0; // +1 for the command, +2 for libtool/mode=execute, +1 for the NULL
+
+ if (_use_libtool)
+ {
+ _argc+= 2; // +2 for libtool --mode=execute
+ }
+
+ for (Options::const_iterator iter= _options.begin(); iter != _options.end(); iter++)
+ {
+ _argc++;
+ if ((*iter).second.empty() == false)
+ {
+ _argc++;
+ }
+ }
+
+ if (args)
+ {
+ for (const char **ptr= args; *ptr; ++ptr)
+ {
+ _argc++;
+ }
+ }
+
+ delete_argv();
+ built_argv= new char * [_argc];
+
+ size_t x= 0;
+ if (_use_libtool)
+ {
+ assert(libtool());
+ built_argv[x++]= strdup(libtool());
+ built_argv[x++]= strdup("--mode=execute");
+ }
+ built_argv[x++]= strdup(_exectuble_with_path.c_str());
+
+ for (Options::const_iterator iter= _options.begin(); iter != _options.end(); iter++)
+ {
+ built_argv[x++]= strdup((*iter).first.c_str());
+ if ((*iter).second.empty() == false)
+ {
+ built_argv[x++]= strdup((*iter).second.c_str());
+ }
+ }
+
+ if (args)
+ {
+ for (const char **ptr= args; *ptr; ++ptr)
+ {
+ built_argv[x++]= strdup(*ptr);
+ }
+ }
+ built_argv[_argc -1]= NULL;
+}
+
+std::string Application::print()
+{
+ return print_argv(built_argv, _argc, _pid);
+}
+
+void Application::delete_argv()
+{
+ if (built_argv == NULL)
+ {
+ return;
+ }
+
+ for (size_t x= 0; x < _argc; x++)
+ {
+ if (built_argv[x])
+ {
+ ::free(built_argv[x]);
+ }
+ }
+ delete[] built_argv;
+ built_argv= NULL;
+ _argc= 0;
+}
+
+
+int exec_cmdline(const std::string& command, const char *args[], bool use_libtool)
+{
+ Application app(command, use_libtool);
+
+ Application::error_t ret= app.run(args);
- if (system(arg_buffer.str().c_str()) == -1)
+ if (ret != Application::SUCCESS)
{
- return false;
+ return int(ret);
}
+ ret= app.wait();
- return true;
+ return int(ret);
}
const char *gearmand_binary()
#pragma once
+#include <spawn.h>
+
namespace libtest {
-bool exec_cmdline(const std::string& executable, const char *args[]);
+class Application {
+private:
+ typedef std::vector< std::pair<std::string, std::string> > Options;
+
+public:
+
+ enum error_t {
+ SUCCESS= EXIT_SUCCESS,
+ FAILURE= EXIT_FAILURE,
+ INVALID= 127
+ };
+
+ class Pipe {
+ public:
+ Pipe();
+ ~Pipe();
+
+ int* fd()
+ {
+ return _fd;
+ }
+
+ enum close_t {
+ READ,
+ WRITE
+ };
+
+ void reset();
+ void close(const close_t& arg);
+ void dup_for_spawn(const close_t& arg,
+ posix_spawn_file_actions_t& file_actions,
+ const int newfildes);
+
+ private:
+ int _fd[2];
+ bool _open[2];
+ };
+
+public:
+ Application(const std::string& arg, const bool _use_libtool_arg= false);
+
+ virtual ~Application();
+
+ void add_option(const std::string&);
+ void add_option(const std::string&, const std::string&);
+ error_t run(const char *args[]= NULL);
+ error_t wait();
+
+ libtest::vchar_t stdout_result() const
+ {
+ return _stdout_buffer;
+ }
+
+ size_t stdout_result_length() const
+ {
+ return _stdout_buffer.size();
+ }
+
+ libtest::vchar_t stderr_result() const
+ {
+ return _stderr_buffer;
+ }
+
+ size_t stderr_result_length() const
+ {
+ return _stderr_buffer.size();
+ }
+
+ std::string print();
+
+private:
+ void create_argv(const char *args[]);
+ void delete_argv();
+
+private:
+ const bool _use_libtool;
+ size_t _argc;
+ std::string _exectuble;
+ std::string _exectuble_with_path;
+ Options _options;
+ Pipe stdin_fd;
+ Pipe stdout_fd;
+ Pipe stderr_fd;
+ char * * built_argv;
+ pid_t _pid;
+ libtest::vchar_t _stdout_buffer;
+ libtest::vchar_t _stderr_buffer;
+};
+
+static inline std::ostream& operator<<(std::ostream& output, const enum Application::error_t &arg)
+{
+ switch (arg)
+ {
+ case Application::SUCCESS:
+ output << "EXIT_SUCCESS";
+ break;
+
+ case Application::FAILURE:
+ output << "EXIT_FAILURE";
+ break;
+
+ case Application::INVALID:
+ output << "127";
+ break;
+ }
+
+ return output;
+}
+
+int exec_cmdline(const std::string& executable, const char *args[], bool use_libtool= false);
const char *gearmand_binary();
#endif
#if defined(HAVE_LIBGEARMAN) && HAVE_LIBGEARMAN
-#include <libgearman/gearman.h>
+#include <libgearman-1.0/ostream.hpp>
#endif
namespace libtest {
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <libtest/common.h>
+
+namespace libtest {
+
+void dream(time_t tv_sec, long tv_nsec)
+{
+#ifdef WIN32
+ if (tv_sec == 0 and tv_nsec)
+ {
+ tv_sec++;
+ }
+ sleep(tv_sec);
+#else
+ struct timespec requested;
+ requested.tv_sec= tv_sec;
+ requested.tv_nsec= tv_nsec;
+ nanosleep(&requested, NULL);
+#endif
+}
+
+}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+namespace libtest {
+
+void dream(time_t tv_sec, long tv_nsec= 0);
+
+}
+
pid_t get_pid(bool error_is_ok)
{
- if (not pid_file().empty())
+ if (pid_file().empty() == false)
{
Wait wait(pid_file(), 0);
bool ping()
{
gearman_client_st *client= gearman_client_create(NULL);
- if (not client)
+ if (client == NULL)
{
Error << "Could not allocate memory for gearman_client_create()";
return false;
}
- gearman_client_set_timeout(client, 1000);
+ gearman_client_set_timeout(client, 3000);
if (gearman_success(gearman_client_add_server(client, hostname().c_str(), port())))
{
gearman_client_free(client);
return true;
}
+#if 0
+ Error << hostname().c_str() << ":" << port() << " was " << gearman_strerror(rc) << " extended: " << gearman_client_error(client);
+#endif
+ }
+ else
+ {
+ Error << "gearman_client_add_server() " << gearman_client_error(client);
}
gearman_client_free(client);
const char *log_file_option()
{
- return "-vvvvv --log-file=";
+ return "--verbose=DEBUG --log-file=";
}
const char *port_option()
return true;
}
+ bool has_syslog() const
+ {
+ return true;
+ }
+
bool build(int argc, const char *argv[]);
};
arg_buffer << " -u root ";
}
- arg_buffer << " --listen=127.0.0.1 ";
+ arg_buffer << " --listen=localhost ";
for (int x= 1 ; x < argc ; x++)
{
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+#include <libtest/has.hpp>
+
+#include <cstdlib>
+
+bool has_memcached_support(void)
+{
+ if (HAVE_LIBMEMCACHED and HAVE_MEMCACHED_BINARY)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool has_drizzle_support(void)
+{
+ if (HAVE_LIBDRIZZLE and HAVE_DRIZZLED_BINARY)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool has_postgres_support(void)
+{
+ if (getenv("POSTGES_IS_RUNNING_AND_SETUP"))
+ {
+
+ if (HAVE_LIBPQ)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+bool has_memcached_support(void);
+
+bool has_drizzle_support(void);
+
+bool has_postgres_support(void);
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <libtest/common.h>
+
+#if defined(HAVE_CURL_CURL_H) && HAVE_CURL_CURL_H
+#include <curl/curl.h>
+#else
+class CURL;
+#endif
+
+namespace libtest {
+namespace http {
+
+#define YATL_USERAGENT "YATL/1.0"
+
+extern "C" size_t
+ http_get_result_callback(void *ptr, size_t size, size_t nmemb, void *data)
+ {
+ size_t body_size= size * nmemb;
+
+ vchar_t *_body= (vchar_t*)data;
+
+ _body->resize(size * nmemb);
+ memcpy(&_body[0], ptr, _body->size());
+
+ return _body->size();
+ }
+
+
+static void init(CURL *curl, const std::string& url)
+{
+ if (HAVE_LIBCURL)
+ {
+#if defined(HAVE_LIBCURL) && HAVE_LIBCURL
+ assert(curl);
+ curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(curl, CURLOPT_USERAGENT, YATL_USERAGENT);
+#endif
+ }
+}
+
+bool GET::execute()
+{
+ if (HAVE_LIBCURL)
+ {
+#if defined(HAVE_LIBCURL) && HAVE_LIBCURL
+ CURL *curl= curl_easy_init();
+
+ init(curl, url());
+
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_get_result_callback);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&_body);
+
+ CURLcode retref= curl_easy_perform(curl);
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, _response);
+
+ curl_easy_cleanup(curl);
+
+ return retref == CURLE_OK;
+#endif
+ }
+
+ return false;
+}
+
+bool POST::execute()
+{
+ if (HAVE_LIBCURL)
+ {
+#if defined(HAVE_LIBCURL) && HAVE_LIBCURL
+ CURL *curl= curl_easy_init();;
+
+ init(curl, url());
+
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, _body.size());
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (void *)&_body[0]);
+
+ CURLcode retref= curl_easy_perform(curl);
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, _response);
+
+ curl_easy_cleanup(curl);
+#endif
+ }
+
+ return false;
+}
+
+bool TRACE::execute()
+{
+ if (HAVE_LIBCURL)
+ {
+#if defined(HAVE_LIBCURL) && HAVE_LIBCURL
+ CURL *curl= curl_easy_init();;
+
+ init(curl, url());
+
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "TRACE");
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_get_result_callback);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&_body[0]);
+
+ CURLcode retref= curl_easy_perform(curl);
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, _response);
+
+ curl_easy_cleanup(curl);
+
+ return retref == CURLE_OK;
+#endif
+ }
+
+ return false;
+}
+
+bool HEAD::execute()
+{
+ if (HAVE_LIBCURL)
+ {
+#if defined(HAVE_LIBCURL) && HAVE_LIBCURL
+ CURL *curl= curl_easy_init();;
+
+ init(curl, url());
+
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "HEAD");
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_get_result_callback);
+
+ CURLcode retref= curl_easy_perform(curl);
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, _response);
+
+ curl_easy_cleanup(curl);
+
+ return retref == CURLE_OK;
+#endif
+ }
+
+ return false;
+}
+
+} // namespace http
+} // namespace libtest
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#pragma once
+
+namespace libtest {
+namespace http {
+
+class HTTP {
+public:
+
+ HTTP(const std::string& url_arg) :
+ _url(url_arg),
+ _response(0)
+ { }
+
+ virtual bool execute()= 0;
+
+ virtual ~HTTP()
+ { }
+
+ const std::string& url() const
+ {
+ return _url;
+ }
+
+ long response()
+ {
+ return _response;
+ }
+
+private:
+ std::string _url;
+
+protected:
+ long _response;
+};
+
+class GET: public HTTP {
+public:
+
+ GET(const std::string& url_arg) :
+ HTTP(url_arg)
+ {
+ }
+
+ bool execute();
+
+private:
+ libtest::vchar_t _body;
+};
+
+class POST: public HTTP {
+public:
+
+ POST(const std::string& url_arg,
+ const vchar_t& post_arg) :
+ HTTP(url_arg),
+ _post(post_arg)
+ {
+ }
+
+ bool execute();
+
+private:
+ libtest::vchar_t _post;
+ libtest::vchar_t _body;
+};
+
+class TRACE: public HTTP {
+public:
+
+ TRACE(const std::string& url_arg,
+ const vchar_t& body_arg) :
+ HTTP(url_arg),
+ _body(body_arg)
+ {
+ }
+
+ bool execute();
+
+private:
+ libtest::vchar_t _body;
+};
+
+class HEAD: public HTTP {
+public:
+
+ HEAD(const std::string& url_arg) :
+ HTTP(url_arg)
+ {
+ }
+
+ bool execute();
+
+private:
+};
+
+} // namespace http
+} // namespace libtest
libtest/common.h \
libtest/comparison.hpp \
libtest/core.h \
+ libtest/dream.h \
libtest/error.h \
libtest/failed.h \
libtest/framework.h \
libtest/gearmand.h \
libtest/get.h \
+ libtest/has.hpp \
+ libtest/http.hpp \
libtest/is_pid.hpp \
libtest/is_local.hpp \
libtest/killpid.h \
libtest/string.hpp \
libtest/test.h \
libtest/test.hpp \
+ libtest/vchar.hpp \
libtest/visibility.h \
libtest/wait.h
libtest/binaries.cc \
libtest/cmdline.cc \
libtest/core.cc \
+ libtest/dream.cc \
libtest/framework.cc \
+ libtest/has.cc \
+ libtest/http.cc \
libtest/is_local.cc \
libtest/killpid.cc \
libtest/libtool.cc \
libtest/signal.cc \
libtest/socket.cc \
libtest/strerror.cc \
- libtest/test.cc
+ libtest/test.cc \
+ libtest/vchar.cc
-libtest_libtest_la_CXXFLAGS= ${AM_CXXFLAGS}
+libtest_libtest_la_CXXFLAGS=
libtest_libtest_la_CXXFLAGS+= ${NO_CONVERSION}
libtest_libtest_la_CXXFLAGS+= -DBUILDING_LIBTEST
libtest_libtest_la_CXXFLAGS+= $(PTHREAD_CFLAGS)
libtest_libtest_la_CXXFLAGS+= -DLIBTEST_TEMP="\"tmp_chroot\""
+libtest_libtest_la_CXXFLAGS+= $(CURL_CFLAGS)
libtest_libtest_la_LIBADD=
libtest_libtest_la_LIBADD+= $(PTHREAD_LIBS)
+libtest_libtest_la_LIBADD+= $(CURL_LIBS)
libtest_libtest_la_DEPENDENCIES= libtest_tmp_dir
# Declare unittest so that we can append to it
libtest_libtest_la_SOURCES+= libtest/gearmand.cc
libtest_libtest_la_SOURCES+= util/instance.cc
libtest_libtest_la_SOURCES+= util/operation.cc
-libtest_libtest_la_CXXFLAGS+= -DGEARMAND_BLOBSLAP_WORKER="\"${abs_top_builddir}/benchmark/blobslap_worker\""
libtest_unittest_LDADD+= libgearman/libgearman.la
libtest_unittest_DEPENDENCIES+= libgearman/libgearman.la
+libtest_unittest_DEPENDENCIES+= gearmand/gearmand
else
if HAVE_LIBGEARMAN
libtest_libtest_la_DEPENDENCIES+= libgearman/libgearman.la
libtest_libtest_la_SOURCES+= libtest/gearmand.cc
libtest_libtest_la_SOURCES+= util/instance.cc
libtest_libtest_la_SOURCES+= util/operation.cc
-libtest_libtest_la_CXXFLAGS+= -DGEARMAND_BLOBSLAP_WORKER=0
-else
-libtest_libtest_la_CXXFLAGS+= -DGEARMAND_BLOBSLAP_WORKER=0
endif
endif
@$(mkdir_p) tmp_chroot/var/run
-libtest_unittest_CXXFLAGS+= ${AM_CXXFLAGS}
libtest_unittest_DEPENDENCIES+= libtest/libtest.la libtest_tmp_dir
libtest_unittest_LDADD+= libtest/libtest.la
libtest_unittest_SOURCES= libtest/unittest.cc
const char *libtool(void)
{
- if (_libtool[0])
+ if (_libtool[0] == 0)
{
std::string libtool_buffer;
- if (getenv("srcdir"))
+ if (getenv("PWD"))
{
- libtool_buffer+= getenv("srcdir");
+ libtool_buffer+= getenv("PWD");
libtool_buffer+= "/";
}
else
libtool_buffer+= "libtool";
if (access(libtool_buffer.c_str(), R_OK | W_OK | X_OK))
{
+ Error << "Could not find libtool via access(" << libtool_buffer << ") :" << strerror(errno);
return NULL;
}
- libtool_buffer+= " --mode=execute ";
-
snprintf(_libtool, sizeof(_libtool), "%s", libtool_buffer.c_str());
}
return _libtool;
}
-}
+} // namespace libtest
#include <libtest/common.h>
-#include <libmemcached/memcached.h>
-#include <libmemcached/util.h>
+#include <libmemcached-1.0/memcached.h>
+#include <libmemcachedutil-1.0/util.h>
using namespace libtest;
#include <libtest/killpid.h>
extern "C" {
- static bool exited_successfully(int status)
+ static bool exited_successfully(int status, const std::string &command)
{
- if (WEXITSTATUS(status) == 0)
+ if (status == 0)
{
return true;
}
- return true;
+ if (WIFEXITED(status) == true)
+ {
+ int ret= WEXITSTATUS(status);
+
+ if (ret == 0)
+ {
+ return true;
+ }
+ else if (ret == EXIT_FAILURE)
+ {
+ libtest::Error << "Command executed, but returned EXIT_FAILURE: " << command;
+ }
+ else
+ {
+ libtest::Error << "Command executed, but returned " << ret;
+ }
+ }
+ else if (WIFSIGNALED(status) == true)
+ {
+ int ret_signal= WTERMSIG(status);
+ libtest::Error << "Died from signal " << strsignal(ret_signal);
+ }
+
+ return false;
}
}
return output; // for multiple << operators
}
-void Server::nap(void)
-{
-#ifdef WIN32
- sleep(1);
-#else
- struct timespec global_sleep_value= { 0, 50000 };
- nanosleep(&global_sleep_value, NULL);
-#endif
-}
-
Server::Server(const std::string& host_arg, const in_port_t port_arg, bool is_socket_arg) :
_is_socket(is_socket_arg),
_pid(-1),
if (kill(current_pid))
{
Log << "Killed existing server," << *this << " with pid:" << current_pid;
- nap();
+ dream(0, 50000);
continue;
}
}
bool Server::start()
{
// If we find that we already have a pid then kill it.
- if (has_pid() and not kill(_pid))
+ if (has_pid() and kill(_pid) == false)
{
Error << "Could not kill() existing server during start() pid:" << _pid;
return false;
assert(not has_pid());
_running.clear();
- if (not command(_running))
+ if (command(_running) == false)
{
Error << "Could not build command()";
return false;
}
int ret= system(_running.c_str());
- if (not exited_successfully(ret))
+ if (exited_successfully(ret, _running) == false)
{
- Error << "system() failed:" << strerror(errno);
+ Error << "system(" << _running << ") failed: " << strerror(errno);
_running.clear();
return false;
}
if (is_helgrind() or is_valgrind())
{
- sleep(4);
+ dream(5, 50000);
}
- if (pid_file_option() and not pid_file().empty())
+ if (pid_file_option() and pid_file().empty() == false)
{
Wait wait(pid_file(), 8);
}
}
- int count= is_helgrind() or is_valgrind() ? 20 : 5;
- while (not ping() and --count)
+ int counter= 0;
+ bool pinged= false;
+ while ((pinged= ping()) == false and
+ counter < (is_helgrind() or is_valgrind() ? 20 : 5))
{
- nap();
+ dream(counter++, 50000);
}
- if (count == 0)
+ if (pinged == false)
{
// If we happen to have a pid file, lets try to kill it
- if (pid_file_option() and not pid_file().empty())
+ if (pid_file_option() and pid_file().empty() == false)
{
+ Error << "We are going to kill it off";
kill_file(pid_file());
}
Error << "Failed to ping() server started with:" << _running;
if (is_libtool())
{
_base_command+= libtool();
+ _base_command+= " --mode=execute ";
}
if (is_debug() and getenv("GDB_COMMAND"))
_base_command+= " ";
}
+ if (is_libtool())
+ {
+ if (getenv("PWD"))
+ {
+ _base_command+= getenv("PWD");
+ _base_command+= "/";
+ }
+ }
+
_base_command+= executable();
}
arg_buffer << " " << log_file_option() << _log_file;
}
+ if (getenv("LIBTEST_SYSLOG") and has_syslog())
+ {
+ arg_buffer << " --syslog";
+ }
+
// Update pid_file
if (pid_file_option())
{
- if (_pid_file.empty() and not set_pid_file())
+ if (_pid_file.empty() and set_pid_file() == false)
{
return false;
}
{
if (check_pid(pid_arg) and kill_pid(pid_arg)) // If we kill it, reset
{
- if (broken_pid_file() and not pid_file().empty())
+ if (broken_pid_file() and pid_file().empty() == false)
{
unlink(pid_file().c_str());
}
return (_port != 0);
}
+ virtual bool has_syslog() const
+ {
+ return false;
+ }
+
// Reset a server if another process has killed the server
void reset()
{
bool command(std::string& command_arg);
protected:
- void nap();
bool set_pid_file();
private:
bool server_startup_st::shutdown(uint32_t number_of_host)
{
- assert(servers.size() > number_of_host);
if (servers.size() > number_of_host)
{
Server* tmp= servers[number_of_host];
}
#endif
sem_destroy(&lock);
+
+ int error;
+ if ((error= pthread_sigmask(SIG_UNBLOCK, &set, NULL)) != 0)
+ {
+ Error << "While trying to reset signal mask to original set, pthread_sigmask() died during pthread_sigmask(" << strerror(error) << ")";
+ }
}
extern "C" {
context->set_shutdown(SHUTDOWN_FORCED);
}
break;
+ case SIGPIPE:
+ {
+ Error << "Ignoring SIGPIPE";
+ }
+ break;
default:
Error << "Signal handling thread got unexpected signal " << strsignal(sig);
sigaddset(&set, SIGQUIT);
sigaddset(&set, SIGINT);
}
+ sigaddset(&set, SIGPIPE);
sigaddset(&set, SIGUSR2);
sem_init(&lock, 0, 0);
+
+ sigemptyset(&original_set);
+ pthread_sigmask(SIG_BLOCK, NULL, &original_set);
}
{
set_shutdown(SHUTDOWN_RUNNING);
- sigset_t old_set;
- sigemptyset(&old_set);
- pthread_sigmask(SIG_BLOCK, NULL, &old_set);
-
- if (sigismember(&old_set, SIGQUIT))
+ if (sigismember(&original_set, SIGQUIT))
{
Error << strsignal(SIGQUIT) << " has been previously set.";
}
- if (sigismember(&old_set, SIGINT))
+ if (sigismember(&original_set, SIGINT))
{
Error << strsignal(SIGINT) << " has been previously set.";
}
- if (sigismember(&old_set, SIGUSR2))
+ if (sigismember(&original_set, SIGUSR2))
{
Error << strsignal(SIGUSR2) << " has been previously set.";
}
volatile shutdown_t __shutdown;
pthread_mutex_t shutdown_mutex;
pthread_t thread;
+ sigset_t original_set;
public:
SignalThread();
+ ~SignalThread();
void test();
void post();
return sigwait(&set, &sig);
}
- ~SignalThread();
-
void set_shutdown(shutdown_t arg);
bool is_shutdown();
shutdown_t get_shutdown();
using namespace libtest;
-collection_st collection[] ={
- {0, 0, 0, 0}
-};
-
static void *world_create(server_startup_st&, test_return_t& rc)
{
rc= TEST_SKIPPED;
void get_world(Framework *world)
{
- world->collections= collection;
world->_create= world_create;
}
#define test_literal_compare_param util_literal_compare_param
#define test_literal_param_size util_literal_param_size
#define test_string_make_from_cstr util_string_make_from_cstr
+#define test_string_make_from_array util_string_make_from_array
#define test_array_length util_array_length
-
-namespace libtest {
-typedef std::vector<char> vchar_t;
-typedef std::vector<char*> vchar_ptr_t;
-}
#include <signal.h>
+#if defined(HAVE_CURL_CURL_H) && HAVE_CURL_CURL_H
+#include <curl/curl.h>
+#endif
+
#ifndef __INTEL_COMPILER
#pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
return s + us;
}
-static Framework *world= NULL;
+static void cleanup_curl(void)
+{
+#if defined(HAVE_CURL_CURL_H) && HAVE_CURL_CURL_H
+ curl_global_cleanup();
+#endif
+}
+
+#include <getopt.h>
+#include <unistd.h>
+
int main(int argc, char *argv[])
{
+#if defined(HAVE_CURL_CURL_H) && HAVE_CURL_CURL_H
+ if (curl_global_init(CURL_GLOBAL_ALL))
+ {
+ Error << "curl_global_init(CURL_GLOBAL_ALL) failed";
+ return EXIT_FAILURE;
+ }
+#endif
+
+ if (atexit(cleanup_curl))
+ {
+ Error << "atexit() failed";
+ return EXIT_FAILURE;
+ }
+
+ bool opt_repeat= false;
+ std::string collection_to_run;
+
+ // Options parsing
+ {
+ enum long_option_t {
+ OPT_LIBYATL_VERSION,
+ OPT_LIBYATL_MATCH_COLLECTION,
+ 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}
+ };
+
+ int option_index= 0;
+ while (1)
+ {
+ int option_rv= getopt_long(argc, argv, "", long_options, &option_index);
+ if (option_rv == -1)
+ {
+ break;
+ }
+
+ switch (option_rv)
+ {
+ case OPT_LIBYATL_VERSION:
+ break;
+
+ case OPT_LIBYATL_REPEAT:
+ opt_repeat= true;
+ break;
+
+ case OPT_LIBYATL_MATCH_COLLECTION:
+ collection_to_run= optarg;
+ break;
+
+ case '?':
+ /* getopt_long already printed an error message. */
+ Error << "unknown option to getopt_long()";
+ exit(EXIT_FAILURE);
+
+ default:
+ break;
+ }
+ }
+ }
+
srandom((unsigned int)time(NULL));
- if (getenv("LIBTEST_QUIET"))
+ if (getenv("LIBTEST_QUIET") and strcmp(getenv("LIBTEST_QUIET"), "0") == 0)
{
close(STDOUT_FILENO);
}
return EXIT_FAILURE;
}
- world= new Framework();
-
- if (world == NULL)
- {
- Error << "Failed to create Framework()";
- return EXIT_FAILURE;
- }
-
- libtest::SignalThread signal;
- if (not signal.setup())
- {
- return EXIT_FAILURE;
- }
-
- Stats stats;
-
- get_world(world);
+ int exit_code;
+ do {
+ exit_code= EXIT_SUCCESS;
+ Framework *world= new Framework();
- test_return_t error;
- void *creators_ptr= world->create(error);
-
- switch (error)
- {
- case TEST_SUCCESS:
- break;
-
- case TEST_SKIPPED:
- Out << "SKIP " << argv[0];
- delete world;
- return EXIT_SUCCESS;
-
- case TEST_FATAL:
- case TEST_FAILURE:
- case TEST_MEMORY_ALLOCATION_FAILURE:
- delete world;
- return EXIT_FAILURE;
- }
-
- char *collection_to_run= NULL;
- if (argc > 1)
- {
- collection_to_run= argv[1];
- }
- else if (getenv("TEST_COLLECTION"))
- {
- if (strlen(getenv("TEST_COLLECTION")))
+ if (world == NULL)
{
- collection_to_run= getenv("TEST_COLLECTION");
+ Error << "Failed to create Framework()";
+ return EXIT_FAILURE;
}
- }
-
- if (collection_to_run)
- {
- Out << "Only testing " << collection_to_run;
- }
-
- char *wildcard= NULL;
- if (argc == 3)
- {
- wildcard= argv[2];
- }
- for (collection_st *next= world->collections; next->name and (not signal.is_shutdown()); next++)
- {
- test_return_t collection_rc= TEST_SUCCESS;
- bool failed= false;
- bool skipped= false;
+ assert(sigignore(SIGPIPE) == 0);
- if (collection_to_run && fnmatch(collection_to_run, next->name, 0))
- continue;
+ libtest::SignalThread signal;
+ if (not signal.setup())
+ {
+ Error << "Failed to setup signals";
+ return EXIT_FAILURE;
+ }
- stats.collection_total++;
+ Stats stats;
- collection_rc= world->startup(creators_ptr);
+ get_world(world);
- if (collection_rc == TEST_SUCCESS and next->pre)
- {
- collection_rc= world->runner()->pre(next->pre, creators_ptr);
- }
+ test_return_t error;
+ void *creators_ptr= world->create(error);
- switch (collection_rc)
+ switch (error)
{
case TEST_SUCCESS:
break;
+ case TEST_SKIPPED:
+ Out << "SKIP " << argv[0];
+ delete world;
+ return EXIT_SUCCESS;
+
case TEST_FATAL:
case TEST_FAILURE:
- Out << next->name << " [ failed ]";
- failed= true;
- signal.set_shutdown(SHUTDOWN_GRACEFUL);
- goto cleanup;
+ case TEST_MEMORY_ALLOCATION_FAILURE:
+ delete world;
+ return EXIT_FAILURE;
+ }
- case TEST_SKIPPED:
- Out << next->name << " [ skipping ]";
- skipped= true;
- goto cleanup;
+ if (getenv("TEST_COLLECTION"))
+ {
+ if (strlen(getenv("TEST_COLLECTION")))
+ {
+ collection_to_run= getenv("TEST_COLLECTION");
+ }
+ }
- case TEST_MEMORY_ALLOCATION_FAILURE:
- test_assert(0, "Allocation failure, or unknown return");
+ if (collection_to_run.empty() == false)
+ {
+ Out << "Only testing " << collection_to_run;
}
- Out << "Collection: " << next->name;
+ char *wildcard= NULL;
+ if (argc == 3)
+ {
+ wildcard= argv[2];
+ }
- for (test_st *run= next->tests; run->name; run++)
+ for (collection_st *next= world->collections; next and next->name and (not signal.is_shutdown()); next++)
{
- struct timeval start_time, end_time;
- long int load_time= 0;
+ bool failed= false;
+ bool skipped= false;
- if (wildcard && fnmatch(wildcard, run->name, 0))
+ if (collection_to_run.empty() == false and fnmatch(collection_to_run.c_str(), next->name, 0))
{
continue;
}
- test_return_t return_code;
- if (test_success(return_code= world->item.startup(creators_ptr)))
- {
- if (test_success(return_code= world->item.flush(creators_ptr, run)))
- {
- // @note pre will fail is SKIPPED is returned
- if (test_success(return_code= world->item.pre(creators_ptr)))
- {
- { // Runner Code
- gettimeofday(&start_time, NULL);
- assert(world->runner());
- assert(run->test_fn);
- return_code= world->runner()->run(run->test_fn, creators_ptr);
- gettimeofday(&end_time, NULL);
- load_time= timedif(end_time, start_time);
- }
- }
+ stats.collection_total++;
- // @todo do something if post fails
- (void)world->item.post(creators_ptr);
- }
- else if (return_code == TEST_SKIPPED)
- { }
- else if (return_code == TEST_FAILURE)
- {
- Error << " item.flush(failure)";
- signal.set_shutdown(SHUTDOWN_GRACEFUL);
- }
- }
- else if (return_code == TEST_SKIPPED)
- { }
- else if (return_code == TEST_FAILURE)
+ test_return_t collection_rc= world->startup(creators_ptr);
+
+ if (collection_rc == TEST_SUCCESS and next->pre)
{
- Error << " item.startup(failure)";
- signal.set_shutdown(SHUTDOWN_GRACEFUL);
+ collection_rc= world->runner()->pre(next->pre, creators_ptr);
}
- stats.total++;
-
- switch (return_code)
+ switch (collection_rc)
{
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_FATAL:
case TEST_FAILURE:
- stats.failed++;
+ Out << next->name << " [ failed ]";
failed= true;
- Out << "\tTesting " << run->name << "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
- break;
+ signal.set_shutdown(SHUTDOWN_GRACEFUL);
+ goto cleanup;
case TEST_SKIPPED:
- stats.skipped++;
+ Out << next->name << " [ skipping ]";
skipped= true;
- Out << "\tTesting " << run->name << "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
- break;
+ goto cleanup;
case TEST_MEMORY_ALLOCATION_FAILURE:
- test_assert(0, "Memory Allocation Error");
+ test_assert(0, "Allocation failure, or unknown return");
}
- if (test_failed(world->on_error(return_code, creators_ptr)))
+ Out << "Collection: " << next->name;
+
+ for (test_st *run= next->tests; run->name; run++)
{
- Error << "Failed while running on_error()";
- signal.set_shutdown(SHUTDOWN_GRACEFUL);
- break;
+ struct timeval start_time, end_time;
+ long int load_time= 0;
+
+ if (wildcard && fnmatch(wildcard, run->name, 0))
+ {
+ continue;
+ }
+
+ test_return_t return_code;
+ try {
+ if (test_success(return_code= world->item.startup(creators_ptr)))
+ {
+ if (test_success(return_code= world->item.flush(creators_ptr, run)))
+ {
+ // @note pre will fail is SKIPPED is returned
+ if (test_success(return_code= world->item.pre(creators_ptr)))
+ {
+ { // Runner Code
+ gettimeofday(&start_time, NULL);
+ assert(world->runner());
+ assert(run->test_fn);
+ return_code= world->runner()->run(run->test_fn, creators_ptr);
+ gettimeofday(&end_time, NULL);
+ load_time= timedif(end_time, start_time);
+ }
+ }
+
+ // @todo do something if post fails
+ (void)world->item.post(creators_ptr);
+ }
+ else if (return_code == TEST_SKIPPED)
+ { }
+ else if (return_code == TEST_FAILURE)
+ {
+ Error << " item.flush(failure)";
+ signal.set_shutdown(SHUTDOWN_GRACEFUL);
+ }
+ }
+ else if (return_code == TEST_SKIPPED)
+ { }
+ else if (return_code == TEST_FAILURE)
+ {
+ Error << " item.startup(failure)";
+ signal.set_shutdown(SHUTDOWN_GRACEFUL);
+ }
+ }
+
+ 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++;
+
+ 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_FATAL:
+ 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;
+
+ case TEST_MEMORY_ALLOCATION_FAILURE:
+ test_assert(0, "Memory Allocation Error");
+ }
+
+ if (test_failed(world->on_error(return_code, creators_ptr)))
+ {
+ Error << "Failed while running on_error()";
+ signal.set_shutdown(SHUTDOWN_GRACEFUL);
+ break;
+ }
}
- }
- (void) world->runner()->post(next->post, creators_ptr);
+ (void) world->runner()->post(next->post, creators_ptr);
cleanup:
- if (failed == false and skipped == false)
- {
- stats.collection_success++;
+ if (failed == false and skipped == false)
+ {
+ stats.collection_success++;
+ }
+
+ if (failed)
+ {
+ stats.collection_failed++;
+ }
+
+ if (skipped)
+ {
+ stats.collection_skipped++;
+ }
+
+ world->shutdown(creators_ptr);
+ Outn();
}
- if (failed)
+ if (not signal.is_shutdown())
{
- stats.collection_failed++;
+ signal.set_shutdown(SHUTDOWN_GRACEFUL);
}
- if (skipped)
+ shutdown_t status= signal.get_shutdown();
+ if (status == SHUTDOWN_FORCED)
{
- stats.collection_skipped++;
+ Out << "Tests were aborted.";
+ exit_code= EXIT_FAILURE;
+ }
+ else if (stats.collection_failed)
+ {
+ Out << "Some test failed.";
+ exit_code= EXIT_FAILURE;
+ }
+ else if (stats.collection_skipped and stats.collection_failed and stats.collection_success)
+ {
+ Out << "Some tests were skipped.";
+ }
+ else if (stats.collection_success and stats.collection_failed == 0)
+ {
+ Out << "All tests completed successfully.";
}
- world->shutdown(creators_ptr);
- Outn();
- }
-
- if (not signal.is_shutdown())
- {
- signal.set_shutdown(SHUTDOWN_GRACEFUL);
- }
-
- int exit_code= EXIT_SUCCESS;
- shutdown_t status= signal.get_shutdown();
- if (status == SHUTDOWN_FORCED)
- {
- Out << "Tests were aborted.";
- exit_code= EXIT_FAILURE;
- }
- else if (stats.collection_failed)
- {
- Out << "Some test failed.";
- exit_code= EXIT_FAILURE;
- }
- else if (stats.collection_skipped and stats.collection_failed and stats.collection_success)
- {
- Out << "Some tests were skipped.";
- }
- else if (stats.collection_success and stats.collection_failed == 0)
- {
- Out << "All tests completed successfully.";
- }
-
- stats_print(&stats);
+ stats_print(&stats);
- delete world;
+ delete world;
- Outn(); // Generate a blank to break up the messages if make check/test has been run
+ Outn(); // Generate a blank to break up the messages if make check/test has been run
+ } while (exit_code == EXIT_SUCCESS and opt_repeat);
return exit_code;
}
return TEST_FAILURE; \
} \
} while (0)
+#define test_true_hint test_true_got
#define test_skip(A,B) \
do \
#define test_strcmp(A,B) \
do \
{ \
- if (strcmp((A), (B))) \
+ if ((A) == NULL or (B) == NULL or strcmp((A), (B))) \
{ \
- fprintf(stderr, "\n%s:%d: Expected %s, got %s\n", __FILE__, __LINE__, (A), (B)); \
+ if ((B) == NULL) fprintf(stderr, "\n%s:%d: Expected %s, got <null>\n", __FILE__, __LINE__, (A)); \
+ else fprintf(stderr, "\n%s:%d: Expected %s, got \"%s\"\n", __FILE__, __LINE__, (A), (B)); \
libtest::create_core(); \
return TEST_FAILURE; \
} \
#define test_memcmp(A,B,C) \
do \
{ \
- if (memcmp((A), (B), (C))) \
+ if ((A) == NULL or (B) == NULL or memcmp((A), (B), (C))) \
{ \
fprintf(stderr, "\n%s:%d: %.*s -> %.*s\n", __FILE__, __LINE__, (int)(C), (char *)(A), (int)(C), (char *)(B)); \
libtest::create_core(); \
} \
} while (0)
+#define test_memcmp_hint(A,B,C,__hint) \
+do \
+{ \
+ if ((A) == NULL or (B) == NULL or memcmp((A), (B), (C))) \
+ { \
+ fprintf(stderr, "\n%s:%d: (hint:%s) %.*s -> %.*s\n", __FILE__, __LINE__, __hint, (int)(C), (char *)(A), (int)(C), (char *)(B)); \
+ libtest::create_core(); \
+ return TEST_FAILURE; \
+ } \
+} while (0)
+
#define test_return_if(__test_return_t) \
do \
{ \
#include <libtest/visibility.h>
#include <libtest/version.h>
+#include <libtest/vchar.hpp>
+
+#include <libtest/has.hpp>
#include <libtest/error.h>
#include <libtest/strerror.h>
#include <libtest/stream.h>
#include <libtest/wait.h>
#include <libtest/callbacks.h>
#include <libtest/test.h>
+#include <libtest/dream.h>
#include <libtest/core.h>
#include <libtest/runner.h>
#include <libtest/port.h>
#include <libtest/cmdline.h>
#include <libtest/string.hpp>
#include <libtest/binaries.h>
+#include <libtest/http.hpp>
#include <libtest/test.hpp>
#if defined(LIBTEST_WITH_LIBMEMCACHED_SUPPORT) && LIBTEST_WITH_LIBMEMCACHED_SUPPORT
-#include <libmemcached/memcached.h>
+#include <libmemcached-1.0/memcached.h>
#endif
#if defined(LIBTEST_WITH_LIBGEARMAN_SUPPORT) && LIBTEST_WITH_LIBGEARMAN_SUPPORT
server_startup_st *servers= (server_startup_st*)object;
test_true(servers);
- if (GEARMAND_BINARY)
- {
- if (HAVE_LIBGEARMAN)
- {
- test_true(has_gearmand_binary());
- const char *argv[1]= { "cycle_gearmand" };
- test_true(server_startup(*servers, "gearmand", 9999, 1, argv));
+#if defined(HAVE_GEARMAND_BINARY) && HAVE_GEARMAND_BINARY
+ test_true(has_gearmand_binary());
+#else
+ test_skip(true, has_gearmand_binary());
+#endif
- return TEST_SUCCESS;
- }
- }
+ const char *argv[1]= { "cycle_gearmand" };
+ test_true(server_startup(*servers, "gearmand", 9999, 1, argv));
- return TEST_SKIPPED;
+ return TEST_SUCCESS;
}
static test_return_t memcached_cycle_test(void *object)
return TEST_SKIPPED;
}
+static test_return_t application_true_BINARY(void *)
+{
+ Application true_app("true");
+
+ test_compare(Application::SUCCESS, true_app.run());
+ test_compare(Application::SUCCESS, true_app.wait());
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t application_true_fubar_BINARY(void *)
+{
+ Application true_app("true");
+
+ const char *args[]= { "--fubar", 0 };
+ test_compare(Application::SUCCESS, true_app.run(args));
+ test_compare(Application::SUCCESS, true_app.wait());
+ test_compare(0, true_app.stdout_result().size());
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t application_true_fubar_eq_doh_BINARY(void *)
+{
+ Application true_app("true");
+
+ const char *args[]= { "--fubar=doh", 0 };
+ test_compare(Application::SUCCESS, true_app.run(args));
+ test_compare(Application::SUCCESS, true_app.wait());
+ test_compare(0, true_app.stdout_result().size());
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t application_true_fubar_eq_doh_option_BINARY(void *)
+{
+ Application true_app("true");
+
+ true_app.add_option("--fubar=", "doh");
+
+ test_compare(Application::SUCCESS, true_app.run());
+ test_compare(Application::SUCCESS, true_app.wait());
+ test_compare(0, true_app.stdout_result().size());
+
+ return TEST_SUCCESS;
+}
+
+
+static test_return_t GET_TEST(void *)
+{
+ libtest::http::GET get("http://foo.example.com/");
+
+ test_compare(false, get.execute());
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t POST_TEST(void *)
+{
+ libtest::vchar_t body;
+ libtest::http::POST post("http://foo.example.com/", body);
+
+ test_compare(false, post.execute());
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t TRACE_TEST(void *)
+{
+ libtest::vchar_t body;
+ libtest::http::TRACE trace("http://foo.example.com/", body);
+
+ test_compare(false, trace.execute());
+
+ return TEST_SUCCESS;
+}
+
+
+static test_return_t vchar_t_TEST(void *)
+{
+ libtest::vchar_t response;
+ libtest::make_vector(response, test_literal_param("fubar\n"));
+ test_compare(response, response);
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t application_echo_fubar_BINARY(void *)
+{
+ Application true_app("echo");
+
+ const char *args[]= { "fubar", 0 };
+ test_compare(Application::SUCCESS, true_app.run(args));
+ test_compare(Application::SUCCESS, true_app.wait());
+
+ libtest::vchar_t response;
+ make_vector(response, test_literal_param("fubar\n"));
+ test_compare(response, true_app.stdout_result());
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t application_echo_fubar_BINARY2(void *)
+{
+ Application true_app("echo");
+
+ true_app.add_option("fubar");
+
+ test_compare(Application::SUCCESS, true_app.run());
+ test_compare(Application::SUCCESS, true_app.wait());
+ libtest::vchar_t response;
+ make_vector(response, test_literal_param("fubar\n"));
+ test_compare(response, true_app.stdout_result());
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t true_BINARY(void *)
+{
+ const char *args[]= { 0 };
+ test_compare(EXIT_SUCCESS, exec_cmdline("true", args));
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t true_fubar_BINARY(void *)
+{
+ const char *args[]= { "--fubar", 0 };
+ test_compare(EXIT_SUCCESS, exec_cmdline("true", args));
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t echo_fubar_BINARY(void *)
+{
+ const char *args[]= { "fubar", 0 };
+ test_compare(EXIT_SUCCESS, exec_cmdline("echo", args));
+
+ return TEST_SUCCESS;
+}
+
static test_return_t wait_BINARY(void *)
{
const char *args[]= { "--quiet", 0 };
- test_true(exec_cmdline("libtest/wait", args));
+ test_compare(EXIT_FAILURE, exec_cmdline("libtest/wait", args, true));
return TEST_SUCCESS;
}
{
const char *args[]= { "--quiet", "--help", 0 };
- test_true(exec_cmdline("libtest/wait", args));
+ test_compare(EXIT_SUCCESS, exec_cmdline("libtest/wait", args, true));
return TEST_SUCCESS;
}
{
const char *args[]= { "--quiet", "--version", 0 };
- test_true(exec_cmdline("libtest/wait", args));
+ test_compare(EXIT_SUCCESS, exec_cmdline("libtest/wait", args, true));
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t wait_services_BINARY(void *)
+{
+ test_skip(0, access("/etc/services", R_OK ));
+
+ const char *args[]= { "--quiet", "/etc/services", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline("libtest/wait", args, true));
return TEST_SUCCESS;
}
+static test_return_t wait_services_BINARY2(void *)
+{
+ test_skip(0, access("/etc/services", R_OK ));
+
+ const char *args[]= { "/etc/services", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline("libtest/wait", args, true));
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t application_wait_services_BINARY2(void *)
+{
+ test_skip(0, access("/etc/services", R_OK ));
+
+ libtest::Application("libtest/wait", true);
+ const char *args[]= { "/etc/services", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline("libtest/wait", args, true));
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t check_for_gearman(void *)
+{
+ test_skip(true, HAVE_LIBGEARMAN);
+ test_skip(true, has_gearmand_binary());
+ return TEST_SUCCESS;
+}
+
+
test_st gearmand_tests[] ={
#if 0
{"pause", 0, pause_test },
#endif
{"gearmand startup-shutdown", 0, gearmand_cycle_test },
+ {"_compare(gearman_return_t)", 0, _compare_gearman_return_t_test },
{0, 0, 0}
};
+static test_return_t check_for_libmemcached(void *)
+{
+ test_skip(true, HAVE_LIBMEMCACHED);
+ test_skip(true, has_memcached_binary());
+ return TEST_SUCCESS;
+}
+
test_st memcached_tests[] ={
{"memcached startup-shutdown", 0, memcached_cycle_test },
{"memcached(socket file) startup-shutdown", 0, memcached_socket_cycle_test },
{"memcached_sasl() startup-shutdown", 0, memcached_sasl_test },
+ {"_compare(memcached_return_t)", 0, _compare_memcached_return_t_test },
{0, 0, 0}
};
test_st comparison_tests[] ={
{"_compare(test_return_t)", 0, _compare_test_return_t_test },
- {"_compare(memcached_return_t)", 0, _compare_memcached_return_t_test },
- {"_compare(gearman_return_t)", 0, _compare_gearman_return_t_test },
{0, 0, 0}
};
test_st cmdline_tests[] ={
+ {"true", 0, true_BINARY },
+ {"true --fubar", 0, true_fubar_BINARY },
+ {"echo fubar", 0, echo_fubar_BINARY },
{"wait --quiet", 0, wait_BINARY },
{"wait --quiet --help", 0, wait_help_BINARY },
{"wait --quiet --version", 0, wait_version_BINARY },
+ {"wait --quiet /etc/services", 0, wait_services_BINARY },
+ {"wait /etc/services", 0, wait_services_BINARY2 },
+ {0, 0, 0}
+};
+
+test_st application_tests[] ={
+ {"vchar_t", 0, vchar_t_TEST },
+ {"true", 0, application_true_BINARY },
+ {"true --fubar", 0, application_true_fubar_BINARY },
+ {"true --fubar=doh", 0, application_true_fubar_eq_doh_BINARY },
+ {"true --fubar=doh add_option()", 0, application_true_fubar_eq_doh_option_BINARY },
+ {"echo fubar", 0, application_echo_fubar_BINARY },
+ {"echo fubar (as option)", 0, application_echo_fubar_BINARY2 },
+ {0, 0, 0}
+};
+
+static test_return_t check_for_curl(void *)
+{
+ test_skip(true, HAVE_LIBCURL);
+ return TEST_SUCCESS;
+}
+
+test_st http_tests[] ={
+ {"GET", 0, GET_TEST },
+ {"POST", 0, POST_TEST },
+ {"TRACE", 0, TRACE_TEST },
{0, 0, 0}
};
{"local", 0, 0, local_log},
{"directories", 0, 0, directories_tests},
{"comparison", 0, 0, comparison_tests},
- {"gearmand", 0, 0, gearmand_tests},
- {"memcached", 0, 0, memcached_tests},
+ {"gearmand", check_for_gearman, 0, gearmand_tests},
+ {"memcached", check_for_libmemcached, 0, memcached_tests},
{"cmdline", 0, 0, cmdline_tests},
+ {"application", 0, 0, application_tests},
+ {"http", check_for_curl, 0, http_tests},
{0, 0, 0, 0}
};
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <libtest/common.h>
+
+namespace libtest {
+
+static std::string printer(const char *str, size_t length)
+{
+ std::ostringstream buf;
+ for (size_t x= 0; x < length; x++)
+ {
+ if (isprint(str[x]))
+ {
+ buf << str[x];
+ }
+ else
+ {
+ buf << "(" << int(str[x]) << ")";
+ }
+ }
+
+ return buf.str();
+}
+
+void make_vector(libtest::vchar_t& arg, const char *str, size_t length)
+{
+ arg.resize(length);
+ memcpy(&arg[0], str, length);
+}
+
+std::ostream& operator<<(std::ostream& output, const libtest::vchar_t& arg)
+{
+ std::string tmp= libtest::printer(&arg[0], arg.size());
+ output << tmp << "[" << arg.size() << "]";
+
+ return output;
+}
+
+} // namespace libtest
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#pragma once
+
+#include <cstring>
+#include <iostream>
+#include <ostream>
+#include <sstream>
+#include <vector>
+
+namespace libtest {
+
+typedef std::vector<char*> vchar_ptr_t;
+typedef std::vector<char> vchar_t;
+
+void make_vector(libtest::vchar_t& arg, const char *str, size_t length);
+
+std::ostream& operator<<(std::ostream& output, const libtest::vchar_t& arg);
+
+} // namespace libtest
+
static void version_command(const char *command_name, int major_version, int minor_version)
{
std::cout << command_name << " " << major_version << "." << minor_version << std::endl;
- exit(EXIT_SUCCESS);
}
static void help_command(const char *command_name,
}
std::cout << std::endl;
- exit(EXIT_SUCCESS);
}
static void close_stdio(void)
bool opt_version= false;
bool opt_help= false;
+ bool opt_quiet= false;
int option_index= 0;
while (1)
{
- int option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index);
+ int option_rv= getopt_long(argc, argv, "", long_options, &option_index);
if (option_rv == -1)
{
break;
opt_help= true;
break;
+ case OPT_VERSION: /* --version or -v */
+ opt_version= true;
+ break;
+
case OPT_QUIET:
- close_stdio();
+ opt_quiet= true;
break;
case '?':
/* getopt_long already printed an error message. */
- exit(EXIT_SUCCESS);
+ exit(EXIT_FAILURE);
default:
- abort();
+ help_command(argv[0], 1, 0, long_options);
+ exit(EXIT_FAILURE);
}
}
+ if (opt_quiet)
+ {
+ close_stdio();
+ }
+
if (opt_version)
{
version_command(argv[0], 1, 0);
int main(int argc, char *argv[])
{
+ if (argc == 1)
+ {
+ return EXIT_FAILURE;
+ }
+
options_parse(argc, argv);
- if (argc == 2)
+ int ret= EXIT_FAILURE;
+ while (optind < argc)
{
- libtest::Wait wait(argv[1]);
+ libtest::Wait wait(argv[optind++]);
+
+ if (wait.successful() == false)
+ {
+ return EXIT_FAILURE;
+ }
- if (wait.successful())
- return EXIT_SUCCESS;
+ ret= EXIT_SUCCESS;
}
- return EXIT_FAILURE;
+ return ret;
}
check_PROGRAMS+= tests/memdump
noinst_PROGRAMS+= tests/memdump
+test-memerror: clients/memerror
+ tests/memerror
+
+valgrind-memerror: clients/memerror
+ @$(VALGRIND_COMMAND) tests/memerror
+
test-memcp: clients/memcp
@echo "Testing memcp"
@@MEMC_BINARY@ -d -u root -P `pwd`/tests/Xumemc.pid -p 12555
value.push_back((char) (x % 127));
}
- for (size_t current_length= 0; current_length < value.size(); current_length++)
+ for (size_t current_length= 1; current_length < value.size(); current_length++)
{
memcached_return_t rc= memcached_set(memc, test_literal_param("foo"),
&value[0], current_length,
test_compare(MEMCACHED_SUCCESS, rc);
test_compare(string_length, current_length);
- test_memcmp(string, &value[0], string_length);
+ char buffer[1024];
+ snprintf(buffer, sizeof(buffer), "%u", uint32_t(string_length));
+ test_memcmp_hint(string, &value[0], string_length, buffer);
free(string);
}
test_literal_param(__func__), // Values
0, 0));
+ memcached_free(memc);
+
return TEST_SUCCESS;
}
{
const char *args[]= { "-q", 0 };
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_FAILURE, exec_cmdline(executable, args, true));
+
return TEST_SUCCESS;
}
static test_return_t help_test(void *)
{
- const char *args[]= { "-q", "--help", 0 };
+ const char *args[]= { "-h", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
static test_return_t ascii_test(void *)
{
char buffer[1024];
- snprintf(buffer, sizeof(buffer), "-p %d", int(default_port()));
- const char *args[]= { "-q", buffer, " -a ", 0 };
+ snprintf(buffer, sizeof(buffer), "%d", int(default_port()));
+ const char *args[]= { "-p", buffer, " -a ", 0 };
+
+ test_true(exec_cmdline(executable, args, true) <= EXIT_FAILURE);
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
static test_return_t binary_test(void *)
{
char buffer[1024];
- snprintf(buffer, sizeof(buffer), "-p %d", int(default_port()));
- const char *args[]= { "-q", buffer, " -b ", 0 };
+ snprintf(buffer, sizeof(buffer), "%d", int(default_port()));
+ const char *args[]= { "-p", buffer, " -b ", 0 };
+
+ test_true(exec_cmdline(executable, args, true) <= EXIT_FAILURE);
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
test_st memcapable_tests[] ={
{"--quiet", 0, quiet_test},
- {"--help", 0, help_test},
+ {"-h", 0, help_test},
{"-a, ascii", 0, ascii_test},
{"-b, binary", 0, binary_test},
{0, 0, 0}
{
const char *args[]= { "--quiet", 0 };
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_FAILURE, exec_cmdline(executable, args, true));
+
return TEST_SUCCESS;
}
static test_return_t help_test(void *)
{
- const char *args[]= { "--quiet", "--help", 0 };
+ const char *args[]= { "--help", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--server=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, "foo", 0 };
+ const char *args[]= { buffer, "foo", 0 };
memcached_st *memc= memcached(buffer, strlen(buffer));
test_true(memc);
test_null(memcached_get(memc, test_literal_param("foo"), 0, 0, &rc));
test_compare(MEMCACHED_SUCCESS, rc);
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
test_null(memcached_get(memc, test_literal_param("foo"), 0, 0, &rc));
test_compare(MEMCACHED_SUCCESS, rc);
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--server=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, "foo", 0 };
+ const char *args[]= { buffer, "foo", 0 };
memcached_st *memc= memcached(buffer, strlen(buffer));
test_true(memc);
test_null(memcached_get(memc, test_literal_param("foo"), 0, 0, &rc));
test_compare(MEMCACHED_NOTFOUND, rc);
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_FAILURE, exec_cmdline(executable, args, true));
test_null(memcached_get(memc, test_literal_param("foo"), 0, 0, &rc));
test_compare(MEMCACHED_NOTFOUND, rc);
{
const char *args[]= { "--quiet", 0 };
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_FAILURE, exec_cmdline(executable, args, true));
+
return TEST_SUCCESS;
}
static test_return_t help_test(void *)
{
- const char *args[]= { "--quiet", "--help", 0 };
+ const char *args[]= { "--help", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, 0 };
+ const char *args[]= { buffer, 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
const char *args[]= { "--quiet", 0 };
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_FAILURE, exec_cmdline(executable, args, true));
+
return TEST_SUCCESS;
}
{
const char *args[]= { "--help", "--quiet", 0 };
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
+
return TEST_SUCCESS;
}
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
const char *args[]= { buffer, 0 };
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
+
return TEST_SUCCESS;
}
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--server=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, 0 };
+ const char *args[]= { buffer, 0 };
memcached_st *memc= memcached(buffer, strlen(buffer));
test_true(memc);
test_null(memcached_get(memc, test_literal_param("foo"), 0, 0, &rc));
test_compare(MEMCACHED_SUCCESS, rc);
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
memcached_free(memc);
static std::string executable;
-static test_return_t quiet_test(void *)
+static test_return_t help_TEST(void *)
{
- const char *args[]= { "--quiet", 0 };
+ const char *args[]= { "--help", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
-static test_return_t help_test(void *)
+static test_return_t version_TEST(void *)
{
- const char *args[]= { "--quiet", "--help", 0 };
+ const char *args[]= { "--version", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
static test_return_t error_test(void *)
{
- const char *args[]= { "--quiet", "MEMCACHED_SUCCESS", 0 };
+ const char *args[]= { "memcached_success", 0 };
+
+ test_compare(EXIT_FAILURE, exec_cmdline(executable, args, true));
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t SUCCESS_TEST(void *)
+{
+ const char *args[]= { "0", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
static test_return_t bad_input_test(void *)
{
- const char *args[]= { "--quiet", "bad input", 0 };
+ const char *args[]= { "bad input", 0 };
+
+ test_compare(EXIT_FAILURE, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
test_st memerror_tests[] ={
- {"--quiet", 0, quiet_test},
- {"--help", 0, help_test},
+ {"--help", 0, help_TEST},
+ {"--version", 0, version_TEST},
{"<error>", 0, error_test},
+ {"0", 0, SUCCESS_TEST},
{"<bad input>", 0, bad_input_test},
{0, 0, 0}
};
{
const char *args[]= { "--quiet", 0 };
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_FAILURE, exec_cmdline(executable, args, true));
+
return TEST_SUCCESS;
}
static test_return_t help_test(void *)
{
- const char *args[]= { "--quiet", "--help", 0 };
+ const char *args[]= { "--help", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, 0 };
+ const char *args[]= { buffer, 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
const char *args[]= { "--quiet", 0 };
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_FAILURE, exec_cmdline(executable, args, true));
return TEST_SUCCESS;
}
static test_return_t help_test(void *)
{
- const char *args[]= { "--quiet", "--help", 0 };
+ const char *args[]= { "--help", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--server=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, "foo", 0 };
memcached_st *memc= memcached(buffer, strlen(buffer));
test_true(memc);
test_null(memcached_get(memc, test_literal_param("foo"), 0, 0, &rc));
test_compare(MEMCACHED_SUCCESS, rc);
- test_true(exec_cmdline(executable, args));
+ const char *args[]= { buffer, "foo", 0 };
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
test_null(memcached_get(memc, test_literal_param("foo"), 0, 0, &rc));
test_compare(MEMCACHED_NOTFOUND, rc);
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--server=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, "foo", 0 };
+ const char *args[]= { buffer, "foo", 0 };
memcached_st *memc= memcached(buffer, strlen(buffer));
test_true(memc);
test_null(memcached_get(memc, test_literal_param("foo"), 0, 0, &rc));
test_compare(MEMCACHED_NOTFOUND, rc);
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
test_null(memcached_get(memc, test_literal_param("foo"), 0, 0, &rc));
test_compare(MEMCACHED_NOTFOUND, rc);
{
const char *args[]= { "--quiet", 0 };
- test_true(exec_cmdline(executable, args));
+ test_compare(EXIT_FAILURE, exec_cmdline(executable, args, true));
+
return TEST_SUCCESS;
}
static test_return_t help_test(void *)
{
- const char *args[]= { "--quiet", "--help", 0 };
+ const char *args[]= { "--help", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, 0 };
+ const char *args[]= { buffer, 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, "--concurrency=10", 0 };
+ const char *args[]= { buffer, "--concurrency=10", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, "--concurrency=10", "--initial-load=1000", 0 };
+ const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", 0 };
+ const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", "--test=get", 0 };
+ const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", "--test=get", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", "--test=set", 0 };
+ const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", "--test=set", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
{
char buffer[1024];
snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port()));
- const char *args[]= { "--quiet", buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", "--test=set", "--non-blocking", 0 };
+ const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", "--test=set", "--non-blocking", 0 };
+
+ test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true));
- test_true(exec_cmdline(executable, args));
return TEST_SUCCESS;
}
return false;
}
- if (not close_io)
+ if (close_io == false)
{
return true;;
}
#include "util/instance.hpp"
#include <cstdio>
-#include <sstream>
#include <iostream>
#include <netdb.h>
+#include <netinet/in.h>
#include <poll.h>
+#include <sstream>
#include <sys/socket.h>
#include <sys/types.h>
-#include <netinet/in.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
namespace datadifferential {
do
{
char buffer[BUFSIZ];
- read_length= recv(_sockfd, buffer, sizeof(buffer), 0);
+ read_length= ::recv(_sockfd, buffer, sizeof(buffer), 0);
if (read_length < 0)
{
switch(errno)
{
default:
- std::cerr << "Error occured while reading data from " << _host.c_str() << std::endl;
+ _last_error.clear();
+ _last_error+= "Error occured while reading data from ";
+ _last_error+= _host;
return false;
}
}
+ else if (read_length == 0)
+ {
+ _last_error.clear();
+ _last_error+= "Socket was shutdown while reading from ";
+ _last_error+= _host;
+
+ return false;
+ }
operation->push(buffer, static_cast<size_t>(read_length));
total_read+= static_cast<size_t>(read_length);
+
} while (more_to_read());
} // end has_response
void Instance::close_socket()
{
if (_sockfd == INVALID_SOCKET)
+ {
return;
+ }
/* in case of death shutdown to avoid blocking at close() */
if (shutdown(_sockfd, SHUT_RDWR) == SOCKET_ERROR && get_socket_errno() != ENOTCONN)
void Instance::free_addrinfo()
{
- if (not _addrinfo)
+ if (_addrinfo == NULL)
+ {
return;
+ }
freeaddrinfo(_addrinfo);
_addrinfo= NULL;
bool Operation::response(std::string &arg)
{
if (_response.empty())
+ {
return false;
+ }
if (not memcmp("OK\r\n", &_response[0], 3))
{ }
#include <pthread.h>
#include <semaphore.h>
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
namespace datadifferential {
namespace util {
#define util_string_make_from_cstr(X) (X), ((X) ? strlen(X) : 0)
+#define util_string_make_from_array(__array) (__array), (strlen(__array))
+
#define util_array_length(__array) sizeof(__array)/sizeof(&__array)