BIND 10 trac213, updated. 26841bf1f0c0f0066e17b53bea2261e759bfbdbe [213] Check the kind passed to the component

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Sep 27 11:17:45 UTC 2011


The branch, trac213 has been updated
       via  26841bf1f0c0f0066e17b53bea2261e759bfbdbe (commit)
       via  6b4582111d6f9e8a09e305ec3da009d8d393603b (commit)
       via  1b5cb4d4168c3fcc2d22bcfdf5260ffc36d0a42e (commit)
       via  f500fc46e6467263b38c50010170f83c10d22e8a (commit)
       via  114e59f9ed93ba3b6e656785df5d527011f8ce2b (commit)
      from  eaa56b3d005a20f945cd333664cf34633cfe5a7e (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 26841bf1f0c0f0066e17b53bea2261e759bfbdbe
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Tue Sep 27 13:15:26 2011 +0200

    [213] Check the kind passed to the component
    
    And raise if it makes no sense.

commit 6b4582111d6f9e8a09e305ec3da009d8d393603b
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Tue Sep 27 13:07:08 2011 +0200

    [213] Handle failures to start

commit 1b5cb4d4168c3fcc2d22bcfdf5260ffc36d0a42e
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Tue Sep 27 12:57:46 2011 +0200

    [213] Use private methods

commit f500fc46e6467263b38c50010170f83c10d22e8a
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Tue Sep 27 12:51:08 2011 +0200

    [213] Test for fail-to-start
    
    If the starting function throws an exception

commit 114e59f9ed93ba3b6e656785df5d527011f8ce2b
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Tue Sep 27 12:40:15 2011 +0200

    [213] Fail of dispensable components

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

Summary of changes:
 src/lib/python/isc/bind10/component.py            |    8 +-
 src/lib/python/isc/bind10/tests/component_test.py |  163 ++++++++++++++++-----
 2 files changed, 133 insertions(+), 38 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/python/isc/bind10/component.py b/src/lib/python/isc/bind10/component.py
index 9c5ac8e..6bef31b 100644
--- a/src/lib/python/isc/bind10/component.py
+++ b/src/lib/python/isc/bind10/component.py
@@ -56,6 +56,8 @@ class Component:
             doesn't start or crashes for some reason, the system simply tries
             to restart it and keeps running.
         """
+        if kind not in ['core', 'needed', 'dispensable']:
+            raise ValueError('Component kind can not be ' + kind)
         self.__running = False
         # Dead like really dead. No resurrection possible.
         self.__dead = False
@@ -74,9 +76,13 @@ class Component:
             raise ValueError("Can't resurrect already dead component")
         if self.running():
             raise ValueError("Can't start already running component")
-        self.start_internal()
         self.__running = True
         self.__start_time = time.time()
+        try:
+            self.start_internal()
+        except:
+            self.failed()
+            raise
 
     def start_internal(self):
         """
diff --git a/src/lib/python/isc/bind10/tests/component_test.py b/src/lib/python/isc/bind10/tests/component_test.py
index ff7102e..33263b3 100644
--- a/src/lib/python/isc/bind10/tests/component_test.py
+++ b/src/lib/python/isc/bind10/tests/component_test.py
@@ -22,6 +22,12 @@ import isc.log
 import time
 from isc.bind10.component import Component
 
+class TestError(Exception):
+    """
+    Just a private exception not known to anybody we use for our tests.
+    """
+    pass
+
 class ComponentTests(unittest.TestCase):
     """
     Tests for the bind10.component.Component class
@@ -47,7 +53,7 @@ class ComponentTests(unittest.TestCase):
         # Return the original time function
         isc.bind10.component.time.time = self.__orig_time
 
-    def timeskip(self):
+    def __timeskip(self):
         """
         Skip in time to future some 30s. Implemented by replacing the
         time.time function in the tested module with function that returns
@@ -56,28 +62,40 @@ class ComponentTests(unittest.TestCase):
         tm = time.time()
         isc.bind10.component.time.time = lambda: tm + 30
 
-    def start(self):
+    def __start(self):
         """
         Mock function, installed into the component into start_internal.
         This only notes the component was "started".
         """
         self.__start_called = True
 
-    def stop(self):
+    def __stop(self):
         """
         Mock function, installed into the component into stop_internal.
         This only notes the component was "stopped".
         """
         self.__stop_called = True
 
-    def fail(self):
+    def __fail(self):
         """
         Mock function, installed into the component into failed_internal.
         This only notes the component called the method.
         """
         self.__failed_called = True
 
-    def create_component(self, kind):
+    def __fail_to_start(self):
+        """
+        Mock function. It can be installed into the component's start_internal
+        to simulate a component that fails to start by raising an exception.
+        """
+        orig_started = self.__start_called
+        self.__start_called = True
+        if not orig_started:
+            # This one is from restart. Avoid infinite recursion for now.
+            # FIXME: We should use the restart scheduler to avoid it, not this.
+            raise TestError("Test error")
+
+    def __create_component(self, kind):
         """
         Convenience function that creates a component of given kind
         and installs the mock functions into it so we can hook up into
@@ -87,12 +105,12 @@ class ComponentTests(unittest.TestCase):
         kind of tests and we pretend to be the boss.
         """
         component = Component('No process', self, kind)
-        component.start_internal = self.start
-        component.stop_internal = self.stop
-        component.failed_internal = self.fail
+        component.start_internal = self.__start
+        component.stop_internal = self.__stop
+        component.failed_internal = self.__fail
         return component
 
-    def check_startup(self, component):
+    def __check_startup(self, component):
         """
         Check that nothing was called yet. A newly created component should
         not get started right away, so this should pass after the creation.
@@ -106,7 +124,7 @@ class ComponentTests(unittest.TestCase):
         self.assertRaises(ValueError, component.stop)
         self.assertRaises(ValueError, component.failed)
 
-    def check_started(self, component):
+    def __check_started(self, component):
         """
         Check the component was started, but not stopped anyhow yet.
         """
@@ -116,7 +134,7 @@ class ComponentTests(unittest.TestCase):
         self.assertFalse(self.__failed_called)
         self.assertTrue(component.running())
 
-    def check_dead(self, component):
+    def __check_dead(self, component):
         """
         Check the component is completely dead, and the server too.
         """
@@ -131,7 +149,7 @@ class ComponentTests(unittest.TestCase):
         # Nor started
         self.assertRaises(ValueError, component.start)
 
-    def check_restarted(self, component):
+    def __check_restarted(self, component):
         """
         Check the component restarted successfully.
 
@@ -151,7 +169,7 @@ class ComponentTests(unittest.TestCase):
         # Check it can't be started again
         self.assertRaises(ValueError, component.start)
 
-    def do_start_stop(self, kind):
+    def __do_start_stop(self, kind):
         """
         This is a body of a test. It creates a componend of given kind,
         then starts it and stops it. It checks correct functions are called
@@ -160,11 +178,11 @@ class ComponentTests(unittest.TestCase):
         It also checks the component can't be started/stopped twice.
         """
         # Create it and check it did not do any funny stuff yet
-        component = self.create_component(kind)
-        self.check_startup(component)
+        component = self.__create_component(kind)
+        self.__check_startup(component)
         # Start it and check it called the correct starting functions
         component.start()
-        self.check_started(component)
+        self.__check_started(component)
         # Check it can't be started twice
         self.assertRaises(ValueError, component.start)
         # Stop it again and check
@@ -186,31 +204,31 @@ class ComponentTests(unittest.TestCase):
         """
         A start-stop test for core component. See do_start_stop.
         """
-        self.do_start_stop('core')
+        self.__do_start_stop('core')
     def test_start_stop_needed(self):
         """
         A start-stop test for needed component. See do_start_stop.
         """
-        self.do_start_stop('needed')
+        self.__do_start_stop('needed')
     def test_start_stop_dispensable(self):
         """
         A start-stop test for dispensable component. See do_start_stop.
         """
-        self.do_start_stop('dispensable')
+        self.__do_start_stop('dispensable')
 
     def test_start_fail_core(self):
         """
         Start and then fail a core component. It should stop the whole server.
         """
         # Just ordinary startup
-        component = self.create_component('core')
-        self.check_startup(component)
+        component = self.__create_component('core')
+        self.__check_startup(component)
         component.start()
-        self.check_started(component)
+        self.__check_started(component)
         # Pretend the component died
         component.failed()
         # It should bring down the whole server
-        self.check_dead(component)
+        self.__check_dead(component)
 
     def test_start_fail_core_later(self):
         """
@@ -218,15 +236,15 @@ class ComponentTests(unittest.TestCase):
         It should still stop the whole server.
         """
         # Just ordinary startup
-        component = self.create_component('core')
-        self.check_startup(component)
+        component = self.__create_component('core')
+        self.__check_startup(component)
         component.start()
-        self.check_started(component)
-        self.timeskip()
+        self.__check_started(component)
+        self.__timeskip()
         # Pretend the componend died some time later
         component.failed()
         # Check the component is still dead
-        self.check_dead(component)
+        self.__check_dead(component)
 
     def test_start_fail_needed(self):
         """
@@ -235,13 +253,13 @@ class ComponentTests(unittest.TestCase):
         whole server.
         """
         # Just ordinary startup
-        component = self.create_component('needed')
-        self.check_startup(component)
+        component = self.__create_component('needed')
+        self.__check_startup(component)
         component.start()
-        self.check_started(component)
+        self.__check_started(component)
         # Make it fail right away.
         component.failed()
-        self.check_dead(component)
+        self.__check_dead(component)
 
     def test_start_fail_needed_later(self):
         """
@@ -249,15 +267,86 @@ class ComponentTests(unittest.TestCase):
         we just restart it and will be happy.
         """
         # Just ordinary startup
-        component = self.create_component('needed')
-        self.check_startup(component)
+        component = self.__create_component('needed')
+        self.__check_startup(component)
+        component.start()
+        self.__check_started(component)
+        # Make it fail later on
+        self.__start_called = False
+        self.__timeskip()
+        component.failed()
+        self.__check_restarted(component)
+
+    def test_start_fail_dispensable(self):
+        """
+        Start and then fail a dispensable component. Should just get restarted.
+        """
+        # Just ordinary startup
+        component = self.__create_component('needed')
+        self.__check_startup(component)
+        component.start()
+        self.__check_started(component)
+        # Make it fail right away
+        self.__start_called = False
+        component.failed()
+        self.__check_restarted(component)
+
+    def test_start_fail_dispensable(self):
+        """
+        Start and then later on fail a dispensable component. Should just get
+        restarted.
+        """
+        # Just ordinary startup
+        component = self.__create_component('needed')
+        self.__check_startup(component)
         component.start()
-        self.check_started(component)
+        self.__check_started(component)
         # Make it fail later on
         self.__start_called = False
-        self.timeskip()
+        self.__timeskip()
         component.failed()
-        self.check_restarted(component)
+        self.__check_restarted(component)
+
+    def test_fail_core(self):
+        """
+        Failure to start a core component. Should bring the system down
+        and the exception should get through.
+        """
+        component = self.__create_component('core')
+        self.__check_startup(component)
+        component.start_internal = self.__fail_to_start
+        self.assertRaises(TestError, component.start)
+        self.__check_dead(component)
+
+    def test_fail_needed(self):
+        """
+        Failure to start a needed component. Should bring the system down
+        and the exception should get through.
+        """
+        component = self.__create_component('needed')
+        self.__check_startup(component)
+        component.start_internal = self.__fail_to_start
+        self.assertRaises(TestError, component.start)
+        self.__check_dead(component)
+
+    def test_fail_dispensable(self):
+        """
+        Failure to start a dispensable component. The exception should get
+        through, but it should be restarted.
+        """
+        component = self.__create_component('dispensable')
+        self.__check_startup(component)
+        component.start_internal = self.__fail_to_start
+        self.assertRaises(TestError, component.start)
+        self.__check_restarted(component)
+
+    def test_bad_kind(self):
+        """
+        Test the component rejects nonsensual kinds. This includes bad
+        capitalization.
+        """
+        for kind in ['Core', 'CORE', 'nonsense', 'need ed', 'required']:
+            self.assertRaises(ValueError, Component, 'No process', self, kind)
 
 if __name__ == '__main__':
     isc.log.init("bind10") # FIXME Should this be needed?




More information about the bind10-changes mailing list