Index: lnt/tests/test_suite.py =================================================================== --- lnt/tests/test_suite.py +++ lnt/tests/test_suite.py @@ -1,4 +1,4 @@ -import subprocess, tempfile, json, os, shlex, platform, pipes +import subprocess, tempfile, json, os, shlex, platform, pipes, sys from optparse import OptionParser, OptionGroup @@ -151,6 +151,20 @@ help="Do not submit the stat of this type [%default]", action='append', choices=KNOWN_SAMPLE_KEYS, type='choice', default=[]) + group.add_option("", "--single-result", dest="single_result", + help=("only execute one test and apply " + "--single-result-predicate to calculate the " + "exit status. Do not submit to a LNT instance " + "or create a JSON report (useful for bisection)")) + group.add_option("", "--single-result-predicate", + dest="single_result_predicate", + help=("the predicate to apply to calculate the exit " + "status (with --single-result). This is a Python " + "expression that will be eval()ed with all metrics " + "available as variables and a boolean 'status'. " + "Example: \n" + " status and exec_time < 3.0"), + default="status") parser.add_option_group(group) group = OptionGroup(parser, "Test tools") @@ -213,6 +227,9 @@ "invalid --test-externals argument, does not exist: %r" % ( opts.test_suite_externals,)) + if self.opts.single_result: + self.opts.only_test = os.path.dirname(self.opts.single_result) + opts.cmake = resolve_command_path(opts.cmake) if not isexecfile(opts.cmake): parser.error("CMake tool not found (looked for %s)" % opts.cmake) @@ -465,6 +482,19 @@ raw_name = test_data['name'].split(' :: ', 1)[1] name = 'nts.' + raw_name.rsplit('.test', 1)[0] is_pass = self._is_pass_code(test_data['code']) + + # If --single-result is given, exit based on --single-result-predicate + if self.opts.single_result and \ + raw_name == self.opts.single_result+'.test': + env = {'status': is_pass} + if 'metrics' in test_data: + for k,v in test_data['metrics'].items(): + env[k] = v + if k in LIT_METRIC_TO_LNT: + env[LIT_METRIC_TO_LNT[k]] = v + status = eval(self.opts.single_result_predicate, {}, env) + sys.exit(0 if status else 1) + if 'metrics' in test_data: for k,v in test_data['metrics'].items(): if k not in LIT_METRIC_TO_LNT or LIT_METRIC_TO_LNT[k] in ignore: @@ -487,6 +517,10 @@ [self._get_lnt_code(test_data['code'])], test_info)) + if self.opts.single_result: + # If we got this far, the result we were looking for didn't exist. + raise RuntimeError("Result %s did not exist!" % + self.opts.single_result) # FIXME: Add more machine info! run_info = {