def reset(self): '''Reset values of attributes in order to perform multiple exec''' BaseEntity.reset(self) self.origin = False self._last_action = None for action in self._actions.values(): action.reset()
def test_resolve_property5(self): '''Test resolution with a property containing special characters''' service = BaseEntity('test_service') service.add_var('NODES', HOSTNAME) service.target = '%NODES' self.assertEqual(service.resolve_property('target'), NodeSet(HOSTNAME))
def reset(self): """Reset values of attributes in order to perform multiple exec""" BaseEntity.reset(self) self.origin = False self._last_action = None for action in self._actions.values(): action.reset()
def test_clear_deps(self): """Test method clear_deps""" ent = BaseEntity('foo') ent_dep = BaseEntity('parent') ent.add_dep(ent_dep) self.assertEqual(len(ent.parents), 1) ent.clear_deps() self.assertEqual(len(ent.parents), 0)
def test_has_child_dep(self): """Test method has_child_dep""" ent = BaseEntity('foo') ent_dep = BaseEntity('child') ent.children['child'] = Dependency(ent_dep) self.assertTrue(ent.has_child_dep('child')) del ent.children['child'] self.assertFalse(ent.has_child_dep('child'))
def test_resolve_2_command_substitutions(self): '''Test 2 command substitutions''' service = BaseEntity('test_service') service.add_var('EXCLUDED_NODES', 'foo') service.add_var('SELECTED_NODES', 'bar') expr = '%([ -n "%SELECTED_NODES" ] && echo "-n %SELECTED_NODES")' + \ ' %([ -n "%EXCLUDED_NODES" ] && echo "-x %EXCLUDED_NODES")' self.assertEqual(service._resolve(expr), '-n bar -x foo')
def test_remote(self): """Test the remote property""" ent1 = BaseEntity('father') self.assertTrue(ent1.remote) ent1.remote = False ent2 = BaseEntity('child') ent2.inherits_from(ent1) self.assertFalse(ent2.remote)
def test_is_strong_dependency(self): """Test the behaviour of is_strong method.""" dep_a = Dependency(BaseEntity("Base"), CHECK) dep_b = Dependency(BaseEntity("Base"), REQUIRE) dep_c = Dependency(BaseEntity("Base"), REQUIRE_WEAK) self.assertTrue(dep_a.is_strong()) self.assertTrue(dep_b.is_strong()) self.assertFalse(dep_c.is_strong())
def test_reset_entity(self): '''Test reset entity''' ent = BaseEntity(name='foo', target='fortoy5') ent.status = NO_STATUS ent.algo_reverse = True ent.reset() self.assertEqual(ent._algo_reversed, False) self.assertEqual(ent.status, NO_STATUS)
def test_has_parent_dep(self): """Test method has_parent_dep""" ent = BaseEntity('foo') ent_dep = BaseEntity('parent') ent.parents['parent'] = Dependency(ent_dep) self.assertTrue(ent.has_parent_dep('parent')) del ent.parents['parent'] self.assertFalse(ent.has_parent_dep('parent'))
def reset(self): ''' Reset values of attributes in order to used the action multiple time. ''' BaseEntity.reset(self) self.start_time = None self.stop_time = None self.worker = None self.tries = 0
def test_dependency_instanciation(self): """Test instanciation of a dependency.""" service = BaseEntity("PARENT") service = BaseEntity("CHILD") self.assertRaises(AssertionError, Dependency, None) self.assertRaises(AssertionError, Dependency, service, "TEST") self.assertTrue(Dependency(service)) self.assertTrue(Dependency(service, CHECK)) self.assertTrue(Dependency(service, CHECK, True))
def filter_nodes(self, nodes): """ Add error nodes to skip list. Nodes in this list will not be used when launching actions. """ BaseEntity.filter_nodes(self, nodes) for service in self._subservices.values(): service.filter_nodes(nodes)
def fromdict(self, grpdict): """Populate group attributes from dict.""" BaseEntity.fromdict(self, grpdict) if 'services' in grpdict: dep_mapping = {} # Wrap dependencies from YAML and build the service for names, props in grpdict['services'].items(): for subservice in NodeSet(names): # Parsing dependencies wrap = DepWrapper() for prop in ('require', 'require_weak', 'before', 'after', 'check'): if prop in props: if prop in ('before', 'after'): props['require_weak'] = props[prop] prop = 'require_weak' wrap.deps[prop] = props[prop] # Get subservices which might be Service or ServiceGroup service = None if 'services' in props: service = ServiceGroup(subservice) service.fromdict(props) else: service = Service(subservice) service.fromdict(props) # Link the group and its new subservice together self._subservices[subservice] = service service.parent = self wrap.source = service dep_mapping[subservice] = wrap # Generate dependency links of the service for wrap in dep_mapping.values(): # Not any dependencies so just attach for dtype in wrap.deps: for dep in wrap.deps[dtype]: if dep not in self._subservices: raise UnknownDependencyError(dep) wrap.source.add_dep(self._subservices[dep], sgth=dtype.upper()) # Bind subgraph to the service group for service in self.iter_subservices(): if not service.children: service.add_dep(self._source, parent=False) if not service.parents: service.add_dep(self._sink) for subser in self.iter_subservices(): subser.inherits_from(self)
def test_eval_deps_error(self): """Test that eval_deps_status return DEP_ERROR""" service = BaseEntity("test_service") serv_a = BaseEntity("A") serv_b = BaseEntity("B") service.add_dep(serv_a) service.add_dep(serv_b, CHECK) serv_b.status = DONE serv_a.status = TIMEOUT self.assertEqual(service.eval_deps_status(), DEP_ERROR)
def test_lookup_variables4(self): '''Test variables resolution with a var referencing a property''' service = BaseEntity('test_service') service.add_var('VAR', 'test') group = BaseEntity('group_service') group.add_var('GVAR', 'group') service.parent = group self.assertEqual(service._lookup_variable('GVAR'), 'group') self.assertEqual(service._lookup_variable('TARGET'), None) self.assertEqual(service._lookup_variable('NAME'), 'test_service')
def test_graph_dep_type(self): """Test the DOT output of a dependency type""" ent = BaseEntity("ENTITY") dep_c = Dependency(BaseEntity("Base"), CHECK) dep_r = Dependency(BaseEntity("Base"), REQUIRE) dep_rw = Dependency(BaseEntity("Base"), REQUIRE_WEAK) self.assertEqual(dep_c.graph(ent), '"ENTITY" -> "Base";\n') self.assertEqual(dep_r.graph(ent), '"ENTITY" -> "Base";\n') self.assertEqual(dep_rw.graph(ent), '"ENTITY" -> "Base" [style=dashed];\n')
def test_resolve_all_variables(self): """resolve_all() resolves variables only once""" entity = BaseEntity('entity') entity.add_var('foo', 'cool') entity.add_var('bar', '%foo') entity.add_var('baz', '%foo') entity.fromdict({'desc': 'New %bar'}) entity.resolve_all() self.assertEqual(entity.variables['foo'], entity.variables['bar']) self.assertEqual(entity.variables['foo'], entity.variables['baz']) self.assertEqual(entity.desc, 'New cool')
def test_excluded(self): """Test the excluded mecanism""" ent1 = BaseEntity('E1') ent2 = BaseEntity('E2') ent3 = BaseEntity('E3') ent3.add_dep(ent2) self.assertFalse(ent1.excluded()) self.assertTrue(ent1.excluded(["E1"])) self.assertTrue(ent3.excluded(["E2"]))
def test_reverse_mod(self): """Test enable reverse mod over a bunch of entity""" ent1 = BaseEntity('foo') ent2 = BaseEntity('bar') manager = entity_manager_self() manager.entities['foo'] = ent1 manager.entities['bar'] = ent2 self.assertRaises(AssertionError, manager._reverse_mod, None) manager._reverse_mod(True) self.assertTrue(ent1._algo_reversed and ent2._algo_reversed) self.assertFalse(not ent1._algo_reversed and not ent2._algo_reversed)
def test_tags(self): """Test tags property""" ent1 = BaseEntity(name='parent') self.assertEqual(ent1.tags, set()) ent1.tags.add('foo') ent2 = BaseEntity(name='child') ent2.inherits_from(ent1) self.assertEqual(ent2.tags, set(['foo'])) ent2.tags = set(['bar']) self.assertEqual(ent2.tags, set(['bar']))
def test_search_node_graph(self): """Test the research of a node through a graph""" ent1 = BaseEntity('E1') ent2 = BaseEntity('E2') ent3 = BaseEntity('E3') ent4 = BaseEntity('E4') ent1.add_dep(ent2) ent1.add_dep(ent3) ent2.add_dep(ent4) ent3.add_dep(ent4) self.assertTrue(ent1.search('E3') is ent3) self.assertTrue(ent1.search('E5') is None)
def test_lookup_variables2(self): '''Test variables resolution through multiple entities''' service = BaseEntity('test_service') service.add_var('VAR', 'test') group = BaseEntity('group_service') group.add_var('GVAR', 'group') service.parent = group self.assertEqual(service._lookup_variable('VAR'), 'test') self.assertEqual(service._lookup_variable('GVAR'), 'group')
def test_lookup_variables3(self): '''Test variables resolution with an undefined var''' service = BaseEntity('test_service') service.add_var('VAR', 'test') group = BaseEntity('group_service') group.add_var('GVAR', 'group') service.parent = group self.assertRaises(UndefinedVariableError, service._lookup_variable, 'BAD_VAR')
def test_fullname(self): '''Test that the property return the fullname of the current entity''' ent1 = BaseEntity('alpha') self.assertEqual(ent1.fullname(), ent1.name) ent2 = BaseEntity('beta') ent3 = BaseEntity('gamma') ent2.parent = ent3 ent1.parent = ent2 self.assertEqual(ent1.fullname(), 'gamma.beta.alpha')
def __init__(self, name, target=None): BaseEntity.__init__(self, name, target) # Define a flag allowing us to specify that this service is the # original caller so we do not have to start his children. self.origin = False # Used for ghost services or services that you do not want to execute. self.simulate = False # Actions of the service self._actions = {} self._last_action = None
def test_clear_parents(self): '''Test remove all parents dependencies''' ent1 = BaseEntity(name='A') ent2 = BaseEntity(name='B') ent3 = BaseEntity(name='C') ent1.add_dep(target=ent2) ent1.add_dep(target=ent3) ent1.clear_parent_deps() self.assertFalse(ent1.has_parent_dep('B')) self.assertFalse(ent1.has_parent_dep('C'))
def test_clear_childs(self): '''Test remove all childrens dependencies''' ent1 = BaseEntity(name='A') ent2 = BaseEntity(name='B') ent3 = BaseEntity(name='C') ent1.add_dep(target=ent2, parent=False) ent1.add_dep(target=ent3, parent=False) ent1.clear_child_deps() self.assertFalse(ent1.has_child_dep('B')) self.assertFalse(ent1.has_child_dep('C'))
def test_add_dep_children(self): """Test method add_dep for children""" ent = BaseEntity('foo') ent_dep = BaseEntity('child') ent.add_dep(target=ent_dep, parent=False) self.assertTrue(ent.has_child_dep('child')) self.assertTrue(ent_dep.has_parent_dep('foo'))
def test_add_dep_parents(self): """Test method add dependency for parents""" ent = BaseEntity('foo') ent_dep = BaseEntity('parent') ent.add_dep(ent_dep) self.assertTrue(ent.has_parent_dep('parent')) self.assertTrue(ent_dep.has_child_dep('foo'))
def test_instanciation_base_entity(self): """Test BaseEntity object instanciation.""" ent = BaseEntity('foo') self.assertTrue(ent) self.assertTrue(isinstance(ent, BaseEntity)) self.assertEqual(ent.name, 'foo') ent = BaseEntity(name='foo', target='fortoy5') self.assertTrue('fortoy5' in ent.target) ent = BaseEntity(name='foo', target=NodeSet('fortoy[8-15]')) self.assertTrue(NodeSet('fortoy[8-15]') == ent.target) self.assertRaises(NodeSetException, BaseEntity, name='foo', target='[fortoy]') self.assertEqual(ent.tags, set())
def test_longname(self): """ """ # No dep, no desc ent1 = BaseEntity('alpha') self.assertEqual(ent1.longname(), "alpha") # Desc, no dep ent1.desc = "small description" self.assertEqual(ent1.longname(), "alpha - small description") # Desc and dep ent2 = BaseEntity('beta') ent2.desc = "another description" ent2.parent = ent1 self.assertEqual(ent2.longname(), "alpha.beta - another description")
def test_inheritance_of_properties1(self): '''Test inheritance between entities''' ent1 = BaseEntity(name='parent', target='aury[10-16]') ent1.fanout = 5 ent1.errors = 2 ent1.timeout = 15 ent2 = BaseEntity(name='child') ent2.inherits_from(ent1) self.assertEqual(ent2.target, NodeSet('aury[10-16]')) self.assertEqual(ent2.fanout, 5) self.assertEqual(ent2.errors, 2) self.assertEqual(ent2.timeout, 15)
def test_instanciation(self): """test on the instanciation of a manager""" manager = entity_manager_self() manager.entities['foo'] = BaseEntity('foo') same_manager = entity_manager_self() self.assertTrue(manager is same_manager) self.assertEqual(len(same_manager.entities), 1)
def test_update_target(self): '''Test update of the target of an entity''' ent = BaseEntity(name='foo', target='fortoy[5-10]') ent.update_target(NodeSet('fortoy[5-8]')) self.assertTrue(ent.target == NodeSet('fortoy[5-8]')) ent.update_target('fortoy[4-6]', mode='DIF') self.assertTrue(ent.target == NodeSet('fortoy[7-8]')) ent.update_target('fortoy8', mode='INT') self.assertTrue(ent.target == NodeSet('fortoy8'))
def test_eval_deps_waiting(self): """Test that eval_deps_status return WAITING_STATUS""" service = BaseEntity("test_service") serv_a = BaseEntity("A") serv_b = BaseEntity("B") service.add_dep(serv_a) service.add_dep(serv_b, CHECK) serv_a.status = WAITING_STATUS self.assertEqual(service.eval_deps_status(), WAITING_STATUS)
def test_remove_variable(self): '''Remove a variable, defined or not, is fine.''' svc = BaseEntity('test_var') svc.add_var('var', 'foo') self.assertEqual(svc._lookup_variable('var'), 'foo') # Remove it svc.remove_var('var') self.assertRaises(UndefinedVariableError, svc._lookup_variable, 'var') # Remove it again does not raise an exception. svc.remove_var('var') self.assertRaises(UndefinedVariableError, svc._lookup_variable, 'var')
def test_add_reserved_var(self): """ Test if reserved local variable can not be overriden """ entity = BaseEntity(name='E1') for name in entity.LOCAL_VARIABLES: self.assertRaises(VariableAlreadyExistError, entity.add_var, varname=name, value='foo')
def test_remove_dep(self): """Test method remove_dep.""" ent = BaseEntity('foo') ent_dep = BaseEntity('child') ent.children['child'] = Dependency(ent_dep) ent_dep.parents['foo'] = Dependency(ent) ent.remove_dep('child', parent=False) self.assertTrue('child' not in ent.children) self.assertTrue('foo' not in ent.parents) self.assertRaises(AssertionError, ent.remove_dep, None)
def test_resolve_property1(self): '''Test replacement of symbols within a property''' service = BaseEntity('test_service') service.add_var('NODES', 'localhost,127.0.0.1') service.desc = 'start %NAME on %TARGET' service.target = '%NODES' self.assertEqual(service.resolve_property('target'), NodeSet('localhost,127.0.0.1')) self.assertEqual(service.resolve_property('name'), 'test_service') self.assertEqual(service.resolve_property('desc'), 'start test_service on 127.0.0.1,localhost')
def test_inheritance_of_non_existing_target(self): ''' Test inheritance between entities with non-existing target/description ''' ent1 = BaseEntity(name='parent') ent1.desc = "foo" ent2 = BaseEntity(name='child', target="@none") ent2.desc = "" ent2.inherits_from(ent1) self.assertEqual(ent2.target, NodeSet()) self.assertEqual(ent2.desc, "")
def test_graph(self): """Test the DOT output of a dependency""" p_service = BaseEntity("PARENT") c_service = BaseEntity("CHILD") dep = Dependency(c_service, REQUIRE) #self.assertEqual(dep.graph(p_service), '"CHILD" -> "PARENT";\n') self.assertEqual(dep.graph(p_service), '"PARENT" -> "CHILD";\n') p_group = ServiceGroup('P_Group') c_group = ServiceGroup('C_Group') p_dep = Dependency(p_group) c_dep = Dependency(c_group) self.assertEqual( c_dep.graph(p_group), '"P_Group.__hook" -> "C_Group.__hook" ' '[ltail="cluster_P_Group",lhead="cluster_C_Group"];\n') self.assertEqual( c_dep.graph(p_service), '"PARENT" -> "C_Group.__hook" ' '[lhead="cluster_C_Group"];\n') self.assertEqual( dep.graph(p_group), '"P_Group.__hook" -> "CHILD" ' '[ltail="cluster_P_Group"];\n')
def test_inheritance_of_properties2(self): ''' Test inheritance between entities but some properties are not inherited ''' ent1 = BaseEntity(name='parent', target='aury[10-16]') ent1.fanout = 5 ent1.errors = 2 ent2 = BaseEntity(name='child') ent2.fanout = 2 ent2.errors = 3 ent2.timeout = 15 ent2.inherits_from(ent1) self.assertEqual(ent2.target, NodeSet('aury[10-16]')) self.assertEqual(ent2.fanout, 2) self.assertEqual(ent2.errors, 3) self.assertEqual(ent2.timeout, 15)
def __init__(self, name, target=None, command=None, timeout=-1, delay=0): BaseEntity.__init__(self, name=name, target=target, delay=delay) # Action's timeout in seconds/milliseconds self.timeout = timeout # Number of action tries self.tries = 0 # Command lines that we would like to run self.command = command # Results and retcodes self.worker = None # Allow us to determine time used by an action within the master task self.start_time = None self.stop_time = None # Store pending targets self.pending_target = NodeSet()
def test_add_dep_bad_cases(self): """Test bad usage of the method add_dep""" ent = BaseEntity('foo') ent_dep = BaseEntity('child') ent.add_dep(ent_dep, CHECK) # Dependency with a None Service self.assertRaises(AssertionError, ent.add_dep, None) # Dependency with bad name identifier self.assertRaises(IllegalDependencyTypeError, ent.add_dep, BaseEntity('A'), 'BAD') #Already referenced dependency r_ent = BaseEntity('child') self.assertRaises(DependencyAlreadyReferenced, ent.add_dep, r_ent) #Same with reversed dependency ent.add_dep(ent_dep, CHECK, parent=False) self.assertRaises(DependencyAlreadyReferenced, ent.add_dep, r_ent, parent=False)