BIND 10 trac2856, updated. 37753c0dc215875538463720a5bdd68afdb4fc4e [2856] Add test for "load" command to builder
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Jul 12 06:38:09 UTC 2013
The branch, trac2856 has been updated
via 37753c0dc215875538463720a5bdd68afdb4fc4e (commit)
via cca0075f103ef62c5b8413bb19a90c03d7bd4e04 (commit)
from 377e88195e5f86ad60bf02bf02dcbd202daa9fa0 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 37753c0dc215875538463720a5bdd68afdb4fc4e
Author: Mukund Sivaraman <muks at isc.org>
Date: Fri Jul 12 11:39:20 2013 +0530
[2856] Add test for "load" command to builder
commit cca0075f103ef62c5b8413bb19a90c03d7bd4e04
Author: Mukund Sivaraman <muks at isc.org>
Date: Fri Jul 12 10:27:14 2013 +0530
[2856] Rename env variable
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 1 +
src/lib/python/isc/memmgr/builder.py | 22 ++--
src/lib/python/isc/memmgr/tests/Makefile.am | 4 +-
src/lib/python/isc/memmgr/tests/builder_tests.py | 115 +++++++++++++++++++-
.../python/isc/memmgr/tests/datasrc_info_tests.py | 6 +-
.../python/isc/memmgr/tests/testdata/Makefile.am | 2 +
.../tests/testdata/example.com.zone} | 0
7 files changed, 136 insertions(+), 14 deletions(-)
create mode 100644 src/lib/python/isc/memmgr/tests/testdata/Makefile.am
copy src/lib/python/isc/{datasrc/tests/testdata/example.com => memmgr/tests/testdata/example.com.zone} (100%)
-----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 8a0118e..7410f24 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1279,6 +1279,7 @@ AC_CONFIG_FILES([Makefile
src/lib/python/isc/ddns/tests/Makefile
src/lib/python/isc/memmgr/Makefile
src/lib/python/isc/memmgr/tests/Makefile
+ src/lib/python/isc/memmgr/tests/testdata/Makefile
src/lib/python/isc/xfrin/Makefile
src/lib/python/isc/xfrin/tests/Makefile
src/lib/python/isc/server_common/Makefile
diff --git a/src/lib/python/isc/memmgr/builder.py b/src/lib/python/isc/memmgr/builder.py
index 07dd4a8..5aa23dc 100644
--- a/src/lib/python/isc/memmgr/builder.py
+++ b/src/lib/python/isc/memmgr/builder.py
@@ -13,6 +13,7 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+import json
from isc.datasrc import ConfigurableClientList
from isc.memmgr.datasrc_info import SegmentInfo
@@ -90,9 +91,10 @@ class MemorySegmentBuilder:
clist = dsrc_info.clients_map[rrclass]
sgmt_info = dsrc_info.segment_info_map[(rrclass, dsrc_name)]
+ params = json.dumps(sgmt_info.get_reset_param(SegmentInfo.WRITER))
clist.reset_memory_segment(dsrc_name,
- ConfigurableClientList.READ_ONLY,
- sgmt_info.get_reset_param(SegmentInfo.WRITER))
+ ConfigurableClientList.READ_WRITE,
+ params)
if zone_name is not None:
zones = [(None, zone_name)]
@@ -100,9 +102,13 @@ class MemorySegmentBuilder:
zones = clist.get_zone_table_accessor(dsrc_name, True)
for _, zone_name in zones:
- cache_load_error = (zone_name is None) # install empty zone initially
- writer = clist.get_cached_zone_writer(zone_name, catch_load_error,
- dsrc_name)
+ catch_load_error = (zone_name is None) # install empty zone initially
+ result, writer = clist.get_cached_zone_writer(zone_name, catch_load_error,
+ dsrc_name)
+ if result != ConfigurableClientList.CACHE_STATUS_ZONE_SUCCESS:
+ # FIXME: log the error
+ continue
+
try:
error = writer.load()
if error is not None:
@@ -119,7 +125,7 @@ class MemorySegmentBuilder:
# public API to just clear the segment)
clist.reset_memory_segment(dsrc_name,
ConfigurableClientList.READ_ONLY,
- sgmt_info.get_reset_param(SegmentInfo.WRITER))
+ params)
self._response_queue.append(('load-completed', dsrc_info, rrclass,
dsrc_name))
@@ -154,8 +160,8 @@ class MemorySegmentBuilder:
# See the comments for __handle_load() for
# details of the tuple passed to the "load"
# command.
- self.__handle_load(command_tuple[1], command_tuple[2],
- command_tuple[3], command_tuple[4])
+ _, zone_name, dsrc_info, rrclass, dsrc_name = command_tuple
+ self.__handle_load(zone_name, dsrc_info, rrclass, dsrc_name)
elif command == 'shutdown':
self.__handle_shutdown()
# When the shutdown command is received, we do
diff --git a/src/lib/python/isc/memmgr/tests/Makefile.am b/src/lib/python/isc/memmgr/tests/Makefile.am
index 7a85083..b171cb1 100644
--- a/src/lib/python/isc/memmgr/tests/Makefile.am
+++ b/src/lib/python/isc/memmgr/tests/Makefile.am
@@ -1,3 +1,4 @@
+SUBDIRS = testdata
PYCOVERAGE_RUN = @PYCOVERAGE_RUN@
PYTESTS = builder_tests.py datasrc_info_tests.py
EXTRA_DIST = $(PYTESTS)
@@ -26,7 +27,8 @@ endif
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
$(LIBRARY_PATH_PLACEHOLDER) \
- TESTDATA_PATH=$(builddir) \
+ TESTDATA_PATH=$(abs_srcdir)/testdata \
+ TESTDATA_WRITE_PATH=$(builddir) \
B10_FROM_BUILD=$(abs_top_builddir) \
HAVE_SHARED_MEMORY=$(HAVE_SHARED_MEMORY) \
PYTHONPATH=$(COMMON_PYTHON_PATH):$(abs_top_builddir)/src/lib/dns/python/.libs \
diff --git a/src/lib/python/isc/memmgr/tests/builder_tests.py b/src/lib/python/isc/memmgr/tests/builder_tests.py
index 94cb8e1..249b5d0 100644
--- a/src/lib/python/isc/memmgr/tests/builder_tests.py
+++ b/src/lib/python/isc/memmgr/tests/builder_tests.py
@@ -14,12 +14,28 @@
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
import unittest
+import os
import socket
import select
import threading
import isc.log
+from isc.dns import *
+import isc.datasrc
from isc.memmgr.builder import *
+from isc.server_common.datasrc_clients_mgr import DataSrcClientsMgr
+from isc.memmgr.datasrc_info import *
+
+TESTDATA_PATH = os.environ['TESTDATA_PATH'] + os.sep
+
+# Defined for easier tests with DataSrcClientsMgr.reconfigure(), which
+# only needs get_value() method
+class MockConfigData:
+ def __init__(self, data):
+ self.__data = data
+
+ def get_value(self, identifier):
+ return self.__data[identifier], False
class TestMemorySegmentBuilder(unittest.TestCase):
def _create_builder_thread(self):
@@ -29,7 +45,8 @@ class TestMemorySegmentBuilder(unittest.TestCase):
self._builder_command_queue = []
self._builder_response_queue = []
- self._builder_cv = threading.Condition()
+ self._builder_lock = threading.Lock()
+ self._builder_cv = threading.Condition(lock=self._builder_lock)
self._builder = MemorySegmentBuilder(self._builder_sock,
self._builder_cv,
@@ -95,7 +112,7 @@ class TestMemorySegmentBuilder(unittest.TestCase):
self._builder_thread.start()
- # Now that the builder thread is running, send it the shutdown
+ # Now that the builder thread is running, send it the "shutdown"
# command. The thread should exit its main loop and be joinable.
with self._builder_cv:
self._builder_command_queue.append(('shutdown',))
@@ -115,6 +132,100 @@ class TestMemorySegmentBuilder(unittest.TestCase):
self.assertEqual(len(self._builder_command_queue), 0)
self.assertEqual(len(self._builder_response_queue), 0)
+ @unittest.skipIf(os.environ['HAVE_SHARED_MEMORY'] != 'yes',
+ 'shared memory is not available')
+ def test_load(self):
+ """
+ Test "load" command.
+ """
+
+ mapped_file_dir = os.environ['TESTDATA_WRITE_PATH']
+ mgr_config = {'mapped_file_dir': mapped_file_dir}
+
+ cfg_data = MockConfigData(
+ {"classes":
+ {"IN": [{"type": "MasterFiles",
+ "params": { "example.com": TESTDATA_PATH + "example.com.zone" },
+ "cache-enable": True,
+ "cache-type": "mapped"}]
+ }
+ })
+ cmgr = DataSrcClientsMgr(use_cache=True)
+ cmgr.reconfigure({}, cfg_data)
+
+ genid, clients_map = cmgr.get_clients_map()
+ datasrc_info = DataSrcInfo(genid, clients_map, mgr_config)
+
+ self.assertEqual(1, datasrc_info.gen_id)
+ self.assertEqual(clients_map, datasrc_info.clients_map)
+ self.assertEqual(1, len(datasrc_info.segment_info_map))
+ sgmt_info = datasrc_info.segment_info_map[(RRClass.IN, 'MasterFiles')]
+ self.assertIsNone(sgmt_info.get_reset_param(SegmentInfo.READER))
+ self.assertIsNotNone(sgmt_info.get_reset_param(SegmentInfo.WRITER))
+
+ self._builder_thread.start()
+
+ # Now that the builder thread is running, send it the "load"
+ # command. We should be notified when the load operation is
+ # complete.
+ with self._builder_cv:
+ self._builder_command_queue.append(('load',
+ isc.dns.Name("example.com"),
+ datasrc_info, RRClass.IN,
+ 'MasterFiles'))
+ self._builder_cv.notify_all()
+
+ # Wait 60 seconds to receive a notification on the socket from
+ # the builder.
+ (reads, _, _) = select.select([self._master_sock], [], [], 60)
+ self.assertTrue(self._master_sock in reads)
+
+ # Reading 1 byte should not block us here, especially as the
+ # socket is ready to read. It's a hack, but this is just a
+ # testcase.
+ got = self._master_sock.recv(1)
+ self.assertEqual(got, b'x')
+
+ with self._builder_lock:
+ # The command queue must be cleared, and the response queue
+ # must contain a response that a bad command was sent. The
+ # thread is no longer running, so we can use the queues
+ # without a lock.
+ self.assertEqual(len(self._builder_command_queue), 0)
+ self.assertEqual(len(self._builder_response_queue), 1)
+
+ response = self._builder_response_queue[0]
+ self.assertTrue(isinstance(response, tuple))
+ self.assertTupleEqual(response, ('load-completed', datasrc_info,
+ RRClass.IN, 'MasterFiles'))
+ del self._builder_response_queue[:]
+
+ # Now try looking for some loaded data
+ clist = datasrc_info.clients_map[RRClass.IN]
+ dsrc, finder, exact = clist.find(isc.dns.Name("example.com"))
+ self.assertIsNotNone(dsrc)
+ self.assertTrue(isinstance(dsrc, isc.datasrc.DataSourceClient))
+ self.assertIsNotNone(finder)
+ self.assertTrue(isinstance(finder, isc.datasrc.ZoneFinder))
+ self.assertTrue(exact)
+
+ # Send the builder thread the "shutdown" command. The thread
+ # should exit its main loop and be joinable.
+ with self._builder_cv:
+ self._builder_command_queue.append(('shutdown',))
+ self._builder_cv.notify_all()
+
+ # Wait 5 seconds at most for the main loop of the builder to
+ # exit.
+ self._builder_thread.join(5)
+ self.assertFalse(self._builder_thread.isAlive())
+
+ # The command queue must be cleared, and the response queue must
+ # be untouched (we don't use it in this test). The thread is no
+ # longer running, so we can use the queues without a lock.
+ self.assertEqual(len(self._builder_command_queue), 0)
+ self.assertEqual(len(self._builder_response_queue), 0)
+
if __name__ == "__main__":
isc.log.init("bind10-test")
isc.log.resetUnitTestRootLogger()
diff --git a/src/lib/python/isc/memmgr/tests/datasrc_info_tests.py b/src/lib/python/isc/memmgr/tests/datasrc_info_tests.py
index 8c8e5e2..ee2b794 100644
--- a/src/lib/python/isc/memmgr/tests/datasrc_info_tests.py
+++ b/src/lib/python/isc/memmgr/tests/datasrc_info_tests.py
@@ -34,7 +34,7 @@ class MockConfigData:
class TestSegmentInfo(unittest.TestCase):
def setUp(self):
- self.__mapped_file_dir = os.environ['TESTDATA_PATH']
+ self.__mapped_file_dir = os.environ['TESTDATA_WRITE_PATH']
self.__sgmt_info = SegmentInfo.create('mapped', 0, RRClass.IN,
'sqlite3',
{'mapped_file_dir':
@@ -372,9 +372,9 @@ class MockClientList:
class TestDataSrcInfo(unittest.TestCase):
def setUp(self):
- self.__mapped_file_dir = os.environ['TESTDATA_PATH']
+ self.__mapped_file_dir = os.environ['TESTDATA_WRITE_PATH']
self.__mgr_config = {'mapped_file_dir': self.__mapped_file_dir}
- self.__sqlite3_dbfile = os.environ['TESTDATA_PATH'] + '/' + 'zone.db'
+ self.__sqlite3_dbfile = os.environ['TESTDATA_WRITE_PATH'] + '/' + 'zone.db'
self.__clients_map = {
# mixture of 'local' and 'mapped' and 'unused' (type =None)
# segments
diff --git a/src/lib/python/isc/memmgr/tests/testdata/Makefile.am b/src/lib/python/isc/memmgr/tests/testdata/Makefile.am
new file mode 100644
index 0000000..22e7ce3
--- /dev/null
+++ b/src/lib/python/isc/memmgr/tests/testdata/Makefile.am
@@ -0,0 +1,2 @@
+EXTRA_DIST = \
+ example.com.zone
diff --git a/src/lib/python/isc/memmgr/tests/testdata/example.com.zone b/src/lib/python/isc/memmgr/tests/testdata/example.com.zone
new file mode 100644
index 0000000..24e22e1
--- /dev/null
+++ b/src/lib/python/isc/memmgr/tests/testdata/example.com.zone
@@ -0,0 +1,8 @@
+example.com. 1000 IN SOA a.dns.example.com. mail.example.com. 1 1 1 1 1
+example.com. 1000 IN NS a.dns.example.com.
+example.com. 1000 IN NS b.dns.example.com.
+example.com. 1000 IN NS c.dns.example.com.
+a.dns.example.com. 1000 IN A 1.1.1.1
+b.dns.example.com. 1000 IN A 3.3.3.3
+b.dns.example.com. 1000 IN AAAA 4:4::4:4
+b.dns.example.com. 1000 IN AAAA 5:5::5:5
More information about the bind10-changes
mailing list