def _shutdown(self, *args): """ Teardown all components and a graceful shutdown """ with self.shutdownLock: if self.closed: return self.closed = True self.logger.info('Shutdown called') processes = [] peers = self.peers.values() if hasattr(self, 'peers') else [] for peer in peers: processes += peer.shutdown() while any( process.is_alive() for process in processes if process ): time.sleep(1) if hasattr(self, 'httpServer'): os.killpg(self.httpServer.pid, signal.SIGTERM) for component in ['udpServer', 'resultWorker']: if not hasattr(self, component): continue getattr(self, component).shutdown() ConfigurationManager.destroySingleton() if os.path.exists(self.tmpDir): shutil.rmtree(self.tmpDir) os._exit(0)
def __init__(self): ''' @param filterName: the name of the filter XML configuration ''' self.attr = '' self.direction = self.FilterDirection.INCLUDE self.values = [] self.configurationManager = ConfigurationManager() self.config = self.configurationManager.getConfiguration('filters') self.__filterString = ""
def __init__(self): ''' @param filterName: The name of the filter XML configuration ''' self.configurationManager = ConfigurationManager() self.config = self.configurationManager.getConfiguration('filters') self.__filterString = "" if not hasattr(self.config.getConfiguration(), 'PriorityFilter'): self.enabled = False return self.priorityFilterCfg = self.config.getConfiguration().PriorityFilter if self.priorityFilterCfg.enabled != "true": self.enabled = False else: self.enabled = True
def __init__(self, output = sys.stdout): self.output = output self.configLoc = None self.monitor = False if '--monitor' in sys.argv: self.monitor = True return if '--config' in sys.argv: index = sys.argv.index('--config') + 1 self.configLoc = sys.argv[index] del sys.argv[index] del sys.argv[index - 1] self.configManager = ConfigurationManager(self.configLoc)
class TestFilter(object): ''' Test filter performs the filtering of the tests in the groups It may leave the specified tests in the list or exclude those from the list depending on the direction specified ''' TEST_FILTER_CONFIG_ATTR = 'TestFilter' CONFIG_DIRECTION_EXCLUDE = 'exclude' CONFIG_ENABLED_FALSE = 'false' class FilterDirection(object): ''' The enumeration class, which specifies the direction of the filtering. EXCLUDE defines that the tests which contain filtering values will be removed from the test list. INCLUDE value defines that only tests which contain filtering values will be left in the test list ''' EXCLUDE = False INCLUDE = True def __init__(self): ''' @param filterName: the name of the filter XML configuration ''' self.attr = '' self.direction = self.FilterDirection.INCLUDE self.values = [] self.configurationManager = ConfigurationManager() self.config = self.configurationManager.getConfiguration('filters') self.__filterString = "" def filterTests(self, source): ''' Filters the tests in the source object. @param source: the source object @return: the source object with filtered test list ''' if not hasattr(self.config.getConfiguration(), self.TEST_FILTER_CONFIG_ATTR): return source for testFilter in self.config.getConfiguration().TestFilter: if testFilter.enabled == self.CONFIG_ENABLED_FALSE: continue if not hasattr(testFilter.values, 'value'): continue self.attr = testFilter.parameter.PCDATA direct = testFilter.direction.PCDATA self.__filterString += "Filter: %s, Direction: %s, Values:" % (self.attr, direct) self.values = [] if direct == self.CONFIG_DIRECTION_EXCLUDE: self.direction = self.FilterDirection.EXCLUDE else: self.direction = self.FilterDirection.INCLUDE self.globalFilter = self.__matchesLiteral if hasattr(testFilter.values, 'type') and \ testFilter.values.type == 'regex': self.globalFilter = self.__matchesRegex for val in testFilter.values.value: self.__filterString += " %s" % (val.PCDATA) self.values.append(val) self.__filterString += "\n" for group in source.groups: group.tests = filter(self.__filterContent, group.tests) return source def isEnabled(self): if not hasattr(self.config.getConfiguration(), self.TEST_FILTER_CONFIG_ATTR): return False for testFilter in self.config.getConfiguration().TestFilter: if testFilter.enabled == 'true': return True return False def __filterContent(self, test): """ Filter content based on the values """ matches = [] for value in self.values: matches.append(self.__getResult(value, test)) if True in matches: return self.direction return not self.direction def __getResult(self, value, test): """ Test if a test attribute matches a value """ content = getattr(test, self.attr, "") if hasattr(value, 'type'): # Use the value filter type return self.__getFilter(value.type)(value, test, content) return self.globalFilter(value, test, content) def __getFilter(self, name): """ Get the filter by name """ if name == 'regex': return self.__matchesRegex return self.__matchesLiteral def __matchesLiteral(self, value, test, content): ''' Method is used for filter() function @return: True or False depending on whether the test attribute value is in the configured value list ''' return str(content) == str(value.PCDATA) def __matchesRegex(self, value, test, content): """ Matches the value against a regex pattern """ if re.match(str(value.PCDATA), str(content)): return True return False def getAppliedFilterDescription(self): return self.__filterString
class PriorityFilter(object): ''' Priority filter performs the division of list of tests into priority groups, or a simple sorting ''' class PriorityDirection(object): ''' Enumeration class which defines the direction of sorting ''' DESCENDING = 1 ASCENDING = 0 def __init__(self): ''' @param filterName: The name of the filter XML configuration ''' self.configurationManager = ConfigurationManager() self.config = self.configurationManager.getConfiguration('filters') self.__filterString = "" if not hasattr(self.config.getConfiguration(), 'PriorityFilter'): self.enabled = False return self.priorityFilterCfg = self.config.getConfiguration().PriorityFilter if self.priorityFilterCfg.enabled != "true": self.enabled = False else: self.enabled = True def filterTests(self, source): ''' If the values of priority are specified in the configuration, then the method divides the default group into priority groups according to specified values. If the values are not specified, then the method performs sorting of the existing groups @param source: the source object @return the modified source object with applied priority ''' if not self.enabled: return source self.__filterString = self.__createDescription(self.priorityFilterCfg) self.attr = self.priorityFilterCfg.parameter.PCDATA self.__sort(source, self.attr, self.priorityFilterCfg.direction.PCDATA) if hasattr(self.priorityFilterCfg.values, 'value'): self.__group(source, self.attr, self.priorityFilterCfg.values) return source def isEnabled(self): return self.enabled def __createDescription(self, priorityFilterCfg): direct = priorityFilterCfg.direction.PCDATA attr = priorityFilterCfg.parameter.PCDATA descBuffer = StringIO() descBuffer.write('Priority Filter: %s, Direction: %s' % (attr, direct)) if not hasattr(priorityFilterCfg.values, 'value'): result = "%s\n" % descBuffer.getvalue() descBuffer.close() return result descBuffer.write(', Values:') for val in priorityFilterCfg.values.value: descBuffer.write(' ') descBuffer.write(val.PCDATA) descBuffer.write("\n") result = descBuffer.getvalue() descBuffer.close() return result def __group(self, source, attr, valuesNode): ''' Performs the grouping of the tests by priority. If more than one group exists, then no modifications applied @param groups: the list of source groups (expected 1 default group) @param attr: the attribute by which divide into priorities @param values: the list of values, of priorities ''' defGroup = source.groups[0] if len(source.groups) != 1 or defGroup.name != 'DefaultGroup': return defaultFilter = self.__literalFilter if hasattr(valuesNode, 'type') and valuesNode.type == 'regex': defaultFilter = self.__regexFilter values = valuesNode.value if not isinstance(values, list): values = [values] for value in values: tests = self.__filterTests(value, defGroup, attr, defaultFilter) if len(tests) == 0: continue newGroup = Group(value, '%s priority group' % attr) newGroup.tests = tests source.groups.insert(0, newGroup) if len(defGroup.tests) == 0: source.groups.remove(defGroup) def __filterTests(self, value, defaultGroup, attr, defaultFilter): tests = [] for test in defaultGroup.tests[:]: content = getattr(test, attr, '') if hasattr(value, 'type'): result = self.__getFilter(value.type)(value.PCDATA, content) else: result = defaultFilter(value.PCDATA, content) if not result: continue tests.append(test) defaultGroup.removeTest(test) return tests def __getFilter(self, name): if name != 'regex': return self.__literalFilter return self.__regexFilter def __literalFilter(self, value, content): return value == content def __regexFilter(self, value, content): return re.match(value, content) != None def __sort(self, source, attr, direction): ''' Performs the sorting of the tests in the group. Method is used when no priority values are specified. @param tests: the list of tests in the group @param attr: the attribute by which the sorting should be applied @param direction: ascending or descending direction @return: the sorted list of tests ''' if direction != 'ascending': direction = self.PriorityDirection.DESCENDING else: direction = self.PriorityDirection.ASCENDING for group in source.groups: tests = sorted(group.tests, key = lambda test: getattr(test, attr, None), reverse = direction) group.tests = tests def getAppliedFilterDescription(self): return self.__filterString
class ArgumentParser(object): def __init__(self, output = sys.stdout): self.output = output self.configLoc = None self.monitor = False if '--monitor' in sys.argv: self.monitor = True return if '--config' in sys.argv: index = sys.argv.index('--config') + 1 self.configLoc = sys.argv[index] del sys.argv[index] del sys.argv[index - 1] self.configManager = ConfigurationManager(self.configLoc) def parse_args(self): configs = self.configManager.configurationNames() configs = [ self.configManager.getConfiguration(n) for n in configs ] parser = argparse.ArgumentParser() for config in configs: paths = self._process_path(config.configuration) for ns, value in paths or []: parser.add_argument('--%s' % ns) parser.add_argument('--config', '-c', help ='Configuration directory location') parser.add_argument('--monitor', '-m', help = 'Monitor UDP broadcasts for slave heartbeats', action="store_true") for key, value in vars(parser.parse_args()).items(): if value == None or key == 'monitor': continue xml_name, path_parts = key.split('.', 1) path_parts = path_parts.split('.') config = self.configManager.getConfiguration(xml_name) self.__processOverride(config.configuration, path_parts, value) self.configManager.revalidateXMLs() def _process_path(self, root_conf, namespace = None): if isinstance(root_conf, unicode): return [(namespace, str(root_conf))] elif not namespace: namespace = root_conf.__class__.__name__[4:] # Gather objects to process objs = [ (name, getattr(root_conf, name)) for name in dir(root_conf) if self._filter_objs(root_conf, name) ] if len(objs) == 0: return results = [] for name, obj in objs: # Update namespace and iterate nm = "%s.%s" % (namespace, name) if name != "PCDATA" else namespace results += self._process_path(obj, nm) or [] return results def _filter_objs(self, root_conf, name): obj = getattr(root_conf, name) if '_' in (name[0], name[-1]): return False elif name.startswith('xmlns') or name.startswith('xsi'): return False if name == "parent": return False isCorrectType = isinstance(obj, _XO_) or isinstance(obj, unicode) return isCorrectType def __processOverride(self, root, path, value): element_name = path.pop(0) new_root = getattr(root, element_name, None) if not new_root: raise Exception("Invalid configuration") elif len(path) > 0: return self.__processOverride(new_root, path, value) value = unicode(value) if isinstance(new_root, _XO_): setattr(root, 'PCDATA', value) elif isinstance(new_root, unicode): setattr(root, element_name, value) else: raise Exception("Invalid configuration")