Browse Source

[213] More parameters for the components

Like the address and parameters.
Michal 'vorner' Vaner 13 years ago
parent
commit
292665a460

+ 17 - 16
src/lib/python/isc/bind10/component.py

@@ -37,7 +37,7 @@ class Component:
     it might be inherited and modified for special-purpose components,
     like the core modules with different ways of starting up.
     """
-    def __init__(self, process, boss, kind):
+    def __init__(self, process, boss, kind, address=None, params=None):
         """
         Creates the component in not running mode.
 
@@ -65,7 +65,11 @@ class Component:
         # Dead like really dead. No resurrection possible.
         self.__dead = False
         self.__kind = kind
-        self.__boss = boss
+        self._boss = boss
+        self._process = process
+        self._start_func = None
+        self._address = address
+        self._params = params
 
     def start(self):
         """
@@ -137,7 +141,7 @@ class Component:
         if self.__kind == 'core' or \
             (self.__kind == 'needed' and time.time() - 10 < self.__start_time):
             self.__dead = True
-            self.__boss.shutdown(1)
+            self._boss.shutdown(1)
         # This means we want to restart
         else:
             self.start()
@@ -162,15 +166,11 @@ class Component:
         return self.__running
 
 class SockCreator(Component):
-    def __init__(self, process, boss, kind):
-        Component.__init__(self, process, boss, kind)
-        self.__boss = boss
-
     def start_internal(self):
         self._boss.curproc = 'b10-sockcreator'
         self.__creator = isc.bind10.sockcreator.Creator(LIBEXECDIR + ':' +
                                                         os.environ['PATH'])
-        self.__boss.register_process(self.__creator.pid(), self)
+        self._boss.register_process(self.__creator.pid(), self)
 
     def stop_internal(self, kill=False):
         if self.__creator is None:
@@ -182,7 +182,7 @@ class SockCreator(Component):
         self.__creator = None
 
 class Msgq(Component):
-    def __init__(self, process, boss, kind):
+    def __init__(self, process, boss, kind, address, params):
         Component.__init__(self, process, boss, kind)
         self._start_func = boss.start_msgq
 
@@ -190,25 +190,25 @@ class Msgq(Component):
         pass # Wait for the boss to actually kill it. There's no stop command.
 
 class CfgMgr(Component):
-    def __init__(self, process, boss, kind):
+    def __init__(self, process, boss, kind, address, params):
         Component.__init__(self, process, boss, kind)
         self._start_func = boss.start_cfgmgr
         self._address = 'ConfigManager'
 
 class Auth(Component):
-    def __init__(self, process, boss, kind):
+    def __init__(self, process, boss, kind, address, params):
         Component.__init__(self, process, boss, kind)
         self._start_func = boss.start_auth
         self._address = 'Auth'
 
 class Resolver(Component):
-    def __init__(self, process, boss, kind):
+    def __init__(self, process, boss, kind, address, params):
         Component.__init__(self, process, boss, kind)
         self._start_func = boss.start_resolver
         self._address = 'Resolver'
 
 class CmdCtl(Component):
-    def __init__(self, process, boss, kind):
+    def __init__(self, process, boss, kind, address, params):
         Component.__init__(self, process, boss, kind)
         self._start_func = boss.start_cmdctl
         self._address = 'Cmdctl'
@@ -332,14 +332,15 @@ class Configurator:
                 if 'special' in params:
                     # TODO: Better error handling
                     creator = specials[params['special']]
-                component = creator(params['process'], self.__boss,
-                                    params['kind'])
+                component = creator(params.get('process', cname), self.__boss,
+                                    params['kind'], params.get('address'),
+                                    params.get('params'))
                 priority = params.get('priority', 0)
                 # We store tuples, priority first, so we can easily sort
                 plan_add.append((priority, {
                     'component': component,
                     'command': 'start',
-                    'name': cname
+                    'name': cname,
                 }))
         # Push the starts there sorted by priority
         plan.extend([command for (_, command) in sorted(plan_add,

+ 45 - 5
src/lib/python/isc/bind10/tests/component_test.py

@@ -124,12 +124,30 @@ class ComponentTests(BossUtils, unittest.TestCase):
         The process used is some nonsense, as this isn't used in this
         kind of tests and we pretend to be the boss.
         """
-        component = Component('No process', self, kind)
+        component = Component('No process', self, kind, 'homeless', [])
         component.start_internal = self.__start
         component.stop_internal = self.__stop
         component.failed_internal = self.__fail
         return component
 
+    def test_name(self):
+        """
+        Test the name provides whatever we passed to the constructor as process.
+        """
+        component = self.__create_component('core')
+        self.assertEqual('No process', component.name())
+
+    def test_guts(self):
+        """
+        Test the correct data are stored inside the component.
+        """
+        component = self.__create_component('core')
+        self.assertEqual(self, component._boss)
+        self.assertEqual("No process", component._process)
+        self.assertEqual(None, component._start_func)
+        self.assertEqual("homeless", component._address)
+        self.assertEqual([], component._params)
+
     def __check_startup(self, component):
         """
         Check that nothing was called yet. A newly created component should
@@ -373,14 +391,14 @@ class TestComponent(Component):
     A test component. It does not start any processes or so, it just logs
     information about what happens.
     """
-    def __init__(self, owner, name, kind):
+    def __init__(self, owner, name, kind, address=None, params=None):
         """
         Initializes the component. The owner is the test that started the
         component. The logging will happen into it.
 
         The process is used as a name for the logging.
         """
-        Component.__init__(self, name, owner, kind)
+        Component.__init__(self, name, owner, kind, address, params)
         self.__owner = owner
         self.__name = name
         self.log('init')
@@ -464,12 +482,12 @@ class ConfiguratorTest(BossUtils, unittest.TestCase):
         BossUtils.tearDown(self)
         specials = self.__orig_specials
 
-    def __component_test(self, process, boss, kind):
+    def __component_test(self, process, boss, kind, address=None, params=None):
         """
         Create a test component. It will log events to us.
         """
         self.assertEqual(self, boss)
-        return TestComponent(self, process, kind)
+        return TestComponent(self, process, kind, address, params)
 
     def test_init(self):
         """
@@ -539,6 +557,9 @@ class ConfiguratorTest(BossUtils, unittest.TestCase):
             self.assertTrue('component' in task)
             self.assertEqual('start', task['command'])
             self.assertEqual(name, task['name'])
+            component = task['component']
+            self.assertIsNone(component._address)
+            self.assertIsNone(component._params)
 
         # A plan to go from older state to newer one containing more components
         bigger = copy.copy(self.__core)
@@ -592,6 +613,25 @@ class ConfiguratorTest(BossUtils, unittest.TestCase):
         self.assertEqual('another', plan[1]['name'])
         self.assertTrue('component' in plan[1])
 
+        # Some slightly insane plans, like missing process, having parameters,
+        # no special, etc
+        plan = configurator._build_plan({}, {
+            'component': {
+                'kind': 'needed',
+                'params': [1, 2],
+                'address': 'address'
+            }
+        })
+        self.assertEqual(1, len(plan))
+        self.assertEqual('start', plan[0]['command'])
+        self.assertEqual('component', plan[0]['name'])
+        component = plan[0]['component']
+        self.assertEqual('component', component.name())
+        self.assertEqual([1, 2], component._params)
+        self.assertEqual('address', component._address)
+        # We don't use isinstance on purpose, it would allow a descendand
+        self.assertTrue(type(component) is Component)
+
     def __do_switch(self, option, value):
         """
         Start it with some component and then switch the configuration of the