Browse Source

sync with trunk

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac190@2152 e5f2f494-b856-4b98-b285-d166d9295462
JINMEI Tatuya 15 years ago
parent
commit
707bae5486

+ 5 - 0
ChangeLog

@@ -1,3 +1,8 @@
+  55.   [bug]      shane
+    bin/xfrout: xfrout exception on Ctrl-C now no longer generates
+    exception for 'Interrupted system call'
+    (Track #136, svn r2147)
+
   54.   [bug]      zhanglikun
 	bin/xfrout: Enable b10-xfrout can be launched in source
 	code tree.

+ 2 - 0
configure.ac

@@ -393,6 +393,7 @@ AC_CONFIG_FILES([Makefile
                  src/bin/bindctl/Makefile
                  src/bin/bindctl/tests/Makefile
                  src/bin/cfgmgr/Makefile
+                 src/bin/cfgmgr/tests/Makefile
                  src/bin/host/Makefile
                  src/bin/loadzone/Makefile
                  src/bin/msgq/Makefile
@@ -423,6 +424,7 @@ AC_CONFIG_FILES([Makefile
                  src/lib/xfr/Makefile
                ])
 AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
+           src/bin/cfgmgr/tests/b10-cfgmgr_test.py
            src/bin/cmdctl/cmdctl.py
            src/bin/cmdctl/run_b10-cmdctl.sh
            src/bin/cmdctl/tests/cmdctl_test

+ 3 - 1
src/bin/cfgmgr/Makefile.am

@@ -1,8 +1,10 @@
+SUBDIRS = tests
+
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 
 pkglibexec_SCRIPTS = b10-cfgmgr
 
-CLEANFILES = b10-cfgmgr
+CLEANFILES = b10-cfgmgr b10-cfgmgr.pyc
 
 b10_cfgmgrdir = @localstatedir@/@PACKAGE@
 #B10_cfgmgr_DATA = 

+ 7 - 1
src/bin/cfgmgr/b10-cfgmgr.py.in

@@ -15,6 +15,8 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
+# $Id$
+
 import sys; sys.path.append ('@@PYTHONPATH@@')
 
 from isc.config.cfgmgr import ConfigManager
@@ -38,7 +40,8 @@ def signal_handler(signal, frame):
     if cm:
         cm.running = False
 
-if __name__ == "__main__":
+def main():
+    global cm
     try:
         cm = ConfigManager(DATA_PATH)
         signal.signal(signal.SIGINT, signal_handler)
@@ -53,3 +56,6 @@ if __name__ == "__main__":
         print("[b10-cfgmgr] Interrupted, exiting")
     if cm:
         cm.write_config()
+
+if __name__ == "__main__":
+    main()

+ 13 - 0
src/bin/cfgmgr/tests/Makefile.am

@@ -0,0 +1,13 @@
+PYTESTS = b10-cfgmgr_test.py
+
+EXTRA_DIST = $(PYTESTS)
+
+# 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
+check-local:
+	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 ; \
+	done

+ 95 - 0
src/bin/cfgmgr/tests/b10-cfgmgr_test.py.in

@@ -0,0 +1,95 @@
+# 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: cfgmgr_test.py 2126 2010-06-16 14:40:22Z jelte $
+
+#
+# Tests for the configuration manager run script
+#
+
+import unittest
+import os
+import sys
+
+class MyConfigManager:
+    def __init__(self, path):
+        self._path = path
+        self.read_config_called = False
+        self.notify_boss_called = False
+        self.run_called = False
+        self.write_config_called = False
+        self.running = True
+
+    def read_config(self):
+        self.read_config_called = True
+
+    def notify_boss(self):
+        self.notify_boss_called = True
+
+    def run(self):
+        self.run_called = True
+
+    def write_config(self):
+        self.write_config_called = True
+
+class TestConfigManagerStartup(unittest.TestCase):
+    def test_cfgmgr(self):
+        # some creative module use;
+        # b10-cfgmgr has a hypen, so we use __import__
+        # this also gives us the chance to override the imported
+        # module ConfigManager in it.
+        b = __import__("b10-cfgmgr")
+        b.ConfigManager = MyConfigManager
+
+        b.main()
+
+        self.assertTrue(b.cm.read_config_called)
+        self.assertTrue(b.cm.notify_boss_called)
+        self.assertTrue(b.cm.run_called)
+        self.assertTrue(b.cm.write_config_called)
+
+        self.assertTrue(b.cm.running)
+        b.signal_handler(None, None)
+        self.assertFalse(b.cm.running)
+
+        # TODO: take value from the 'global config module'
+        # (and rename the .in away from this file again)
+        data_path = "@localstatedir@/@PACKAGE@".replace("${prefix}", "@prefix@")
+        self.assertEqual(data_path, b.DATA_PATH)
+
+        # remove the 'module' again, or later tests may fail
+        # (if it is already present it won't be loaded again)
+        sys.modules.pop("b10-cfgmgr")
+
+    def test_cfgmgr_from_source(self):
+        tmp_env_var = "/just/some/dir"
+        env_var = None
+        if "B10_FROM_SOURCE" in os.environ:
+            env_var = os.environ["B10_FROM_SOURCE"]
+
+        os.environ["B10_FROM_SOURCE"] = tmp_env_var
+        b = __import__("b10-cfgmgr", globals(), locals())
+        b.ConfigManager = MyConfigManager
+        self.assertEqual(tmp_env_var, b.DATA_PATH)
+
+        if env_var != None:
+            os.environ["B10_FROM_SOURCE"] = env_var
+
+        sys.modules.pop("b10-cfgmgr")
+
+
+if __name__ == '__main__':
+    unittest.main()
+

+ 1 - 1
src/bin/cmdctl/cmdctl.py.in

@@ -416,7 +416,7 @@ def set_signal_handler():
 def run(addr = 'localhost', port = 8080, idle_timeout = 1200, verbose = False):
     ''' Start cmdctl as one https server. '''
     if verbose:
-        sys.stdout.write("[b10-cmdctl] starting on :%s port:%d\n" %(addr, port))
+        sys.stdout.write("[b10-cmdctl] starting on %s port:%d\n" %(addr, port))
     httpd = SecureHTTPServer((addr, port), SecureHTTPRequestHandler, idle_timeout, verbose)
     httpd.serve_forever()
 

+ 14 - 2
src/bin/xfrout/xfrout.py.in

@@ -28,6 +28,7 @@ import os
 from isc.config.ccsession import *
 from isc.cc import SessionError
 import socket
+import select
 import errno
 from optparse import OptionParser, OptionValueError
 try:
@@ -363,11 +364,22 @@ class UnixSockServer(ThreadingUnixStreamServer):
         self._lock.release()
 
 def listen_on_xfr_query(unix_socket_server):
-
     '''Listen xfr query in one single thread. Polls for shutdown 
     every 0.1 seconds, is there a better time?
     '''
-    unix_socket_server.serve_forever(poll_interval = 0.1)
+
+    while True:
+        try:
+            unix_socket_server.serve_forever(poll_interval = 0.1)
+        except select.error as err:
+            # serve_forever() calls select.select(), which can be 
+            # interrupted.
+            # If it is interrupted, it raises select.error with the 
+            # errno set to EINTR. We ignore this case, and let the
+            # normal program flow continue by trying serve_forever()
+            # again.
+            if err.args[0] != errno.EINTR: raise
+
    
 
 class XfroutServer: