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

Unified Diff: presubmit_canned_checks.py

Issue 14247012: Add support for parallel presubmit unit testing. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: fix nits Created 7 years, 8 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 | « PRESUBMIT.py ('k') | presubmit_support.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: presubmit_canned_checks.py
diff --git a/presubmit_canned_checks.py b/presubmit_canned_checks.py
index 285077d9b70e838f077e8fab718c205ab2981e8a..cd3dc23b4316ec4bf559bb7280d7f80f1187c738 100644
--- a/presubmit_canned_checks.py
+++ b/presubmit_canned_checks.py
@@ -483,8 +483,7 @@ def CheckTreeIsOpen(input_api, output_api,
long_text=str(e))]
return []
-
-def RunUnitTestsInDirectory(
+def GetUnitTestsInDirectory(
input_api, output_api, directory, whitelist=None, blacklist=None):
"""Lists all files in a directory and runs them. Doesn't recurse.
@@ -517,10 +516,10 @@ def RunUnitTestsInDirectory(
'Out of %d files, found none that matched w=%r, b=%r in directory %s'
% (found, whitelist, blacklist, directory))
]
- return RunUnitTests(input_api, output_api, unit_tests)
+ return GetUnitTests(input_api, output_api, unit_tests)
-def RunUnitTests(input_api, output_api, unit_tests):
+def GetUnitTests(input_api, output_api, unit_tests):
"""Runs all unit tests in a directory.
On Windows, sys.executable is used for unit tests ending with ".py".
@@ -541,20 +540,14 @@ def RunUnitTests(input_api, output_api, unit_tests):
if input_api.verbose:
print('Running %s' % unit_test)
cmd.append('--verbose')
- try:
- if input_api.verbose:
- input_api.subprocess.check_call(cmd, cwd=input_api.PresubmitLocalPath())
- else:
- input_api.subprocess.check_output(
- cmd,
- stderr=input_api.subprocess.STDOUT,
- cwd=input_api.PresubmitLocalPath())
- except (OSError, input_api.subprocess.CalledProcessError), e:
- results.append(message_type('%s failed!\n%s' % (unit_test, e)))
+ results.append(input_api.Command(
+ name=unit_test,
+ cmd=cmd,
+ kwargs={'cwd': input_api.PresubmitLocalPath()},
+ message=message_type))
return results
-
-def RunPythonUnitTests(input_api, output_api, unit_tests):
+def GetPythonUnitTests(input_api, output_api, unit_tests):
"""Run the unit tests out of process, capture the output and use the result
code to determine success.
@@ -590,14 +583,42 @@ def RunPythonUnitTests(input_api, output_api, unit_tests):
backpath.append(env.get('PYTHONPATH'))
env['PYTHONPATH'] = input_api.os_path.pathsep.join((backpath))
cmd = [input_api.python_executable, '-m', '%s' % unit_test]
- try:
- input_api.subprocess.check_output(
- cmd, stderr=input_api.subprocess.STDOUT, cwd=cwd, env=env)
- except (OSError, input_api.subprocess.CalledProcessError), e:
- results.append(message_type('%s failed!\n%s' % (unit_test_name, e)))
+ results.append(input_api.Command(
+ name=unit_test_name,
+ cmd=cmd,
+ kwargs={'env': env, 'cwd': cwd},
+ message=message_type))
return results
+def RunUnitTestsInDirectory(input_api, *args, **kwargs):
+ """Run tests in a directory serially.
+
+ For better performance, use GetUnitTestsInDirectory and then
+ pass to input_api.RunTests.
+ """
+ return input_api.RunTests(
+ GetUnitTestsInDirectory(input_api, *args, **kwargs), False)
+
+
+def RunUnitTests(input_api, *args, **kwargs):
+ """Run tests serially.
+
+ For better performance, use GetUnitTests and then pass to
+ input_api.RunTests.
+ """
+ return input_api.RunTests(GetUnitTests(input_api, *args, **kwargs), False)
+
+
+def RunPythonUnitTests(input_api, *args, **kwargs):
+ """Run python tests in a directory serially.
+
+ DEPRECATED
+ """
+ return input_api.RunTests(
+ GetPythonUnitTests(input_api, *args, **kwargs), False)
+
+
def _FetchAllFiles(input_api, white_list, black_list):
"""Hack to fetch all files."""
# We cannot use AffectedFiles here because we want to test every python
@@ -626,7 +647,7 @@ def _FetchAllFiles(input_api, white_list, black_list):
return files
-def RunPylint(input_api, output_api, white_list=None, black_list=None,
+def GetPylint(input_api, output_api, white_list=None, black_list=None,
disabled_warnings=None, extra_paths_list=None):
"""Run pylint on python files.
@@ -669,6 +690,7 @@ def RunPylint(input_api, output_api, white_list=None, black_list=None,
files = _FetchAllFiles(input_api, white_list, black_list)
if not files:
return []
+ files.sort()
input_api.logging.info('Running pylint on %d files', len(files))
input_api.logging.debug('Running pylint on: %s', files)
@@ -679,31 +701,23 @@ def RunPylint(input_api, output_api, white_list=None, black_list=None,
env['PYTHONPATH'] = input_api.os_path.pathsep.join(
extra_paths_list + sys.path).encode('utf8')
- def run_lint(files):
- # We can't import pylint directly due to licensing issues, so we run
- # it in another process. Windows needs help running python files so we
- # explicitly specify the interpreter to use. It also has limitations on
- # the size of the command-line, so we pass arguments via a pipe.
- command = [input_api.python_executable,
- input_api.os_path.join(_HERE, 'third_party', 'pylint.py'),
- '--args-on-stdin']
- try:
- child = input_api.subprocess.Popen(command, env=env,
- stdin=input_api.subprocess.PIPE)
-
- # Dump the arguments to the child process via a pipe.
- for filename in files:
- child.stdin.write(filename + '\n')
- for arg in extra_args:
- child.stdin.write(arg + '\n')
- child.stdin.close()
-
- child.communicate()
- return child.returncode
- except OSError:
- return 'Pylint failed!'
-
- result = None
+ def GetPylintCmd(files):
+ # Windows needs help running python files so we explicitly specify
+ # the interpreter to use. It also has limitations on the size of
+ # the command-line, so we pass arguments via a pipe.
+ if len(files) == 1:
+ description = files[0]
+ else:
+ description = '%s files' % len(files)
+
+ return input_api.Command(
+ name='Pylint (%s)' % description,
+ cmd=[input_api.python_executable,
+ input_api.os_path.join(_HERE, 'third_party', 'pylint.py'),
+ '--args-on-stdin'],
+ kwargs={'env': env, 'stdin': '\n'.join(files + extra_args)},
+ message=error_type)
+
# Always run pylint and pass it all the py files at once.
# Passing py files one at time is slower and can produce
# different results. input_api.verbose used to be used
@@ -713,17 +727,18 @@ def RunPylint(input_api, output_api, white_list=None, black_list=None,
# a quick local edit to diagnose pylint issues more
# easily.
if True:
- print('Running pylint on %d files.' % len(files))
- result = run_lint(sorted(files))
+ return [GetPylintCmd(files)]
else:
- for filename in sorted(files):
- print('Running pylint on %s' % filename)
- result = run_lint([filename]) or result
- if isinstance(result, basestring):
- return [error_type(result)]
- elif result:
- return [error_type('Fix pylint errors first.')]
- return []
+ return map(GetPylintCmd, files)
+
+
+def RunPylint(input_api, *args, **kwargs):
+ """Legacy presubmit function.
+
+ For better performance, get all tests and then pass to
+ input_api.RunTests.
+ """
+ return input_api.RunTests(GetPylint(input_api, *args, **kwargs), False)
# TODO(dpranke): Get the host_url from the input_api instead
« no previous file with comments | « PRESUBMIT.py ('k') | presubmit_support.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698