Browse Source

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

Mukund Sivaraman 12 years ago
parent
commit
6916c32a3f

+ 20 - 3
src/lib/python/isc/memmgr/builder.py

@@ -40,7 +40,9 @@ class MemorySegmentBuilder:
 
             response_queue: A list of responses sent by this object to
                             the main thread. The format of this is
-                            currently undefined.
+                            currently not strictly defined. Future
+                            tickets will be able to define it based on
+                            how it's used.
         """
 
         self._sock = sock
@@ -78,6 +80,21 @@ class MemorySegmentBuilder:
                 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

+ 30 - 0
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