aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Nicolas Noble <nnoble@google.com>2015-01-14 16:57:24 -0800
committerGravatar Nicolas Noble <nnoble@google.com>2015-01-14 17:28:12 -0800
commit044db7422a83368aa44eb0bbdfbffef19b61a800 (patch)
tree252ac9c849eb757b939796a59baca6389cf8774d
parente55e1155d3f8776b5645d0e741353da0820bdd92 (diff)
Various cosmetic improvements to run_tests.py
-) Adding a new command line flag to be able to see which tests are passing. -) Adding more status when the tool is idle in forever mode. -) Adding a last status when the tool is finished so to avoid leaving the console in a weird state. -) Adding a status message in the forever mode if the previous run failed. -) Swapped the message and its explanation, so you don't have to scroll up to see which test failed. -) Fixed a race condition in the watch_dir.py code if a file is deleted during the loop.
-rwxr-xr-xtools/run_tests/jobset.py37
-rwxr-xr-xtools/run_tests/run_tests.py21
-rwxr-xr-xtools/run_tests/watch_dirs.py7
3 files changed, 46 insertions, 19 deletions
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index 17fb1d6924..0214e95ed3 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -40,9 +40,11 @@ _KILLED = object()
_COLORS = {
- 'red': 31,
- 'green': 32,
- 'yellow': 33,
+ 'red': [ 31, 0 ],
+ 'green': [ 32, 0 ],
+ 'yellow': [ 33, 0 ],
+ 'lightgray': [ 37, 0],
+ 'gray': [ 30, 1 ],
}
@@ -53,32 +55,37 @@ _CLEAR_LINE = '\x1b[2K'
_TAG_COLOR = {
'FAILED': 'red',
'PASSED': 'green',
- 'START': 'yellow',
+ 'START': 'gray',
'WAITING': 'yellow',
+ 'SUCCESS': 'green',
+ 'IDLE': 'gray',
}
-def message(tag, message, explanatory_text=None):
- sys.stdout.write('%s%s\x1b[%dm%s\x1b[0m: %s%s' % (
+def message(tag, message, explanatory_text=None, do_newline=False):
+ sys.stdout.write('%s%s%s\x1b[%d;%dm%s\x1b[0m: %s%s' % (
_BEGINNING_OF_LINE,
_CLEAR_LINE,
- _COLORS[_TAG_COLOR[tag]],
+ '\n%s' % explanatory_text if explanatory_text is not None else '',
+ _COLORS[_TAG_COLOR[tag]][1],
+ _COLORS[_TAG_COLOR[tag]][0],
tag,
message,
- '\n%s\n' % explanatory_text if explanatory_text is not None else ''))
+ '\n' if do_newline or explanatory_text is not None else ''))
sys.stdout.flush()
class Job(object):
"""Manages one job."""
- def __init__(self, cmdline):
+ def __init__(self, cmdline, newline_on_success):
self._cmdline = ' '.join(cmdline)
self._tempfile = tempfile.TemporaryFile()
self._process = subprocess.Popen(args=cmdline,
stderr=subprocess.STDOUT,
stdout=self._tempfile)
self._state = _RUNNING
+ self._newline_on_success = newline_on_success
message('START', self._cmdline)
def state(self):
@@ -91,7 +98,7 @@ class Job(object):
message('FAILED', '%s [ret=%d]' % (self._cmdline, self._process.returncode), stdout)
else:
self._state = _SUCCESS
- message('PASSED', '%s' % self._cmdline)
+ message('PASSED', '%s' % self._cmdline, do_newline=self._newline_on_success)
return self._state
def kill(self):
@@ -103,13 +110,14 @@ class Job(object):
class Jobset(object):
"""Manages one run of jobs."""
- def __init__(self, check_cancelled, maxjobs):
+ def __init__(self, check_cancelled, maxjobs, newline_on_success):
self._running = set()
self._check_cancelled = check_cancelled
self._cancelled = False
self._failures = 0
self._completed = 0
self._maxjobs = maxjobs
+ self._newline_on_success = newline_on_success
def start(self, cmdline):
"""Start a job. Return True on success, False on failure."""
@@ -117,7 +125,7 @@ class Jobset(object):
if self.cancelled(): return False
self.reap()
if self.cancelled(): return False
- self._running.add(Job(cmdline))
+ self._running.add(Job(cmdline, self._newline_on_success))
return True
def reap(self):
@@ -157,9 +165,10 @@ def _never_cancelled():
return False
-def run(cmdlines, check_cancelled=_never_cancelled, maxjobs=None):
+def run(cmdlines, check_cancelled=_never_cancelled, maxjobs=None, newline_on_success=False):
js = Jobset(check_cancelled,
- maxjobs if maxjobs is not None else _DEFAULT_MAX_JOBS)
+ maxjobs if maxjobs is not None else _DEFAULT_MAX_JOBS,
+ newline_on_success)
for cmdline in shuffle_iteratable(cmdlines):
if not js.start(cmdline):
break
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 428f6c41b4..0e627d8f96 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -56,6 +56,10 @@ argp.add_argument('-f', '--forever',
default=False,
action='store_const',
const=True)
+argp.add_argument('--newline_on_success',
+ default=False,
+ action='store_const',
+ const=True)
args = argp.parse_args()
# grab config
@@ -69,7 +73,7 @@ runs_per_test = args.runs_per_test
forever = args.forever
-def _build_and_run(check_cancelled):
+def _build_and_run(check_cancelled, newline_on_success, forever=False):
"""Do one pass of building & running tests."""
# build latest, sharing cpu between the various makes
if not jobset.run(
@@ -88,20 +92,29 @@ def _build_and_run(check_cancelled):
for x in itertools.chain.from_iterable(itertools.repeat(
glob.glob('bins/%s/%s_test' % (
config.build_config, filt)),
- runs_per_test))), check_cancelled):
+ runs_per_test))), check_cancelled, newline_on_success=newline_on_success):
+ if not forever:
+ jobset.message('FAILED', 'Some tests failed', do_newline=True)
return 2
+ if not forever:
+ jobset.message('SUCCESS', 'All tests passed', do_newline=True)
return 0
if forever:
+ success = True
while True:
dw = watch_dirs.DirWatcher(['src', 'include', 'test'])
initial_time = dw.most_recent_change()
have_files_changed = lambda: dw.most_recent_change() != initial_time
- _build_and_run(have_files_changed)
+ previous_success = success
+ success = _build_and_run(have_files_changed, newline_on_success=False, forever=True) == 0
+ if not previous_success and success:
+ jobset.message('SUCCESS', 'All tests are now passing properly', do_newline=True)
+ jobset.message('IDLE', 'No change detected')
while not have_files_changed():
time.sleep(1)
else:
- sys.exit(_build_and_run(lambda: False))
+ sys.exit(_build_and_run(lambda: False, newline_on_success=args.newline_on_success))
diff --git a/tools/run_tests/watch_dirs.py b/tools/run_tests/watch_dirs.py
index 056e69a16c..9ef6924454 100755
--- a/tools/run_tests/watch_dirs.py
+++ b/tools/run_tests/watch_dirs.py
@@ -25,7 +25,12 @@ class DirWatcher(object):
continue
for root, _, files in os.walk(path):
for f in files:
- st = os.stat(os.path.join(root, f))
+ try:
+ st = os.stat(os.path.join(root, f))
+ except OSError as e:
+ if e.errno == os.errno.ENOENT:
+ continue
+ raise
if most_recent_change is None:
most_recent_change = st.st_mtime
else: