From: Serge Rehbinder Date: Wed, 20 Jul 2016 12:52:45 +0000 (+0200) Subject: 'sat test': add the script and the script traces in the log X-Git-Tag: 5.0.0a0~6 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=41b996848dfb04c3394902459518be9114e20bb6;p=tools%2Fsat.git 'sat test': add the script and the script traces in the log --- diff --git a/commands/test.py b/commands/test.py index d16e9df..571f67c 100644 --- a/commands/test.py +++ b/commands/test.py @@ -37,8 +37,8 @@ parser = src.options.Options() parser.add_option('a', 'appli', 'string', 'appli', _('Use this option to specify the path to an installed application.')) parser.add_option('g', 'grid', 'string', 'grid', - _("""Indicate the name of the grid to test. -\tThis name has to be registered in sat. If your test base is not known by sat, use the option --dir.""")) + _("Indicate the name of the grid to test.\n\tThis name has to be registered" + " in sat. If your test base is not known by sat, use the option --dir.")) parser.add_option('m', 'module', 'list', 'modules', _('Indicate which module(s) to test (subdirectory of the grid).')) parser.add_option('t', 'type', 'list', 'types', @@ -46,12 +46,11 @@ parser.add_option('t', 'type', 'list', 'types', parser.add_option('d', 'dir', 'string', 'dir', _('Indicate the directory containing the test base.'), "") parser.add_option('', 'mode', 'string', 'mode', - _("Indicate which kind of test to run. If MODE is 'batch' only python and NO_GUI tests are run."), "normal") + _("Indicate which kind of test to run. If MODE is 'batch' only python and" + " NO_GUI tests are run."), "normal") parser.add_option('', 'display', 'string', 'display', - _("""Set the display where to launch SALOME. -\tIf value is NO then option --show-desktop=0 will be used to launch SALOME.""")) -parser.add_option('n', 'name', 'string', 'session', - _('Give a name to the test session (REQUIRED if no product).')) + _("Set the display where to launch SALOME." +"\tIf value is NO then option --show-desktop=0 will be used to launch SALOME.")) parser.add_option('', 'light', 'boolean', 'light', _('Only run minimal tests declared in TestsLight.txt.'), False) @@ -64,6 +63,13 @@ def description(): return _("The test command runs a test base on a SALOME installation.") def parse_option(args, config): + """ Parse the options and do some verifications about it + + :param args List: The list of arguments of the command + :param config Config: The global configuration + :return: the options of the current command launch and the full arguments + :rtype: Tuple (options, args) + """ (options, args) = parser.parse_args(args) if not options.appli: @@ -81,6 +87,8 @@ def parse_option(args, config): return (options, args) def ask_a_path(): + """ + """ path = raw_input("enter a path where to save the result: ") if path == "": result = raw_input("the result will be not save. Are you sure to " @@ -218,27 +226,6 @@ def check_remote_machine(machine_name, logger): else: logger.write(src.printcolors.printcSuccess(src.OK_STATUS) + "\n\n", 4) -## -# Transform YYYYMMDD_hhmmss into YYYY-MM-DD hh:mm:ss. -def parse_date(date): - if len(date) != 15: - return date - res = "%s-%s-%s %s:%s:%s" % (date[0:4], date[4:6], date[6:8], date[9:11], date[11:13], date[13:]) - return res - -## -# Writes a report file from a XML tree. -def write_report(filename, xmlroot, stylesheet): - if not os.path.exists(os.path.dirname(filename)): - os.makedirs(os.path.dirname(filename)) - - f = open(filename, "w") - f.write("\n") - if len(stylesheet) > 0: - f.write("\n" % stylesheet) - f.write(etree.tostring(xmlroot, encoding='utf-8')) - f.close() - ## # Creates the XML report for a product. def create_test_report(config, dest_path, stylesheet, xmlname=""): @@ -251,18 +238,24 @@ def create_test_report(config, dest_path, stylesheet, xmlname=""): if withappli: - add_simple_node(prod_node, "version_to_download", config.APPLICATION.name) + add_simple_node(prod_node, "version_to_download", + config.APPLICATION.name) add_simple_node(prod_node, "out_dir", config.APPLICATION.workdir) # add environment exec_node = add_simple_node(prod_node, "exec") exec_node.append(etree.Element("env", name="Host", value=config.VARS.node)) - exec_node.append(etree.Element("env", name="Architecture", value=config.VARS.dist)) - exec_node.append(etree.Element("env", name="Number of processors", value=str(config.VARS.nb_proc))) - exec_node.append(etree.Element("env", name="Begin date", value=parse_date(config.VARS.datehour))) - exec_node.append(etree.Element("env", name="Command", value=config.VARS.command)) - exec_node.append(etree.Element("env", name="sat version", value=config.INTERNAL.sat_version)) + exec_node.append(etree.Element("env", name="Architecture", + value=config.VARS.dist)) + exec_node.append(etree.Element("env", name="Number of processors", + value=str(config.VARS.nb_proc))) + exec_node.append(etree.Element("env", name="Begin date", + value=src.parse_date(config.VARS.datehour))) + exec_node.append(etree.Element("env", name="Command", + value=config.VARS.command)) + exec_node.append(etree.Element("env", name="sat version", + value=config.INTERNAL.sat_version)) if 'TESTS' in config: tests = add_simple_node(prod_node, "tests") @@ -295,9 +288,8 @@ def create_test_report(config, dest_path, stylesheet, xmlname=""): types["%s/%s" % (test.module, test.type)] = tyn for script in test.script: - tn = add_simple_node(types["%s/%s" % (test.module, test.type)], "test") - #tn.attrib['grid'] = test.grid - #tn.attrib['module'] = test.module + tn = add_simple_node(types[ + "%s/%s" % (test.module, test.type)], "test") tn.attrib['type'] = test.type tn.attrib['script'] = script.name if 'callback' in script: @@ -305,14 +297,27 @@ def create_test_report(config, dest_path, stylesheet, xmlname=""): cnode = add_simple_node(tn, "callback") if src.architecture.is_windows(): import string - cnode.text = filter(lambda x: x in string.printable, - script.callback) + cnode.text = filter( + lambda x: x in string.printable, + script.callback) else: - cnode.text = script.callback.decode('string_escape') + cnode.text = script.callback.decode( + 'string_escape') except UnicodeDecodeError as exc: - zz = script.callback[:exc.start] + '?' + script.callback[exc.end-2:] + zz = (script.callback[:exc.start] + + '?' + + script.callback[exc.end-2:]) cnode = add_simple_node(tn, "callback") cnode.text = zz.decode("UTF-8") + + # Add the script content + cnode = add_simple_node(tn, "content") + cnode.text = script.content + + # Add the script execution log + cnode = add_simple_node(tn, "out") + cnode.text = script.out + if 'amend' in script: cnode = add_simple_node(tn, "amend") cnode.text = script.amend.decode("UTF-8") @@ -325,8 +330,11 @@ def create_test_report(config, dest_path, stylesheet, xmlname=""): if "amend" in script: amend_test = add_simple_node(amend, "atest") - amend_test.attrib['name'] = os.path.join(test.module, test.type, script.name) - amend_test.attrib['reason'] = script.amend.decode("UTF-8") + amend_test.attrib['name'] = os.path.join(test.module, + test.type, + script.name) + amend_test.attrib['reason'] = script.amend.decode( + "UTF-8") # calculate status nb += 1 @@ -337,21 +345,29 @@ def create_test_report(config, dest_path, stylesheet, xmlname=""): if "known_error" in script: kf_script = add_simple_node(known_errors, "error") - kf_script.attrib['name'] = os.path.join(test.module, test.type, script.name) + kf_script.attrib['name'] = os.path.join(test.module, + test.type, + script.name) kf_script.attrib['date'] = script.known_error.date - kf_script.attrib['expected'] = script.known_error.expected - kf_script.attrib['comment'] = script.known_error.comment.decode("UTF-8") - kf_script.attrib['fixed'] = str(script.known_error.fixed) - overdue = datetime.datetime.today().strftime("%Y-%m-%d") > script.known_error.expected + kf_script.attrib[ + 'expected'] = script.known_error.expected + kf_script.attrib[ + 'comment'] = script.known_error.comment.decode("UTF-8") + kf_script.attrib['fixed'] = str( + script.known_error.fixed) + overdue = datetime.datetime.today().strftime("%Y-%m-" + "%d") > script.known_error.expected if overdue: kf_script.attrib['overdue'] = str(overdue) elif script.res == src.KO_STATUS: new_err = add_simple_node(new_errors, "new_error") - script_path = os.path.join(test.module, test.type, script.name) + script_path = os.path.join(test.module, + test.type, script.name) new_err.attrib['name'] = script_path - new_err.attrib['cmd'] = "sat testerror %s -s %s -c 'my comment' -p %s" % \ - (application_name, script_path, config.VARS.dist) + new_err.attrib['cmd'] = ("sat testerror %s -s %s -c 'my" + " comment' -p %s" % \ + (application_name, script_path, config.VARS.dist)) gn.attrib['total'] = str(nb) @@ -365,7 +381,9 @@ def create_test_report(config, dest_path, stylesheet, xmlname=""): if not xmlname.endswith(".xml"): xmlname += ".xml" - write_report(os.path.join(dest_path, xmlname), root, stylesheet) + src.xmlManager.write_report(os.path.join(dest_path, xmlname), + root, + stylesheet) return src.OK_STATUS def run(args, runner, logger): @@ -377,19 +395,19 @@ def run(args, runner, logger): raise src.SatException(_("The options --grid and --dir are not " "compatible!")) - with_product = False + with_application = False if runner.cfg.VARS.application != 'None': logger.write(_('Running tests on application %s\n') % src.printcolors.printcLabel( runner.cfg.VARS.application), 1) - with_product = True + with_application = True elif options.dir: logger.write(_('Running tests from directory %s\n') % src.printcolors.printcLabel(options.dir), 1) elif not options.grid: raise src.SatException(_('a grid or a directory is required')) - if with_product: + if with_application: # check if environment is loaded if 'KERNEL_ROOT_DIR' in os.environ: logger.write(src.printcolors.printcWarning(_("WARNING: " @@ -403,11 +421,6 @@ def run(args, runner, logger): logger.write(src.printcolors.printcWarning(_("WARNING running " "without a product.")) + "\n\n", 1) - # name for session is required - if not options.session: - raise src.SatException(_("--name argument is required when no " - "product is specified.")) - # check if environment is loaded if not 'KERNEL_ROOT_DIR' in os.environ: raise src.SatException(_("SALOME environment not found") + "\n") @@ -422,7 +435,8 @@ def run(args, runner, logger): os.environ['DISPLAY'] = options.display elif 'DISPLAY' not in os.environ: # if no display set - if 'display' in runner.cfg.SITE.test and len(runner.cfg.SITE.test.display) > 0: + if ('display' in runner.cfg.SITE.test and + len(runner.cfg.SITE.test.display) > 0): # use default value for test tool os.environ['DISPLAY'] = runner.cfg.SITE.test.display else: @@ -430,8 +444,8 @@ def run(args, runner, logger): # initialization ################# - if with_product: - tmp_dir = runner.cfg.SITE.test.tmp_dir_with_product + if with_application: + tmp_dir = runner.cfg.SITE.test.tmp_dir_with_application else: tmp_dir = runner.cfg.SITE.test.tmp_dir @@ -461,7 +475,7 @@ def run(args, runner, logger): content = "\n".join(lines) # create hash from session information - dirname = sha1(content).hexdigest() + dirname = sha1(content.encode()).hexdigest() session_dir = os.path.join(tmp_dir, dirname) os.makedirs(session_dir) os.environ['TT_TMP_RESULT'] = session_dir @@ -489,7 +503,8 @@ def run(args, runner, logger): grid = "" if options.grid: grid = options.grid - elif not options.dir and with_product and "test_base" in runner.cfg.APPLICATION: + elif (not options.dir and with_application and + "test_base" in runner.cfg.APPLICATION): grid = runner.cfg.APPLICATION.test_base.name src.printcolors.print_value(logger, _('Display'), os.environ['DISPLAY'], 2) @@ -516,7 +531,7 @@ def run(args, runner, logger): # run the test logger.allowPrintLevel = False - retcode = test_runner.run_all_tests(options.session) + retcode = test_runner.run_all_tests() logger.allowPrintLevel = True logger.write(_("Tests finished"), 1) @@ -526,7 +541,10 @@ def run(args, runner, logger): out_dir = os.path.join(runner.cfg.SITE.log.log_dir, "TEST") src.ensure_path_exists(out_dir) name_xml_board = logger.logFileName.split(".")[0] + "board" + ".xml" - create_test_report(runner.cfg, out_dir, "test.xsl", xmlname = name_xml_board) + create_test_report(runner.cfg, + out_dir, + "test.xsl", + xmlname = name_xml_board) xml_board_path = os.path.join(out_dir, name_xml_board) logger.l_logFiles.append(xml_board_path) logger.add_link(os.path.join("TEST", name_xml_board), diff --git a/data/site.pyconf b/data/site.pyconf index 60ff90d..6652e7d 100644 --- a/data/site.pyconf +++ b/data/site.pyconf @@ -9,7 +9,7 @@ SITE : } #base : $USER.workdir + $VARS.sep + "BASE-FROM-SITE" test :{ - tmp_dir_with_product : '/tmp' + $VARS.sep + $VARS.user + $VARS.sep + $APPLICATION.name + $VARS.sep + 'test' + tmp_dir_with_application : '/tmp' + $VARS.sep + $VARS.user + $VARS.sep + $APPLICATION.name + $VARS.sep + 'test' tmp_dir : '/tmp' + $VARS.sep + $VARS.user + $VARS.sep + 'test' timeout : 150 } diff --git a/src/__init__.py b/src/__init__.py index fdc236b..f4c065d 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -312,4 +312,21 @@ def deepcopy_list(input_list): res = [] for elem in input_list: res.append(elem) - return res \ No newline at end of file + return res + +def parse_date(date): + """Transform YYYYMMDD_hhmmss into YYYY-MM-DD hh:mm:ss. + + :param date str: The date to transform + :return: The date in the new format + :rtype: str + """ + if len(date) != 15: + return date + res = "%s-%s-%s %s:%s:%s" % (date[0:4], + date[4:6], + date[6:8], + date[9:11], + date[11:13], + date[13:]) + return res diff --git a/src/test_module.py b/src/test_module.py index db4cb85..e8dfb86 100644 --- a/src/test_module.py +++ b/src/test_module.py @@ -16,15 +16,24 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# Python 2/3 compatibility for execfile function +try: + execfile +except: + def execfile(somefile, global_vars, local_vars): + with open(somefile) as f: + code = compile(f.read(), somefile, 'exec') + exec(code, global_vars, local_vars) + + import os, sys, datetime, shutil, string import subprocess -import fork +from . import fork import src # directories not considered as test modules C_IGNORE_MODULES = ['.git', '.svn', 'RESSOURCES'] -C_TESTS_SOURCE_DIR = "Tests" C_TESTS_LIGHT_FILE = "TestsLight.txt" # Get directory to be used for the temporary files. @@ -90,12 +99,15 @@ class Test: symlinks=True) def prepare_grid_from_dir(self, grid_name, grid_dir): - self.logger.write(_("get grid from dir: %s\n") % src.printcolors.printcLabel(grid_dir), 3) + self.logger.write(_("get grid from dir: %s\n") % \ + src.printcolors.printcLabel(grid_dir), 3) if not os.access(grid_dir, os.X_OK): - raise src.SatException(_("testbase %(name)s (%(dir)s) does not exist ...\n") % \ - { 'name': grid_name, 'dir': grid_dir }) + raise src.SatException(_("testbase %(name)s (%(dir)s) does not " + "exist ...\n") % { 'name': grid_name, + 'dir': grid_dir }) - self._copy_dir(grid_dir, os.path.join(self.sessionDir, 'BASES', grid_name)) + self._copy_dir(grid_dir, + os.path.join(self.sessionDir, 'BASES', grid_name)) def prepare_grid_from_git(self, grid_name, grid_base, grid_tag): self.logger.write( @@ -116,7 +128,9 @@ class Test: else: cmd += " && git fetch origin %(branch)s:%(branch)s" cmd += " && git checkout %(branch)s" - cmd = cmd % { 'branch': grid_tag, 'base': grid_base, 'dir': grid_name } + cmd = cmd % { 'branch': grid_tag, + 'base': grid_base, + 'dir': grid_name } self.logger.write("> %s\n" % cmd, 5) if src.architecture.is_windows(): @@ -134,15 +148,17 @@ class Test: stdout=self.logger.logTxtFile, stderr=subprocess.PIPE) if res != 0: - raise src.SatException(_("Error: unable to get test base '%(name)s' from git '%(repo)s'.") % \ - { 'name': grid_name, 'repo': grid_base }) + raise src.SatException(_("Error: unable to get test base " + "'%(name)s' from git '%(repo)s'.") % \ + { 'name': grid_name, 'repo': grid_base }) except OSError: self.logger.error(_("git is not installed. exiting...\n")) sys.exit(0) def prepare_grid_from_svn(self, user, grid_name, grid_base): - self.logger.write(_("get grid '%s' from svn\n") % src.printcolors.printcLabel(grid_name), 3) + self.logger.write(_("get grid '%s' from svn\n") % \ + src.printcolors.printcLabel(grid_name), 3) try: def set_signal(): # pragma: no cover """see http://bugs.python.org/issue1652""" @@ -306,6 +322,30 @@ class Test: pass results[test] = [status, exec_time, callback, expected] + + # check if .py file exists + testfile = os.path.join(self.currentDir, + self.currentModule, + self.currentType, + test) + + if not os.path.exists(testfile): + results[test].append('') + else: + text = open(testfile, "r").read() + results[test].append(text) + + # check if .out.py file exists + outfile = os.path.join(self.currentDir, + self.currentModule, + self.currentType, + test[:-3] + ".out.py") + + if not os.path.exists(outfile): + results[test].append('') + else: + text = open(outfile, "r").read() + results[test].append(text) return results @@ -401,8 +441,8 @@ class Test: def get_test_timeout(self, test_name, default_value): - if (self.settings.has_key("timeout") and - self.settings["timeout"].has_key(test_name)): + if ("timeout" in self.settings and + test_name in self.settings["timeout"]): return self.settings["timeout"][test_name] return default_value @@ -443,7 +483,7 @@ class Test: else: # New application binSalome = self.appli - binPython = self.appli + ' shell' + binPython = self.appli + ' context' killSalome = self.appli + ' killall' return binSalome, binPython, killSalome @@ -480,7 +520,7 @@ class Test: if src.architecture.is_windows(): binSalome += '.bat' - binPython = binSalome + ' shell' + binPython = binSalome + ' context' killSalome = binSalome + ' killall' return binSalome, binPython, killSalome @@ -585,7 +625,10 @@ class Test: script_info.known_error.expected = kfres[1] script_info.known_error.comment = kfres[2] script_info.known_error.fixed = kfres[3] - + + script_info.content = script_results[sr][4] + script_info.out = script_results[sr][5] + # add it to the list of results test_info.script.append(script_info, '') @@ -784,7 +827,7 @@ class Test: self.logger.write(src.printcolors.printcHeader("----------- end" " %s" % script_name) + "\n", 2) - def run_all_tests(self, session_name=""): + def run_all_tests(self): initTime = datetime.datetime.now() self.run_script('test_setup') @@ -839,9 +882,6 @@ class Test: status = src.KNOWNFAILURE_STATUS self.logger.write(_("Status: %s\n" % status), 3) - - if session_name is not None and len(session_name) > 0: - self.config.RESULTS.test["session"] = session_name return self.nb_run - self.nb_succeed - self.nb_acknoledge diff --git a/src/xmlManager.py b/src/xmlManager.py index 7332cb4..c125c51 100644 --- a/src/xmlManager.py +++ b/src/xmlManager.py @@ -169,3 +169,20 @@ def append_node_attrib(root_node, attrib): :param attrib dixt: The attrib to append ''' root_node.attrib.update(attrib) + +def write_report(filename, xmlroot, stylesheet): + """Writes a report file from a XML tree. + + :param filename str: The path to the file to create + :param xmlroot etree.Element: the Etree element to write to the file + :param stylesheet str: The stylesheet to add to the begin of the file + """ + if not os.path.exists(os.path.dirname(filename)): + os.makedirs(os.path.dirname(filename)) + + f = open(filename, "w") + f.write("\n") + if len(stylesheet) > 0: + f.write("\n" % stylesheet) + f.write(etree.tostring(xmlroot, encoding='utf-8')) + f.close() \ No newline at end of file diff --git a/src/xsl/test.xsl b/src/xsl/test.xsl index 0ebe140..f517cac 100644 --- a/src/xsl/test.xsl +++ b/src/xsl/test.xsl @@ -79,6 +79,7 @@ @@ -281,7 +289,20 @@ - + + + + javascript:Toggle('') + Click to see the script content + + +   + + javascript:Toggle('log') + Click to see the execution log + log + + @@ -291,7 +312,19 @@ - + + + javascript:Toggle('') + Click to see the script content + + +   + + javascript:Toggle('log') + Click to see the execution log + log + + @@ -299,7 +332,7 @@ - Amended + Amended @@ -309,7 +342,20 @@ - + + + + +
+
+
+
log +
+
+
+
+
+