[svn] commit: r1850 - in /branches/trac185/src/bin/xfrin: tests/xfrin_test.py xfrin.py.in

BIND 10 source code commits bind10-changes at lists.isc.org
Wed May 19 00:20:51 UTC 2010


Author: jinmei
Date: Wed May 19 00:20:51 2010
New Revision: 1850

Log:
introduced a separate main() function and moved the code logic of the
__main__ case there, following the BIND 10 coding style, and for testing
this part.

Modified:
    branches/trac185/src/bin/xfrin/tests/xfrin_test.py
    branches/trac185/src/bin/xfrin/xfrin.py.in

Modified: branches/trac185/src/bin/xfrin/tests/xfrin_test.py
==============================================================================
--- branches/trac185/src/bin/xfrin/tests/xfrin_test.py (original)
+++ branches/trac185/src/bin/xfrin/tests/xfrin_test.py Wed May 19 00:20:51 2010
@@ -44,10 +44,21 @@
 class XfrinTestException(Exception):
     pass
 
-# Rewrite the class for unittest.
 class MockXfrin(Xfrin):
+    # This is a class attribute of a callable object that specifies a non
+    # default behavior triggered in _cc_check_command().  Specific test methods
+    # are expected to explicitly set this attribute before creating a
+    # MockXfrin object (when it needs a non default behavior).
+    # See the TestMain class.
+    check_command_hook = None
+
     def _cc_setup(self):
         pass
+    
+    def _cc_check_command(self):
+        self._shutdown_event.set()
+        if MockXfrin.check_command_hook:
+            MockXfrin.check_command_hook()
 
 class MockXfrinConnection(XfrinConnection):
     def __init__(self, TEST_ZONE_NAME, db_file, shutdown_event, master_addr):
@@ -284,10 +295,9 @@
         self.assertEqual(self.recorder.xfrin_in_progress(TEST_ZONE_NAME), False)
 
 class TestXfrin(unittest.TestCase):
-    args = {}
-
     def setUp(self):
         self.xfr = MockXfrin()
+        self.args = {}
         self.args['zone_name'] = TEST_ZONE_NAME
         self.args['port'] = TEST_MASTER_PORT
         self.args['master'] = TEST_MASTER_IPV4_ADDRESS
@@ -390,6 +400,37 @@
         self.assertEqual(self.xfr.command_handler("refresh",
                                                   self.args)['result'][0], 0)
 
+def raise_interrupt():
+    raise KeyboardInterrupt()
+
+def raise_ccerror():
+    raise isc.cc.session.SessionError('test error')
+
+def raise_excpetion():
+    raise Exception('test exception')
+
+class TestMain(unittest.TestCase):
+    def setUp(self):
+        MockXfrin.check_command_hook = None
+
+    def tearDown(self):
+        MockXfrin.check_command_hook = None
+
+    def test_startup(self):
+        main(MockXfrin, False)
+
+    def test_startup_interrupt(self):
+        MockXfrin.check_command_hook = raise_interrupt
+        main(MockXfrin, False)
+
+    def test_startup_ccerror(self):
+        MockXfrin.check_command_hook = raise_ccerror
+        main(MockXfrin, False)
+
+    def test_startup_generalerror(self):
+        MockXfrin.check_command_hook = raise_excpetion
+        main(MockXfrin, False)
+
 if __name__== "__main__":
     try:
         unittest.main()

Modified: branches/trac185/src/bin/xfrin/xfrin.py.in
==============================================================================
--- branches/trac185/src/bin/xfrin/xfrin.py.in (original)
+++ branches/trac185/src/bin/xfrin/xfrin.py.in Wed May 19 00:20:51 2010
@@ -298,7 +298,7 @@
     xfrin_recorder.decrement(zone_name)
 
 
-class XfrinRecorder():
+class XfrinRecorder:
     def __init__(self):
         self._lock = threading.Lock()
         self._zones = []
@@ -326,7 +326,7 @@
         self._lock.release()
         return ret
 
-class Xfrin():
+class Xfrin:
     def __init__(self, verbose = False):
         self._cc_setup()
         self._max_transfers_in = 10
@@ -345,6 +345,13 @@
                                               self.command_handler)
         self._cc.start()
 
+    def _cc_check_command(self):
+        '''
+This is a straightforward wrapper for cc.check_command, but provided as
+a separate method for the convenience of unit tests.
+'''
+        self._cc.check_command()
+
     def config_handler(self, new_config):
         # TODO, process new config data
         return create_answer(0)
@@ -409,8 +416,7 @@
 
     def startup(self):
         while not self._shutdown_event.is_set():
-            self._cc.check_command()
-
+            self._cc_check_command()
 
     def xfrin_start(self, zone_name, db_file, master_addr, 
                     port = 53, 
@@ -467,15 +473,24 @@
     parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
             help="display more about what is going on")
 
-    
-if __name__ == '__main__':
+def main(xfrin_class, use_signal = True):
+    """The main loop of the Xfrin daemon.
+
+    @param xfrin_class: A class of the Xfrin object.  This is normally Xfrin,
+    but can be a subclass of it for customization.
+    @param use_signal: True if this process should catch signals.  This is
+    normally True, but may be disabled when this function is called in a
+    testing context."""
+    global xfrind
+
     try:
         parser = OptionParser(version = __version__)
         set_cmd_options(parser)
         (options, args) = parser.parse_args()
 
-        set_signal_handler()
-        xfrind = Xfrin(verbose = options.verbose)
+        if use_signal:
+            set_signal_handler()
+        xfrind = xfrin_class(verbose = options.verbose)
         xfrind.startup()
     except KeyboardInterrupt:
         log_error("exit b10-xfrin")
@@ -487,3 +502,6 @@
 
     if xfrind:
         xfrind.shutdown()
+
+if __name__ == '__main__':
+    main(Xfrin)




More information about the bind10-changes mailing list