[svn] commit: r2801 - in /branches/trac310: ./ src/bin/auth/ src/bin/auth/tests/ src/bin/bind10/ src/bin/bind10/tests/ src/bin/bindctl/tests/ src/bin/cfgmgr/tests/ src/bin/cmdctl/tests/ src/bin/loadzone/tests/correct/ src/bin/loadzone/tests/error/ src/bin/msgq/ src/bin/msgq/tests/ src/bin/xfrin/ src/bin/xfrin/tests/ src/bin/xfrout/tests/ src/bin/zonemgr/tests/ src/lib/bench/ src/lib/cc/ src/lib/cc/tests/ src/lib/config/ src/lib/config/testdata/ src/lib/config/tests/ src/lib/datasrc/ src/lib/dns/ src/lib/dns/python/ src/lib/dns/python/tests/ src/lib/dns/rdata/generic/ src/lib/dns/tests/ src/lib/dns/util/ src/lib/exceptions/tests/ src/lib/python/isc/cc/ src/lib/python/isc/cc/tests/ src/lib/python/isc/config/ src/lib/python/isc/config/tests/ src/lib/python/isc/log/tests/ src/lib/python/isc/notify/ src/lib/python/isc/notify/tests/
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Aug 25 22:05:05 UTC 2010
Author: jinmei
Date: Wed Aug 25 22:05:04 2010
New Revision: 2801
Log:
sync with trunk
Added:
branches/trac310/src/lib/cc/tests/session_unittests_config.h.in
- copied unchanged from r2800, trunk/src/lib/cc/tests/session_unittests_config.h.in
branches/trac310/src/lib/config/testdata/Makefile.am
- copied unchanged from r2800, trunk/src/lib/config/testdata/Makefile.am
branches/trac310/src/lib/config/testdata/b10-config.db.master
- copied unchanged from r2800, trunk/src/lib/config/testdata/b10-config.db.master
Removed:
branches/trac310/src/lib/config/testdata/b10-config.db
Modified:
branches/trac310/ (props changed)
branches/trac310/ChangeLog
branches/trac310/Makefile.am
branches/trac310/configure.ac
branches/trac310/src/bin/auth/asio_link.h
branches/trac310/src/bin/auth/tests/auth_srv_unittest.cc
branches/trac310/src/bin/bind10/bind10.py.in
branches/trac310/src/bin/bind10/run_bind10.sh.in
branches/trac310/src/bin/bind10/tests/Makefile.am
branches/trac310/src/bin/bindctl/tests/Makefile.am
branches/trac310/src/bin/cfgmgr/tests/Makefile.am
branches/trac310/src/bin/cmdctl/tests/Makefile.am
branches/trac310/src/bin/loadzone/tests/correct/Makefile.am
branches/trac310/src/bin/loadzone/tests/error/Makefile.am
branches/trac310/src/bin/msgq/msgq.py.in
branches/trac310/src/bin/msgq/tests/Makefile.am
branches/trac310/src/bin/xfrin/ (props changed)
branches/trac310/src/bin/xfrin/tests/Makefile.am
branches/trac310/src/bin/xfrin/tests/xfrin_test.py
branches/trac310/src/bin/xfrout/tests/Makefile.am
branches/trac310/src/bin/zonemgr/tests/Makefile.am
branches/trac310/src/bin/zonemgr/tests/zonemgr_test.py
branches/trac310/src/lib/bench/ (props changed)
branches/trac310/src/lib/cc/ (props changed)
branches/trac310/src/lib/cc/session.cc
branches/trac310/src/lib/cc/session.h
branches/trac310/src/lib/cc/tests/ (props changed)
branches/trac310/src/lib/cc/tests/session_unittests.cc
branches/trac310/src/lib/config/Makefile.am
branches/trac310/src/lib/config/ccsession.cc
branches/trac310/src/lib/config/ccsession.h
branches/trac310/src/lib/config/config_data.h
branches/trac310/src/lib/config/documentation.txt
branches/trac310/src/lib/config/tests/fake_session.h
branches/trac310/src/lib/datasrc/ (props changed)
branches/trac310/src/lib/dns/ (props changed)
branches/trac310/src/lib/dns/messagerenderer.h
branches/trac310/src/lib/dns/python/Makefile.am
branches/trac310/src/lib/dns/python/rrclass_python.cc
branches/trac310/src/lib/dns/python/rrtype_python.cc
branches/trac310/src/lib/dns/python/tests/Makefile.am
branches/trac310/src/lib/dns/rdata/generic/rrsig_46.cc (props changed)
branches/trac310/src/lib/dns/tests/ (props changed)
branches/trac310/src/lib/dns/util/ (props changed)
branches/trac310/src/lib/exceptions/tests/ (props changed)
branches/trac310/src/lib/python/isc/cc/session.py
branches/trac310/src/lib/python/isc/cc/tests/Makefile.am
branches/trac310/src/lib/python/isc/cc/tests/session_test.py
branches/trac310/src/lib/python/isc/config/cfgmgr.py
branches/trac310/src/lib/python/isc/config/tests/Makefile.am
branches/trac310/src/lib/python/isc/config/tests/cfgmgr_test.py
branches/trac310/src/lib/python/isc/config/tests/unittest_fakesession.py (contents, props changed)
branches/trac310/src/lib/python/isc/log/tests/Makefile.am
branches/trac310/src/lib/python/isc/log/tests/log_test.py
branches/trac310/src/lib/python/isc/notify/notify_out.py
branches/trac310/src/lib/python/isc/notify/tests/Makefile.am
Modified: branches/trac310/ChangeLog
==============================================================================
--- branches/trac310/ChangeLog (original)
+++ branches/trac310/ChangeLog Wed Aug 25 22:05:04 2010
@@ -1,3 +1,21 @@
+ 90. [build] jinmei
+ (Darwin/Mac OS X specific) Specify DYLD_LIBRARY_PATH for tests and
+ experimental run under the source tree. Without this loadable
+ python modules refer to installation paths, which may confuse the
+ operation due to version mismatch or even trigger run time errors
+ due to missing libraries. (Trac #313, r2782)
+
+ 89. [build] jinmei
+ Generate b10-config.db for tests at build time so that the source
+ tree does not have to be writable. (Trac #315, r2776)
+
+ 88. [func] jelte
+ Blocking reads on the msgq command channel now have a timeout
+ (defaults to 4 seconds, modifiable as needed by modules).
+ Because of this, modules will no longer block indefinitely
+ if they are waiting for a message that is not sent for whatever
+ reason. (Trac #296, r2761)
+
87. [func] zhanglikun
lib/python/isc/notifyout: Add the feature of notify-out, when
zone axfr/ixfr finishing, the server will notify its slaves.
Modified: branches/trac310/Makefile.am
==============================================================================
--- branches/trac310/Makefile.am (original)
+++ branches/trac310/Makefile.am Wed Aug 25 22:05:04 2010
@@ -28,6 +28,7 @@
c++/4.4\*/ext/\* \
c++/4.4\*/\*-\*/bits/\* \
boost/\* \
+ ext/asio/\* \
gtest/\* \
usr/include/\* \
tests/\* \
Modified: branches/trac310/configure.ac
==============================================================================
--- branches/trac310/configure.ac (original)
+++ branches/trac310/configure.ac Wed Aug 25 22:05:04 2010
@@ -40,14 +40,30 @@
[enable_static_link=yes], [enable_static_link=no])
AM_CONDITIONAL(USE_STATIC_LINK, test $enable_static_link = yes)
-# OS dependent compiler flags
+# OS dependent configuration
+SET_ENV_LIBRARY_PATH=no
+ENV_LIBRARY_PATH=LD_LIBRARY_PATH
+
case "$host" in
*-solaris*)
# Solaris requires special definitions to get some standard libraries
# (e.g. getopt(3)) available with common used header files.
CPPFLAGS="$CPPFLAGS -D_XPG4_2 -D__EXTENSIONS__"
;;
+*-apple-darwin*)
+ # libtool doesn't work pefectly with Darwin: libtool embeds the
+ # final install path in dynamic libraries and our loadable python
+ # modules always refer to that path even if it's loaded within the
+ # source tree. This prevents pre-install tests from working.
+ # To work around this problem we explicitly specify paths to dynamic
+ # libraries when we use them in the source tree.
+ SET_ENV_LIBRARY_PATH=yes
+ ENV_LIBRARY_PATH=DYLD_LIBRARY_PATH
+ ;;
esac
+AM_CONDITIONAL(SET_ENV_LIBRARY_PATH, test $SET_ENV_LIBRARY_PATH = yes)
+AC_SUBST(SET_ENV_LIBRARY_PATH)
+AC_SUBST(ENV_LIBRARY_PATH)
m4_define([_AM_PYTHON_INTERPRETER_LIST], [python python3 python3.1])
AC_ARG_WITH([pythonpath],
@@ -433,6 +449,7 @@
src/lib/python/isc/notify/tests/Makefile
src/lib/config/Makefile
src/lib/config/tests/Makefile
+ src/lib/config/testdata/Makefile
src/lib/dns/Makefile
src/lib/dns/tests/Makefile
src/lib/dns/python/Makefile
@@ -487,6 +504,7 @@
src/lib/python/bind10_config.py
src/lib/dns/tests/testdata/gen-wiredata.py
src/lib/cc/session_config.h.pre
+ src/lib/cc/tests/session_unittests_config.h
], [
chmod +x src/bin/cmdctl/run_b10-cmdctl.sh
chmod +x src/bin/xfrin/run_b10-xfrin.sh
Modified: branches/trac310/src/bin/auth/asio_link.h
==============================================================================
--- branches/trac310/src/bin/auth/asio_link.h (original)
+++ branches/trac310/src/bin/auth/asio_link.h Wed Aug 25 22:05:04 2010
@@ -207,7 +207,7 @@
/// will be thrown.
///
/// Memory for the created object will be dynamically allocated. It's
- /// caller's responsibility to \c delete it later.
+ /// the caller's responsibility to \c delete it later.
/// If resource allocation for the new object fails, a corresponding
/// standard exception will be thrown.
///
Modified: branches/trac310/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac310/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac310/src/bin/auth/tests/auth_srv_unittest.cc Wed Aug 25 22:05:04 2010
@@ -95,6 +95,8 @@
virtual void startRead(boost::function<void()> read_callback);
virtual int reply(ConstElementPtr envelope, ConstElementPtr newmsg);
virtual bool hasQueuedMsgs() const;
+ virtual void setTimeout(size_t timeout UNUSED_PARAM) {};
+ virtual size_t getTimeout() const { return 0; };
void setMessage(ConstElementPtr msg) { msg_ = msg; }
void disableSend() { send_ok_ = false; }
@@ -543,7 +545,6 @@
EXPECT_EQ("example.com.", notify_args->get("zone_name")->stringValue());
EXPECT_EQ(DEFAULT_REMOTE_ADDRESS,
notify_args->get("master")->stringValue());
- cout << "[XX] ARGS: " << notify_args << endl;
EXPECT_EQ("IN", notify_args->get("zone_class")->stringValue());
// On success, the server should return a response to the notify.
Modified: branches/trac310/src/bin/bind10/bind10.py.in
==============================================================================
--- branches/trac310/src/bin/bind10/bind10.py.in (original)
+++ branches/trac310/src/bin/bind10/bind10.py.in Wed Aug 25 22:05:04 2010
@@ -18,7 +18,7 @@
"""\
This file implements the Boss of Bind (BoB, or bob) program.
-It's purpose is to start up the BIND 10 system, and then manage the
+Its purpose is to start up the BIND 10 system, and then manage the
processes, by starting and stopping processes, plus restarting
processes that exit.
Modified: branches/trac310/src/bin/bind10/run_bind10.sh.in
==============================================================================
--- branches/trac310/src/bin/bind10/run_bind10.sh.in (original)
+++ branches/trac310/src/bin/bind10/run_bind10.sh.in Wed Aug 25 22:05:04 2010
@@ -24,8 +24,15 @@
export PATH
PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/lib/dns/python/.libs:@abs_top_builddir@/src/lib/xfr/.libs
-#PYTHONPATH=@abs_top_srcdir@/src/lib/python:@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/lib/dns/.libs:@abs_top_builddir@/src/lib/xfr/.libs
export PYTHONPATH
+
+# If necessary (rare cases), explicitly specify paths to dynamic libraries
+# required by loadable python modules.
+SET_ENV_LIBRARY_PATH=@SET_ENV_LIBRARY_PATH@
+if test $SET_ENV_LIBRARY_PATH = yes; then
+ @ENV_LIBRARY_PATH@=@abs_top_builddir@/src/lib/dns/.libs:@abs_top_builddir@/src/lib/exceptions/.libs:$@ENV_LIBRARY_PATH@
+ export @ENV_LIBRARY_PATH@
+fi
B10_FROM_SOURCE=@abs_top_srcdir@
export B10_FROM_SOURCE
Modified: branches/trac310/src/bin/bind10/tests/Makefile.am
==============================================================================
--- branches/trac310/src/bin/bind10/tests/Makefile.am (original)
+++ branches/trac310/src/bin/bind10/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -8,5 +8,5 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/bin/bind10 \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/bin/bindctl/tests/Makefile.am
==============================================================================
--- branches/trac310/src/bin/bindctl/tests/Makefile.am (original)
+++ branches/trac310/src/bin/bindctl/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -8,5 +8,5 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_srcdir)/src/bin \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/bin/cfgmgr/tests/Makefile.am
==============================================================================
--- branches/trac310/src/bin/cfgmgr/tests/Makefile.am (original)
+++ branches/trac310/src/bin/cfgmgr/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -9,5 +9,5 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/bin/cfgmgr \
- $(PYCOVERAGE) $(abs_builddir)/$$pytest ; \
+ $(PYCOVERAGE) $(abs_builddir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/bin/cmdctl/tests/Makefile.am
==============================================================================
--- branches/trac310/src/bin/cmdctl/tests/Makefile.am (original)
+++ branches/trac310/src/bin/cmdctl/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -10,5 +10,5 @@
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/bin/cmdctl \
CMDCTL_SPEC_PATH=$(abs_top_builddir)/src/bin/cmdctl \
CMDCTL_SRC_PATH=$(abs_top_srcdir)/src/bin/cmdctl \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/bin/loadzone/tests/correct/Makefile.am
==============================================================================
--- branches/trac310/src/bin/loadzone/tests/correct/Makefile.am (original)
+++ branches/trac310/src/bin/loadzone/tests/correct/Makefile.am Wed Aug 25 22:05:04 2010
@@ -21,5 +21,5 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/bin/loadzone \
- $(SHELL) $(abs_builddir)/$$pytest ; \
+ $(SHELL) $(abs_builddir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/bin/loadzone/tests/error/Makefile.am
==============================================================================
--- branches/trac310/src/bin/loadzone/tests/error/Makefile.am (original)
+++ branches/trac310/src/bin/loadzone/tests/error/Makefile.am Wed Aug 25 22:05:04 2010
@@ -21,5 +21,5 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/bin/loadzone \
- $(SHELL) $(abs_builddir)/$$pytest ; \
+ $(SHELL) $(abs_builddir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/bin/msgq/msgq.py.in
==============================================================================
--- branches/trac310/src/bin/msgq/msgq.py.in (original)
+++ branches/trac310/src/bin/msgq/msgq.py.in Wed Aug 25 22:05:04 2010
@@ -212,7 +212,10 @@
EOF."""
received = b''
while len(received) < length:
- data = sock.recv(length - len(received))
+ try:
+ data = sock.recv(length - len(received))
+ except socket.error:
+ raise MsgQReceiveError(socket.error)
if len(data) == 0:
raise MsgQReceiveError("EOF")
received += data
Modified: branches/trac310/src/bin/msgq/tests/Makefile.am
==============================================================================
--- branches/trac310/src/bin/msgq/tests/Makefile.am (original)
+++ branches/trac310/src/bin/msgq/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -8,6 +8,6 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_builddir)/src/bin/msgq:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/bin/xfrin/tests/Makefile.am
==============================================================================
--- branches/trac310/src/bin/xfrin/tests/Makefile.am (original)
+++ branches/trac310/src/bin/xfrin/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -1,5 +1,12 @@
PYTESTS = xfrin_test.py
EXTRA_DIST = $(PYTESTS)
+
+# If necessary (rare cases), explicitly specify paths to dynamic libraries
+# required by loadable python modules.
+LIBRARY_PATH_PLACEHOLDER =
+if SET_ENV_LIBRARY_PATH
+LIBRARY_PATH_PLACEHOLDER += $(ENV_LIBRARY_PATH)=$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/exceptions/.libs:$(abs_top_builddir)/src/lib/xfr/.libs:$$$(ENV_LIBRARY_PATH)
+endif
# later will have configure option to choose this, like: coverage run --branch
PYCOVERAGE = $(PYTHON)
@@ -8,5 +15,6 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/bin/xfrin:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ $(LIBRARY_PATH_PLACEHOLDER) \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/bin/xfrin/tests/xfrin_test.py
==============================================================================
--- branches/trac310/src/bin/xfrin/tests/xfrin_test.py (original)
+++ branches/trac310/src/bin/xfrin/tests/xfrin_test.py Wed Aug 25 22:05:04 2010
@@ -559,7 +559,7 @@
def raise_ccerror():
raise isc.cc.session.SessionError('test error')
-def raise_excpetion():
+def raise_exception():
raise Exception('test exception')
class TestMain(unittest.TestCase):
@@ -581,7 +581,7 @@
main(MockXfrin, False)
def test_startup_generalerror(self):
- MockXfrin.check_command_hook = raise_excpetion
+ MockXfrin.check_command_hook = raise_exception
main(MockXfrin, False)
if __name__== "__main__":
Modified: branches/trac310/src/bin/xfrout/tests/Makefile.am
==============================================================================
--- branches/trac310/src/bin/xfrout/tests/Makefile.am (original)
+++ branches/trac310/src/bin/xfrout/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -1,5 +1,12 @@
PYTESTS = xfrout_test.py
EXTRA_DIST = $(PYTESTS)
+
+# If necessary (rare cases), explicitly specify paths to dynamic libraries
+# required by loadable python modules.
+LIBRARY_PATH_PLACEHOLDER =
+if SET_ENV_LIBRARY_PATH
+LIBRARY_PATH_PLACEHOLDER += $(ENV_LIBRARY_PATH)=$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/exceptions/.libs:$(abs_top_builddir)/src/lib/xfr/.libs:$$$(ENV_LIBRARY_PATH)
+endif
# later will have configure option to choose this, like: coverage run --branch
PYCOVERAGE = $(PYTHON)
@@ -8,5 +15,6 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_builddir)/src/bin/xfrout:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/xfr/.libs \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ $(LIBRARY_PATH_PLACEHOLDER) \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/bin/zonemgr/tests/Makefile.am
==============================================================================
--- branches/trac310/src/bin/zonemgr/tests/Makefile.am (original)
+++ branches/trac310/src/bin/zonemgr/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -8,5 +8,5 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_builddir)/src/bin/zonemgr:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/xfr/.libs \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/bin/zonemgr/tests/zonemgr_test.py
==============================================================================
--- branches/trac310/src/bin/zonemgr/tests/zonemgr_test.py (original)
+++ branches/trac310/src/bin/zonemgr/tests/zonemgr_test.py Wed Aug 25 22:05:04 2010
@@ -388,16 +388,20 @@
'zone_state': ZONE_OK}
}
master_socket, slave_socket = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
+ self.zone_refresh._socket = master_socket
+ master_socket.close()
+ self.assertRaises(ZonemgrException, self.zone_refresh.run_timer)
+
self.zone_refresh._socket = slave_socket
listener = threading.Thread(target = self.zone_refresh.run_timer, args = ())
listener.setDaemon(True)
listener.start()
- slave_socket.close()
+ time.sleep(1)
+
zone_state = self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN]["zone_state"]
self.assertTrue("refresh_timeout" in self.zone_refresh._zonemgr_refresh_info[ZONE_NAME_CLASS1_IN].keys())
self.assertTrue(zone_state == ZONE_REFRESHING)
- self.assertRaises(ZonemgrException, self.zone_refresh.run_timer)
def tearDown(self):
sys.stdout = self.stdout_backup
Modified: branches/trac310/src/lib/cc/session.cc
==============================================================================
--- branches/trac310/src/lib/cc/session.cc (original)
+++ branches/trac310/src/lib/cc/session.cc Wed Aug 25 22:05:04 2010
@@ -28,6 +28,7 @@
#include <unistd.h> // for some IPC/network system calls
#include <asio.hpp>
#include <asio/error_code.hpp>
+#include <asio/deadline_timer.hpp>
#include <asio/system_error.hpp>
#include <cstdio>
@@ -38,7 +39,9 @@
#include <sys/un.h>
#include <boost/bind.hpp>
+#include <boost/optional.hpp>
#include <boost/function.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <exceptions/exceptions.h>
@@ -53,20 +56,39 @@
// (e.g. write(2)) so we don't import the entire asio namespace.
using asio::io_service;
+namespace {
+/// \brief Sets the given Optional 'result' to the given error code
+/// Used as a callback for emulating sync reads with async calls
+/// \param result Pointer to the optional to set
+/// \param err The error code to set it to
+void
+setResult(boost::optional<asio::error_code>* result,
+ const asio::error_code& err)
+{
+ result->reset(err);
+}
+}
+
namespace isc {
namespace cc {
+
class SessionImpl {
public:
SessionImpl(io_service& io_service) :
sequence_(-1), queue_(Element::createList()),
- io_service_(io_service), socket_(io_service_), data_length_(0)
+ io_service_(io_service), socket_(io_service_), data_length_(0),
+ timeout_(MSGQ_DEFAULT_TIMEOUT)
{}
void establish(const char& socket_file);
void disconnect();
void writeData(const void* data, size_t datalen);
size_t readDataLength();
+ // Blocking read. Will throw a SessionTimeout if the timeout value
+ // (in seconds) is thrown. If timeout is 0 it will block forever
void readData(void* data, size_t datalen);
void startRead(boost::function<void()> user_handler);
+ void setTimeout(size_t seconds) { timeout_ = seconds; };
+ size_t getTimeout() const { return timeout_; };
long int sequence_; // the next sequence number to use
std::string lname_;
@@ -82,6 +104,17 @@
uint32_t data_length_;
boost::function<void()> user_handler_;
asio::error_code error_;
+ size_t timeout_;
+
+ // By default, unless changed or disabled, blocking reads on
+ // the msgq channel will time out after 4 seconds in this
+ // implementation.
+ // This number is chosen to be low enough so that whatever
+ // component is blocking does not seem to be hanging, but
+ // still gives enough time for other modules to respond if they
+ // are busy. If this choice turns out to be a bad one, we can
+ // change it later.
+ static const size_t MSGQ_DEFAULT_TIMEOUT = 4000;
};
void
@@ -131,8 +164,51 @@
void
SessionImpl::readData(void* data, size_t datalen) {
+ boost::optional<asio::error_code> read_result;
+ boost::optional<asio::error_code> timer_result;
+
try {
- asio::read(socket_, asio::buffer(data, datalen));
+ asio::async_read(socket_, asio::buffer(data, datalen),
+ boost::bind(&setResult, &read_result, _1));
+ asio::deadline_timer timer(socket_.io_service());
+
+ if (getTimeout() != 0) {
+ timer.expires_from_now(boost::posix_time::milliseconds(getTimeout()));
+ timer.async_wait(boost::bind(&setResult, &timer_result, _1));
+ }
+
+ // wait until either we have read the data we want, the
+ // timer expires, or one of the two is triggered with an error.
+ // When one of them has a result, cancel the other, and wait
+ // until the cancel is processed before we continue
+ while (!read_result && !timer_result) {
+ socket_.io_service().run_one();
+
+ // Don't cancel the timer if we haven't set it
+ if (read_result && getTimeout() != 0) {
+ timer.cancel();
+ while (!timer_result) {
+ socket_.io_service().run_one();
+ }
+ } else if (timer_result) {
+ socket_.cancel();
+ while (!read_result) {
+ socket_.io_service().run_one();
+ }
+ }
+ }
+
+ // asio::error_code evaluates to false if there was no error
+ if (*read_result) {
+ if (*read_result == asio::error::operation_aborted) {
+ isc_throw(SessionTimeout,
+ "Timeout while reading data from cc session");
+ } else {
+ isc_throw(SessionError,
+ "Error while reading data from cc session: " <<
+ read_result->message());
+ }
+ }
} catch (const asio::system_error& asio_ex) {
// to hide ASIO specific exceptions, we catch them explicitly
// and convert it to SessionError.
@@ -144,11 +220,11 @@
SessionImpl::startRead(boost::function<void()> user_handler) {
data_length_ = 0;
user_handler_ = user_handler;
- async_read(socket_, asio::buffer(&data_length_,
- sizeof(data_length_)),
- boost::bind(&SessionImpl::internalRead, this,
- asio::placeholders::error,
- asio::placeholders::bytes_transferred));
+ asio::async_read(socket_, asio::buffer(&data_length_,
+ sizeof(data_length_)),
+ boost::bind(&SessionImpl::internalRead, this,
+ asio::placeholders::error,
+ asio::placeholders::bytes_transferred));
}
void
@@ -412,5 +488,14 @@
return (impl_->queue_->size() > 0);
}
-}
-}
+void
+Session::setTimeout(size_t milliseconds) {
+ impl_->setTimeout(milliseconds);
+}
+
+size_t
+Session::getTimeout() const {
+ return (impl_->getTimeout());
+}
+}
+}
Modified: branches/trac310/src/lib/cc/session.h
==============================================================================
--- branches/trac310/src/lib/cc/session.h (original)
+++ branches/trac310/src/lib/cc/session.h Wed Aug 25 22:05:04 2010
@@ -37,6 +37,15 @@
class SessionError : public isc::Exception {
public:
SessionError(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+ };
+
+ /// \brief A standard Exception class that is thrown when a
+ /// blocking readData call does not read the given number of
+ /// bytes before the timeout expires
+ class SessionTimeout : public isc::Exception {
+ public:
+ SessionTimeout(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
@@ -88,6 +97,17 @@
virtual int reply(isc::data::ConstElementPtr envelope,
isc::data::ConstElementPtr newmsg) = 0;
virtual bool hasQueuedMsgs() const = 0;
+
+ /// \brief Sets the default timeout for blocking reads
+ /// in this session to the given number of milliseconds
+ /// \param milliseconds the timeout for blocking reads in
+ /// milliseconds, if this is set to 0, reads will block
+ /// forever.
+ virtual void setTimeout(size_t milliseconds) = 0;
+
+ /// \brief Returns the current timeout for blocking reads
+ /// \return The timeout (in milliseconds)
+ virtual size_t getTimeout() const = 0;
};
class Session : public AbstractSession {
@@ -121,6 +141,8 @@
virtual int reply(isc::data::ConstElementPtr envelope,
isc::data::ConstElementPtr newmsg);
virtual bool hasQueuedMsgs() const;
+ virtual void setTimeout(size_t milliseconds);
+ virtual size_t getTimeout() const;
private:
void sendmsg(isc::data::ConstElementPtr msg);
void sendmsg(isc::data::ConstElementPtr env,
Modified: branches/trac310/src/lib/cc/tests/session_unittests.cc
==============================================================================
--- branches/trac310/src/lib/cc/tests/session_unittests.cc (original)
+++ branches/trac310/src/lib/cc/tests/session_unittests.cc Wed Aug 25 22:05:04 2010
@@ -22,10 +22,13 @@
#include <asio.hpp>
#include <gtest/gtest.h>
+#include <boost/bind.hpp>
#include <exceptions/exceptions.h>
#include <cc/session.h>
+#include <cc/data.h>
+#include <session_unittests_config.h>
using namespace isc::cc;
@@ -48,3 +51,190 @@
);
}
+
+// This class sets up a domain socket for the session to connect to
+// it will impersonate the msgq a tiny bit (if setSendLname() has
+// been called, it will send an 'answer' to the lname query that is
+// sent in the initialization of Session objects)
+class TestDomainSocket {
+
+public:
+ TestDomainSocket(asio::io_service& io_service, const char* file) :
+ io_service_(io_service),
+ ep_(file),
+ acceptor_(io_service_, ep_),
+ socket_(io_service_)
+ {
+ acceptor_.async_accept(socket_,
+ boost::bind(&TestDomainSocket::acceptHandler,
+ this, _1));
+ }
+
+ ~TestDomainSocket() {
+ socket_.close();
+ unlink(BIND10_TEST_SOCKET_FILE);
+ }
+
+ void
+ acceptHandler(const asio::error_code& error UNUSED_PARAM) {
+ }
+
+ void
+ sendmsg(isc::data::ElementPtr& env, isc::data::ElementPtr& msg) {
+ const std::string header_wire = env->toWire();
+ const std::string body_wire = msg->toWire();
+ const unsigned int length = 2 + header_wire.length() +
+ body_wire.length();
+ const unsigned int length_net = htonl(length);
+ const unsigned short header_length = header_wire.length();
+ const unsigned short header_length_net = htons(header_length);
+
+ socket_.send(asio::buffer(&length_net, sizeof(length_net)));
+ socket_.send(asio::buffer(&header_length_net,
+ sizeof(header_length_net)));
+ socket_.send(asio::buffer(header_wire.data(), header_length));
+ socket_.send(asio::buffer(body_wire.data(), body_wire.length()));
+ }
+
+ void
+ sendLname() {
+ isc::data::ElementPtr lname_answer1 =
+ isc::data::Element::fromJSON("{ \"type\": \"lname\" }");
+ isc::data::ElementPtr lname_answer2 =
+ isc::data::Element::fromJSON("{ \"lname\": \"foobar\" }");
+ sendmsg(lname_answer1, lname_answer2);
+ }
+
+ void
+ setSendLname() {
+ // ignore whatever data we get, send back an lname
+ asio::async_read(socket_, asio::buffer(data_buf, 0),
+ boost::bind(&TestDomainSocket::sendLname, this));
+ }
+
+private:
+ asio::io_service& io_service_;
+ asio::local::stream_protocol::endpoint ep_;
+ asio::local::stream_protocol::acceptor acceptor_;
+ asio::local::stream_protocol::socket socket_;
+ char data_buf[1024];
+};
+
+class SessionTest : public ::testing::Test {
+protected:
+ SessionTest() : sess(my_io_service), work(my_io_service) {
+ // The TestDomainSocket is held as a 'new'-ed pointer,
+ // so we can call unlink() first.
+ unlink(BIND10_TEST_SOCKET_FILE);
+ tds = new TestDomainSocket(my_io_service, BIND10_TEST_SOCKET_FILE);
+ }
+
+ ~SessionTest() {
+ delete tds;
+ }
+
+public:
+ // used in the handler test
+ // This handler first reads (and ignores) whatever message caused
+ // it to be invoked. Then it calls group_recv for a second message.
+ // If this message is { "command": "stop" } it'll tell the
+ // io_service it is done. Otherwise it'll re-register this handler
+ void someHandler() {
+ isc::data::ConstElementPtr env, msg;
+ sess.group_recvmsg(env, msg, false, -1);
+
+ sess.group_recvmsg(env, msg, false, -1);
+ if (msg && msg->contains("command") &&
+ msg->get("command")->stringValue() == "stop") {
+ my_io_service.stop();
+ } else {
+ sess.startRead(boost::bind(&SessionTest::someHandler, this));
+ }
+ }
+
+protected:
+ asio::io_service my_io_service;
+ TestDomainSocket* tds;
+ Session sess;
+ // Keep run() from stopping right away by informing it it has work to do
+ asio::io_service::work work;
+};
+
+TEST_F(SessionTest, timeout_on_connect) {
+ // set to a short timeout so the test doesn't take too long
+ EXPECT_EQ(4000, sess.getTimeout());
+ sess.setTimeout(100);
+ EXPECT_EQ(100, sess.getTimeout());
+ // no answer, should timeout
+ EXPECT_THROW(sess.establish(BIND10_TEST_SOCKET_FILE), SessionTimeout);
+}
+
+TEST_F(SessionTest, connect_ok) {
+ tds->setSendLname();
+ sess.establish(BIND10_TEST_SOCKET_FILE);
+}
+
+TEST_F(SessionTest, connect_ok_no_timeout) {
+ tds->setSendLname();
+
+ sess.setTimeout(0);
+ sess.establish(BIND10_TEST_SOCKET_FILE);
+}
+
+TEST_F(SessionTest, connect_ok_connection_reset) {
+ tds->setSendLname();
+
+ sess.establish(BIND10_TEST_SOCKET_FILE);
+ // Close the session again, so the next recv() should throw
+ sess.disconnect();
+
+ isc::data::ConstElementPtr env, msg;
+ EXPECT_THROW(sess.group_recvmsg(env, msg, false, -1), SessionError);
+}
+
+TEST_F(SessionTest, run_with_handler) {
+ tds->setSendLname();
+
+ sess.establish(BIND10_TEST_SOCKET_FILE);
+ sess.startRead(boost::bind(&SessionTest::someHandler, this));
+
+ isc::data::ElementPtr env = isc::data::Element::fromJSON("{ \"to\": \"me\" }");
+ isc::data::ElementPtr msg = isc::data::Element::fromJSON("{ \"some\": \"message\" }");
+ tds->sendmsg(env, msg);
+
+ msg = isc::data::Element::fromJSON("{ \"another\": \"message\" }");
+ tds->sendmsg(env, msg);
+
+ msg = isc::data::Element::fromJSON("{ \"a third\": \"message\" }");
+ tds->sendmsg(env, msg);
+
+ msg = isc::data::Element::fromJSON("{ \"command\": \"stop\" }");
+ tds->sendmsg(env, msg);
+
+
+ size_t count = my_io_service.run();
+ ASSERT_EQ(2, count);
+}
+
+TEST_F(SessionTest, run_with_handler_timeout) {
+ tds->setSendLname();
+
+ sess.establish(BIND10_TEST_SOCKET_FILE);
+ sess.startRead(boost::bind(&SessionTest::someHandler, this));
+ sess.setTimeout(100);
+
+ isc::data::ElementPtr env = isc::data::Element::fromJSON("{ \"to\": \"me\" }");
+ isc::data::ElementPtr msg = isc::data::Element::fromJSON("{ \"some\": \"message\" }");
+ tds->sendmsg(env, msg);
+
+ msg = isc::data::Element::fromJSON("{ \"another\": \"message\" }");
+ tds->sendmsg(env, msg);
+
+ msg = isc::data::Element::fromJSON("{ \"a third\": \"message\" }");
+ tds->sendmsg(env, msg);
+
+ // No followup message, should time out.
+ ASSERT_THROW(my_io_service.run(), SessionTimeout);
+}
+
+
Modified: branches/trac310/src/lib/config/Makefile.am
==============================================================================
--- branches/trac310/src/lib/config/Makefile.am (original)
+++ branches/trac310/src/lib/config/Makefile.am Wed Aug 25 22:05:04 2010
@@ -1,3 +1,5 @@
+SUBDIRS = . testdata tests
+
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
AM_CXXFLAGS = $(B10_CXXFLAGS) -Wno-strict-aliasing
@@ -7,16 +9,11 @@
CLEANFILES = *.gcno *.gcda
-TESTS =
-if HAVE_GTEST
-SUBDIRS = . tests
-endif
-
EXTRA_DIST = testdata/b10-config-bad1.db
EXTRA_DIST += testdata/b10-config-bad2.db
EXTRA_DIST += testdata/b10-config-bad3.db
EXTRA_DIST += testdata/b10-config-bad4.db
-EXTRA_DIST += testdata/b10-config.db
+EXTRA_DIST += testdata/b10-config.db.master #.db will be auto-generated
EXTRA_DIST += testdata/data22_1.data
EXTRA_DIST += testdata/data22_2.data
EXTRA_DIST += testdata/data22_3.data
Modified: branches/trac310/src/lib/config/ccsession.cc
==============================================================================
--- branches/trac310/src/lib/config/ccsession.cc (original)
+++ branches/trac310/src/lib/config/ccsession.cc Wed Aug 25 22:05:04 2010
@@ -201,7 +201,7 @@
isc::data::ConstElementPtr new_config),
isc::data::ConstElementPtr(*command_handler)(
const std::string& command, isc::data::ConstElementPtr args)
- ) throw (isc::cc::SessionError) :
+ ) :
session_(session)
{
module_specification_ = readModuleSpecification(spec_file_name);
Modified: branches/trac310/src/lib/config/ccsession.h
==============================================================================
--- branches/trac310/src/lib/config/ccsession.h (original)
+++ branches/trac310/src/lib/config/ccsession.h Wed Aug 25 22:05:04 2010
@@ -137,7 +137,7 @@
isc::data::ConstElementPtr(*command_handler)(
const std::string& command,
isc::data::ConstElementPtr args) = NULL
- ) throw (isc::cc::SessionError);
+ );
/**
* Optional optimization for checkCommand loop; returns true
Modified: branches/trac310/src/lib/config/config_data.h
==============================================================================
--- branches/trac310/src/lib/config/config_data.h (original)
+++ branches/trac310/src/lib/config/config_data.h Wed Aug 25 22:05:04 2010
@@ -40,7 +40,7 @@
/// Constructs a ConfigData option with no specification and an
/// empty configuration.
ConfigData() { _config = Element::createMap(); };
-
+
/// Constructs a ConfigData option with the given specification
/// and an empty configuration.
/// \param module_spec A ModuleSpec for the relevant module
@@ -75,18 +75,18 @@
/// Set the ModuleSpec associated with this ConfigData object
void setModuleSpec(ModuleSpec module_spec) { _module_spec = module_spec; };
-
+
/// Set the local configuration (i.e. all non-default values)
/// \param config An ElementPtr pointing to a MapElement containing
/// *all* non-default configuration values. Existing values
/// will be removed.
void setLocalConfig(ElementPtr config) { _config = config; }
-
+
/// Returns the local (i.e. non-default) configuration.
/// \returns An ElementPtr pointing to a MapElement containing all
/// non-default configuration options.
ElementPtr getLocalConfig() { return (_config); }
-
+
/// Returns a list of all possible configuration options as specified
/// by the ModuleSpec.
/// \param identifier If given, show the items at the given identifier
@@ -99,7 +99,7 @@
/// and recurse==false)
ConstElementPtr getItemList(const std::string& identifier = "",
bool recurse = false) const;
-
+
/// Returns all current configuration settings (both non-default and default).
/// \return An ElementPtr pointing to a MapElement containing
/// string->value elements, where the string is the
Modified: branches/trac310/src/lib/config/documentation.txt
==============================================================================
--- branches/trac310/src/lib/config/documentation.txt (original)
+++ branches/trac310/src/lib/config/documentation.txt Wed Aug 25 22:05:04 2010
@@ -53,7 +53,7 @@
The new_config is a ElementPtr pointing to a MapElement containing data in the form as specified by the specification file. It only contains values that were changed.
-The module can walk through this set and alter it's behaviour accordingly if necessary. It can also simply check them and return success (see below) and reference the needed configuration values directly when necessary by calling get_config_value(std::string identifier).
+The module can walk through this set and alter its behaviour accordingly if necessary. It can also simply check them and return success (see below) and reference the needed configuration values directly when necessary by calling get_config_value(std::string identifier).
The callback function must return an answer message, which is created with isc::config::createAnswer(). For successful handling of the configuration, it should return the result of createAnswer(0) (0 being the result code for success). If there is a problem, the function can return the result of createAnswer(non-zero, "string_with_error_message"). In this case, the new configuration is not stored, and the error is fed back to the configuration manager.
Modified: branches/trac310/src/lib/config/tests/fake_session.h
==============================================================================
--- branches/trac310/src/lib/config/tests/fake_session.h (original)
+++ branches/trac310/src/lib/config/tests/fake_session.h Wed Aug 25 22:05:04 2010
@@ -63,6 +63,8 @@
virtual int reply(isc::data::ConstElementPtr envelope,
isc::data::ConstElementPtr newmsg);
virtual bool hasQueuedMsgs() const;
+ virtual void setTimeout(size_t milliseconds) {}
+ virtual size_t getTimeout() const { return (0); }
isc::data::ConstElementPtr getFirstMessage(std::string& group,
std::string& to) const;
void addMessage(isc::data::ConstElementPtr, const std::string& group,
Modified: branches/trac310/src/lib/dns/messagerenderer.h
==============================================================================
--- branches/trac310/src/lib/dns/messagerenderer.h (original)
+++ branches/trac310/src/lib/dns/messagerenderer.h Wed Aug 25 22:05:04 2010
@@ -109,7 +109,7 @@
/// The destructor does nothing on the given \c buffer on construction;
/// in fact, it is expected that the user will use the resulting buffer
/// for some post rendering purposes (e.g., send the data to the network).
- /// It's user's responsibility to do any necessary cleanup for the
+ /// It's the user's responsibility to do any necessary cleanup for the
/// \c buffer.
~MessageRenderer();
//@}
Modified: branches/trac310/src/lib/dns/python/Makefile.am
==============================================================================
--- branches/trac310/src/lib/dns/python/Makefile.am (original)
+++ branches/trac310/src/lib/dns/python/Makefile.am Wed Aug 25 22:05:04 2010
@@ -1,9 +1,7 @@
SUBDIRS = tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
-if USE_GXX
-AM_CPPFLAGS += -Wno-write-strings
-endif
+AM_CXXFLAGS = $(B10_CXXFLAGS)
#lib_LTLIBRARIES = libdns_python_name.la libdns_python_rrset.la
#libdns_python_name_la_SOURCES = name_python.cc
Modified: branches/trac310/src/lib/dns/python/rrclass_python.cc
==============================================================================
--- branches/trac310/src/lib/dns/python/rrclass_python.cc (original)
+++ branches/trac310/src/lib/dns/python/rrclass_python.cc Wed Aug 25 22:05:04 2010
@@ -157,7 +157,7 @@
unsigned int i;
PyObject* bytes = NULL;
// The constructor argument can be a string ("IN"), an integer (1),
- // or a sequence of numbers between 0 and 255 (wire code)
+ // or a sequence of numbers between 0 and 65535 (wire code)
// Note that PyArg_ParseType can set PyError, and we need to clear
// that if we try several like here. Otherwise the *next* python
@@ -170,7 +170,7 @@
} else if (PyArg_ParseTuple(args, "I", &i)) {
PyErr_Clear();
if (i > 65535) {
- PyErr_SetString(po_InvalidRRClass, "Class number too high");
+ PyErr_SetString(po_InvalidRRClass, "RR class number too high");
return (-1);
}
self->rrclass = new RRClass(i);
Modified: branches/trac310/src/lib/dns/python/rrtype_python.cc
==============================================================================
--- branches/trac310/src/lib/dns/python/rrtype_python.cc (original)
+++ branches/trac310/src/lib/dns/python/rrtype_python.cc Wed Aug 25 22:05:04 2010
@@ -186,8 +186,8 @@
const char* s;
unsigned int i;
PyObject* bytes = NULL;
- // The constructor argument can be a string ("IN"), an integer (1),
- // or a sequence of numbers between 0 and 255 (wire code)
+ // The constructor argument can be a string ("A"), an integer (1),
+ // or a sequence of numbers between 0 and 65535 (wire code)
// Note that PyArg_ParseType can set PyError, and we need to clear
// that if we try several like here. Otherwise the *next* python
@@ -200,7 +200,7 @@
} else if (PyArg_ParseTuple(args, "I", &i)) {
PyErr_Clear();
if (i > 65535) {
- PyErr_SetString(po_InvalidRRType, "Class number too high");
+ PyErr_SetString(po_InvalidRRType, "RR Type number too high");
return (-1);
}
self->rrtype = new RRType(i);
Modified: branches/trac310/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- branches/trac310/src/lib/dns/python/tests/Makefile.am (original)
+++ branches/trac310/src/lib/dns/python/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -10,6 +10,13 @@
EXTRA_DIST = $(PYTESTS)
+# If necessary (rare cases), explicitly specify paths to dynamic libraries
+# required by loadable python modules.
+LIBRARY_PATH_PLACEHOLDER =
+if SET_ENV_LIBRARY_PATH
+LIBRARY_PATH_PLACEHOLDER += $(ENV_LIBRARY_PATH)=$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/exceptions/.libs:$$$(ENV_LIBRARY_PATH)
+endif
+
# later will have configure option to choose this, like: coverage run --branch
PYCOVERAGE = $(PYTHON)
# test using command-line arguments, so use check-local target instead of TESTS
@@ -18,5 +25,6 @@
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs \
TESTDATA_PATH=$(abs_top_srcdir)/src/lib/dns/tests/testdata \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ $(LIBRARY_PATH_PLACEHOLDER) \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/lib/python/isc/cc/session.py
==============================================================================
--- branches/trac310/src/lib/python/isc/cc/session.py (original)
+++ branches/trac310/src/lib/python/isc/cc/session.py Wed Aug 25 22:05:04 2010
@@ -29,6 +29,10 @@
class Session:
def __init__(self, socket_file=None):
self._socket = None
+ # store the current timeout value in seconds (the way
+ # settimeout() wants them, our API takes milliseconds
+ # so that it is consistent with the C++ version)
+ self._socket_timeout = 4;
self._lname = None
self._recvbuffer = bytearray()
self._recvlength = 0
@@ -44,7 +48,6 @@
self.socket_file = bind10_config.BIND10_MSGQ_SOCKET_FILE
else:
self.socket_file = socket_file
-
try:
self._socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
@@ -123,6 +126,10 @@
self._socket.setblocking(0)
else:
self._socket.setblocking(1)
+ if self._socket_timeout == 0.0:
+ self._socket.settimeout(None)
+ else:
+ self._socket.settimeout(self._socket_timeout)
if self._recvlength == 0:
length = 4
@@ -208,6 +215,15 @@
}, isc.cc.message.to_wire(msg))
return seq
+ def set_timeout(self, milliseconds):
+ """Sets the socket timeout for blocking reads to the given
+ number of milliseconds"""
+ self._socket_timeout = milliseconds / 1000.0
+
+ def get_timeout(self):
+ """Returns the current timeout for blocking reads (in milliseconds)"""
+ return self._socket_timeout * 1000.0
+
if __name__ == "__main__":
import doctest
doctest.testmod()
Modified: branches/trac310/src/lib/python/isc/cc/tests/Makefile.am
==============================================================================
--- branches/trac310/src/lib/python/isc/cc/tests/Makefile.am (original)
+++ branches/trac310/src/lib/python/isc/cc/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -11,5 +11,6 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ BIND10_TEST_SOCKET_FILE=$(builddir)/test_socket.sock \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/lib/python/isc/cc/tests/session_test.py
==============================================================================
--- branches/trac310/src/lib/python/isc/cc/tests/session_test.py (original)
+++ branches/trac310/src/lib/python/isc/cc/tests/session_test.py Wed Aug 25 22:05:04 2010
@@ -89,13 +89,20 @@
if msg:
self.recvqueue.extend(msg)
+ def settimeout(self, val):
+ pass
+
+ def gettimeout(self):
+ return 0
+
#
# We subclass the Session class we're testing here, only
# to override the __init__() method, which wants a socket,
# and we need to use our fake socket
class MySession(Session):
- def __init__(self, port=9912):
+ def __init__(self, port=9912, s=None):
self._socket = None
+ self._socket_timeout = 1
self._lname = None
self._recvbuffer = bytearray()
self._recvlength = 0
@@ -104,13 +111,16 @@
self._queue = []
self._lock = threading.RLock()
- try:
- self._socket = MySocket(socket.AF_INET, socket.SOCK_STREAM)
- self._socket.connect(tuple(['127.0.0.1', port]))
- self._lname = "test_name"
- # testing getlname here isn't useful, code removed
- except socket.error as se:
- raise SessionError(se)
+ if s is not None:
+ self._socket = s
+ else:
+ try:
+ self._socket = MySocket(socket.AF_INET, socket.SOCK_STREAM)
+ self._socket.connect(tuple(['127.0.0.1', port]))
+ self._lname = "test_name"
+ # testing getlname here isn't useful, code removed
+ except socket.error as se:
+ raise SessionError(se)
class testSession(unittest.TestCase):
@@ -323,7 +333,27 @@
sess.group_reply({ 'from': 'me', 'group': 'our_group', 'instance': 'other_instance', 'seq': 9}, {"hello": "a"})
sent = sess._socket.readsentmsg();
self.assertEqual(sent, b'\x00\x00\x00\x8b\x00{{"from": "test_name", "seq": 3, "to": "me", "instance": "other_instance", "reply": 9, "group": "our_group", "type": "send"}{"hello": "a"}')
-
+
+ def test_timeout(self):
+ if "BIND10_TEST_SOCKET_FILE" not in os.environ:
+ self.assertEqual("", "This test can only run if the value BIND10_TEST_SOCKET_FILE is set in the environment")
+ TEST_SOCKET_FILE = os.environ["BIND10_TEST_SOCKET_FILE"]
+
+ # create a read domain socket to pass into the session
+ s1 = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ if os.path.exists(TEST_SOCKET_FILE):
+ os.remove(TEST_SOCKET_FILE)
+ s1.bind(TEST_SOCKET_FILE)
+ s1.listen(1)
+
+ s2 = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ s2.connect(TEST_SOCKET_FILE)
+ sess = MySession(1, s2)
+ # set timeout to 100 msec, so test does not take too long
+ sess.set_timeout(100)
+ env, msg = sess.group_recvmsg(False)
+ self.assertEqual(None, env)
+ self.assertEqual(None, msg)
if __name__ == "__main__":
unittest.main()
Modified: branches/trac310/src/lib/python/isc/config/cfgmgr.py
==============================================================================
--- branches/trac310/src/lib/python/isc/config/cfgmgr.py (original)
+++ branches/trac310/src/lib/python/isc/config/cfgmgr.py Wed Aug 25 22:05:04 2010
@@ -395,8 +395,9 @@
self.running = True
while (self.running):
msg, env = self.cc.group_recvmsg(False)
- if msg and not 'result' in msg:
+ # ignore 'None' value (current result of timeout)
+ # and messages that are answers to questions we did
+ # not ask
+ if msg is not None and not 'result' in msg:
answer = self.handle_msg(msg);
self.cc.group_reply(env, answer)
- else:
- self.running = False
Modified: branches/trac310/src/lib/python/isc/config/tests/Makefile.am
==============================================================================
--- branches/trac310/src/lib/python/isc/config/tests/Makefile.am (original)
+++ branches/trac310/src/lib/python/isc/config/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -11,5 +11,6 @@
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python \
CONFIG_TESTDATA_PATH=$(abs_top_srcdir)/src/lib/config/testdata \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ CONFIG_WR_TESTDATA_PATH=$(abs_top_builddir)/src/lib/config/testdata \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/lib/python/isc/config/tests/cfgmgr_test.py
==============================================================================
--- branches/trac310/src/lib/python/isc/config/tests/cfgmgr_test.py (original)
+++ branches/trac310/src/lib/python/isc/config/tests/cfgmgr_test.py Wed Aug 25 22:05:04 2010
@@ -28,19 +28,20 @@
class TestConfigManagerData(unittest.TestCase):
def setUp(self):
self.data_path = os.environ['CONFIG_TESTDATA_PATH']
- self.config_manager_data = ConfigManagerData(self.data_path)
+ self.writable_data_path = os.environ['CONFIG_WR_TESTDATA_PATH']
+ self.config_manager_data = ConfigManagerData(self.writable_data_path)
self.assert_(self.config_manager_data)
def test_init(self):
self.assertEqual(self.config_manager_data.data['version'],
config_data.BIND10_CONFIG_DATA_VERSION)
self.assertEqual(self.config_manager_data.data_path,
- self.data_path)
+ self.writable_data_path)
self.assertEqual(self.config_manager_data.db_filename,
- self.data_path + os.sep + "b10-config.db")
+ self.writable_data_path + os.sep + "b10-config.db")
def test_read_from_file(self):
- ConfigManagerData.read_from_file(self.data_path)
+ ConfigManagerData.read_from_file(self.writable_data_path)
self.assertRaises(ConfigManagerDataEmpty,
ConfigManagerData.read_from_file,
"doesnotexist")
@@ -84,14 +85,15 @@
def setUp(self):
self.data_path = os.environ['CONFIG_TESTDATA_PATH']
+ self.writable_data_path = os.environ['CONFIG_WR_TESTDATA_PATH']
self.fake_session = FakeModuleCCSession()
- self.cm = ConfigManager(self.data_path, self.fake_session)
+ self.cm = ConfigManager(self.writable_data_path, self.fake_session)
self.name = "TestModule"
self.spec = isc.config.module_spec_from_file(self.data_path + os.sep + "/spec2.spec")
def test_init(self):
self.assert_(self.cm.module_specs == {})
- self.assert_(self.cm.data_path == self.data_path)
+ self.assert_(self.cm.data_path == self.writable_data_path)
self.assert_(self.cm.config != None)
self.assert_(self.fake_session.has_subscription("ConfigManager"))
self.assert_(self.fake_session.has_subscription("Boss", "ConfigManager"))
@@ -287,13 +289,14 @@
def test_run(self):
self.fake_session.group_sendmsg({ "command": [ "get_commands_spec" ] }, "ConfigManager")
+ self.fake_session.group_sendmsg({ "command": [ "shutdown" ] }, "ConfigManager")
self.cm.run()
pass
if __name__ == '__main__':
- if not 'CONFIG_TESTDATA_PATH' in os.environ:
- print("You need to set the environment variable CONFIG_TESTDATA_PATH to point to the directory containing the test data files")
+ if not 'CONFIG_TESTDATA_PATH' in os.environ or not 'CONFIG_WR_TESTDATA_PATH' in os.environ:
+ print("You need to set the environment variable CONFIG_TESTDATA_PATH and CONFIG_WR_TESTDATA_PATH to point to the directory containing the test data files")
exit(1)
unittest.main()
Modified: branches/trac310/src/lib/python/isc/config/tests/unittest_fakesession.py
==============================================================================
--- branches/trac310/src/lib/python/isc/config/tests/unittest_fakesession.py (original)
+++ branches/trac310/src/lib/python/isc/config/tests/unittest_fakesession.py Wed Aug 25 22:05:04 2010
@@ -1,4 +1,19 @@
+# Copyright (C) 2010 Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+# $Id$
#
# We can probably use a more general version of this
Modified: branches/trac310/src/lib/python/isc/log/tests/Makefile.am
==============================================================================
--- branches/trac310/src/lib/python/isc/log/tests/Makefile.am (original)
+++ branches/trac310/src/lib/python/isc/log/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -8,5 +8,5 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/python/isc/log \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac310/src/lib/python/isc/log/tests/log_test.py
==============================================================================
--- branches/trac310/src/lib/python/isc/log/tests/log_test.py (original)
+++ branches/trac310/src/lib/python/isc/log/tests/log_test.py Wed Aug 25 22:05:04 2010
@@ -1,3 +1,22 @@
+# Copyright (C) 2010 Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+#
+# Tests for the python logging module
+#
+
from isc.log.log import *
import unittest
import os
Modified: branches/trac310/src/lib/python/isc/notify/notify_out.py
==============================================================================
--- branches/trac310/src/lib/python/isc/notify/notify_out.py (original)
+++ branches/trac310/src/lib/python/isc/notify/notify_out.py Wed Aug 25 22:05:04 2010
@@ -256,7 +256,7 @@
def _zone_notify_handler(self, zone_notify_info, event_type):
'''Notify handler for one zone. The first notify message is
always triggered by the event "_EVENT_TIMEOUT" since when
- one zone prepares to notify its slaves, it's notify_timeout
+ one zone prepares to notify its slaves, its notify_timeout
is set to now, which is used to trigger sending notify
message when dispatcher() scanning zones. '''
tgt = zone_notify_info.get_current_notify_target()
Modified: branches/trac310/src/lib/python/isc/notify/tests/Makefile.am
==============================================================================
--- branches/trac310/src/lib/python/isc/notify/tests/Makefile.am (original)
+++ branches/trac310/src/lib/python/isc/notify/tests/Makefile.am Wed Aug 25 22:05:04 2010
@@ -1,5 +1,12 @@
PYTESTS = notify_out_test.py
EXTRA_DIST = $(PYTESTS)
+
+# If necessary (rare cases), explicitly specify paths to dynamic libraries
+# required by loadable python modules.
+LIBRARY_PATH_PLACEHOLDER =
+if SET_ENV_LIBRARY_PATH
+LIBRARY_PATH_PLACEHOLDER += $(ENV_LIBRARY_PATH)=$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/exceptions/.libs:$$$(ENV_LIBRARY_PATH)
+endif
# later will have configure option to choose this, like: coverage run --branch
PYCOVERAGE = $(PYTHON)
@@ -8,5 +15,6 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs \
- $(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+ $(LIBRARY_PATH_PLACEHOLDER) \
+ $(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
More information about the bind10-changes
mailing list