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())
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'} })
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})
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)
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)
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)