From 32afefafced6dd2a3aefd0a7c4b73ee58bd3c4af Mon Sep 17 00:00:00 2001 From: Christian Van Wambeke Date: Tue, 22 May 2018 16:49:02 +0200 Subject: [PATCH] fix linksXml.py --- data/local.pyconf | 7 +- src/configManager.py | 4 +- src/linksXml.py | 141 ++++++++++++++++++++++++++++++++++++++ src/loggingSat.py | 24 +++++-- src/salomeTools.py | 20 ++++-- test/test_019_linksXml.py | 93 +++++++++++++++++++++++++ 6 files changed, 274 insertions(+), 15 deletions(-) create mode 100755 src/linksXml.py create mode 100755 test/test_019_linksXml.py diff --git a/data/local.pyconf b/data/local.pyconf index c91da53..e62c609 100644 --- a/data/local.pyconf +++ b/data/local.pyconf @@ -12,7 +12,10 @@ { project_file_paths : [ - "/home/christian/SAT_SALOME/salome.pyconf" - "/home/christian/SAT_MATIX/matix.pyconf" + "/volatile/wambeke/SAT5/SAT5_S840_MATIX24/SAT_SALOME/salome.pyconf", + # "/home/uranietm/proJET/saTJOBS/saT5/uranie.pyconf", + # cloned 2017/12 for matix + # "/home/matix/GitRepo/uranie/saT5/uranie.pyconf", + # "/volatile/wambeke/SAT5/SAT_MATIX/matix.pyconf" ] } diff --git a/src/configManager.py b/src/configManager.py index 4cb62ee..0f3967d 100644 --- a/src/configManager.py +++ b/src/configManager.py @@ -696,7 +696,7 @@ def getStrConfigValue(config, path, show_label=False, level=0, show_full_path=Fa outStream = DBG.OutStream() getConfigColored(config, path, outStream, show_label, level, show_full_path) res = outStream.getvalue() # stream not closed - return res + return res[:-1] def getStrConfigDebug(config, aPath, show_label=False, level=0, show_full_path=False): @@ -719,7 +719,7 @@ def getStrConfigDebug(config, aPath, show_label=False, level=0, show_full_path=F outStream = DBG.OutStream() DBG.saveConfigDbg(val, outStream, path=path) res = outStream.value - return res + return res[:-1] def get_config_children(config, args): diff --git a/src/linksXml.py b/src/linksXml.py new file mode 100755 index 0000000..f567208 --- /dev/null +++ b/src/linksXml.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- + +# Copyright (C) 2010-2013 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +""" +Contains LinkXml class to store logger tree structure of +main command calls sequence of microcommand(s) +which calls other sequence of microcommand(s) etc. +command(s) are identified (and their logger handler(s)) +by '_idCommandHandlers' attribute +""" + +import pprint as PP + +class LinkXml(object): + """ + class to store logger tree structure of + main command calls sequence of microcommand(s) + which calls other sequence of microcommand(s) etc. + Before and during and after execution of theses commands + permits storing information(s) for final writing file(s) logs xml + """ + # authorized attributes for setAttribLinksForCommand() + _authAttrib = "log_file_name cmd_name cmd_res full_launched_cmd".split(" ") + + def __init__(self, idName): + """Initialization + + :param idName: (int) The id as idCmdHandler + for original/root node is set to -1 + """ + self.reset(idName) + + def reset(self, idName=None): + # after execution of command info to set (as cmd result) + self.idName = idName + self.log_file_name = None + self.cmd_name = None + self.cmd_res = None + self.full_launched_cmd = None + # future could add more informations attributes here... + self._linksXml = [] # empty list of linkXml for micro commands + + def __repr__(self): + aDict = { + "idName": self.idName, + "log_file_name": self.log_file_name, + "full_launched_cmd": self.full_launched_cmd, + "self.cmd_res": self.cmd_res, + "links": self._linksXml, + } + tmp = PP.pformat(aDict) + res = "LinkXml(%s)" % tmp[1:-1] + return res + + def findLink(self, idName): + if self.idName == idName: + return self + else: + for i in self._linksXml: + res = i.findLink(idName) + if res is not None: + return res + return None + + def appendLink(self, idName): + import src.debug as DBG + if self.findLink(idName) is not None: + msg = "appendLink: idname '%s' existing yet" % idName + DBG.write(msg, self, True) + raise Exception(msg) + app = LinkXml(idName) + self._linksXml.append(app) + return app + + def getAllIdNames(self): + """recursive trip for sequence xml""" + res = [self.idName] + for i in self._linksXml: + res.extend(i.getAllIdNames()) + return res + + def setAuthAttr(self, nameAttrib, value): + if nameAttrib in self._authAttrib: + self.__setattr__(nameAttrib, value) # without precaution + else: + msg = "setAuthAttr %s attribute not authorized" % nameAttrib + raise Exception(msg) + + +##################################################### +# module methods and singleton +##################################################### + +_LinkXml = LinkXml(-1) # singleton instance root -1 + +def getLinksXml(): + """get singleton instance for everywhere easy access""" + return _LinkXml + +def resetLinksXml(): + """reset singleton instance for everywhere easy access""" + _LinkXml.reset(-1) # singleton instance root -1 + +def appendLinkForCommand(cmdParent, cmdNew): + """init a new link for a new command in singleton tree""" + k0 = getLinksXml() # get singleton + idParent = cmdParent.getId() + idNew = cmdNew.getId() + kParent = k0.findLink(idParent) + if kParent is None: + msg = "cmdParent id %i not found" % idParent + raise Exception(msg) + import src.debug as DBG + kNew = kParent.appendLink(idNew) + DBG.write("appendLinkForCommand %i for parent %i" % (idNew, idParent), k0, True) + return kNew + +def setAttribLinkForCommand(cmd, nameAttrib, value): + """init an attribute value in link of a command in singleton tree""" + k0 = getLinksXml() # get singleton + idCmd = cmd.getId() + kCmd = k0.findLink(idCmd) + k0.setAuthAttr(nameAttrib, value) + + diff --git a/src/loggingSat.py b/src/loggingSat.py index 8388846..360ccd9 100755 --- a/src/loggingSat.py +++ b/src/loggingSat.py @@ -262,7 +262,7 @@ class LoggerSat(LOGI.Logger): return 0 return level >= self.getEffectiveLevel() - def setFileHandlerForCommand(self, cmdInstance): + def setFileHandlerForCommand(self, cmdParent, cmdInstance): """ add file handler to logger to set log files for a salometools command. @@ -372,6 +372,10 @@ class LoggerSat(LOGI.Logger): logger.addHandler(handler) cmdInstance.setIdCommandHandlers(self.idCommandHandlers) + newLink = self.initLinkForCommand(cmdParent, cmdInstance) + newLink.setAuthAttr("cmd_name", cmd) + newLink.setAuthAttr("log_file_name", nameFileXml) + self.idCommandHandlers += 1 log("setFileHandler %s" % logger) return self.idCommandHandlers @@ -390,6 +394,11 @@ class LoggerSat(LOGI.Logger): self.warning("Existing logger handler without idCommandHandlers attribute %s" % str(handl)) pass + def initLinkForCommand(self, cmdParent, cmdNew): + import src.linksXml as LIXML + newLink = LIXML.appendLinkForCommand(cmdParent, cmdNew) + return newLink + def testNoReturn(self): """test when message ending '...' and level info then no return mode""" testNoReturn(self) # module method @@ -711,7 +720,8 @@ class XmlHandler(BufferingHandler): def initLoggerAsDefault(logger, fmt=None, level=None): """ init logger as prefixed message and indented message if multi line - exept info() outed 'as it' without any format + exept info() outed 'as it' without any format. + level could be modified during execution """ log("initLoggerAsDefault name=%s\nfmt='%s' level='%s'" % (logger.name, fmt, level)) handler = StreamHandlerSat(sys.stdout) # Logging vers console @@ -722,10 +732,12 @@ def initLoggerAsDefault(logger, fmt=None, level=None): handler.setFormatter(formatter) handler.idCommandHandlers = 0 logger.addHandler(handler) - if level is not None: + if level is not None: # level could be modified during execution.... logger.setLevel(level) + handler.setLevel(level) # on screen log as user wants else: - logger.setLevel(logger.INFO) + logger.setLevel(LOGI.STEP) # in xml files log step + handler.setLevel(LOGI.INFO) # on screen no log step, which are in xml files def initLoggerAsUnittest(logger, fmt=None, level=None): @@ -750,7 +762,7 @@ def initLoggerAsUnittest(logger, fmt=None, level=None): if level is not None: logger.setLevel(level) else: - logger.setLevel(logger.DEBUG) + logger.setLevel(LOGI.DEBUG) def getDefaultLogger(): @@ -845,5 +857,5 @@ else: # get two LoggerSat instance used in salomeTools, no more needed. _loggerDefault = getDefaultLogger() _loggerUnittest = getUnittestLogger() - initLoggerAsDefault(_loggerDefault, '%(levelname)s :: %(message)s', level=LOGI.INFO) + initLoggerAsDefault(_loggerDefault, '%(levelname)s :: %(message)s') initLoggerAsUnittest(_loggerUnittest, '%(asctime)s :: %(levelname)s :: %(message)s', level=LOGI.DEBUG) diff --git a/src/salomeTools.py b/src/salomeTools.py index 831a882..3f7897c 100755 --- a/src/salomeTools.py +++ b/src/salomeTools.py @@ -190,6 +190,10 @@ class _BaseCommand(object): raise Exception("type parent full name unexpected '%s'" % parentFullName) self._fullName = pfn + [self.name] # make copy precaution DBG.write("initFullName", self._fullName) + + def getId(self): + """assimiled as integer incremented on _idCommandHandlers""" + return self._idCommandHandlers def getFullNameStr(self): """returns 'prepare_clean' when micro command 'clean' of 'prepare'""" @@ -235,7 +239,7 @@ class _BaseCommand(object): cmdInstance.setConfig(config) # micro command config cmdInstance.setOptions(options) - logger.setFileHandlerForCommand(cmdInstance) + logger.setFileHandlerForCommand(self, cmdInstance) return cmdInstance def run(self, cmd_arguments): @@ -427,10 +431,14 @@ class Sat(object): res = "Sat(\n %s\n)\n" % tmp[1:-1] return res + def getId(self): + """assimiled as integer incremented on _idCommandHandlers""" + return -1 # assimiled as root of main first command + def getLogger(self): if self.logger is None: # could use owner Sat instance logger import src.loggingSat as LOG - self.logger=LOG.getDefaultLogger() + self.logger = LOG.getDefaultLogger() self.logger.critical("Sat logger not set, unexpected situation, fixed as default") return self.logger else: # could use local logger @@ -553,7 +561,7 @@ class Sat(object): cmdInstance.setConfig(config) logger = self.getLogger() - logger.setFileHandlerForCommand(cmdInstance) + logger.setFileHandlerForCommand(self, cmdInstance) # Run the main command using the remainders command arguments strArgs = " ".join(commandArguments) @@ -563,6 +571,10 @@ class Sat(object): msg = "END main launch command %s on (%s)\n%s" % (self.nameCommandToLoad, strArgs, str(returnCode)) logger.step(msg) + import src.linksXml as LKXML + LKXML.setAttribLinkForCommand(cmdInstance, "full_launched_cmd", cmdInstance.getLastRunArgs()) + LKXML.setAttribLinkForCommand(cmdInstance, "cmd_res", returnCode.toXml()) + logger.closeFileHandlerForCommand(cmdInstance) return returnCode @@ -643,7 +655,5 @@ class Sat(object): self.getLogger().info(msg) self.getLogger().info("YES (as automatic answer)") return "YES" - - diff --git a/test/test_019_linksXml.py b/test/test_019_linksXml.py new file mode 100755 index 0000000..b88017b --- /dev/null +++ b/test/test_019_linksXml.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- + +# Copyright (C) 2010-2018 CEA/DEN +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import os +import sys +import unittest + +import initializeTest # set PATH etc for test +import src.debug as DBG # Easy print stderr (for DEBUG only) + +import src.linksXml as LIXML + +class TestCase(unittest.TestCase): + "Test the debug.py""" + + def test_000(self): + # one shot setUp() for this TestCase + DBG.push_debug(True) + # SAT.setNotLocale() # test english + return + + def test_999(self): + # one shot tearDown() for this TestCase + # SAT.setLocale() # end test english + DBG.pop_debug() + return + + def test_005(self): + k0 = LIXML.getLinksXml() # get singleton + DBG.write("LinkXml k1 singleton", k0) + self.assertEqual(k0.findLink(-1), k0) + self.assertEqual(k0.findLink(1), None) + k0.appendLink(1) + self.assertEqual(k0.findLink(-1), k0) + self.assertEqual(k0.findLink(1).idName, 1) + DBG.write("LinkXml k0 singleton", k0) + + LIXML.resetLinksXml() + k00 = LIXML.getLinksXml() # get new singleton + self.assertEqual(id(k0), id(k00)) + self.assertEqual(k0, k00) + DBG.write("LinkXml k00 singleton", k00) + + self.assertEqual(k00.findLink(1), None) + k00.appendLink(0) + k00.appendLink(1) + self.assertEqual(k00.findLink(-1), k00) + self.assertEqual(k00.findLink(0).idName, 0) + self.assertEqual(k00.findLink(1).idName, 1) + + def test_010(self): + k0 = LIXML.getLinksXml() # get singleton + with self.assertRaises(Exception): + k0.appendLink(1) + k0.appendLink(2) + self.assertEqual(len(k0._linksXml), 3) + self.assertEqual(k0.findLink(2).idName, 2) + DBG.write("LinkXml k0 singleton", k0) + k1 = k0.findLink(1) + k11 = k1.appendLink(11) + k2 = k0.findLink(2) + k21 = k2.appendLink(21) + k22 = k2.appendLink(22) + self.assertEqual(k0.findLink(11), k11) + self.assertEqual(k0.findLink(21), k21) + self.assertEqual(k0.findLink(22), k22) + kk = k0.getAllIdNames() + self.assertEqual(kk, [-1, 0, 1, 11, 2, 21, 22]) + + def test_015(self): + k0 = LIXML.getLinksXml() # get singleton + + +if __name__ == '__main__': + unittest.main(exit=False) + pass + -- 2.39.2