11 from __future__
import print_function
12 from future
import standard_library
13 standard_library.install_aliases()
14 from builtins
import range
15 from builtins
import object
23 from yapsy.PluginManager
import PluginManager
25 from distutils.spawn
import find_executable
26 from threading
import Semaphore
27 from pathlib
import Path
29 is_py2 = sys.version[0] ==
'2'
36 sub_path = os.path.dirname(path)
37 if sub_path
and not os.path.exists(sub_path):
39 if not os.path.exists(path):
80 if self.
options[
'clean']
and os.path.isdir(self.
options[
'scratchdir']) :
81 shutil.rmtree(self.
options[
'scratchdir'])
87 if opt
is None or type(opt)
is str:
89 elif type(opt)
is bool:
90 if type(inval)
is bool:
92 elif type(inval)
is str:
93 if inval.lower()
in [
'true',
'1',
't',
'y',
'yes']:
97 elif type(inval)
is int:
102 elif is_py2
and type(inval)
is unicode:
106 print(
"Unknown conversion required for " + inval)
108 elif type(opt)
is int:
109 if type(inval)
is int:
111 elif type(inval)
is str:
115 print(
"Unknown conversion required for " + inval)
117 elif type(opt)
is float:
118 if type(inval)
is float:
120 elif type(inval)
is str
or type(inval)
is int:
121 return 0, float(inval)
124 print(
"Unknown conversion required for " + inval)
158 opts = list(options.keys())
159 kvkeys = list(keyvals.keys())
167 if keyvals[kvkey]
is None:
173 if len(keyvals[kvkey]) == 0:
177 if keyvals[kvkey][0][0] ==
"[":
179 val = keyvals[kvkey].replace(
'[',
'')
180 val = val.replace(
']',
'')
188 target[opt] = newvals
196 target[opt] = options[opt][0]
201 keys = self.defaults.options.keys()
203 if key
not in target:
204 target[key] = self.defaults.options[key][0]
209 unsupported_options = []
212 if kvkey
in [
'section',
'plugin']:
215 if target[kvkey]
is not None:
219 if kvkey
in [
'parent',
'asis']:
220 target[kvkey] = keyvals[kvkey]
222 unsupported_options.append(kvkey)
223 if unsupported_options:
224 sys.exit(
"ERROR: Unsupported options for section [%s]: %s" % (log[
'section'],
",".join(unsupported_options)))
227 log[
'options'] = target
232 print(
"Cannot load plugins multiple times")
238 m = imp.load_source(
"LoadClasses", os.path.join(basedir,
"LoadClasses.py"));
240 print(
"ERROR: unable to load LoadClasses that must contain the class loader object")
242 cls = getattr(m,
"LoadClasses")
250 plugindirs.append(topdir)
253 x = self.
options[
'plugindir'].split(
',')
259 plugindirs.insert(0, y)
262 for dirPath
in plugindirs:
263 if not Path(dirPath).exists():
264 print(
"Attempted to load plugins from non-existent path:", dirPath)
267 self.loader.load(dirPath)
268 except Exception
as e:
269 print(
"Exception caught while loading plugins:")
274 self.
stages = PluginManager()
276 self.stages.setPluginPlaces(plugindirs)
282 self.stages.setCategoriesFilter(self.loader.stages)
284 self.stages.collectPlugins()
293 self.
tools = PluginManager()
295 self.tools.setPluginPlaces(plugindirs)
300 self.tools.setCategoriesFilter(self.loader.tools)
302 self.tools.collectPlugins()
311 self.utilities.setPluginPlaces(plugindirs)
313 self.utilities.setCategoriesFilter(self.loader.utilities)
315 self.utilities.collectPlugins()
319 availUtil = list(self.loader.utilities.keys())
320 for util
in availUtil:
321 for pluginInfo
in self.utilities.getPluginsOfCategory(util):
322 if "ExecuteCmd" == pluginInfo.plugin_object.print_name():
323 self.
execmd = pluginInfo.plugin_object
324 elif "ModuleCmd" == pluginInfo.plugin_object.print_name():
325 self.
modcmd = pluginInfo.plugin_object
327 self.modcmd.setCommand(self.
options)
328 elif "Watchdog" == pluginInfo.plugin_object.print_name():
329 self.
watchdog = pluginInfo.plugin_object
333 print(
"ExecuteCmd plugin was not found")
334 print(
"This is a basic capability required")
335 print(
"for MTT operations - cannot continue")
338 print(self.tools.getPluginsOfCategory(
"Harasser"))
339 for pluginInfo
in self.tools.getPluginsOfCategory(
"Harasser"):
340 if "Harasser" == pluginInfo.plugin_object.print_name():
341 self.
harasser = pluginInfo.plugin_object
344 print(
"Harasser plugin was not found")
345 print(
"This is required for all TestRun plugins")
346 print(
"cannot continue")
350 for pluginInfo
in self.stages.getPluginsOfCategory(
"MTTDefaults"):
351 if pri < pluginInfo.plugin_object.priority():
352 self.
defaults = pluginInfo.plugin_object
353 pri = pluginInfo.plugin_object.priority()
359 if self.
options[
'listsections']:
360 print(
"Supported MTT stages:")
362 for stage
in self.loader.stageOrder:
367 if self.
options[
'listplugins']:
369 if self.
options[
'listplugins'] ==
"*":
370 sections = self.loader.stageOrder
372 sections = self.
options[
'listplugins'].split(
',')
374 for section
in sections:
377 for pluginInfo
in self.stages.getPluginsOfCategory(section):
378 print(
" " + pluginInfo.plugin_object.print_name())
380 print(
" Invalid stage name " + section)
385 if self.
options[
'liststageoptions']:
387 if self.
options[
'liststageoptions'] ==
"*":
388 sections = self.loader.stageOrder
390 sections = self.
options[
'liststageoptions'].split(
',')
392 for section
in sections:
395 for pluginInfo
in self.stages.getPluginsOfCategory(section):
396 print(
" " + pluginInfo.plugin_object.print_name() +
":")
397 pluginInfo.plugin_object.print_options(self,
" ")
399 print(
" Invalid stage name " + section)
405 print(
"Available MTT tools:")
406 availTools = list(self.loader.tools.keys())
407 for tool
in availTools:
412 if self.
options[
'listtoolmodules']:
414 if self.
options[
'listtoolmodules'] ==
"*":
416 availTools = list(self.loader.tools.keys())
418 availTools = self.
options[
'listtoolmodules'].split(
',')
420 for tool
in availTools:
423 for pluginInfo
in self.tools.getPluginsOfCategory(tool):
424 print(
" " + pluginInfo.plugin_object.print_name())
426 print(
" Invalid tool type name",tool)
431 if self.
options[
'listtooloptions']:
433 if self.
options[
'listtooloptions'] ==
"*":
434 availTools = list(self.loader.tools.keys())
436 availTools = self.
options[
'listtooloptions'].split(
',')
438 for tool
in availTools:
441 for pluginInfo
in self.tools.getPluginsOfCategory(tool):
442 print(
" " + pluginInfo.plugin_object.print_name() +
":")
443 pluginInfo.plugin_object.print_options(self,
" ")
445 print(
" Invalid tool type name " + tool)
451 print(
"Available MTT utilities:")
452 availUtils = list(self.loader.utilities.keys())
453 for util
in availUtils:
458 if self.
options[
'listutilmodules']:
460 if self.
options[
'listutilmodules'] ==
"*":
462 availUtils = list(self.loader.utilities.keys())
464 availUtils = self.
options[
'listutilitymodules'].split(
',')
466 for util
in availUtils:
469 for pluginInfo
in self.utilities.getPluginsOfCategory(util):
470 print(
" " + pluginInfo.plugin_object.print_name())
472 print(
" Invalid utility type name")
477 if self.
options[
'listutiloptions']:
479 if self.
options[
'listutiloptions'] ==
"*":
480 availUtils = list(self.loader.utilities.keys())
482 availUtils = self.
options[
'listutiloptions'].split(
',')
484 for util
in availUtils:
487 for pluginInfo
in self.utilities.getPluginsOfCategory(util):
488 print(
" " + pluginInfo.plugin_object.print_name() +
":")
489 pluginInfo.plugin_object.print_options(self,
" ")
491 print(
" Invalid utility type name " + util)
498 for pluginInfo
in self.tools.getPluginsOfCategory(
"Version"):
499 print(
"MTT Base: " + pluginInfo.plugin_object.getVersion())
500 print(
"MTT Client: " + pluginInfo.plugin_object.getClientVersion())
506 if not self.utilities.activatePluginByName(
"Logger",
"Base"):
507 print(
"Required Logger plugin not found or could not be activated")
510 self.
logger = self.utilities.getPluginByName(
"Logger",
"Base").plugin_object
511 self.logger.open(self)
515 if isinstance(sublog, str):
516 self.config.set(
"LOG", basestr, sublog.replace(
"$",
"$$"))
517 elif isinstance(sublog, dict):
518 for k,v
in sublog.items():
520 elif isinstance(sublog, list):
521 if sum([((isinstance(t, list)
or isinstance(t, tuple))
and len(t) == 2)
for t
in sublog]) == len(sublog):
524 for i,v
in enumerate(sublog):
531 self.
config = configparser.SafeConfigParser(interpolation=configparser.ExtendedInterpolation())
534 self.config.optionxform = str
537 self.config.add_section(
'ENV')
538 for k,v
in os.environ.items():
539 self.config.set(
'ENV', k, v.replace(
"$",
"$$"))
542 self.config.add_section(
'LOG')
543 thefulllog = self.logger.getLog(
None)
550 self.
log[
'inifiles'] = self.args.ini_files[0]
555 if self.args.section:
556 sections = self.args.section.split(
",")
558 elif self.args.skipsections:
559 sections = self.args.skipsections.split(
",")
564 for testFile
in self.
log[
'inifiles']:
565 if not os.path.isfile(testFile):
566 print(
"Test description file",testFile,
"not found!")
568 self.config.read(self.
log[
'inifiles'])
572 all_file_contents = []
573 for testFile
in self.
log[
'inifiles']:
574 file_contents = open(testFile,
"r").read()
575 file_contents = "\n".join([
"%s %d: %s" % (testFile.split(
"/")[-1],i,l)
for i,l
in enumerate(file_contents.split(
"\n"))
if not l.lstrip().startswith(
"#")])
576 all_file_contents.append(file_contents)
577 if "${ENV:" in file_contents:
578 required_env.extend([s.split(
"}")[0]
for s
in file_contents.split(
"${ENV:")[1:]])
579 env_not_found = set([e
for e
in required_env
if e
not in os.environ.keys()])
580 lines_with_env_not_found = []
581 for file_contents
in all_file_contents:
582 lines_with_env_not_found.extend([
"%s: %s"%(
",".join([e
for e
in env_not_found
if "${ENV:%s}"%e
in l]),l) \
583 for l
in file_contents.split(
"\n") \
584 if sum([
"${ENV:%s}"%e
in l
for e
in env_not_found])])
585 if lines_with_env_not_found:
586 print(
"ERROR: Not all required environment variables are defined.")
587 print(
"ERROR: Still need:")
588 for l
in lines_with_env_not_found:
592 for section
in self.config.sections():
593 if section.startswith(
"SKIP")
or section.startswith(
"skip"):
601 if sections
is not None:
610 if not found
and not skip:
613 self.actives.append(section)
614 if sections
is not None and 0 != len(sections)
and not skip:
615 print(
"ERROR: sections were specified for execution and not found:",sections)
623 for section
in self.config.sections():
624 self.config.remove_section(section)
626 self.config.read(file)
627 for section
in self.config.sections():
628 if section.startswith(
"SKIP")
or section.startswith(
"skip"):
634 if self.
logger is not None:
635 self.logger.verbose_print(
"SECTION: " + section)
636 self.logger.verbose_print(self.config.items(section))
642 print(
"Plugins have not been loaded - cannot execute test")
645 print(
"No test definition file was parsed - cannot execute test")
647 if not self.tools.getPluginByName(executor,
"Executor"):
648 print(
"Specified executor %s not found" % executor)
651 self.tools.activatePluginByName(executor,
"Executor")
653 executor = self.tools.getPluginByName(executor,
"Executor")
654 status = executor.plugin_object.execute(self)
655 if status == 0
and self.
options[
'clean_after']
and os.path.isdir(self.
options[
'scratchdir']):
656 self.logger.verbose_print(
"Cleaning up scratchdir after successful run")
657 shutil.rmtree(self.
options[
'scratchdir'])
659 if enable_loop
and self.
options[
'loopforever']:
662 self.
executeTest(enable_loop=
False, executor=executor)
666 return self.
executeTest(enable_loop=enable_loop, executor=
"combinatorial")
675 vals = list(options.keys())
678 if options[val][0]
is None:
680 elif isinstance(options[val][0], bool):
685 elif isinstance(options[val][0], list):
686 opts.append(
" ".join(options[val][0]))
687 elif isinstance(options[val][0], int):
688 opts.append(str(options[val][0]))
690 opts.append(options[val][0])
691 opts.append(options[val][1])
696 for i
in range(0,len(opts),3):
701 if len(opts[i]) > max1:
703 if type(opts[i+1])
is not str:
704 optout = str(opts[i+1])
707 if len(optout) > max2:
716 for i
in range(0,len(opts),3):
717 line = opts[i] + (max1-len(opts[i]))*sp
718 if type(opts[i+1])
is not str:
719 optout = str(opts[i+1])
722 line = line + optout + (max2-len(optout))*sp
726 if 130 < (len(line) + len(opts[i+2])):
728 words = opts[i+2].split()
731 if (len(line) + len(word)) < 130:
736 line = line +
" " + word
739 line = (max1 + max2)*sp + word
744 line = line + opts[i+2]
753 if category ==
"stage":
755 availStages = list(self.loader.stages.keys())
756 for stage
in availStages:
757 for pluginInfo
in self.stages.getPluginsOfCategory(stage):
758 if name == pluginInfo.plugin_object.print_name():
759 return pluginInfo.plugin_object
764 elif category ==
"tool":
766 availTools = list(self.loader.tools.keys())
767 for tool
in availTools:
768 for pluginInfo
in self.tools.getPluginsOfCategory(tool):
769 if name == pluginInfo.plugin_object.print_name():
770 return pluginInfo.plugin_object
775 elif category ==
"utility":
777 availUtils = list(self.loader.utilities.keys())
778 for util
in availUtils:
779 for pluginInfo
in self.utilities.getPluginsOfCategory(util):
780 if name == pluginInfo.plugin_object.print_name():
781 return pluginInfo.plugin_object
787 print(
"Unrecognized category:",category)
def fill_log_interpolation