Exemple #1
0
 def test_init(self):
     """
     Tests the configurator can be created and it does not create
     any components yet, nor does it remember anything.
     """
     configurator = Configurator(self, self.__specials)
     self.assertEqual([], self.log)
     self.assertEqual({}, configurator._components)
     self.assertFalse(configurator.running())
Exemple #2
0
 def test_init(self):
     """
     Tests the configurator can be created and it does not create
     any components yet, nor does it remember anything.
     """
     configurator = Configurator(self, self.__specials)
     self.assertEqual([], self.log)
     self.assertEqual({}, configurator._components)
     self.assertFalse(configurator.running())
Exemple #3
0
 def test_sort_no_prio(self):
     """
     There was a bug if there were two things with the same priority
     (or without priority), it failed as it couldn't compare the dicts
     there. This tests it doesn't crash.
     """
     configurator = Configurator(self, self.__specials)
     configurator._build_plan({}, {
                                      "c1": { 'kind': 'dispensable'},
                                      "c2": { 'kind': 'dispensable'}
                                  })
Exemple #4
0
 def test_sort_no_prio(self):
     """
     There was a bug if there were two things with the same priority
     (or without priority), it failed as it couldn't compare the dicts
     there. This tests it doesn't crash.
     """
     configurator = Configurator(self, self.__specials)
     configurator._build_plan({}, {
         "c1": {
             'kind': 'dispensable'
         },
         "c2": {
             'kind': 'dispensable'
         }
     })
Exemple #5
0
 def __do_switch(self, option, value):
     """
     Start it with some component and then switch the configuration of the
     component. This will probably raise, as it is not yet supported.
     """
     configurator = Configurator(self, self.__specials)
     compconfig = {
         'special': 'test',
         'process': 'process',
         'priority': 13,
         'kind': 'core'
     }
     modifiedconfig = copy.copy(compconfig)
     modifiedconfig[option] = value
     return configurator._build_plan({'comp': (compconfig, None)},
                                     {'comp': modifiedconfig})
Exemple #6
0
 def __do_switch(self, option, value):
     """
     Start it with some component and then switch the configuration of the
     component. This will probably raise, as it is not yet supported.
     """
     configurator = Configurator(self, self.__specials)
     compconfig = {
         'special': 'test',
         'process': 'process',
         'priority': 13,
         'kind': 'core'
     }
     modifiedconfig = copy.copy(compconfig)
     modifiedconfig[option] = value
     return configurator._build_plan({'comp': (compconfig, None)},
                                     {'comp': modifiedconfig})
Exemple #7
0
    def test_run_plan(self):
        """
        Test the internal function of running plans. Just see it can handle
        the commands in the given order. We see that by the log.

        Also includes one that raises, so we see it just stops there.
        """
        # Prepare the configurator and the plan
        configurator = Configurator(self, self.__specials)
        started = self.__component_test('second', self, 'dispensable')
        started.start()
        stopped = self.__component_test('first', self, 'core')
        configurator._components = {'second': started}
        plan = [
            {
                'component': stopped,
                'command': 'start',
                'name': 'first',
                'config': {'a': 1}
            },
            {
                'component': started,
                'command': 'stop',
                'name': 'second',
                'config': {}
            },
            {
                'component': FailComponent('third', self, 'needed'),
                'command': 'start',
                'name': 'third',
                'config': {}
            },
            {
                'component': self.__component_test('fourth', self, 'core'),
                'command': 'start',
                'name': 'fourth',
                'config': {}
            }
        ]
        # Don't include the preparation into the log
        self.log = []
        # The error from the third component is propagated
        self.assertRaises(TestError, configurator._run_plan, plan)
        # The first two were handled, the rest not, due to the exception
        self.assertEqual([('first', 'start'), ('second', 'stop')], self.log)
        self.assertEqual({'first': ({'a': 1}, stopped)},
                         configurator._components)
Exemple #8
0
    def test_run_plan(self):
        """
        Test the internal function of running plans. Just see it can handle
        the commands in the given order. We see that by the log.

        Also includes one that raises, so we see it just stops there.
        """
        # Prepare the configurator and the plan
        configurator = Configurator(self, self.__specials)
        started = self.__component_test('second', self, 'dispensable')
        started.start()
        stopped = self.__component_test('first', self, 'core')
        configurator._components = {'second': started}
        plan = [{
            'component': stopped,
            'command': 'start',
            'name': 'first',
            'config': {
                'a': 1
            }
        }, {
            'component': started,
            'command': 'stop',
            'name': 'second',
            'config': {}
        }, {
            'component': FailComponent('third', self, 'needed'),
            'command': 'start',
            'name': 'third',
            'config': {}
        }, {
            'component': self.__component_test('fourth', self, 'core'),
            'command': 'start',
            'name': 'fourth',
            'config': {}
        }]
        # Don't include the preparation into the log
        self.log = []
        # The error from the third component is propagated
        self.assertRaises(TestError, configurator._run_plan, plan)
        # The first two were handled, the rest not, due to the exception
        self.assertEqual([('first', 'start'), ('second', 'stop')], self.log)
        self.assertEqual({'first': ({
            'a': 1
        }, stopped)}, configurator._components)
Exemple #9
0
    def test_build_plan(self):
        """
        Test building the plan correctly. Not complete yet, this grows as we
        add more ways of changing the plan.
        """
        configurator = Configurator(self, self.__specials)
        plan = configurator._build_plan({}, self.__core)
        # This should have created the components
        self.assertEqual(self.__core_log_create, self.log)
        self.assertEqual(3, len(plan))
        for (task, name) in zip(plan, ['core1', 'core3', 'core2']):
            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)
        bigger['additional'] = {
            'priority': 6,
            'special': 'test',
            'process': 'additional',
            'kind': 'dispensable'  # need to be dispensable so it could restart
        }
        self.log = []
        plan = configurator._build_plan(self.__build_components(self.__core),
                                        bigger)
        self.assertEqual([('additional', 'init'),
                          ('additional', 'dispensable')], self.log)
        self.assertEqual(1, len(plan))
        self.assertTrue('component' in plan[0])
        component = plan[0]['component']
        self.assertEqual('start', plan[0]['command'])
        self.assertEqual('additional', plan[0]['name'])

        # Now remove the one component again
        # We run the plan so the component is wired into internal structures
        configurator._run_plan(plan)
        # We should have the 'additional' component in the configurator.
        self.assertTrue(configurator.has_component(component))
        for count in [0, 1]:  # repeat two times, see below
            self.log = []
            plan = configurator._build_plan(self.__build_components(bigger),
                                            self.__core)
            self.assertEqual([], self.log)
            self.assertEqual([{
                'command': 'stop',
                'name': 'additional',
                'component': component
            }], plan)

            if count is 0:
                # We then emulate unexpected failure of the component (but
                # before it restarts).  It shouldn't confuse the
                # configurator in the second phase of the test
                component.failed(0)
        # Run the plan, confirm the specified component is gone.
        configurator._run_plan(plan)
        self.assertFalse(configurator.has_component(component))
        # There shouldn't be any other object that has the same name
        self.assertFalse('additional' in configurator._components)

        # We want to switch a component. So, prepare the configurator so it
        # holds one
        configurator._run_plan(
            configurator._build_plan(self.__build_components(self.__core),
                                     bigger))
        # Get a different configuration with a different component
        different = copy.copy(self.__core)
        different['another'] = {
            'special': 'test',
            'process': 'another',
            'kind': 'dispensable'
        }
        self.log = []
        plan = configurator._build_plan(self.__build_components(bigger),
                                        different)
        self.assertEqual([('another', 'init'), ('another', 'dispensable')],
                         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'])
        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)
        self.assertEqual('needed', component._kind)
        # We don't use isinstance on purpose, it would allow a descendant
        self.assertTrue(type(component) is Component)
        plan = configurator._build_plan({},
                                        {'component': {
                                            'kind': 'dispensable'
                                        }})
        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.assertIsNone(component._params)
        self.assertIsNone(component._address)
        self.assertEqual('dispensable', component._kind)
Exemple #10
0
    def test_run(self):
        """
        Passes some configuration to the startup method and sees if
        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, self.__specials)
        # Can't reconfigure nor stop yet
        self.assertRaises(ValueError, configurator.reconfigure, self.__core)
        self.assertRaises(ValueError, configurator.shutdown)
        self.assertFalse(configurator.running())
        # Start it
        configurator.startup(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[core],
                             configurator._components[core][0])
        self.assertEqual(set(self.__core), set(configurator._components))
        self.assertTrue(configurator.running())
        # 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.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[core],
                             configurator._components[core][0])
        self.assertEqual(set(self.__core), set(configurator._components))
        self.assertTrue(configurator.running())

        # Do a shutdown
        self.log = []
        configurator.shutdown()
        self.assertEqual({}, configurator._components)
        self.assertFalse(configurator.running())
        self.__check_shutdown_log()

        # It can't be stopped twice
        self.assertRaises(ValueError, configurator.shutdown)
Exemple #11
0
    def test_build_plan(self):
        """
        Test building the plan correctly. Not complete yet, this grows as we
        add more ways of changing the plan.
        """
        configurator = Configurator(self, self.__specials)
        plan = configurator._build_plan({}, self.__core)
        # This should have created the components
        self.assertEqual(self.__core_log_create, self.log)
        self.assertEqual(3, len(plan))
        for (task, name) in zip(plan, ['core1', 'core3', 'core2']):
            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)
        bigger['additional'] = {
            'priority': 6,
            'special': 'test',
            'process': 'additional',
            'kind': 'needed'
        }
        self.log = []
        plan = configurator._build_plan(self.__build_components(self.__core),
                                        bigger)
        self.assertEqual([('additional', 'init'), ('additional', 'needed')],
                         self.log)
        self.assertEqual(1, len(plan))
        self.assertTrue('component' in plan[0])
        component = plan[0]['component']
        self.assertEqual('start', plan[0]['command'])
        self.assertEqual('additional', plan[0]['name'])

        # Now remove the one component again
        # We run the plan so the component is wired into internal structures
        configurator._run_plan(plan)
        self.log = []
        plan = configurator._build_plan(self.__build_components(bigger),
                                        self.__core)
        self.assertEqual([], self.log)
        self.assertEqual([{
            'command': 'stop',
            'name': 'additional',
            'component': component
        }], plan)

        # We want to switch a component. So, prepare the configurator so it
        # holds one
        configurator._run_plan(configurator._build_plan(
             self.__build_components(self.__core), bigger))
        # Get a different configuration with a different component
        different = copy.copy(self.__core)
        different['another'] = {
            'special': 'test',
            'process': 'another',
            'kind': 'dispensable'
        }
        self.log = []
        plan = configurator._build_plan(self.__build_components(bigger),
                                        different)
        self.assertEqual([('another', 'init'), ('another', 'dispensable')],
                         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'])
        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)
        self.assertEqual('needed', component._kind)
        # We don't use isinstance on purpose, it would allow a descendant
        self.assertTrue(type(component) is Component)
        plan = configurator._build_plan({}, {
            'component': { 'kind': 'dispensable' }
        })
        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.assertIsNone(component._params)
        self.assertIsNone(component._address)
        self.assertEqual('dispensable', component._kind)
Exemple #12
0
    def test_run(self):
        """
        Passes some configuration to the startup method and sees if
        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, self.__specials)
        # Can't reconfigure nor stop yet
        self.assertRaises(ValueError, configurator.reconfigure, self.__core)
        self.assertRaises(ValueError, configurator.shutdown)
        self.assertFalse(configurator.running())
        # Start it
        configurator.startup(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[core],
                             configurator._components[core][0])
        self.assertEqual(set(self.__core), set(configurator._components))
        self.assertTrue(configurator.running())
        # 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.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[core],
                             configurator._components[core][0])
        self.assertEqual(set(self.__core), set(configurator._components))
        self.assertTrue(configurator.running())

        # Do a shutdown
        self.log = []
        configurator.shutdown()
        self.assertEqual({}, configurator._components)
        self.assertFalse(configurator.running())
        self.__check_shutdown_log()

        # It can't be stopped twice
        self.assertRaises(ValueError, configurator.shutdown)