19 from yapsy.PluginManager
import PluginManager
30 parser = argparse.ArgumentParser(
31 formatter_class=argparse.RawDescriptionHelpFormatter,
33 Environment Variables:
34 MTT_HOME - this must be set to the top-level directory of your MTT installation.
35 MTT_ARGS - list of commandline arguments that you want set for each invocation.
36 Example: export MTT_ARGS="--verbose --log=/tmp/out.log"
39 parser.add_argument(
'ini_files', action=
'append', metavar=
'FILE', nargs=
'*', help =
".ini file to be used")
41 infoGroup = parser.add_argument_group(
'InfoGroup',
'Informational Options')
42 infoGroup.add_argument(
"-v",
"--version",
43 action=
"store_true", dest=
"version", default=
False,
45 infoGroup.add_argument(
"--list-stages",
46 action=
"store_true", dest=
"listsections", default=
False,
47 help=
"List section names understood by this client")
48 infoGroup.add_argument(
"--list-stage-plugins",
49 action=
"store", dest=
"listplugins", metavar=
"STAGE",
50 help=
"List available plugins for SECTION (* => all)")
51 infoGroup.add_argument(
"--list-stage-options",
52 action=
"store", dest=
"liststageoptions", metavar=
"STAGE",
53 help=
"List available options for STAGE (* => all)")
54 infoGroup.add_argument(
"--list-tools",
55 action=
"store_true", dest=
"listtools", default=
False,
56 help=
"List tools available to this client")
57 infoGroup.add_argument(
"--list-tool-plugins",
58 action=
"store", dest=
"listtoolmodules", metavar=
"TYPE",
59 help=
"List available modules for TYPE (* => all)")
60 infoGroup.add_argument(
"--list-tool-options",
61 action=
"store", dest=
"listtooloptions", metavar=
"TOOL",
62 help=
"List available options for TOOL (* => all)")
63 infoGroup.add_argument(
"--list-utilities",
64 action=
"store_true", dest=
"listutils", default=
False,
65 help=
"List utilities available to this client")
66 infoGroup.add_argument(
"--list-utility-plugins",
67 action=
"store", dest=
"listutilmodules", metavar=
"TYPE",
68 help=
"List available modules for TYPE (* => all)")
69 infoGroup.add_argument(
"--list-utility-options",
70 action=
"store", dest=
"listutiloptions", metavar=
"UTILITY",
71 help=
"List available options for UTILITY (* => all)")
73 execGroup = parser.add_argument_group(
'execGroup',
"Execution Options")
74 execGroup.add_argument(
"--description", dest=
"description",
75 help=
"Provide a brief title/description to be included in the log for this test")
76 execGroup.add_argument(
"-e",
"--executor", dest=
"executor",
77 help=
"Use the specified execution STRATEGY module", metavar=
"STRATEGY")
78 execGroup.add_argument(
"--base-dir", dest=
"basedir",
79 help=
"Specify the DIRECTORY where we can find the TestDef class (checks DIRECTORY, DIRECTORY/Utilities, and DIRECTORY/pylib/Utilities locations) - also serves as default plugin-dir", metavar=
"DIRECTORY")
80 execGroup.add_argument(
"--plugin-dir", dest=
"plugindir",
81 help=
"Specify the DIRECTORY where additional plugins can be found (or comma-delimited list of DIRECTORYs)", metavar=
"DIRECTORY")
82 execGroup.add_argument(
"--ignore-loadpath-errors", action=
"store_true", dest=
"ignoreloadpatherrs", default=
False,
83 help=
"Ignore errors in plugin paths")
84 execGroup.add_argument(
"--scratch-dir", dest=
"scratchdir", default=
None,
85 help=
"Specify the DIRECTORY under which scratch files are to be stored", metavar=
"DIRECTORY")
86 execGroup.add_argument(
"--print-section-time", dest=
"sectime",
87 action=
"store_true", default=
True,
88 help=
"Display section timestamps and execution time")
89 execGroup.add_argument(
"--print-cmd-time", dest=
"cmdtime",
90 action=
"store_true", default=
False,
91 help=
"Display stdout/stderr timestamps and cmd execution time")
92 execGroup.add_argument(
"--timestamp", dest=
"time",
93 action=
"store_true", default=
False,
94 help=
"Alias for --print-section-time --print-cmd-time")
95 execGroup.add_argument(
"--clean-start", dest=
"clean",
97 help=
"Clean the scratch directory from past MTT invocations before running")
98 execGroup.add_argument(
"-c",
"--cleanup", dest=
"clean_after",
100 help=
"Clean the scratch directory after a successful run")
101 execGroup.add_argument(
"-s",
"--sections", dest=
"section",
102 help=
"Execute the specified SECTION (or comma-delimited list of SECTIONs)", metavar=
"SECTION")
103 execGroup.add_argument(
"--skip-sections", dest=
"skipsections",
104 help=
"Skip the specified SECTION (or comma-delimited list of SECTIONs)", metavar=
"SECTION")
105 execGroup.add_argument(
"-l",
"--log", dest=
"logfile", default=
None,
106 help=
"Log all output to FILE (defaults to stdout)", metavar=
"FILE")
107 execGroup.add_argument(
"--group-results", dest=
"submit_group_results", default=
True,
108 help=
"Report results from each test section as it is completed")
109 execGroup.add_argument(
"--default-make-options", dest=
"default_make_options", default=
"-j10",
110 help=
"Default options when running the \"make\" command")
111 execGroup.add_argument(
"--env-module-wrapper", dest=
"env_module_wrapper", default=
None,
112 help=
"Python environment module wrapper")
113 execGroup.add_argument(
"--stop-on-fail", dest=
"stop_on_fail",
114 action=
"store_true", default=
False,
115 help=
"If a stage fails, exit and issue a non-zero return code")
116 execGroup.add_argument(
"--duration",
117 dest=
"duration", default=
None,
118 help=
"Add a maximum duration for test before interrupting.")
119 execGroup.add_argument(
"--loop",
120 dest=
"loop", default=
None,
121 help=
"Causes MTT to loop until provided number of seconds finishes")
122 execGroup.add_argument(
"--loopforever", dest=
"loopforever",
123 action=
"store_true", default=
False,
124 help=
"Causes MTT to continue to loop forever running same set of tests")
125 execGroup.add_argument(
"--harass_trigger",
126 dest=
"harass_trigger_scripts", default=
None,
127 help=
"Paths to scripts that are run to harass the system while the test is running.")
128 execGroup.add_argument(
"--harass_stop",
129 dest=
"harass_stop_scripts", default=
None,
130 help=
"Paths to scripts that are run to stop harassing the system after the test finishes.")
131 execGroup.add_argument(
"--harass_join_timeout",
132 dest=
"harass_join_timeout", default=
None,
133 help=
"Number of seconds to wait while ending harass scripts. Default is infinity.")
135 debugGroup = parser.add_argument_group(
'debugGroup',
'Debug Options')
136 debugGroup.add_argument(
"-d",
"--debug", dest=
"debug",
137 action=
"store_true", default=
False,
138 help=
"Output lots of debug messages")
139 debugGroup.add_argument(
"--verbose",
140 action=
"store_true", dest=
"verbose", default=
False,
141 help=
"Output some status/verbose messages while processing")
142 debugGroup.add_argument(
"--extraverbose",
143 action=
"store_true", dest=
"extraverbose", default=
False,
144 help=
"Output timestamps with every verbose message")
145 debugGroup.add_argument(
"--dryrun",
146 action=
"store_true", dest=
"dryrun", default=
False,
147 help=
"Show commands, but do not execute them")
148 debugGroup.add_argument(
"--trial",
149 action=
"store_true", dest=
"trial", default=
False,
150 help=
"Use when testing your MTT client setup; results that are generated and submitted to the database are marked as \"trials\" and are not included in normal reporting.")
152 elkGroup = parser.add_argument_group(
'elkGroup',
'ELK-friendly output options')
153 elkGroup.add_argument(
"--elk_testcase", dest=
"elk_testcase",
154 default=os.environ[
'MTT_ELK_TESTCASE']
if 'MTT_ELK_TESTCASE' in os.environ
else None,
155 help=
"Specifies which testcase to log results as when using elk-friendly output. You can also set this through the enviroment variable MTT_ELK_TESTCASE")
156 elkGroup.add_argument(
"--elk_testcycle", dest=
"elk_testcycle",
157 default=os.environ[
'MTT_ELK_TESTCYCLE']
if 'MTT_ELK_TESTCYCLE' in os.environ
else None,
158 help=
"Specifies which testcycle to log results as when using elk-friendly output. You can also set this through the enviroment variable MTT_ELK_TESTCYCLE")
159 elkGroup.add_argument(
"--elk_id", dest=
"elk_id",
160 default=os.environ[
'MTT_ELK_ID']
if 'MTT_ELK_ID' in os.environ
else None,
161 help=
"Specifies which execution id to log results as when using elk-friendly output. You can also set this through the enviroment variable MTT_ELK_ID")
162 elkGroup.add_argument(
"--elk_head", dest=
"elk_head",
163 default=os.environ[
'MTT_ELK_HEAD']
if 'MTT_ELK_HEAD' in os.environ
else None,
164 help=
"Specifies which location to log <caseid>_<elk_id>.elog files for elk-friendly output. You can also set this through the environment variable MTT_ELK_HEAD")
165 elkGroup.add_argument(
"--elk_chown", dest=
"elk_chown",
166 default=os.environ[
'MTT_ELK_CHOWN']
if 'MTT_ELK_CHOWN' in os.environ
else None,
167 help=
"Specifies what user and group to set for *.elog file permissions. You can also set this through the environment variable MTT_ELK_CHOWN")
168 elkGroup.add_argument(
"--elk_maxsize", dest=
"elk_maxsize",
169 default=os.environ[
'MTT_ELK_MAXSIZE']
if 'MTT_ELK_MAXSIZE' in os.environ
else None,
170 help=
"Specifies a max number of lines to log for stdout and stderr in elk-friendly output, and otherwise truncate. You can also set this through the environment variable MTT_ELK_MAXSIZE")
171 elkGroup.add_argument(
"--elk_nostdout", dest=
"elk_nostdout", action=
"store_true",
172 default=
True if 'MTT_ELK_NOSTDOUT' in os.environ
and os.environ[
'MTT_ELK_NOSTDOUT'].lower() !=
'false' else False,
173 help=
"Specifies whether to include stdout in elk-friendly output. You can also set this through the environment variable MTT_ELK_NOSTDOUT")
174 elkGroup.add_argument(
"--elk_nostderr", dest=
"elk_nostderr", action=
"store_true",
175 default=
True if 'MTT_ELK_NOSTDERR' in os.environ
and os.environ[
'MTT_ELK_NOSTDERR'].lower() !=
'false' else False,
176 help=
"Specifies whether to include stdout in elk-friendly output. You can also set this through the environment variable MTT_ELK_NOSTDERR")
177 elkGroup.add_argument(
"--elk_debug", dest=
"elk_debug", action=
"store_true",
178 default=
True if 'MTT_ELK_DEBUG' in os.environ
and os.environ[
'MTT_ELK_DEBUG'].lower() !=
'false' else False,
179 help=
"Specifies whether to output everything logged to *.elog files to the screen as extra verbose output. You can also set this through the environment variable MTT_ELK_DEBUG")
180 elkGroup.add_argument(
"--elk_hide_execmd", dest=
"elk_hide_execmd",
181 default=
True if 'MTT_ELK_HIDE_EXECID' in os.environ
and os.environ[
'MTT_ELK_HIDE_EXECID'].lower() !=
'false' else False,
182 help=
"Comma delimited list of plugins and/or sections to hide execmd output from. Also set through environment variable MTT_ELK_HIDE_EXECMD. Use \"Default\" to hide execmd output when no plugin is specified.")
184 args = parser.parse_args()
189 if 'MTT_ARGS' in os.environ
and os.environ.get(
'MTT_ARGS') !=
None:
190 mttArgs = shlex.split(os.environ[
'MTT_ARGS'])
191 args = parser.parse_args(sys.argv[1:] + mttArgs)
195 mtthome = os.environ[
'MTT_HOME']
197 print(
"MTT_HOME could not be found in your environment")
198 print(
"Python client requires that this be set and point")
199 print(
"to the top-level directory of your MTT installation")
203 if not os.path.isabs(mtthome):
204 print(
"MTT_HOME environment variable:")
206 print(
"is not an absolute path")
210 if not os.path.exists(mtthome):
211 print(
"MTT_HOME points to a non-existent location:")
213 print(
"Please correct")
217 topdir = os.path.join(mtthome,
"pylib")
218 if not os.path.exists(topdir)
or not os.path.isdir(topdir):
219 print(
"MTT_HOME points to a location that does not\ninclude the \"pylib\" subdirectory:")
221 print(
"does not exist. Please correct")
225 if args.basedir
and not os.path.isabs(args.basedir):
226 print(
"The basedir cmd line option is not an absolute path:")
227 print(
" ", args.basedir)
228 print(
"Please correct")
231 basedir = args.basedir
or os.path.join(mtthome,
"pylib",
"System")
232 if not os.path.exists(basedir)
or not os.path.isdir(basedir):
233 if basedir == args.basedir:
234 print(
"The basedir cmd line option points to a location that does not exist:")
236 print(
"Please correct")
238 print(
"MTT_HOME points to a location that does not\ninclude the \"pylib/System\" subdirectory:")
240 print(
"does not exist. Please correct")
245 logging.basicConfig(level=logging.DEBUG)
250 m = imp.load_source(
"TestDef", os.path.join(basedir,
"TestDef.py"))
252 print(
"ERROR: unable to load TestDef that must contain the Test Definition object")
254 cls = getattr(m,
"TestDef")
259 testDef = a.__class__();
260 testDef.setOptions(args)
263 testDef.loadPlugins(basedir, topdir)
271 if not args.ini_files
or not args.ini_files[0]:
272 sys.exit(
'MTT requires at least one test-specification file')
275 if args.section
and args.skipsections:
276 print(
"ERROR: Cannot both execute specific sections and specify sections to be skipped")
284 testDef.openElkLogger()
291 fallback =
"sequential"
292 executor = args.executor
or testDef.config.get(
'MTTDefaults',
'executor', fallback=fallback)
296 testDef.config.set(
'MTTDefaults',
'executor', executor.lower())
298 status = testDef.executeTest(executor=executor.lower())