unittests/unittests
tests/libmemcached-1.0/testsocket
example/t/memcached_light
+libtest/abort
#include <example/byteorder.h>
#include "example/memcached_light.h"
#include "example/storage.h"
+#include "util/log.hpp"
+
+
+using namespace datadifferential;
+
+static util::log_info_st *log_file= NULL;
static protocol_binary_response_status noop_command_handler(const void *cookie,
protocol_binary_request_header *header,
response.message.header.response.opcode= header->request.opcode;
response.message.header.response.opaque= header->request.opaque;
- if (!delete_item(key, keylen))
+ if (delete_item(key, keylen) == false)
{
+ log_file->write(util::VERBOSE_NOTICE, "%s not found: %.*s", __func__, keylen, key);
response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_KEY_ENOENT);
return response_handler(cookie, header, (protocol_binary_response_header*)&response);
}
else if (header->request.opcode == PROTOCOL_BINARY_CMD_DELETE)
{
+ log_file->write(util::VERBOSE_NOTICE, "%s not found: %.*s", __func__, keylen, key);
/* DELETEQ doesn't want success response */
response.message.header.response.status= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS);
return response_handler(cookie, header, (protocol_binary_response_header*)&response);
}
+ log_file->write(util::VERBOSE_NOTICE, "%s deleted: %.*s", __func__, keylen, key);
+
return PROTOCOL_BINARY_RESPONSE_SUCCESS;
}
memcached_binary_protocol_callback_st interface_v0_impl;
-void initialize_interface_v0_handler(void)
+void initialize_interface_v0_handler(util::log_info_st& arg)
{
+ log_file= &arg;
+
interface_v0_impl.interface_version= MEMCACHED_PROTOCOL_HANDLER_V0;
interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_GET]= get_command_handler;
interface_v0_impl.interface.v0.comcode[PROTOCOL_BINARY_CMD_SET]= set_command_handler;
* command is being sent.
*/
#include "config.h"
-#include <assert.h>
+
+#include <cassert>
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <fcntl.h>
#include <sys/types.h>
-#include <stdio.h>
#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
#include <libmemcachedprotocol-0.0/handler.h>
#include <example/byteorder.h>
#include "example/memcached_light.h"
#include "example/storage.h"
+#include "util/log.hpp"
+
+static datadifferential::util::log_info_st *log_file= NULL;
static protocol_binary_response_status add_handler(const void *cookie,
const void *key,
memcached_binary_protocol_callback_st interface_v1_impl;
-void initialize_interface_v1_handler(void)
+void initialize_interface_v1_handler(datadifferential::util::log_info_st& arg)
{
+ log_file= &arg;
memset(&interface_v1_impl, 0, sizeof(memcached_binary_protocol_callback_st));
interface_v1_impl.interface_version= MEMCACHED_PROTOCOL_HANDLER_V1;
{
memcached_binary_protocol_callback_st *interface= &interface_v0_impl;
- /*
- * We need to initialize the handlers manually due to a bug in the
- * warnings generated by struct initialization in gcc (all the way up to 4.4)
- */
- initialize_interface_v0_handler();
- initialize_interface_v1_handler();
-
{
enum long_option_t {
OPT_HELP,
util::log_info_st log_file(argv[0], global_options.log_file, false);
log_file.write(util::VERBOSE_NOTICE, "starting log");
+ /*
+ * We need to initialize the handlers manually due to a bug in the
+ * warnings generated by struct initialization in gcc (all the way up to 4.4)
+ */
+ initialize_interface_v0_handler(log_file);
+ initialize_interface_v1_handler(log_file);
+
+
if (server_socket(log_file, global_options.service) == false)
{
return EXIT_FAILURE;
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Memcached Light interface definitions
+ *
+ * Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
/* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
#pragma once
-extern void initialize_interface_v0_handler(void);
-extern void initialize_interface_v1_handler(void);
+#include "util/log.hpp"
+
+void initialize_interface_v0_handler(datadifferential::util::log_info_st&);
+void initialize_interface_v1_handler(datadifferential::util::log_info_st&);
libmemcached/libmemcached.la \
libmemcached/libmemcachedutil.la \
libtest/libtest.la
-example_t_memcached_light_SOURCES= example/t/memcached_light.cc
+
+example_t_memcached_light_SOURCES=
+example_t_memcached_light_LDADD=
+
+example_t_memcached_light_SOURCES+= example/t/memcached_light.cc
+example_t_memcached_light_SOURCES+= tests/libmemcached-1.0/memcached_get.cc
+example_t_memcached_light_SOURCES+= tests/libmemcached-1.0/setup_and_teardowns.cc
example_t_memcached_light_CXXFLAGS = $(AM_CXXFLAGS)
example_t_memcached_light_DEPENDENCIES= $(MEMCACHED_LIGHT_TESTS_LDADDS) example/memcached_light
-example_t_memcached_light_LDADD= $(MEMCACHED_LIGHT_TESTS_LDADDS)
+example_t_memcached_light_LDADD+= $(MEMCACHED_LIGHT_TESTS_LDADDS)
+example_t_memcached_light_LDADD+= $(LIBUUID_LDFLAGS)
check_PROGRAMS+= example/t/memcached_light
noinst_PROGRAMS+= example/t/memcached_light
-test-memcached_light: example/t/memcached_light
+test-memcached_light: example/t/memcached_light example/memcached_light
@example/t/memcached_light
+
+gdb-memcached_light: example/t/memcached_light example/memcached_light
+ @$(DEBUG_COMMAND) example/t/memcached_light
+
+valgrind-memcached_light: example/t/memcached_light example/memcached_light
+ $(VALGRIND_COMMAND) example/t/memcached_light
#include <libtest/test.hpp>
#include <libmemcached/memcached.h>
+#include "tests/libmemcached-1.0/memcached_get.h"
+
using namespace libtest;
#ifndef __INTEL_COMPILER
return TEST_SUCCESS;
}
+typedef test_return_t (*libmemcached_test_callback_fn)(memcached_st *);
+
+static test_return_t _runner_default(libmemcached_test_callback_fn func, void *object)
+{
+ if (func)
+ {
+ test_true(object);
+ test_return_t ret;
+ try {
+ ret= func((memcached_st*)object);
+ }
+ catch (std::exception& e)
+ {
+ libtest::Error << e.what();
+ return TEST_FAILURE;
+ }
+
+ return ret;
+ }
+
+ return TEST_SUCCESS;
+}
+
+class MemcachedLightRunner : public libtest::Runner {
+public:
+ test_return_t run(test_callback_fn* func, void *object)
+ {
+ return _runner_default(libmemcached_test_callback_fn(func), object);
+ }
+};
+
+static MemcachedLightRunner defualt_libmemcached_runner;
+
test_st cmdline_option_TESTS[] ={
{"--help", true, help_TEST },
{"--verbose", true, verbose_TEST },
{0, 0, 0}
};
+/* Clean the server before beginning testing */
+test_st basic_TESTS[] ={
+#if 0
+ {"memcached_get()", true, (test_callback_fn*)get_test },
+ {"memcached_get() test 2", false, (test_callback_fn*)get_test2 },
+ {"memcached_get() test 3", false, (test_callback_fn*)get_test3 },
+ {"memcached_get() test 4", false, (test_callback_fn*)get_test4 },
+ {"memcached_get() test 5", false, (test_callback_fn*)get_test5 },
+#endif
+ {0, 0, 0}
+};
+
collection_st collection[] ={
{"command line options", 0, 0, cmdline_option_TESTS },
+ {"basic", 0, 0, basic_TESTS },
{0, 0, 0, 0}
};
error= TEST_FAILURE;
}
- return &servers;
+
+ char buffer[1024];
+ int length= snprintf(buffer, sizeof(buffer), "--server=localhost:%d", int(libtest::default_port()));
+ fatal_assert(length > 0);
+
+ memcached_st *memc= memcached(buffer, length);
+
+ fatal_assert(memc);
+
+ return (void*)memc;
+}
+
+static bool world_destroy(void *object)
+{
+ memcached_st *memc= (memcached_st*)object;
+ memcached_free(memc);
+
+ return TEST_SUCCESS;
}
void get_world(Framework *world)
{
- world->collections= collection;
world->_create= world_create;
+ world->_destroy= world_destroy;
+ world->collections= collection;
+ world->set_runner(&defualt_libmemcached_runner);
}
--- /dev/null
+#include <cstdlib>
+
+int main(void)
+{
+ if (1)
+ {
+ abort();
+ }
+
+ return 0;
+}
#include <cstdlib>
#include <cstring>
#include <fcntl.h>
+#include <fstream>
#include <memory>
#include <spawn.h>
#include <sstream>
namespace {
- std::string print_argv(char * * & built_argv, const size_t& argc, const pid_t& pid)
+ std::string print_argv(char * * & built_argv, const size_t& argc)
{
std::stringstream arg_buffer;
return arg_buffer.str();
}
+ std::string print_argv(char** argv)
+ {
+ std::stringstream arg_buffer;
+
+ for (char** ptr= argv; *ptr; ptr++)
+ {
+ arg_buffer << *ptr << " ";
+ }
+
+ return arg_buffer.str();
+ }
+
static Application::error_t int_to_error_t(int arg)
{
switch (arg)
Application::Application(const std::string& arg, const bool _use_libtool_arg) :
_use_libtool(_use_libtool_arg),
+ _use_valgrind(false),
+ _use_gdb(false),
_argc(0),
_exectuble(arg),
built_argv(NULL),
}
}
+ // Find just the name of the application with no path
+ {
+ size_t found= arg.find_last_of("/\\");
+ if (found)
+ {
+ _exectuble_name= arg.substr(found +1);
+ }
+ else
+ {
+ _exectuble_name= arg;
+ }
+ }
+
if (_use_libtool and getenv("PWD"))
{
_exectuble_with_path+= getenv("PWD");
create_argv(args);
int spawn_ret;
- if (_use_libtool)
+ if (_use_gdb)
{
- spawn_ret= posix_spawn(&_pid, built_argv[0], &file_actions, NULL, built_argv, NULL);
+ std::string gdb_run_file= create_tmpfile(_exectuble_name);
+ std::fstream file_stream;
+ file_stream.open(gdb_run_file.c_str(), std::fstream::out | std::fstream::trunc);
+
+ _gdb_filename= create_tmpfile(_exectuble_name);
+ file_stream
+ << "set logging redirect on" << std::endl
+ << "set logging file " << _gdb_filename << std::endl
+ << "set logging overwrite on" << std::endl
+ << "set logging on" << std::endl
+ << "set environment LIBTEST_IN_GDB=1" << std::endl
+ << "run " << arguments() << std::endl
+ << "thread apply all bt" << std::endl
+ << "quit" << std::endl;
+
+ fatal_assert(file_stream.good());
+ file_stream.close();
+
+ if (_use_libtool)
+ {
+ // libtool --mode=execute gdb -f -x binary
+ char *argv[]= {
+ const_cast<char *>(libtool()),
+ const_cast<char *>("--mode=execute"),
+ const_cast<char *>("gdb"),
+ const_cast<char *>("-batch"),
+ const_cast<char *>("-f"),
+ const_cast<char *>("-x"),
+ const_cast<char *>(gdb_run_file.c_str()),
+ const_cast<char *>(_exectuble_with_path.c_str()),
+ 0};
+
+ spawn_ret= posix_spawnp(&_pid, libtool(), &file_actions, NULL, argv, NULL);
+ }
+ else
+ {
+ // gdb binary
+ char *argv[]= {
+ const_cast<char *>("gdb"),
+ const_cast<char *>("-batch"),
+ const_cast<char *>("-f"),
+ const_cast<char *>("-x"),
+ const_cast<char *>(gdb_run_file.c_str()),
+ const_cast<char *>(_exectuble_with_path.c_str()),
+ 0};
+ spawn_ret= posix_spawnp(&_pid, "gdb", &file_actions, NULL, argv, NULL);
+ }
}
else
{
- spawn_ret= posix_spawnp(&_pid, built_argv[0], &file_actions, NULL, built_argv, NULL);
+ if (_use_libtool)
+ {
+ 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);
}
}
+#if 0
if (exit_code == Application::INVALID)
{
- Error << print_argv(built_argv, _argc, _pid);
+ Error << print_argv(built_argv, _argc);
}
+#endif
return exit_code;
}
_argc+= 2; // +2 for libtool --mode=execute
}
+ /*
+ valgrind --error-exitcode=1 --leak-check=yes --show-reachable=yes --track-fds=yes --malloc-fill=A5 --free-fill=DE
+ */
+ if (_use_valgrind)
+ {
+ _argc+= 7;
+ }
+ else if (_use_gdb) // gdb
+ {
+ _argc+= 1;
+ }
+
for (Options::const_iterator iter= _options.begin(); iter != _options.end(); iter++)
{
_argc++;
built_argv[x++]= strdup(libtool());
built_argv[x++]= strdup("--mode=execute");
}
+
+ if (_use_valgrind)
+ {
+ /*
+ valgrind --error-exitcode=1 --leak-check=yes --show-reachable=yes --track-fds=yes --malloc-fill=A5 --free-fill=DE
+ */
+ built_argv[x++]= strdup("valgrind");
+ built_argv[x++]= strdup("--error-exitcode=1");
+ built_argv[x++]= strdup("--leak-check=yes");
+ built_argv[x++]= strdup("--show-reachable=yes");
+ built_argv[x++]= strdup("--track-fds=yes");
+ built_argv[x++]= strdup("--malloc-fill=A5");
+ built_argv[x++]= strdup("--free-fill=DE");
+ }
+ else if (_use_gdb)
+ {
+ built_argv[x++]= strdup("gdb");
+ }
+
built_argv[x++]= strdup(_exectuble_with_path.c_str());
for (Options::const_iterator iter= _options.begin(); iter != _options.end(); iter++)
std::string Application::print()
{
- return print_argv(built_argv, _argc, _pid);
+ return print_argv(built_argv, _argc);
+}
+
+std::string Application::arguments()
+{
+ std::stringstream arg_buffer;
+
+ for (size_t x= 1 + _use_libtool ? 2 : 0;
+ x < _argc and built_argv[x];
+ x++)
+ {
+ arg_buffer << built_argv[x] << " ";
+ }
+
+ return arg_buffer.str();
}
void Application::delete_argv()
std::string print();
+ void use_valgrind(bool arg= true)
+ {
+ _use_valgrind= arg;
+ }
+
+ void use_gdb(bool arg= true)
+ {
+ _use_gdb= arg;
+ }
+
+ std::string arguments();
+
+ std::string gdb_filename()
+ {
+ return _gdb_filename;
+ }
+
private:
void create_argv(const char *args[]);
void delete_argv();
private:
const bool _use_libtool;
+ bool _use_valgrind;
+ bool _use_gdb;
size_t _argc;
+ std::string _exectuble_name;
std::string _exectuble;
std::string _exectuble_with_path;
+ std::string _gdb_filename;
Options _options;
Pipe stdin_fd;
Pipe stdout_fd;
libtest/killpid.h \
libtest/libtool.hpp \
libtest/memcached.h \
- libtest/runner.h \
libtest/port.h \
+ libtest/runner.h \
libtest/server.h \
libtest/server_container.h \
libtest/signal.h \
libtest/string.hpp \
libtest/test.h \
libtest/test.hpp \
+ libtest/tmpfile.hpp \
libtest/vchar.hpp \
libtest/visibility.h \
libtest/wait.h
libtest/socket.cc \
libtest/strerror.cc \
libtest/test.cc \
+ libtest/tmpfile.cc \
libtest/vchar.cc
libtest_libtest_la_CXXFLAGS=
@$(mkdir_p) tmp_chroot/var/run
-libtest_unittest_DEPENDENCIES+= libtest/libtest.la libtest_tmp_dir
+libtest_unittest_DEPENDENCIES+= libtest/libtest.la libtest_tmp_dir libtest/abort libtest/wait
libtest_unittest_LDADD+= libtest/libtest.la
libtest_unittest_SOURCES= libtest/unittest.cc
check_PROGRAMS+= libtest/unittest
libtest_wait_SOURCES= libtest/wait.cc
noinst_PROGRAMS+= libtest/wait
+
+libtest_abort_SOURCES= libtest/abort.cc
+noinst_PROGRAMS+= libtest/abort
// Memcached is slow to start, so we need to do this
if (not pid_file().empty())
{
- if (not wait_for_pidfile())
+ if (wait_for_pidfile() == false)
{
Error << "Pidfile was not found:" << pid_file();
return -1;
return true;
}
+ void log_file_option(Application& app, const std::string& arg)
+ {
+ if (arg.empty() == false)
+ {
+ std::string buffer("--log-file=");
+ buffer+= arg;
+ app.add_option("--verbose");
+ app.add_option(buffer);
+ }
+ }
+
+ bool has_log_file_option() const
+ {
+ return true;
+ }
+
bool build(size_t argc, const char *argv[]);
};
+set logging on
+set logging overwrite on
set environment LIBTEST_IN_GDB=1
run
+thread apply all bt
+quit
}
Application app(executable(), is_libtool());
+
+ if (is_debug())
+ {
+ app.use_gdb();
+ }
+ else if (getenv("TESTS_ENVIRONMENT"))
+ {
+ if (strstr(getenv("TESTS_ENVIRONMENT"), "gdb"))
+ {
+ app.use_gdb();
+ }
+ }
+
if (args(app) == false)
{
Error << "Could not build command()";
int fd;
if ((fd= mkstemp(file_buffer)) == -1)
{
- perror(file_buffer);
- return false;
+ libtest::fatal(LIBYATL_DEFAULT_PARAM, "mkstemp() failed on %s with %s", file_buffer, strerror(errno));
}
close(fd);
{
// Set a log file if it was requested (and we can)
- if (getenv("LIBTEST_LOG") and has_log_file_option())
+ if (has_log_file_option())
{
- if (not set_log_file())
- {
- return false;
- }
-
+ set_log_file();
log_file_option(app, _log_file);
}
}
}
- bool has_log_file_option() const
+ virtual bool has_log_file_option() const
{
return false;
}
#include <libtest/binaries.h>
#include <libtest/http.hpp>
#include <libtest/cpu.hpp>
+#include <libtest/tmpfile.hpp>
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2012 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 {
+
+std::string create_tmpfile(const std::string& name)
+{
+ char file_buffer[FILENAME_MAX];
+ file_buffer[0]= 0;
+
+ int length= snprintf(file_buffer, sizeof(file_buffer), "var/tmp/%s.XXXXXX", name.c_str());
+ fatal_assert(length > 0);
+
+ int fd;
+ if ((fd= mkstemp(file_buffer)) == -1)
+ {
+ libtest::fatal(LIBYATL_DEFAULT_PARAM, "mkstemp() failed on %s with %s", file_buffer, strerror(errno));
+ }
+ close(fd);
+ unlink(file_buffer);
+
+ return file_buffer;
+}
+
+} // namespace libtest
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * libtest
+ *
+ * Copyright (C) 2012 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 <libtest/common.h>
+
+namespace libtest {
+
+std::string create_tmpfile(const std::string&);
+
+} // namespace libtest
+
return TEST_SUCCESS;
}
+static test_return_t application_gdb_true_BINARY2(void *)
+{
+ Application true_app("true");
+ true_app.use_gdb();
+
+ test_compare(Application::SUCCESS, true_app.run());
+ test_compare(Application::SUCCESS, true_app.wait());
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t application_gdb_true_BINARY(void *)
+{
+ Application true_app("true");
+ true_app.use_gdb();
+
+ const char *args[]= { "--fubar", 0 };
+ test_compare(Application::SUCCESS, true_app.run(args));
+ test_compare(Application::SUCCESS, true_app.wait());
+
+ return TEST_SUCCESS;
+}
+
static test_return_t application_true_fubar_BINARY(void *)
{
Application true_app("true");
return TEST_SUCCESS;
}
+static test_return_t application_doesnotexist_BINARY(void *)
+{
+ Application true_app("doesnotexist");
+
+ const char *args[]= { "--fubar", 0 };
+ test_compare(Application::SUCCESS, true_app.run(args));
+ test_compare(Application::INVALID, 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");
return TEST_SUCCESS;
}
-static test_return_t application_wait_services_BINARY2(void *)
+static test_return_t wait_services_appliction_TEST(void *)
{
test_skip(0, access("/etc/services", R_OK ));
- libtest::Application("libtest/wait", true);
+ libtest::Application wait_app("libtest/wait", true);
+ wait_app.use_gdb();
+
const char *args[]= { "/etc/services", 0 };
+ test_compare(Application::SUCCESS, wait_app.run(args));
+ test_compare(Application::SUCCESS, wait_app.wait());
- test_compare(EXIT_SUCCESS, exec_cmdline("libtest/wait", args, true));
+ return TEST_SUCCESS;
+}
+
+static test_return_t gdb_wait_services_appliction_TEST(void *)
+{
+ test_skip(0, access("/etc/services", R_OK ));
+
+ libtest::Application wait_app("libtest/wait", true);
+ wait_app.use_gdb();
+
+ const char *args[]= { "/etc/services", 0 };
+ test_compare(Application::SUCCESS, wait_app.run(args));
+ test_compare(Application::SUCCESS, wait_app.wait());
+
+ return TEST_SUCCESS;
+}
+
+static test_return_t gdb_abort_services_appliction_TEST(void *)
+{
+ libtest::Application abort_app("libtest/abort", true);
+ abort_app.use_gdb();
+
+ test_compare(Application::SUCCESS, abort_app.run());
+ test_compare(Application::SUCCESS, abort_app.wait());
+
+ std::string gdb_filename= abort_app.gdb_filename();
+ const char *args[]= { "SIGABRT", gdb_filename.c_str(), 0 };
+ test_compare(EXIT_SUCCESS, exec_cmdline("grep", args));
+
+ // Sanity test
+ args[0]= "THIS_WILL_NOT_BE_FOUND";
+ test_compare(EXIT_FAILURE, exec_cmdline("grep", args));
return TEST_SUCCESS;
}
return TEST_SUCCESS;
}
+static test_return_t create_tmpfile_TEST(void *)
+{
+ std::string tmp= create_tmpfile(__func__);
+
+ Application touch_app("touch");
+ const char *args[]= { tmp.c_str(), 0 };
+ test_compare(Application::SUCCESS, touch_app.run(args));
+ test_compare(Application::SUCCESS, touch_app.wait());
+
+ test_compare_hint(0, access(tmp.c_str(), R_OK), strerror(errno));
+ test_compare_hint(0, unlink(tmp.c_str()), strerror(errno));
+
+ return TEST_SUCCESS;
+}
+
static test_return_t fatal_message_TEST(void *)
{
test_compare(fatal_calls++, fatal::disabled_counter());
{"wait --quiet --version", 0, wait_version_BINARY },
{"wait --quiet /etc/services", 0, wait_services_BINARY },
{"wait /etc/services", 0, wait_services_BINARY2 },
+ {"wait /etc/services", 0, wait_services_appliction_TEST },
+ {"gdb wait /etc/services", 0, gdb_wait_services_appliction_TEST },
+ {"gdb abort", 0, gdb_abort_services_appliction_TEST },
{0, 0, 0}
};
{0, 0, 0}
};
+test_st create_tmpfile_TESTS[] ={
+ {"libtest::create_tmpfile()", 0, create_tmpfile_TEST },
+ {0, 0, 0}
+};
+
test_st application_tests[] ={
{"vchar_t", 0, vchar_t_TEST },
{"true", 0, application_true_BINARY },
+ {"gbd true --fubar", 0, application_gdb_true_BINARY },
+ {"gbd true", 0, application_gdb_true_BINARY2 },
{"true --fubar", 0, application_true_fubar_BINARY },
+ {"doesnotexist --fubar", 0, application_doesnotexist_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 },
{"get_free_port()", 0, 0, get_free_port_TESTS },
{"fatal", disable_fatal_exception, enable_fatal_exception, fatal_message_TESTS },
{"number_of_cpus()", 0, 0, number_of_cpus_TESTS },
+ {"create_tmpfile()", 0, 0, create_tmpfile_TESTS },
{0, 0, 0, 0}
};
#pragma once
+#include <tests/libmemcached-1.0/memcached_get.h>
+
/* Clean the server before beginning testing */
test_st tests[] ={
tests/libmemcached-1.0/generate.h \
tests/libmemcached-1.0/haldenbrand.h \
tests/libmemcached-1.0/mem_functions.h \
+ tests/libmemcached-1.0/memcached_get.h \
tests/libmemcached-1.0/setup_and_teardowns.h \
tests/libmemcached-1.0/stat.h \
tests/namespace.h \
tests/libmemcached-1.0/haldenbrand.cc \
tests/libmemcached-1.0/ketama.cc \
tests/libmemcached-1.0/mem_functions.cc \
+ tests/libmemcached-1.0/memcached_get.cc \
tests/libmemcached-1.0/namespace.cc \
tests/libmemcached-1.0/parser.cc \
tests/libmemcached-1.0/pool.cc \
tests/libmemcached-1.0/haldenbrand.cc \
tests/libmemcached-1.0/ketama.cc \
tests/libmemcached-1.0/mem_functions.cc \
+ tests/libmemcached-1.0/memcached_get.cc \
tests/libmemcached-1.0/namespace.cc \
tests/libmemcached-1.0/parser.cc \
tests/libmemcached-1.0/pool.cc \
std::vector<size_t> _lengths;
};
-static memcached_return_t return_value_based_on_buffering(memcached_st *memc)
-{
- if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS))
- {
- return MEMCACHED_BUFFERED;
- }
-
- return MEMCACHED_SUCCESS;
-}
-
static memcached_st * create_single_instance_memcached(const memcached_st *original_memc, const char *options)
{
/*
return TEST_SUCCESS;
}
-test_return_t get_test(memcached_st *memc)
-{
- uint64_t query_id= memcached_query_id(memc);
- memcached_return_t rc= memcached_delete(memc,
- test_literal_param(__func__),
- time_t(0));
- test_true_hint(rc == MEMCACHED_BUFFERED or rc == MEMCACHED_NOTFOUND, memcached_last_error_message(memc));
- test_compare(query_id +1, memcached_query_id(memc));
-
- size_t string_length;
- uint32_t flags;
- char *string= memcached_get(memc,
- test_literal_param(__func__),
- &string_length, &flags, &rc);
-
- test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_last_error_message(memc));
- test_false(string_length);
- test_false(string);
-
- return TEST_SUCCESS;
-}
-
-test_return_t get_test2(memcached_st *memc)
-{
- const char *value= "when we sanitize";
-
- uint64_t query_id= memcached_query_id(memc);
- test_compare(return_value_based_on_buffering(memc),
- memcached_set(memc,
- test_literal_param(__func__),
- value, strlen(value),
- time_t(0), uint32_t(0)));
- test_compare(query_id +1, memcached_query_id(memc));
-
- query_id= memcached_query_id(memc);
- test_true(query_id);
-
- uint32_t flags;
- size_t string_length;
- memcached_return_t rc;
- char *string= memcached_get(memc,
- test_literal_param(__func__),
- &string_length, &flags, &rc);
- test_compare(query_id +1, memcached_query_id(memc));
-
- test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
- test_compare_got(MEMCACHED_SUCCESS, memcached_last_error(memc), memcached_last_error_message(memc));
- test_true(string);
- test_compare(strlen(value), string_length);
- test_memcmp(string, value, string_length);
-
- free(string);
-
- return TEST_SUCCESS;
-}
-
test_return_t set_test2(memcached_st *memc)
{
for (uint32_t x= 0; x < 10; x++)
return TEST_SUCCESS;
}
-test_return_t get_test3(memcached_st *memc)
-{
- size_t value_length= 8191;
-
- libtest::vchar_t value;
- value.reserve(value_length);
- for (uint32_t x= 0; x < value_length; x++)
- {
- value.push_back(char(x % 127));
- }
-
- test_compare_hint(return_value_based_on_buffering(memc),
- memcached_set(memc,
- test_literal_param(__func__),
- &value[0], value.size(),
- time_t(0), uint32_t(0)),
- memcached_last_error_message(memc));
-
- size_t string_length;
- uint32_t flags;
- memcached_return_t rc;
- char *string= memcached_get(memc,
- test_literal_param(__func__),
- &string_length, &flags, &rc);
-
- test_compare(MEMCACHED_SUCCESS, rc);
- test_true(string);
- test_compare(value.size(), string_length);
- test_memcmp(string, &value[0], string_length);
-
- free(string);
-
- return TEST_SUCCESS;
-}
-
-test_return_t get_test4(memcached_st *memc)
-{
- size_t value_length= 8191;
-
- libtest::vchar_t value;
- value.reserve(value_length);
- for (uint32_t x= 0; x < value_length; x++)
- {
- value.push_back(char(x % 127));
- }
-
- test_compare_hint(return_value_based_on_buffering(memc),
- memcached_set(memc,
- test_literal_param(__func__),
- &value[0], value.size(),
- time_t(0), uint32_t(0)),
- memcached_last_error_message(memc));
-
- for (uint32_t x= 0; x < 10; x++)
- {
- uint32_t flags;
- size_t string_length;
- memcached_return_t rc;
- char *string= memcached_get(memc,
- test_literal_param(__func__),
- &string_length, &flags, &rc);
-
- test_compare(MEMCACHED_SUCCESS, rc);
- test_true(string);
- test_compare(value.size(), string_length);
- test_memcmp(string, &value[0], string_length);
- free(string);
- }
-
- return TEST_SUCCESS;
-}
-
-/*
- * This test verifies that memcached_read_one_response doesn't try to
- * dereference a NIL-pointer if you issue a multi-get and don't read out all
- * responses before you execute a storage command.
- */
-test_return_t get_test5(memcached_st *memc)
-{
- /*
- ** Request the same key twice, to ensure that we hash to the same server
- ** (so that we have multiple response values queued up) ;-)
- */
- const char *keys[]= { "key", "key" };
- size_t lengths[]= { 3, 3 };
- uint32_t flags;
- size_t rlen;
-
- test_compare_hint(return_value_based_on_buffering(memc),
- memcached_set(memc, keys[0], lengths[0],
- keys[0], lengths[0],
- time_t(0), uint32_t(0)),
- memcached_last_error_message(memc));
- test_compare(MEMCACHED_SUCCESS, memcached_mget(memc, keys, lengths, test_array_length(keys)));
-
- memcached_result_st results_obj;
- memcached_result_st *results= memcached_result_create(memc, &results_obj);
- test_true(results);
-
- memcached_return_t rc;
- results= memcached_fetch_result(memc, &results_obj, &rc);
- test_true(results);
-
- memcached_result_free(&results_obj);
-
- /* Don't read out the second result, but issue a set instead.. */
- test_compare(MEMCACHED_SUCCESS, memcached_set(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0));
-
- char *val= memcached_get_by_key(memc, keys[0], lengths[0], "yek", 3,
- &rlen, &flags, &rc);
- test_false(val);
- test_compare(MEMCACHED_NOTFOUND, rc);
- val= memcached_get(memc, keys[0], lengths[0], &rlen, &flags, &rc);
- test_true(val);
- test_compare(MEMCACHED_SUCCESS, rc);
- free(val);
-
- return TEST_SUCCESS;
-}
-
test_return_t mget_end(memcached_st *memc)
{
const char *keys[]= { "foo", "foo2" };
test_return_t fnv1a_64_run (memcached_st *);
test_return_t get_stats(memcached_st *memc);
test_return_t get_stats_keys(memcached_st *memc);
-test_return_t get_test(memcached_st *memc);
-test_return_t get_test2(memcached_st *memc);
-test_return_t get_test3(memcached_st *memc);
-test_return_t get_test4(memcached_st *memc);
-test_return_t get_test5(memcached_st *memc);
test_return_t getpid_connection_failure_test(memcached_st *memc);
test_return_t getpid_test(memcached_st *memc);
test_return_t hash_sanity_test (memcached_st *memc);
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
+ *
+ * Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+#include <libtest/test.hpp>
+
+/*
+ Test cases
+*/
+
+#include <libmemcached-1.0/memcached.h>
+#include "tests/libmemcached-1.0/memcached_get.h"
+#include "tests/libmemcached-1.0/setup_and_teardowns.h"
+
+test_return_t get_test(memcached_st *memc)
+{
+ uint64_t query_id= memcached_query_id(memc);
+ memcached_return_t rc= memcached_delete(memc,
+ test_literal_param(__func__),
+ time_t(0));
+ test_true_hint(rc == MEMCACHED_BUFFERED or rc == MEMCACHED_NOTFOUND, memcached_last_error_message(memc));
+ test_compare(query_id +1, memcached_query_id(memc));
+
+ size_t string_length;
+ uint32_t flags;
+ char *string= memcached_get(memc,
+ test_literal_param(__func__),
+ &string_length, &flags, &rc);
+
+ test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_last_error_message(memc));
+ test_false(string_length);
+ test_false(string);
+
+ return TEST_SUCCESS;
+}
+
+test_return_t get_test2(memcached_st *memc)
+{
+ const char *value= "when we sanitize";
+
+ uint64_t query_id= memcached_query_id(memc);
+ test_compare(return_value_based_on_buffering(memc),
+ memcached_set(memc,
+ test_literal_param(__func__),
+ value, strlen(value),
+ time_t(0), uint32_t(0)));
+ test_compare(query_id +1, memcached_query_id(memc));
+
+ query_id= memcached_query_id(memc);
+ test_true(query_id);
+
+ uint32_t flags;
+ size_t string_length;
+ memcached_return_t rc;
+ char *string= memcached_get(memc,
+ test_literal_param(__func__),
+ &string_length, &flags, &rc);
+ test_compare(query_id +1, memcached_query_id(memc));
+
+ test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
+ test_compare_got(MEMCACHED_SUCCESS, memcached_last_error(memc), memcached_last_error_message(memc));
+ test_true(string);
+ test_compare(strlen(value), string_length);
+ test_memcmp(string, value, string_length);
+
+ free(string);
+
+ return TEST_SUCCESS;
+}
+
+test_return_t get_test3(memcached_st *memc)
+{
+ size_t value_length= 8191;
+
+ libtest::vchar_t value;
+ value.reserve(value_length);
+ for (uint32_t x= 0; x < value_length; x++)
+ {
+ value.push_back(char(x % 127));
+ }
+
+ test_compare_hint(return_value_based_on_buffering(memc),
+ memcached_set(memc,
+ test_literal_param(__func__),
+ &value[0], value.size(),
+ time_t(0), uint32_t(0)),
+ memcached_last_error_message(memc));
+
+ size_t string_length;
+ uint32_t flags;
+ memcached_return_t rc;
+ char *string= memcached_get(memc,
+ test_literal_param(__func__),
+ &string_length, &flags, &rc);
+
+ test_compare(MEMCACHED_SUCCESS, rc);
+ test_true(string);
+ test_compare(value.size(), string_length);
+ test_memcmp(string, &value[0], string_length);
+
+ free(string);
+
+ return TEST_SUCCESS;
+}
+
+test_return_t get_test4(memcached_st *memc)
+{
+ size_t value_length= 8191;
+
+ libtest::vchar_t value;
+ value.reserve(value_length);
+ for (uint32_t x= 0; x < value_length; x++)
+ {
+ value.push_back(char(x % 127));
+ }
+
+ test_compare_hint(return_value_based_on_buffering(memc),
+ memcached_set(memc,
+ test_literal_param(__func__),
+ &value[0], value.size(),
+ time_t(0), uint32_t(0)),
+ memcached_last_error_message(memc));
+
+ for (uint32_t x= 0; x < 10; x++)
+ {
+ uint32_t flags;
+ size_t string_length;
+ memcached_return_t rc;
+ char *string= memcached_get(memc,
+ test_literal_param(__func__),
+ &string_length, &flags, &rc);
+
+ test_compare(MEMCACHED_SUCCESS, rc);
+ test_true(string);
+ test_compare(value.size(), string_length);
+ test_memcmp(string, &value[0], string_length);
+ free(string);
+ }
+
+ return TEST_SUCCESS;
+}
+
+/*
+ * This test verifies that memcached_read_one_response doesn't try to
+ * dereference a NIL-pointer if you issue a multi-get and don't read out all
+ * responses before you execute a storage command.
+ */
+test_return_t get_test5(memcached_st *memc)
+{
+ /*
+ ** Request the same key twice, to ensure that we hash to the same server
+ ** (so that we have multiple response values queued up) ;-)
+ */
+ const char *keys[]= { "key", "key" };
+ size_t lengths[]= { 3, 3 };
+ uint32_t flags;
+ size_t rlen;
+
+ test_compare_hint(return_value_based_on_buffering(memc),
+ memcached_set(memc, keys[0], lengths[0],
+ keys[0], lengths[0],
+ time_t(0), uint32_t(0)),
+ memcached_last_error_message(memc));
+ test_compare(MEMCACHED_SUCCESS, memcached_mget(memc, keys, lengths, test_array_length(keys)));
+
+ memcached_result_st results_obj;
+ memcached_result_st *results= memcached_result_create(memc, &results_obj);
+ test_true(results);
+
+ memcached_return_t rc;
+ results= memcached_fetch_result(memc, &results_obj, &rc);
+ test_true(results);
+
+ memcached_result_free(&results_obj);
+
+ /* Don't read out the second result, but issue a set instead.. */
+ test_compare(MEMCACHED_SUCCESS, memcached_set(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0));
+
+ char *val= memcached_get_by_key(memc, keys[0], lengths[0], "yek", 3,
+ &rlen, &flags, &rc);
+ test_false(val);
+ test_compare(MEMCACHED_NOTFOUND, rc);
+ val= memcached_get(memc, keys[0], lengths[0], &rlen, &flags, &rc);
+ test_true(val);
+ test_compare(MEMCACHED_SUCCESS, rc);
+ free(val);
+
+ return TEST_SUCCESS;
+}
--- /dev/null
+/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ * Libmemcached library
+ *
+ * Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * The names of its contributors may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+test_return_t get_test(memcached_st*);
+test_return_t get_test2(memcached_st*);
+test_return_t get_test3(memcached_st*);
+test_return_t get_test4(memcached_st*);
+test_return_t get_test5(memcached_st*);
+
#include <sys/stat.h>
+
+memcached_return_t return_value_based_on_buffering(memcached_st *memc)
+{
+ if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS))
+ {
+ return MEMCACHED_BUFFERED;
+ }
+
+ return MEMCACHED_SUCCESS;
+}
+
/**
@note This should be testing to see if the server really supports the binary protocol.
*/
#pragma once
+memcached_return_t return_value_based_on_buffering(memcached_st*);
+
test_return_t pre_behavior_ketama(memcached_st*);
test_return_t pre_behavior_ketama_weighted(memcached_st*);
test_return_t pre_binary(memcached_st*);
#pragma once
#include <cerrno>
+#include <cstdarg>
#include <cstdio>
#include <fcntl.h>
#include <iostream>
return fd;
}
- void write(verbose_t verbose, const char *mesg)
+ void write(verbose_t verbose, const char *format, ...)
{
- if (opt_file)
+ if (opt_file or opt_syslog)
{
- char buffer[UTIL_MAX_ERROR_SIZE];
- int buffer_length= snprintf(buffer, sizeof(buffer), "%7s %s\n", verbose_name(verbose), mesg);
- if (::write(file(), buffer, buffer_length) == -1)
+ va_list args;
+ va_start(args, format);
+ char mesg[BUFSIZ];
+ int mesg_length= vsnprintf(mesg, sizeof(mesg), format, args);
+ va_end(args);
+
+ if (opt_file)
{
- std::cerr << "Could not write to log file." << std::endl;
- syslog(LOG_EMERG, "gearmand could not open log file %s, got error %s", filename.c_str(), strerror(errno));
- }
+ char buffer[UTIL_MAX_ERROR_SIZE];
+ int buffer_length= snprintf(buffer, sizeof(buffer), "%7s %.*s\n", verbose_name(verbose), mesg_length, mesg);
+ if (::write(file(), buffer, buffer_length) == -1)
+ {
+ std::cerr << "Could not write to log file." << std::endl;
+ syslog(LOG_EMERG, "gearmand could not open log file %s, got error %s", filename.c_str(), strerror(errno));
+ }
- }
+ }
- if (opt_syslog)
- {
- syslog(int(verbose), "%7s %s", verbose_name(verbose), mesg);
+ if (opt_syslog)
+ {
+ syslog(int(verbose), "%7s %.*s", verbose_name(verbose), mesg_length, mesg);
+ }
}
}