Bug 753619 - Fix progress bar totals in jstests.py; r=dmandelin

Something in the previous refactorings has messed up the display of the
progress bar such that it occasionally jumps over 100% and 80chars.
This commit is contained in:
Terrence Cole 2012-05-10 16:06:41 -07:00
parent 6bf0f798df
commit aca286389c
3 changed files with 42 additions and 48 deletions

View File

@ -21,25 +21,12 @@ else:
def run_tests(options, tests, results):
"""Run the given tests, sending raw results to the given results accumulator."""
pb = None
if not options.hide_progress:
try:
from lib.progressbar import ProgressBar
pb = ProgressBar('', len(tests), 16)
except ImportError:
pass
results.pb = pb
try:
results.finished = run_all_tests(tests, results, options)
completed = run_all_tests(tests, results, options)
except KeyboardInterrupt:
results.finished = False
completed = False
if pb:
pb.finish()
if not options.tinderbox:
results.list()
results.finish(completed)
def parse_args():
"""
@ -107,14 +94,14 @@ def parse_args():
options, args = op.parse_args()
# Acquire the JS shell given on the command line.
js_shell = None
options.js_shell = None
requested_paths = set()
if len(args) > 0:
js_shell = os.path.abspath(args[0])
options.js_shell = os.path.abspath(args[0])
requested_paths |= set(args[1:])
# If we do not have a shell, we must be in a special mode.
if js_shell is None and not options.make_manifests:
if options.js_shell is None and not options.make_manifests:
op.error('missing JS_SHELL argument')
# Valgrind and gdb are mutually exclusive.
@ -128,7 +115,7 @@ def parse_args():
if os.uname()[0] == 'Darwin':
prefix.append('--dsymutil=yes')
options.show_output = True
TestCase.set_js_cmd_prefix(js_shell, options.shell_args.split(), prefix)
TestCase.set_js_cmd_prefix(options.js_shell, options.shell_args.split(), prefix)
# If files with lists of tests to run were specified, add them to the
# requested tests set.
@ -152,19 +139,20 @@ def parse_args():
fp.close()
# Handle output redirection, if requested and relevant.
output_file = sys.stdout
options.output_fp = sys.stdout
if options.output_file and (options.show_cmd or options.show_output):
output_file = open(options.output_file, 'w')
ResultsSink.output_file = output_file
try:
options.output_fp = open(options.output_file, 'w')
except IOError, ex:
raise SystemExit("Failed to open output file: " + str(ex))
# Hide the progress bar if it will get in the way of other output.
if ((options.show_cmd or options.show_output) and
output_file == sys.stdout or options.tinderbox):
options.hide_progress = True
options.hide_progress = ((options.show_cmd or options.show_output) and
options.output_fp == sys.stdout or options.tinderbox)
return (options, js_shell, requested_paths, excluded_paths)
return (options, requested_paths, excluded_paths)
def load_tests(options, js_shell, requested_paths, excluded_paths):
def load_tests(options, requested_paths, excluded_paths):
"""
Returns a tuple: (skipped_tests, test_list)
skip_list: [iterable<Test>] Tests found but skipped.
@ -172,16 +160,16 @@ def load_tests(options, js_shell, requested_paths, excluded_paths):
"""
import lib.manifest as manifest
if js_shell is None:
if options.js_shell is None:
xul_tester = manifest.NullXULInfoTester()
else:
if options.xul_info_src is None:
xul_info = manifest.XULInfo.create(js_shell)
xul_info = manifest.XULInfo.create(options.js_shell)
else:
xul_abi, xul_os, xul_debug = options.xul_info_src.split(r':')
xul_debug = xul_debug.lower() is 'true'
xul_info = manifest.XULInfo(xul_abi, xul_os, xul_debug)
xul_tester = manifest.XULInfoTester(xul_info, js_shell)
xul_tester = manifest.XULInfoTester(xul_info, options.js_shell)
test_dir = os.path.dirname(os.path.abspath(__file__))
test_list = manifest.load(test_dir, xul_tester)
@ -229,8 +217,8 @@ def load_tests(options, js_shell, requested_paths, excluded_paths):
return skip_list, test_list
def main():
options, js_shell, requested_paths, excluded_paths = parse_args()
skip_list, test_list = load_tests(options, js_shell, requested_paths, excluded_paths)
options, requested_paths, excluded_paths = parse_args()
skip_list, test_list = load_tests(options, requested_paths, excluded_paths)
if not test_list:
print 'no tests selected'
@ -259,16 +247,13 @@ def main():
results = None
try:
results = ResultsSink(ResultsSink.output_file, options)
results = ResultsSink(options, len(skip_list) + len(test_list))
for t in skip_list:
results.push(NullTestOutput(t))
run_tests(options, test_list, results)
finally:
os.chdir(curdir)
if ResultsSink.output_file != sys.stdout:
ResultsSink.output_file.close()
if results is None or not results.all_passed():
return 1

View File

@ -23,8 +23,9 @@ class ProgressBar:
sys.stdout.write(self.fmt % (self.label[:self.label_width], pct, bar, dt))
sys.stdout.flush()
def finish(self):
self.update(self.limit)
def finish(self, complete=True):
final_count = self.limit if complete else self.cur
self.update(final_count)
sys.stdout.write('\n')
if __name__ == '__main__':

View File

@ -1,5 +1,6 @@
import re
from subprocess import list2cmdline
from progressbar import ProgressBar
class TestOutput:
"""Output from a test run."""
@ -77,16 +78,17 @@ class TestResult:
return cls(test, result, results)
class ResultsSink:
def __init__(self, output_file, options):
self.output_file = output_file
def __init__(self, options, testcount):
self.options = options
self.fp = options.output_fp
self.groups = {}
self.counts = [ 0, 0, 0 ]
self.n = 0
self.finished = False
self.pb = None
if not options.hide_progress:
self.pb = ProgressBar('', testcount, 16)
def push(self, output):
if isinstance(output, NullTestOutput):
@ -96,12 +98,12 @@ class ResultsSink:
self.n += 1
else:
if self.options.show_cmd:
print >> self.output_file, list2cmdline(output.cmd)
print >> self.fp, list2cmdline(output.cmd)
if self.options.show_output:
print >> self.output_file, ' rc = %d, run time = %f' % (output.rc, output.dt)
self.output_file.write(output.out)
self.output_file.write(output.err)
print >> self.fp, ' rc = %d, run time = %f' % (output.rc, output.dt)
self.fp.write(output.out)
self.fp.write(output.err)
result = TestResult.from_output(output)
tup = (result.result, result.test.expect, result.test.random)
@ -134,6 +136,12 @@ class ResultsSink:
self.pb.label = '[%4d|%4d|%4d]'%tuple(self.counts)
self.pb.update(self.n)
def finish(self, completed):
if self.pb:
self.pb.finish(completed)
if not self.options.tinderbox:
self.list(completed)
# Conceptually, this maps (test result x test expection) to text labels.
# key is (result, expect, random)
# value is (tinderbox label, dev test category)
@ -154,7 +162,7 @@ class ResultsSink:
(TestResult.PASS, True, True): ('TEST-PASS (EXPECTED RANDOM)', ''),
}
def list(self):
def list(self, completed):
for label, paths in sorted(self.groups.items()):
if label == '': continue
@ -173,7 +181,7 @@ class ResultsSink:
print >> failure_file, path
failure_file.close()
suffix = '' if self.finished else ' (partial run -- interrupted by user)'
suffix = '' if completed else ' (partial run -- interrupted by user)'
if self.all_passed():
print 'PASS' + suffix
else: