def writeToXMLFile(self, fileName): '''Writes the current state of environment to a XML file. NOTE: There is no trace of actions taken, variables are written with a set action only. ''' writer = xmlModule.XMLFile() for varName in self.variables: if varName == '.': continue # this is an internal transient variable writer.writeVar( varName, 'set', self.variables[varName].value(True, self.separator)) writer.writeToFile(fileName)
def __init__(self, loadFromSystem=True, useAsWriter=False, searchPath=None): '''Initial variables to be pushed and setup append switch between append and prepend for initial variables. loadFromSystem causes variable`s system value to be loaded on first encounter. If useAsWriter == True than every change to variables is recorded to XML file. reportLevel sets the level of messaging. ''' self.log = logging.getLogger('Environment') self.separator = ':' # Prepeare the internal search path for xml files (used by 'include' # elements) if searchPath is None: self.searchPath = [] else: self.searchPath = list(searchPath) self.actions = {} self.actions['include'] = lambda n, c, h: self.loadXML( self._locate(n, c, h)) self.actions['append'] = lambda n, v, _: self.append(n, v) self.actions['prepend'] = lambda n, v, _: self.prepend(n, v) self.actions['set'] = lambda n, v, _: self.set(n, v) self.actions['unset'] = lambda n, v, _: self.unset(n, v) self.actions['default'] = lambda n, v, _: self.default(n, v) self.actions['remove'] = lambda n, v, _: self.remove(n, v) self.actions[ 'remove-regexp'] = lambda n, v, _: self.remove_regexp(n, v) self.actions['declare'] = self.declare self.actions['search_path'] = lambda n, _1, _2: self.searchPath.extend( n.split(self.separator)) self.variables = {} self.loadFromSystem = loadFromSystem self.asWriter = useAsWriter if useAsWriter: self.writer = xmlModule.XMLFile() self.startXMLinput() self.loadedFiles = set() # Prepare the stack for the directory of the loaded file(s) self._fileDirStack = [] # Note: cannot use self.declare() because we do not want to write out # the changes to ${.} dot = Variable.Scalar('.', local=True) dot.expandVars = False dot.set('') self.variables['.'] = dot
def testParsingError(self): fd, filename = mkstemp() f = os.fdopen(fd, 'w') f.write('''<?xml version="1.0" ?> <env:config xmlns:env="EnvSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="EnvSchema ./EnvSchema.xsd "> <env:set variable="error">invalid</env:default> </env:config>''') f.close() try: import logging stream = StringIO() hdlr = logging.StreamHandler(stream) logging.getLogger().addHandler(hdlr) loader = xmlModule.XMLFile() self.assertRaises(SystemExit, loader.variable, filename) self.assertTrue(('Failed to parse %s:' % filename) in stream.getvalue(), 'missing error message') finally: logging.getLogger().removeHandler(hdlr) os.remove(filename)
def loadXML(self, fileName=None, namespace='EnvSchema'): '''Loads XML file for input variables.''' XMLfile = xmlModule.XMLFile() fileName = self._locate(fileName) if fileName in self.loadedFiles: return # ignore recursion self.loadedFiles.add(fileName) dot = self.variables['.'] # push the previous value of ${.} onto the stack... self._fileDirStack.append(dot.value()) # ... and update the variable dot.set(os.path.dirname(fileName)) variables = XMLfile.variable(fileName, namespace=namespace) for i, (action, args) in enumerate(variables): if action not in self.actions: self.log.error('Node {0}: No action taken with var "{1}". Probably wrong action argument: "{2}".'.format( i, args[0], action)) else: self.actions[action](*args) # pylint: disable=W0142 # restore the old value of ${.} dot.set(self._fileDirStack.pop()) # ensure that a change of ${.} in the file is reverted when exiting it self.variables['.'] = dot
def testFileLoad(self): '''Test loading of previously written file.''' self.control = Control.Environment(useAsWriter = True) self.control.unset('varToUnset') self.control.declare('myVar', 'list', True) self.control.set('myVar', 'setVal:$local') self.control.append('myVar', 'appVal:appVal2') self.control.prepend('myVar', 'prepVal:prepVal2') self.control.declare('myScalar', 'scalar', False) self.control.set('myScalar', 'setValscal') self.control.append('myScalar', 'appValscal') self.control.prepend('myScalar', 'prepValscal') self.control.declare('myScalar2', 'scalar', True) self.control.finishXMLinput('testOutputFile.xml') loader = xmlModule.XMLFile() variables = loader.variable('testOutputFile.xml') expected = [('declare', ('varToUnset', 'list', 'false')), ('unset', ('varToUnset', '', None)), ('declare', ('myVar', 'list', 'true')), ('set', ('myVar', 'setVal:$local', None)), ('append', ('myVar', 'appVal:appVal2', None)), ('prepend', ('myVar', 'prepVal:prepVal2', None)), ('declare', ('myScalar', 'scalar', 'false')), ('set', ('myScalar', 'setValscal', None)), ('append', ('myScalar', 'appValscal', None)), ('prepend', ('myScalar', 'prepValscal', None)), ('declare', ('myScalar2', 'scalar', 'true'))] self.assertEqual(variables, expected) os.remove('testOutputFile.xml')
def testParsing(self): data = StringIO('''<?xml version="1.0" ?> <env:config xmlns:env="EnvSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="EnvSchema ./EnvSchema.xsd "> <env:declare local="false" type="list" variable="varToUnset"/> <env:unset variable="varToUnset"/> <env:declare local="true" type="list" variable="myVar"/> <env:set variable="myVar">setVal:$local</env:set> <env:append variable="myVar">appVal:appVal2</env:append> <env:prepend variable="myVar">prepVal:prepVal2</env:prepend> <env:declare local="false" type="scalar" variable="myScalar"/> <env:set variable="myScalar">setValscal</env:set> <env:append variable="myScalar">appValscal</env:append> <env:prepend variable="myScalar">prepValscal</env:prepend> <env:declare local="true" type="scalar" variable="myScalar2"/> <env:include>some_file.xml</env:include> <env:include hints="some:place">another_file.xml</env:include> </env:config>''') loader = xmlModule.XMLFile() variables = loader.variable(data) expected = [('declare', ('varToUnset', 'list', 'false')), ('unset', ('varToUnset', '', None)), ('declare', ('myVar', 'list', 'true')), ('set', ('myVar', 'setVal:$local', None)), ('append', ('myVar', 'appVal:appVal2', None)), ('prepend', ('myVar', 'prepVal:prepVal2', None)), ('declare', ('myScalar', 'scalar', 'false')), ('set', ('myScalar', 'setValscal', None)), ('append', ('myScalar', 'appValscal', None)), ('prepend', ('myScalar', 'prepValscal', None)), ('declare', ('myScalar2', 'scalar', 'true')), ('include', ('some_file.xml', None, '')), ('include', ('another_file.xml', None, 'some:place'))] self.assertEqual(variables, expected)
def searchFile(self, filename, varName): '''Searches for appearance of variable in a file.''' XMLFile = xmlModule.XMLFile() variable = XMLFile.variable(filename, name=varName) return variable