Commit dc3884d6 authored by Mukund Sivaraman's avatar Mukund Sivaraman

Merge branch 'master' into trac2357

parents 195617a1 653d1d85
......@@ -12,6 +12,20 @@ AC_CONFIG_MACRO_DIR([m4macros])
# Checks for programs.
AC_PROG_CXX
# Enable low-performing debugging facilities? This option optionally
# enables some debugging aids that perform slowly and hence aren't built
# by default.
AC_ARG_ENABLE([debug],
AS_HELP_STRING([--enable-debug],
[enable debugging (default is no)]),
[case "${enableval}" in
yes) debug_enabled=yes ;;
no) debug_enabled=no ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
esac],[debug_enabled=no])
AM_CONDITIONAL([DEBUG_ENABLED], [test x$debug_enabled = xyes])
AM_COND_IF([DEBUG_ENABLED], [AC_DEFINE([ENABLE_DEBUG], [1], [Enable low-performing debugging facilities?])])
# Libtool configuration
#
......@@ -1112,6 +1126,7 @@ AC_CONFIG_FILES([Makefile
src/bin/bindctl/Makefile
src/bin/bindctl/tests/Makefile
src/bin/cfgmgr/Makefile
src/bin/cfgmgr/local_plugins/Makefile
src/bin/cfgmgr/plugins/Makefile
src/bin/cfgmgr/plugins/tests/Makefile
src/bin/cfgmgr/tests/Makefile
......@@ -1421,6 +1436,7 @@ Features:
$enable_features
Developer:
Enable Debugging: $debug_enabled
Google Tests: $enable_gtest
Valgrind: $found_valgrind
C++ Code Coverage: $USE_LCOV
......
SUBDIRS = . plugins tests
SUBDIRS = . plugins local_plugins tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
......
# Nothing is installed from this directory. This local_plugins
# directory overrides the plugins directory when lettuce is run, and the
# spec file here is used to serve the static zone from the source tree
# for testing (instead of installation prefix).
noinst_DATA = datasrc.spec
datasrc.spec: ../plugins/datasrc.spec.pre
$(SED) -e "s|@@STATIC_ZONE_FILE@@|$(abs_top_builddir)/src/lib/datasrc/static.zone|;s|@@SQLITE3_DATABASE_FILE@@|$(abs_top_builddir)/local.zone.sqlite3|" ../plugins/datasrc.spec.pre >$@
CLEANFILES = datasrc.spec
......@@ -3,7 +3,7 @@ SUBDIRS = tests
EXTRA_DIST = README logging.spec tsig_keys.spec
datasrc.spec: datasrc.spec.pre
$(SED) -e "s|@@PKGDATADIR@@|$(pkgdatadir)|;s|@@LOCALSTATEDIR@@|$(localstatedir)|" datasrc.spec.pre >$@
$(SED) -e "s|@@STATIC_ZONE_FILE@@|$(pkgdatadir)/static.zone|;s|@@SQLITE3_DATABASE_FILE@@|$(localstatedir)/$(PACKAGE)/zone.sqlite3|" datasrc.spec.pre >$@
config_plugindir = @prefix@/share/@PACKAGE@/config_plugins
config_plugin_DATA = logging.spec tsig_keys.spec datasrc.spec
......
......@@ -12,7 +12,7 @@
{
"type": "sqlite3",
"params": {
"database_file": "@@LOCALSTATEDIR@@/@PACKAGE@/zone.sqlite3"
"database_file": "@@SQLITE3_DATABASE_FILE@@"
}
}
],
......@@ -20,7 +20,7 @@
{
"type": "static",
"cache-enable": false,
"params": "@@PKGDATADIR@@/static.zone"
"params": "@@STATIC_ZONE_FILE@@"
}
]
},
......
......@@ -51,7 +51,7 @@ def reload():
# tree the programs in the tree (not installed ones) will be used.
#
# B10_FROM_SOURCE_LOCALSTATEDIR is specifically intended to be used for
# tests where we want to use variuos types of configuration within the test
# tests where we want to use various types of configuration within the test
# environment. (We may want to make it even more generic so that the path
# is passed from the boss process)
if "B10_FROM_SOURCE" in os.environ:
......@@ -60,6 +60,8 @@ def reload():
else:
DATA_PATH = os.environ["B10_FROM_SOURCE"]
PLUGIN_PATHS = [os.environ["B10_FROM_SOURCE"] +
'/src/bin/cfgmgr/local_plugins',
os.environ["B10_FROM_SOURCE"] +
'/src/bin/cfgmgr/plugins']
programdirs = ['auth', 'cfgmgr', 'cmdctl', 'ddns', 'dhcp6', 'msgq',
'resolver', 'sockcreator', 'stats', 'xfrin', 'xfrout',
......
......@@ -12,6 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include "config.h"
#include "sync.h"
#include <exceptions/exceptions.h>
......@@ -31,12 +33,16 @@ namespace thread {
class Mutex::Impl {
public:
Impl() :
locked_count(0)
Impl()
#ifdef ENABLE_DEBUG
: locked_count(0)
#endif // ENABLE_DEBUG
{}
pthread_mutex_t mutex;
// Only in debug mode
#ifdef ENABLE_DEBUG
size_t locked_count;
#endif // ENABLE_DEBUG
};
namespace {
......@@ -70,12 +76,20 @@ Mutex::Mutex() :
isc_throw(isc::InvalidOperation, std::strerror(result));
}
Deinitializer deinitializer(attributes);
// TODO: Distinguish if debug mode is enabled in compilation.
// If so, it should be PTHREAD_MUTEX_NORMAL or NULL
// If debug mode is enabled in compilation, use the slower
// error-checking mutexes that detect deadlocks. Otherwise, use fast
// mutexes which don't. See the pthread_mutexattr_settype() POSIX
// documentation which describes these type attributes.
#ifdef ENABLE_DEBUG
result = pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_ERRORCHECK);
#else
result = pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_NORMAL);
#endif // ENABLE_DEBUG
if (result != 0) {
isc_throw(isc::InvalidOperation, std::strerror(result));
}
auto_ptr<Impl> impl(new Impl);
result = pthread_mutex_init(&impl->mutex, &attributes);
switch (result) {
......@@ -93,12 +107,17 @@ Mutex::Mutex() :
Mutex::~Mutex() {
if (impl_ != NULL) {
const int result = pthread_mutex_destroy(&impl_->mutex);
#ifdef ENABLE_DEBUG
const bool locked = impl_->locked_count != 0;
#endif // ENABLE_DEBUG
delete impl_;
// We don't want to throw from the destructor. Also, if this ever
// fails, something is really screwed up a lot.
assert(result == 0);
#ifdef ENABLE_DEBUG
// We should not try to destroy a locked mutex, bad threaded monsters
// could get loose if we ever do and it is also forbidden by pthreads.
......@@ -106,28 +125,18 @@ Mutex::~Mutex() {
// pthread_mutex_destroy should check for it already. But it seems
// there are systems that don't check it.
assert(!locked);
#endif // ENABLE_DEBUG
}
}
#ifdef ENABLE_DEBUG
void
Mutex::postLockAction() {
// This assertion would fail only in non-debugging mode, in which case
// this method wouldn't be called either, so we simply assert the
// condition.
assert(impl_->locked_count == 0);
++impl_->locked_count;
}
void
Mutex::lock() {
assert(impl_ != NULL);
const int result = pthread_mutex_lock(&impl_->mutex);
if (result != 0) {
isc_throw(isc::InvalidOperation, std::strerror(result));
}
postLockAction(); // Only in debug mode
}
void
Mutex::preUnlockAction(bool throw_ok) {
if (impl_->locked_count == 0) {
......@@ -141,20 +150,35 @@ Mutex::preUnlockAction(bool throw_ok) {
--impl_->locked_count;
}
bool
Mutex::locked() const {
return (impl_->locked_count != 0);
}
#endif // ENABLE_DEBUG
void
Mutex::lock() {
assert(impl_ != NULL);
const int result = pthread_mutex_lock(&impl_->mutex);
if (result != 0) {
isc_throw(isc::InvalidOperation, std::strerror(result));
}
#ifdef ENABLE_DEBUG
postLockAction(); // Only in debug mode
#endif // ENABLE_DEBUG
}
void
Mutex::unlock() {
assert(impl_ != NULL);
#ifdef ENABLE_DEBUG
preUnlockAction(false); // Only in debug mode. Ensure no throw.
#endif // ENABLE_DEBUG
const int result = pthread_mutex_unlock(&impl_->mutex);
assert(result == 0); // This should never be possible
}
// TODO: Disable in non-debug build
bool
Mutex::locked() const {
return (impl_->locked_count != 0);
}
class CondVar::Impl {
public:
Impl() {
......@@ -187,10 +211,13 @@ CondVar::~CondVar() {
void
CondVar::wait(Mutex& mutex) {
#ifdef ENABLE_DEBUG
mutex.preUnlockAction(true); // Only in debug mode
const int result = pthread_cond_wait(&impl_->cond_, &mutex.impl_->mutex);
mutex.postLockAction(); // Only in debug mode
#else
const int result = pthread_cond_wait(&impl_->cond_, &mutex.impl_->mutex);
#endif
// pthread_cond_wait should normally succeed unless mutex is completely
// broken.
if (result != 0) {
......
......@@ -112,6 +112,9 @@ private:
// Commonly called after acquiring the lock, checking and updating
// internal state for debug.
//
// Note that this method is only available when the build is
// configured with debugging support.
void postLockAction();
// Commonly called before releasing the lock, checking and updating
......@@ -121,6 +124,9 @@ private:
// fails; otherwise it aborts the process. This parameter must be set
// to false if the call to this shouldn't result in an exception (e.g.
// when called from a destructor).
//
// Note that this method is only available when the build is
// configured with debugging support.
void preUnlockAction(bool throw_ok);
class Impl;
......
......@@ -149,11 +149,15 @@ TEST_F(CondVarTest, DISABLED_destroyWhileWait) {
}, "");
}
#ifdef ENABLE_DEBUG
TEST_F(CondVarTest, badWait) {
// In our implementation, wait() requires acquiring the lock beforehand.
EXPECT_THROW(condvar_.wait(mutex_), isc::InvalidOperation);
}
#endif // ENABLE_DEBUG
TEST_F(CondVarTest, emptySignal) {
// It's okay to call signal when no one waits.
EXPECT_NO_THROW(condvar_.signal());
......
......@@ -26,20 +26,26 @@ using namespace isc::util::thread;
namespace {
// If we try to lock the debug mutex multiple times, it should throw.
#ifdef ENABLE_DEBUG
// If we try to lock the debug mutex multiple times, it should
// throw. This test will complete properly only when pthread debugging
// facilities are enabled by configuring the code for debug build.
TEST(MutexTest, lockMultiple) {
// TODO: Once we support non-debug mutexes, disable the test if we compile
// with them.
Mutex mutex;
EXPECT_FALSE(mutex.locked()); // Debug-only build
Mutex::Locker l1(mutex);
EXPECT_TRUE(mutex.locked()); // Debug-only build
EXPECT_THROW({
Mutex::Locker l2(mutex); // Attempt to lock again.
}, isc::InvalidOperation);
EXPECT_TRUE(mutex.locked()); // Debug-only build
}
#endif // ENABLE_DEBUG
// Destroying a locked mutex is a bad idea as well
#ifdef EXPECT_DEATH
TEST(MutexTest, destroyLocked) {
......
{
"version": 2,
"Logging": {
"loggers": [ {
"debuglevel": 99,
"severity": "DEBUG",
"name": "*"
} ]
},
"Auth": {
"listen_on": [ {
"port": 47806,
"address": "127.0.0.1"
} ]
},
"Boss": {
"components": {
"b10-auth": { "kind": "needed", "special": "auth" },
"b10-cmdctl": { "special": "cmdctl", "kind": "needed" }
}
}
}
Feature: Basic Authoritative DNS server
This feature set is for testing the execution of the b10-auth
component using its default datasource configurations. This
will start it and perform queries against it.
Scenario: Query builtin bind zone
Given I have bind10 running with configuration auth/auth_basic.config
And wait for bind10 stderr message BIND10_STARTED_CC
And wait for bind10 stderr message CMDCTL_STARTED
And wait for bind10 stderr message AUTH_SERVER_STARTED
bind10 module Auth should be running
And bind10 module Resolver should not be running
A query for example.com should have rcode REFUSED
A query for version.bind type TXT class CH should have rcode NOERROR
A query for authors.bind type TXT class CH should have rcode NOERROR
# TODO: to be compatible with BIND 9
# A query for nonexistent.bind type TXT class CH should have rcode REFUSED
......@@ -49,6 +49,8 @@ copylist = [
"configurations/example.org.config"],
["configurations/bindctl/bindctl.config.orig",
"configurations/bindctl/bindctl.config"],
["configurations/auth/auth_basic.config.orig",
"configurations/auth/auth_basic.config"],
["configurations/resolver/resolver_basic.config.orig",
"configurations/resolver/resolver_basic.config"],
["configurations/multi_instance/multi_auth.config.orig",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment