Parcourir la source

[213] High level reconfigure and shutdown

With tests. Includes a bugfix, the _build_plan did not include the name
when asking to shut down a component.
Michal 'vorner' Vaner il y a 13 ans
Parent
commit
a730ddd17c

+ 20 - 6
src/lib/python/isc/bind10/component.py

@@ -182,6 +182,13 @@ class Configurator:
         self._old_config = {}
         self._running = False
 
+    def __reconfigure_internal(self, old, new):
+        """
+        Does a switch from one configuration to another.
+        """
+        self._run_plan(self._build_plan(old, new))
+        self._old_config = new
+
     def startup(self, configuration):
         """
         Starts the first set of processes. This configuration is expected
@@ -191,22 +198,28 @@ class Configurator:
         if self._running:
             raise ValueError("Trying to start the component configurator " +
                              "twice")
-        self._run_plan(self._build_plan({}, configuration))
-        self._old_config = configuration
+        self.__reconfigure_internal({}, configuration)
         self._running = True
 
     def shutdown(self):
         """
         Shuts everything down.
         """
-        pass
+        if not self._running:
+            raise ValueError("Trying to shutdown the component " +
+                             "configurator while it's not yet running")
+        self.__reconfigure_internal(self._old_config, {})
+        self._running = False
 
-    def reconfigure(configuration):
+    def reconfigure(self, configuration):
         """
         Changes configuration from the current one to the provided. It
         starts and stops all the components as needed.
         """
-        pass
+        if not self._running:
+            raise ValueError("Trying to reconfigure the component " +
+                             "configurator while it's not yet running")
+        self.__reconfigure_internal(self._old_config, configuration)
 
     def _build_plan(self, old, new):
         """
@@ -227,7 +240,8 @@ class Configurator:
                 if component.running():
                     plan.append({
                         'command': 'stop',
-                        'component': component
+                        'component': component,
+                        'name': cname
                     })
         # Handle transitions of configuration of what is here
         for cname in new.keys():

+ 52 - 2
src/lib/python/isc/bind10/tests/component_test.py

@@ -566,6 +566,7 @@ class ConfiguratorTest(BossUtils, unittest.TestCase):
         self.assertEqual([], self.log)
         self.assertEqual([{
             'command': 'stop',
+            'name': 'additional',
             'component': component
         }], plan)
 
@@ -585,6 +586,7 @@ class ConfiguratorTest(BossUtils, unittest.TestCase):
                          self.log)
         self.assertEqual(2, len(plan))
         self.assertEqual('stop', plan[0]['command'])
+        self.assertEqual('additional', plan[0]['name'])
         self.assertTrue('component' in plan[0])
         self.assertEqual('start', plan[1]['command'])
         self.assertEqual('another', plan[1]['name'])
@@ -625,14 +627,34 @@ class ConfiguratorTest(BossUtils, unittest.TestCase):
         # instance
         self.assertEqual([], self.__do_switch('special', 'test'))
 
-    def test_startup(self):
+    def __check_shutdown_log(self):
+        """
+        Checks the log for shutting down from the core configuration.
+        """
+        # We know everything must be stopped, we know what it is.
+        # But we don't know the order, so we check everything is exactly
+        # once in the log
+        components = set(self.__core.keys())
+        for (name, command) in self.log:
+            self.assertEqual('stop', command)
+            self.assertTrue(name in components)
+            components.remove(name)
+        self.assertEqual(set([]), components, "Some component wasn't stopped")
+
+    def test_run(self):
         """
         Passes some configuration to the startup method and sees if
-        the components are started up.
+        the components are started up. Then it reconfigures it with
+        empty configuration, the original configuration again and shuts
+        down.
 
         It also checks the components are kept inside the configurator.
         """
         configurator = Configurator(self)
+        # Can't reconfigure nor stop yet
+        self.assertRaises(ValueError, configurator.reconfigure, self.__core)
+        self.assertRaises(ValueError, configurator.shutdown)
+        # Start it
         configurator.startup(self.__core)
         self.assertEqual(self.__core_log, self.log)
         for core in self.__core.keys():
@@ -642,6 +664,34 @@ class ConfiguratorTest(BossUtils, unittest.TestCase):
         # It can't be started twice
         self.assertRaises(ValueError, configurator.startup, self.__core)
 
+        self.log = []
+        # Reconfigure - stop everything
+        configurator.reconfigure({})
+        self.assertEqual({}, configurator._components)
+        self.assertEqual({}, configurator._old_config)
+        self.assertTrue(configurator._running)
+        self.__check_shutdown_log()
+
+        # Start it again
+        self.log = []
+        configurator.reconfigure(self.__core)
+        self.assertEqual(self.__core_log, self.log)
+        for core in self.__core.keys():
+            self.assertTrue(core in configurator._components)
+        self.assertEqual(self.__core, configurator._old_config)
+        self.assertTrue(configurator._running)
+
+        # Do a shutdown
+        self.log = []
+        configurator.shutdown()
+        self.assertEqual({}, configurator._components)
+        self.assertEqual({}, configurator._old_config)
+        self.assertFalse(configurator._running)
+        self.__check_shutdown_log()
+
+        # It can't be stopped twice
+        self.assertRaises(ValueError, configurator.shutdown)
+
 if __name__ == '__main__':
     isc.log.init("bind10") # FIXME Should this be needed?
     isc.log.resetUnitTestRootLogger()