# Define all possible option for the test command : sat test <options>
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."""))
-parser.add_option('m', 'module', 'list', 'modules',
- _('Indicate which module(s) to test (subdirectory of the grid).'))
-parser.add_option('t', 'type', 'list', 'types',
- _('Indicate which type(s) to test (subdirectory of the module).'))
-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")
+parser.add_option('b', 'base', 'string', 'base',
+ _("Optional: Indicate the name of the test base to use.\n\tThis name has to"
+ " be registered in your application and in a project.\n\tA path to a "
+ "test base can also be used."))
+parser.add_option('l', 'launcher', 'string', 'launcher',
+ _("Optional: Use this option to specify the path to a SALOME launcher to "
+ "use to launch the test scripts of the test base."))
+parser.add_option('g', 'grid', 'list', 'grids',
+ _('Optional: Indicate which grid(s) to test (subdirectory of the test '
+ 'base).'))
+parser.add_option('s', 'session', 'list', 'sessions',
+ _('Optional: indicate which session(s) to test (subdirectory of the '
+ 'grid).'))
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).'))
-parser.add_option('', 'light', 'boolean', 'light',
- _('Only run minimal tests declared in TestsLight.txt.'), False)
+ _("Optional: set the display where to launch SALOME.\n"
+"\tIf value is NO then option --show-desktop=0 will be used to launch SALOME."))
def description():
'''method that is called when salomeTools is called with --help option.
:return: The text to display for the test command description.
:rtype: str
'''
- return _("The test command runs a test base on a SALOME installation.")
+ return _("The test command runs a test base on a SALOME installation.\n\n"
+ "example:\nsat test SALOME-master --grid GEOM --session light")
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:
- options.appli = ""
- elif not os.path.isabs(options.appli):
+ if not options.launcher:
+ options.launcher = ""
+ elif not os.path.isabs(options.launcher):
if not src.config_has_application(config):
raise src.SatException(_("An application is required to use a "
"relative path with option --appli"))
- options.appli = os.path.join(config.APPLICATION.workdir, options.appli)
+ options.launcher = os.path.join(config.APPLICATION.workdir,
+ options.launcher)
- if not os.path.exists(options.appli):
- raise src.SatException(_("Application not found: %s") %
- options.appli)
+ if not os.path.exists(options.launcher):
+ raise src.SatException(_("Launcher not found: %s") %
+ options.launcher)
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 "
shutil.copy2(os.path.join(in_dir, what, 'env_info.py'),
os.path.join(finalPath, what, 'env_info.py'))
- # for all sub directory (ie grid) in the BASES directory
- for grid in os.listdir(os.path.join(in_dir, what, 'BASES')):
- outgrid = os.path.join(finalPath, what, 'BASES', grid)
- ingrid = os.path.join(in_dir, what, 'BASES', grid)
+ # for all sub directory (ie testbase) in the BASES directory
+ for testbase in os.listdir(os.path.join(in_dir, what, 'BASES')):
+ outtestbase = os.path.join(finalPath, what, 'BASES', testbase)
+ intestbase = os.path.join(in_dir, what, 'BASES', testbase)
# ignore files in root dir
- if not os.path.isdir(ingrid):
+ if not os.path.isdir(intestbase):
continue
- os.makedirs(outgrid)
- #logger.write(" copy grid %s\n" % grid, 5)
+ os.makedirs(outtestbase)
+ #logger.write(" copy testbase %s\n" % testbase, 5)
- for module_ in [m for m in os.listdir(ingrid) if os.path.isdir(
- os.path.join(ingrid, m))]:
+ for grid_ in [m for m in os.listdir(intestbase) if os.path.isdir(
+ os.path.join(intestbase, m))]:
# ignore source configuration directories
- if module_[:4] == '.git' or module_ == 'CVS':
+ if grid_[:4] == '.git' or grid_ == 'CVS':
continue
- outmodule = os.path.join(outgrid, module_)
- inmodule = os.path.join(ingrid, module_)
- os.makedirs(outmodule)
- #logger.write(" copy module %s\n" % module_, 5)
+ outgrid = os.path.join(outtestbase, grid_)
+ ingrid = os.path.join(intestbase, grid_)
+ os.makedirs(outgrid)
+ #logger.write(" copy grid %s\n" % grid_, 5)
- if module_ == 'RESSOURCES':
- for file_name in os.listdir(inmodule):
- if not os.path.isfile(os.path.join(inmodule,
+ if grid_ == 'RESSOURCES':
+ for file_name in os.listdir(ingrid):
+ if not os.path.isfile(os.path.join(ingrid,
file_name)):
continue
- f = open(os.path.join(outmodule, file_name), "w")
- f.write(save_file(os.path.join(inmodule, file_name),
+ f = open(os.path.join(outgrid, file_name), "w")
+ f.write(save_file(os.path.join(ingrid, file_name),
finalPath))
f.close()
else:
- for type_name in [t for t in os.listdir(inmodule) if
- os.path.isdir(os.path.join(inmodule, t))]:
- outtype = os.path.join(outmodule, type_name)
- intype = os.path.join(inmodule, type_name)
- os.makedirs(outtype)
+ for session_name in [t for t in os.listdir(ingrid) if
+ os.path.isdir(os.path.join(ingrid, t))]:
+ outsession = os.path.join(outgrid, session_name)
+ insession = os.path.join(ingrid, session_name)
+ os.makedirs(outsession)
- for file_name in os.listdir(intype):
- if not os.path.isfile(os.path.join(intype,
+ for file_name in os.listdir(insession):
+ if not os.path.isfile(os.path.join(insession,
file_name)):
continue
if file_name.endswith('result.py'):
- shutil.copy2(os.path.join(intype, file_name),
- os.path.join(outtype, file_name))
+ shutil.copy2(os.path.join(insession, file_name),
+ os.path.join(outsession, file_name))
else:
- f = open(os.path.join(outtype, file_name), "w")
- f.write(save_file(os.path.join(intype,
+ f = open(os.path.join(outsession, file_name), "w")
+ f.write(save_file(os.path.join(insession,
file_name),
finalPath))
f.close()
if p.returncode != 0:
logger.write(src.printcolors.printc(src.KO_STATUS) + "\n", 1)
logger.write(" " + src.printcolors.printcError(p.stderr.read()), 2)
- raise src.SatException("No ssh access to the display machine.")
+ logger.write(src.printcolors.printcWarning((
+ "No ssh access to the display machine.")),1)
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("<?xml version='1.0' encoding='utf-8'?>\n")
- if len(stylesheet) > 0:
- f.write("<?xml-stylesheet type='text/xsl' href='%s'?>\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=""):
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")
amend = add_simple_node(prod_node, "amend")
tt = {}
for test in config.TESTS:
- if not tt.has_key(test.grid):
- tt[test.grid] = [test]
+ if not tt.has_key(test.testbase):
+ tt[test.testbase] = [test]
else:
- tt[test.grid].append(test)
+ tt[test.testbase].append(test)
- for grid in tt.keys():
- gn = add_simple_node(tests, "grid")
- gn.attrib['name'] = grid
+ for testbase in tt.keys():
+ gn = add_simple_node(tests, "testbase")
+ gn.attrib['name'] = testbase
nb, nb_pass, nb_failed, nb_timeout, nb_not_run = 0, 0, 0, 0, 0
- modules = {}
- types = {}
- for test in tt[grid]:
- #print test.module
- if not modules.has_key(test.module):
- mn = add_simple_node(gn, "module")
- mn.attrib['name'] = test.module
- modules[test.module] = mn
-
- if not types.has_key("%s/%s" % (test.module, test.type)):
- tyn = add_simple_node(mn, "type")
- tyn.attrib['name'] = test.type
- types["%s/%s" % (test.module, test.type)] = tyn
+ grids = {}
+ sessions = {}
+ for test in tt[testbase]:
+ #print test.grid
+ if not grids.has_key(test.grid):
+ mn = add_simple_node(gn, "grid")
+ mn.attrib['name'] = test.grid
+ grids[test.grid] = mn
+
+ if not sessions.has_key("%s/%s" % (test.grid, test.session)):
+ tyn = add_simple_node(mn, "session")
+ tyn.attrib['name'] = test.session
+ sessions["%s/%s" % (test.grid, test.session)] = 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.attrib['type'] = test.type
+ tn = add_simple_node(sessions[
+ "%s/%s" % (test.grid, test.session)], "test")
+ tn.attrib['session'] = test.session
tn.attrib['script'] = script.name
if 'callback' in script:
try:
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")
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.grid,
+ test.session,
+ script.name)
+ amend_test.attrib['reason'] = script.amend.decode(
+ "UTF-8")
# calculate status
nb += 1
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.grid,
+ test.session,
+ 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.grid,
+ test.session, 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)
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):
'''
(options, args) = parse_option(args, runner.cfg)
- if options.grid and options.dir:
- 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
- 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:
+ with_application = True
+ elif not options.base:
+ raise src.SatException(_('A test base is required. Use the --base '
+ 'option'))
+
+ if with_application:
# check if environment is loaded
if 'KERNEL_ROOT_DIR' in os.environ:
logger.write(src.printcolors.printcWarning(_("WARNING: "
"SALOME environment already sourced")) + "\n", 1)
- elif options.appli:
+ elif options.launcher:
logger.write(src.printcolors.printcWarning(_("Running SALOME "
"application.")) + "\n\n", 1)
else:
- 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")
+ msg = _("Impossible to find any launcher.\nPlease specify an "
+ "application or a launcher")
+ logger.write(src.printcolors.printcError(msg))
+ logger.write("\n")
+ return 1
# set the display
show_desktop = (options.display and options.display.upper() == "NO")
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:
# 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
content = "\n".join(lines)
- # create hash from session information
- dirname = sha1(content).hexdigest()
- session_dir = os.path.join(tmp_dir, dirname)
- os.makedirs(session_dir)
- os.environ['TT_TMP_RESULT'] = session_dir
+ # create hash from context information
+ dirname = sha1(content.encode()).hexdigest()
+ base_dir = os.path.join(tmp_dir, dirname)
+ os.makedirs(base_dir)
+ os.environ['TT_TMP_RESULT'] = base_dir
# create env_info file
- f = open(os.path.join(session_dir, 'env_info.py'), "w")
+ f = open(os.path.join(base_dir, 'env_info.py'), "w")
f.write(content)
f.close()
# create working dir and bases dir
- working_dir = os.path.join(session_dir, 'WORK')
+ working_dir = os.path.join(base_dir, 'WORK')
os.makedirs(working_dir)
- os.makedirs(os.path.join(session_dir, 'BASES'))
+ os.makedirs(os.path.join(base_dir, 'BASES'))
os.chdir(working_dir)
if 'PYTHONPATH' not in os.environ:
# launch of the tests
#####################
- grid = ""
- if options.grid:
- grid = options.grid
- elif not options.dir and with_product and "test_base" in runner.cfg.APPLICATION:
- grid = runner.cfg.APPLICATION.test_base.name
+ test_base = ""
+ if options.base:
+ test_base = options.base
+ elif with_application and "test_base" in runner.cfg.APPLICATION:
+ test_base = runner.cfg.APPLICATION.test_base.name
src.printcolors.print_value(logger, _('Display'), os.environ['DISPLAY'], 2)
src.printcolors.print_value(logger, _('Timeout'),
runner.cfg.SITE.test.timeout, 2)
- if 'timeout_app' in runner.cfg.SITE.test:
- src.printcolors.print_value(logger, _('Timeout Salome'),
- runner.cfg.SITE.test.timeout_app, 2)
- src.printcolors.print_value(logger, _('Light mode'), options.light, 2)
- src.printcolors.print_value(logger, _("Working dir"), session_dir, 3)
+ src.printcolors.print_value(logger, _("Working dir"), base_dir, 3)
# create the test object
test_runner = src.test_module.Test(runner.cfg,
logger,
- session_dir,
- grid=grid,
- modules=options.modules,
- types=options.types,
- appli=options.appli,
- mode=options.mode,
- dir_=options.dir,
- show_desktop=show_desktop,
- light=options.light)
+ base_dir,
+ testbase=test_base,
+ grids=options.grids,
+ sessions=options.sessions,
+ launcher=options.launcher,
+ show_desktop=show_desktop)
+ if not test_runner.test_base_found:
+ # Fail
+ return 1
+
# 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)
logger.write("\n", 2, False)
logger.write(_("\nGenerate the specific test log\n"), 5)
- out_dir = os.path.join(runner.cfg.SITE.log.log_dir, "TEST")
+ out_dir = os.path.join(runner.cfg.USER.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),
retcode,
"Click on the link to get the detailed test results")
+ logger.write(_("Removing the temporary directory: "
+ "rm -rf %s\n" % test_runner.tmp_working_dir), 5)
+ if os.path.exists(test_runner.tmp_working_dir):
+ shutil.rmtree(test_runner.tmp_working_dir)
+
return retcode