Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Unified Diff: tools/nocompile_driver.py

Issue 2644003002: Make no-compile test deterministic (Closed)
Patch Set: fix comments Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/nocompile_driver.py
diff --git a/tools/nocompile_driver.py b/tools/nocompile_driver.py
index 1c48c4ba54570e45f887298ee9e4673315687b4d..5e5e7396b4d6a53e218d0688a2d6242d54c44bd0 100755
--- a/tools/nocompile_driver.py
+++ b/tools/nocompile_driver.py
@@ -15,7 +15,6 @@ For more info, see:
import StringIO
import ast
-import locale
import os
import re
import select
@@ -66,15 +65,13 @@ RESULT_FILE_HEADER = """
"""
-# The GUnit test function to output on a successful test completion.
-SUCCESS_GUNIT_TEMPLATE = """
-TEST(%s, %s) {
- LOG(INFO) << "Took %f secs. Started at %f, ended at %f";
-}
+# The log message on a test completion.
+LOG_TEMPLATE = """
+TEST(%s, %s) took %f secs. Started at %f, ended at %f.
"""
-# The GUnit test function to output for a disabled test.
-DISABLED_GUNIT_TEMPLATE = """
+# The GUnit test function to output for a successful or disabled test.
dcheng 2017/01/19 05:36:22 Nit: probably OK to just remove "successful or dis
wychen 2017/01/19 15:43:57 But failed tests wouldn't use this template.
+GUNIT_TEMPLATE = """
TEST(%s, %s) { }
"""
@@ -241,24 +238,25 @@ def StartTest(sourcefile_path, cflags, config):
'expectations': expectations}
-def PassTest(resultfile, test):
+def PassTest(resultfile, resultlog, test):
"""Logs the result of a test started by StartTest(), or a disabled test
configuration.
Args:
resultfile: File object for .cc file that results are written to.
+ resultlog: File object for the log file.
test: An instance of the dictionary returned by StartTest(), a
configuration from ExtractTestConfigs().
"""
+ resultfile.write(GUNIT_TEMPLATE % (
+ test['suite_name'], test['name']))
+
# The 'started_at' key is only added if a test has been started.
if 'started_at' in test:
- resultfile.write(SUCCESS_GUNIT_TEMPLATE % (
+ resultlog.write(LOG_TEMPLATE % (
test['suite_name'], test['name'],
test['finished_at'] - test['started_at'],
test['started_at'], test['finished_at']))
- else:
- resultfile.write(DISABLED_GUNIT_TEMPLATE % (
- test['suite_name'], test['name']))
def FailTest(resultfile, test, error, stdout=None, stderr=None):
@@ -285,31 +283,32 @@ def FailTest(resultfile, test, error, stdout=None, stderr=None):
resultfile.write('\n')
-def WriteStats(resultfile, suite_name, timings):
- """Logs the peformance timings for each stage of the script into a fake test.
+def WriteStats(resultlog, suite_name, timings):
+ """Logs the peformance timings for each stage of the script.
Args:
- resultfile: File object for .cc file that results are written to.
+ resultlog: File object for the log file.
suite_name: The name of the GUnit suite this test belongs to.
timings: Dictionary with timestamps for each stage of the script run.
"""
- stats_template = ("Started %f, Ended %f, Total %fs, Extract %fs, "
- "Compile %fs, Process %fs")
+ stats_template = """
+TEST(%s): Started %f, Ended %f, Total %fs, Extract %fs, Compile %fs, Process %fs
+"""
total_secs = timings['results_processed'] - timings['started']
extract_secs = timings['extract_done'] - timings['started']
compile_secs = timings['compile_done'] - timings['extract_done']
process_secs = timings['results_processed'] - timings['compile_done']
- resultfile.write('TEST(%s, Stats) { LOG(INFO) << "%s"; }\n' % (
- suite_name, stats_template % (
- timings['started'], timings['results_processed'], total_secs,
- extract_secs, compile_secs, process_secs)))
+ resultlog.write(stats_template % (
+ suite_name, timings['started'], timings['results_processed'], total_secs,
+ extract_secs, compile_secs, process_secs))
-def ProcessTestResult(resultfile, test):
+def ProcessTestResult(resultfile, resultlog, test):
"""Interprets and logs the result of a test started by StartTest()
Args:
resultfile: File object for .cc file that results are written to.
+ resultlog: File object for the log file.
test: The dictionary from StartTest() to process.
"""
# Snap a copy of stdout and stderr into the test dictionary immediately
@@ -333,14 +332,14 @@ def ProcessTestResult(resultfile, test):
# Check the output has the right expectations. If there are no
# expectations, then we just consider the output "matched" by default.
if len(test['expectations']) == 0:
- PassTest(resultfile, test)
+ PassTest(resultfile, resultlog, test)
return
# Otherwise test against all expectations.
for regexp in test['expectations']:
if (regexp.search(stdout) is not None or
regexp.search(stderr) is not None):
- PassTest(resultfile, test)
+ PassTest(resultfile, resultlog, test)
return
expectation_str = ', '.join(
["r'%s'" % regexp.pattern for regexp in test['expectations']])
@@ -350,7 +349,7 @@ def ProcessTestResult(resultfile, test):
return
-def CompleteAtLeastOneTest(resultfile, executing_tests):
+def CompleteAtLeastOneTest(executing_tests):
"""Blocks until at least one task is removed from executing_tests.
This function removes completed tests from executing_tests, logging failures
@@ -375,7 +374,7 @@ def CompleteAtLeastOneTest(resultfile, executing_tests):
read_set = []
for test in executing_tests.values():
read_set.extend([test['proc'].stderr, test['proc'].stdout])
- result = select.select(read_set, [], read_set, NCTEST_TERMINATE_TIMEOUT_SEC)
+ select.select(read_set, [], read_set, NCTEST_TERMINATE_TIMEOUT_SEC)
# Now attempt to process results.
now = time.time()
@@ -425,6 +424,7 @@ def main():
timings['extract_done'] = time.time()
resultfile = StringIO.StringIO()
+ resultlog = StringIO.StringIO()
resultfile.write(RESULT_FILE_HEADER % sourcefile_path)
# Run the no-compile tests, but ensure we do not run more than |parallelism|
@@ -447,10 +447,10 @@ def main():
# acts as a semaphore. We cannot use threads + a real semaphore because
# subprocess forks, which can cause all sorts of hilarity with threads.
if len(executing_tests) >= parallelism:
- finished_tests.extend(CompleteAtLeastOneTest(resultfile, executing_tests))
+ finished_tests.extend(CompleteAtLeastOneTest(executing_tests))
if config['name'].startswith('DISABLED_'):
- PassTest(resultfile, config)
+ PassTest(resultfile, resultlog, config)
else:
test = StartTest(sourcefile_path, cflags, config)
assert test['name'] not in executing_tests
@@ -459,7 +459,7 @@ def main():
# If there are no more test to start, we still need to drain the running
# ones.
while len(executing_tests) > 0:
- finished_tests.extend(CompleteAtLeastOneTest(resultfile, executing_tests))
+ finished_tests.extend(CompleteAtLeastOneTest(executing_tests))
timings['compile_done'] = time.time()
for test in finished_tests:
@@ -469,11 +469,13 @@ def main():
if return_code != 0:
sys.stderr.write(stderr)
continue
- ProcessTestResult(resultfile, test)
+ ProcessTestResult(resultfile, resultlog, test)
timings['results_processed'] = time.time()
- WriteStats(resultfile, suite_name, timings)
+ WriteStats(resultlog, suite_name, timings)
+ with open(resultfile_path + '.log', 'w') as fd:
+ fd.write(resultlog.getvalue())
if return_code == 0:
with open(resultfile_path, 'w') as fd:
fd.write(resultfile.getvalue())
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698