BIND 10 trac2855, updated. f801e1bb33d3853a53784094c3eb2d71c0d45315 [2855] Test what happens when a bad command is passed

BIND 10 source code commits bind10-changes at lists.isc.org
Sun Jun 23 18:50:10 UTC 2013


The branch, trac2855 has been updated
       via  f801e1bb33d3853a53784094c3eb2d71c0d45315 (commit)
       via  026b0cc0f2b04ecf569e73a177017a0eff07a1f8 (commit)
       via  a4aca5bc8d1e0fe47711de927d738922f404b95f (commit)
      from  67b02186bb243b3da6cbed3c0fc224af9168809e (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 f801e1bb33d3853a53784094c3eb2d71c0d45315
Author: Mukund Sivaraman <muks at isc.org>
Date:   Mon Jun 24 00:19:59 2013 +0530

    [2855] Test what happens when a bad command is passed

commit 026b0cc0f2b04ecf569e73a177017a0eff07a1f8
Author: Mukund Sivaraman <muks at isc.org>
Date:   Mon Jun 24 00:08:07 2013 +0530

    [2855] Add more code comments

commit a4aca5bc8d1e0fe47711de927d738922f404b95f
Author: Mukund Sivaraman <muks at isc.org>
Date:   Mon Jun 24 00:05:40 2013 +0530

    [2855] Add class documentation

-----------------------------------------------------------------------

Summary of changes:
 src/lib/python/isc/memmgr/builder.py             |   64 ++++++++++++++++++++--
 src/lib/python/isc/memmgr/tests/builder_tests.py |   30 ++++++++++
 2 files changed, 88 insertions(+), 6 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/python/isc/memmgr/builder.py b/src/lib/python/isc/memmgr/builder.py
index c1970d6..f01f830 100644
--- a/src/lib/python/isc/memmgr/builder.py
+++ b/src/lib/python/isc/memmgr/builder.py
@@ -20,6 +20,31 @@ class MemorySegmentBuilder:
     """
 
     def __init__(self, sock, cv, lock, command_queue, response_queue):
+        """ The constructor takes the following arguments:
+
+            sock: A socket using which this builder object notifies the
+                  main thread that it has a response waiting for it.
+
+            cv: A condition variable object that is used by the main
+                thread to tell this builder object that new commands are
+                available to it.
+
+            lock: A lock object which should be acquired before using or
+                  modifying the contents of command_queue and
+                  response_queue.
+
+            command_queue: A list of commands sent by the main thread to
+                           this object. Commands should be executed
+                           sequentially in the given order by this
+                           object.
+
+            response_queue: A list of responses sent by this object to
+                            the main thread. The format of this is
+                            currently not strictly defined. Future
+                            tickets will be able to define it based on
+                            how it's used.
+        """
+
         self._sock = sock
         self._cv = cv
         self._lock = lock
@@ -28,21 +53,48 @@ class MemorySegmentBuilder:
         self._shutdown = False
 
     def run(self):
+        """ This is the method invoked when the builder thread is
+            started.  In this thread, be careful when modifying
+            variables passed-by-reference in the constructor. If they are
+            reassigned, they will not refer to the main thread's objects
+            any longer. Any use of command_queue and response_queue must
+            be synchronized by acquiring the lock. This method must
+            normally terminate only when the 'shutdown' command is sent
+            to it.
+        """
+
+        # Acquire the condition variable while running the loop.
         with self._cv:
             while not self._shutdown:
                 while len(self._command_queue) == 0:
                     self._cv.wait()
-                # move the queue content to a local queue
+                # Move the queue content to a local queue. Be careful of
+                # not making assignments to reference variables.
                 with self._lock:
                     local_command_queue = self._command_queue.copy()
                     self._command_queue.clear()
 
-                # run commands in the queue in the given order.  For
-                # now, it only supports the "shutdown" command, which
-                # just exits the thread.
+                # Run commands passed in the command queue sequentially
+                # in the given order.  For now, it only supports the
+                # "shutdown" command, which just exits the thread.
                 for command in local_command_queue:
                     if command == 'shutdown':
                         self._shutdown = True
+                        # When the shutdown command is received, we do
+                        # not process any further commands.
                         break
-                    raise Exception('Unknown command passed to ' +
-                                    'MemorySegmentBuilder: ' + command)
+                    else:
+                        # A bad command was received. Raising an
+                        # exception is not useful in this case as we are
+                        # likely running in a different thread from the
+                        # main thread which would need to be
+                        # notified. Instead return this in the response
+                        # queue.
+                        with self._lock:
+                            self._response_queue.append('bad_command')
+                            # In this case, we do not notify the main
+                            # thread about a response on the socket, as
+                            # we quit the main loop here anyway (and any
+                            # enclosing thread).
+                            self._shutdown = True
+                            break
diff --git a/src/lib/python/isc/memmgr/tests/builder_tests.py b/src/lib/python/isc/memmgr/tests/builder_tests.py
index 2a3d231..2b21337 100644
--- a/src/lib/python/isc/memmgr/tests/builder_tests.py
+++ b/src/lib/python/isc/memmgr/tests/builder_tests.py
@@ -49,6 +49,33 @@ class TestMemorySegmentBuilder(unittest.TestCase):
         self._master_sock.close()
         self._builder_sock.close()
 
+    def test_bad_command(self):
+        """Tests what happens when a bad command is passed to the
+        MemorySegmentBuilder.
+        """
+
+        self._builder_thread.start()
+
+        # 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:
+            with self._builder_lock:
+                self._builder_command_queue.append('bad_command')
+            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).
+        with self._builder_lock:
+            self.assertEqual(len(self._builder_command_queue), 0)
+            self.assertEqual(len(self._builder_response_queue), 1)
+            self.assertListEqual(self._builder_response_queue, ['bad_command'])
+            self._builder_response_queue.clear()
+
     def test_shutdown(self):
         """Tests that shutdown command exits the MemorySegmentBuilder
         loop.
@@ -61,6 +88,9 @@ class TestMemorySegmentBuilder(unittest.TestCase):
         with self._builder_cv:
             with self._builder_lock:
                 self._builder_command_queue.append('shutdown')
+                # Commands after 'shutdown' must be ignored.
+                self._builder_command_queue.append('bad_command_1')
+                self._builder_command_queue.append('bad_command_2')
             self._builder_cv.notify_all()
 
         # Wait 5 seconds at most for the main loop of the builder to



More information about the bind10-changes mailing list