12 class TestOrder(enum
.Enum
):
19 parser
= argparse
.ArgumentParser(prog
="lit", fromfile_prefix_chars
="@")
24 help="File or path to include in the test suite",
28 "--version", action
="version", version
="%(prog)s " + lit
.__version
__
37 help="Number of workers used for testing",
39 default
=lit
.util
.usable_core_count(),
45 help="Prefix for 'lit' config files",
52 help="Add 'NAME' = 'VAL' to the user defined parameters",
57 format_group
= parser
.add_argument_group("Output Format")
58 # FIXME: I find these names very confusing, although I like the
60 format_group
.add_argument(
61 "-q", "--quiet", help="Suppress no error output", action
="store_true"
63 format_group
.add_argument(
66 help="Reduce amount of output."
67 " Additionally, show a progress bar,"
68 " unless --no-progress-bar is specified.",
71 format_group
.add_argument(
75 help="Show test output for failures",
78 format_group
.add_argument(
80 "--echo-all-commands",
81 dest
="echoAllCommands",
83 help="Echo all commands as they are executed to stdout. In case of "
84 "failure, last command shown will be the failing one.",
86 format_group
.add_argument(
90 help="Display all commandlines and output",
93 format_group
.add_argument(
96 type=lit
.reports
.JsonReport
,
97 help="Write test results to the provided path",
100 format_group
.add_argument(
102 dest
="useProgressBar",
103 help="Do not use curses based progress bar",
104 action
="store_false",
107 # Note: this does not generate flags for user-defined result codes.
108 success_codes
= [c
for c
in lit
.Test
.ResultCode
.all_codes() if not c
.isFailure
]
109 for code
in success_codes
:
110 format_group
.add_argument(
111 "--show-{}".format(code
.name
.lower()),
113 help="Show {} tests ({})".format(code
.label
.lower(), code
.name
),
114 action
="append_const",
119 execution_group
= parser
.add_argument_group("Test Execution")
120 execution_group
.add_argument(
122 help="Additional paths to add to testing environment",
125 type=os
.path
.abspath
,
127 execution_group
.add_argument(
128 "--vg", dest
="useValgrind", help="Run tests under valgrind", action
="store_true"
130 execution_group
.add_argument(
132 dest
="valgrindLeakCheck",
133 help="Check for memory leaks under valgrind",
136 execution_group
.add_argument(
140 help="Specify an extra argument for valgrind",
144 execution_group
.add_argument(
146 help="Track elapsed wall time for each test",
149 execution_group
.add_argument(
152 help="Don't execute any tests (assume PASS)",
155 execution_group
.add_argument(
156 "--xunit-xml-output",
157 type=lit
.reports
.XunitReport
,
158 help="Write XUnit-compatible XML test reports to the specified file",
160 execution_group
.add_argument(
162 type=lit
.reports
.ResultDBReport
,
163 help="Write LuCI ResuldDB compatible JSON to the specified file",
165 execution_group
.add_argument(
166 "--time-trace-output",
167 type=lit
.reports
.TimeTraceReport
,
168 help="Write Chrome tracing compatible JSON to the specified file",
170 execution_group
.add_argument(
172 dest
="maxIndividualTestTime",
173 help="Maximum time to spend running a single test (in seconds). "
174 "0 means no time limit. [Default: 0]",
175 type=_non_negative_int
,
177 execution_group
.add_argument(
179 help="Stop execution after the given number of failures.",
182 execution_group
.add_argument(
183 "--allow-empty-runs",
184 help="Do not fail the run if all tests are filtered out",
187 execution_group
.add_argument(
191 help="Exit with status zero even if some tests fail",
193 execution_group
.add_argument(
194 "--no-indirectly-run-check",
195 dest
="indirectlyRunCheck",
196 help="Do not error if a test would not be run if the user had "
197 "specified the containing directory instead of naming the "
199 action
="store_false",
202 selection_group
= parser
.add_argument_group("Test Selection")
203 selection_group
.add_argument(
206 help="Maximum number of tests to run",
209 selection_group
.add_argument(
213 help="Maximum time to spend testing (in seconds)",
216 selection_group
.add_argument(
218 choices
=[x
.value
for x
in TestOrder
],
219 default
=TestOrder
.SMART
,
220 help="Test order to use (default: smart)",
222 selection_group
.add_argument(
225 help="Run tests in random order (DEPRECATED: use --order=random)",
226 action
="store_const",
227 const
=TestOrder
.RANDOM
,
229 selection_group
.add_argument(
232 help="Run failed tests first (DEPRECATED: use --order=smart)",
235 selection_group
.add_argument(
238 type=_case_insensitive_regex
,
239 help="Only run tests with paths matching the given regular expression",
240 default
=os
.environ
.get("LIT_FILTER", ".*"),
242 selection_group
.add_argument(
245 type=_case_insensitive_regex
,
246 help="Filter out tests with paths matching the given regular expression",
247 default
=os
.environ
.get("LIT_FILTER_OUT", "^$"),
249 selection_group
.add_argument(
252 type=_semicolon_list
,
253 help="XFAIL tests with paths in the semicolon separated list",
254 default
=os
.environ
.get("LIT_XFAIL", ""),
256 selection_group
.add_argument(
259 type=_semicolon_list
,
260 help="do not XFAIL tests with paths in the semicolon separated list",
261 default
=os
.environ
.get("LIT_XFAIL_NOT", ""),
263 selection_group
.add_argument(
267 help="Split testsuite into M pieces and only run one",
269 default
=os
.environ
.get("LIT_NUM_SHARDS"),
271 selection_group
.add_argument(
275 help="Run shard #N of the testsuite",
277 default
=os
.environ
.get("LIT_RUN_SHARD"),
280 debug_group
= parser
.add_argument_group("Debug and Experimental Options")
281 debug_group
.add_argument(
282 "--debug", help="Enable debugging (for 'lit' development)", action
="store_true"
284 debug_group
.add_argument(
286 help="Show discovered test suites and exit",
289 debug_group
.add_argument(
290 "--show-tests", help="Show all discovered tests and exit", action
="store_true"
292 debug_group
.add_argument(
293 "--show-used-features",
294 help="Show all features used in the test suite (in XFAIL, UNSUPPORTED and REQUIRES) and exit",
298 # LIT is special: environment variables override command line arguments.
299 env_args
= shlex
.split(os
.environ
.get("LIT_OPTS", ""))
300 args
= sys
.argv
[1:] + env_args
301 opts
= parser
.parse_args(args
)
303 # Validate command line options
304 if opts
.echoAllCommands
:
305 opts
.showOutput
= True
309 "WARNING: --incremental is deprecated. Failing tests now always run first."
312 if opts
.numShards
or opts
.runShard
:
313 if not opts
.numShards
or not opts
.runShard
:
314 parser
.error("--num-shards and --run-shard must be used together")
315 if opts
.runShard
> opts
.numShards
:
316 parser
.error("--run-shard must be between 1 and --num-shards (inclusive)")
317 opts
.shard
= (opts
.runShard
, opts
.numShards
)
321 opts
.reports
= filter(
325 opts
.xunit_xml_output
,
326 opts
.resultdb_output
,
327 opts
.time_trace_output
,
334 def _positive_int(arg
):
335 return _int(arg
, "positive", lambda i
: i
> 0)
338 def _non_negative_int(arg
):
339 return _int(arg
, "non-negative", lambda i
: i
>= 0)
342 def _int(arg
, kind
, pred
):
343 desc
= "requires {} integer, but found '{}'"
347 raise _error(desc
, kind
, arg
)
349 raise _error(desc
, kind
, arg
)
353 def _case_insensitive_regex(arg
):
357 return re
.compile(arg
, re
.IGNORECASE
)
358 except re
.error
as reason
:
359 raise _error("invalid regular expression: '{}', {}", arg
, reason
)
362 def _semicolon_list(arg
):
363 return arg
.split(";")
366 def _error(desc
, *args
):
367 msg
= desc
.format(*args
)
368 return argparse
.ArgumentTypeError(msg
)