Add RunUnitTests() and RunUnitTestsInDirectory() canned checks.

Deprecate RunPythonUnitTests() since it is a bit awkward.

Add os_listdir, os_walk and platform to InputApi.

GOAL=Slowly adds python 2.5 support for unit tests
BUG=none
TEST=new unit test
R=dpranke@chromium.org

Review URL: http://codereview.chromium.org/6778027

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@80009 0039d316-1c4b-4281-b951-d872f2087c98
experimental/szager/collated-output
maruel@chromium.org 14 years ago
parent e6a4ab30db
commit 2b5ce56a97

1
.gitignore vendored

@ -1,6 +1,7 @@
*.pyc *.pyc
/git_cl_repo /git_cl_repo
/tests/pymox /tests/pymox
/tests/rietveld
/tests/_trial /tests/_trial
/python /python
/python.bat /python.bat

@ -410,9 +410,76 @@ def CheckTreeIsOpen(input_api, output_api,
return [] return []
def RunUnitTestsInDirectory(
input_api, output_api, directory, whitelist=None, blacklist=None,
verbose=False):
"""Lists all files in a directory and runs them. Doesn't recurse.
It's mainly a wrapper for RunUnitTests. USe whitelist and blacklist to filter
tests accordingly.
"""
unit_tests = []
test_path = input_api.os_path.abspath(
input_api.os_path.join(input_api.PresubmitLocalPath(), directory))
def check(filename, filters):
return any(True for i in filters if input_api.re.match(i, filename))
for filename in input_api.os_listdir(test_path):
fullpath = input_api.os_path.join(test_path, filename)
if not input_api.os_path.isfile(fullpath):
continue
if whitelist and not check(filename, whitelist):
continue
if blacklist and check(filename, blacklist):
continue
unit_tests.append(input_api.os_path.join(directory, filename))
return RunUnitTests(input_api, output_api, unit_tests, verbose)
def RunUnitTests(input_api, output_api, unit_tests, verbose=False):
"""Runs all unit tests in a directory.
On Windows, sys.executable is used for unit tests ending with ".py".
"""
# We don't want to hinder users from uploading incomplete patches.
if input_api.is_committing:
message_type = output_api.PresubmitError
else:
message_type = output_api.PresubmitPromptWarning
if verbose:
pipe = None
else:
pipe = input_api.subprocess.PIPE
results = []
for unit_test in unit_tests:
cmd = []
if input_api.platform == 'win32' and unit_test.endswith('.py'):
# Windows needs some help.
cmd = [input_api.python_executable]
cmd.append(unit_test)
if verbose:
print('Running %s' % unit_test)
try:
proc = input_api.subprocess.Popen(
cmd, cwd=input_api.PresubmitLocalPath(), stdout=pipe, stderr=pipe)
out = '\n'.join(filter(None, proc.communicate()))
if proc.returncode:
results.append(message_type(
'%s failed with return code %d\n%s' % (
unit_test, proc.returncode, out)))
except (OSError, input_api.subprocess.CalledProcessError):
results.append(message_type('%s failed' % unit_test))
return results
def RunPythonUnitTests(input_api, output_api, unit_tests): def RunPythonUnitTests(input_api, output_api, unit_tests):
"""Run the unit tests out of process, capture the output and use the result """Run the unit tests out of process, capture the output and use the result
code to determine success. code to determine success.
DEPRECATED.
""" """
# We don't want to hinder users from uploading incomplete patches. # We don't want to hinder users from uploading incomplete patches.
if input_api.is_committing: if input_api.is_committing:
@ -477,10 +544,10 @@ def _FetchAllFiles(input_api, white_list, black_list):
return True return True
return False return False
import os
files = [] files = []
path_len = len(input_api.PresubmitLocalPath()) path_len = len(input_api.PresubmitLocalPath())
for dirpath, dirnames, filenames in os.walk(input_api.PresubmitLocalPath()): for dirpath, dirnames, filenames in input_api.os_walk(
input_api.PresubmitLocalPath()):
# Passes dirnames in black list to speed up search. # Passes dirnames in black list to speed up search.
for item in dirnames[:]: for item in dirnames[:]:
filepath = input_api.os_path.join(dirpath, item)[path_len + 1:] filepath = input_api.os_path.join(dirpath, item)[path_len + 1:]

@ -6,7 +6,7 @@
"""Enables directory-specific presubmit checks to run at upload and/or commit. """Enables directory-specific presubmit checks to run at upload and/or commit.
""" """
__version__ = '1.4' __version__ = '1.5'
# TODO(joi) Add caching where appropriate/needed. The API is designed to allow # TODO(joi) Add caching where appropriate/needed. The API is designed to allow
# caching (between all different invocations of presubmit scripts for a given # caching (between all different invocations of presubmit scripts for a given
@ -251,6 +251,8 @@ class InputApi(object):
self.cPickle = cPickle self.cPickle = cPickle
self.cStringIO = cStringIO self.cStringIO = cStringIO
self.json = json self.json = json
self.os_listdir = os.listdir
self.os_walk = os.walk
self.os_path = os.path self.os_path = os.path
self.pickle = pickle self.pickle = pickle
self.marshal = marshal self.marshal = marshal

@ -1,5 +1,5 @@
#!/usr/bin/python #!/usr/bin/env python2.5
# Copyright (c) 2010 The Chromium Authors. All rights reserved. # Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
@ -9,6 +9,7 @@
# pylint: disable=E1101,E1103,W0212,W0403 # pylint: disable=E1101,E1103,W0212,W0403
import StringIO import StringIO
import sys
# Fixes include path. # Fixes include path.
from super_mox import mox, SuperMoxTestBase from super_mox import mox, SuperMoxTestBase
@ -726,8 +727,8 @@ class InputApiUnittest(PresubmitTestsBase):
'LocalToDepotPath', 'LocalToDepotPath',
'PresubmitLocalPath', 'ReadFile', 'RightHandSideLines', 'ServerPaths', 'PresubmitLocalPath', 'ReadFile', 'RightHandSideLines', 'ServerPaths',
'basename', 'cPickle', 'cStringIO', 'canned_checks', 'change', 'environ', 'basename', 'cPickle', 'cStringIO', 'canned_checks', 'change', 'environ',
'host_url', 'is_committing', 'json', 'marshal', 'os_path', 'host_url', 'is_committing', 'json', 'marshal', 'os_listdir', 'os_walk',
'owners_db', 'pickle', 'platform', 'python_executable', 're', 'os_path', 'owners_db', 'pickle', 'platform', 'python_executable', 're',
'subprocess', 'tbr', 'tempfile', 'time', 'traceback', 'unittest', 'subprocess', 'tbr', 'tempfile', 'time', 'traceback', 'unittest',
'urllib2', 'version', 'urllib2', 'version',
] ]
@ -1237,6 +1238,8 @@ class CannedChecksUnittest(PresubmitTestsBase):
def MockInputApi(self, change, committing): def MockInputApi(self, change, committing):
input_api = self.mox.CreateMock(presubmit.InputApi) input_api = self.mox.CreateMock(presubmit.InputApi)
input_api.cStringIO = presubmit.cStringIO input_api.cStringIO = presubmit.cStringIO
input_api.os_listdir = self.mox.CreateMockAnything()
input_api.os_walk = self.mox.CreateMockAnything()
input_api.os_path = presubmit.os.path input_api.os_path = presubmit.os.path
input_api.re = presubmit.re input_api.re = presubmit.re
input_api.traceback = presubmit.traceback input_api.traceback = presubmit.traceback
@ -1249,6 +1252,7 @@ class CannedChecksUnittest(PresubmitTestsBase):
input_api.is_committing = committing input_api.is_committing = committing
input_api.tbr = False input_api.tbr = False
input_api.python_executable = 'pyyyyython' input_api.python_executable = 'pyyyyython'
input_api.platform = sys.platform
return input_api return input_api
def testMembersChanged(self): def testMembersChanged(self):
@ -1273,6 +1277,7 @@ class CannedChecksUnittest(PresubmitTestsBase):
'CheckSvnModifiedDirectories', 'CheckSvnModifiedDirectories',
'CheckSvnForCommonMimeTypes', 'CheckSvnProperty', 'CheckSvnForCommonMimeTypes', 'CheckSvnProperty',
'RunPythonUnitTests', 'RunPylint', 'RunPythonUnitTests', 'RunPylint',
'RunUnitTests', 'RunUnitTestsInDirectory',
] ]
# If this test fails, you should add the relevant test. # If this test fails, you should add the relevant test.
self.compareMembers(presubmit_canned_checks, members) self.compareMembers(presubmit_canned_checks, members)
@ -2010,6 +2015,60 @@ mac|success|blew
self.AssertOwnersWorks(approvers=set(['ben@example.com']), self.AssertOwnersWorks(approvers=set(['ben@example.com']),
uncovered_files=set()) uncovered_files=set())
def testCannedRunUnitTests(self):
change = presubmit.Change(
'foo1', 'description1', self.fake_root_dir, None, 0, 0)
input_api = self.MockInputApi(change, False)
unit_tests = ['allo', 'bar.py']
input_api.PresubmitLocalPath().AndReturn(self.fake_root_dir)
input_api.PresubmitLocalPath().AndReturn(self.fake_root_dir)
proc1 = self.mox.CreateMockAnything()
input_api.subprocess.Popen(['allo'], cwd=self.fake_root_dir,
stderr=None, stdout=None).AndReturn(proc1)
proc1.returncode = 0
proc1.communicate().AndReturn(['baz', None])
proc2 = self.mox.CreateMockAnything()
input_api.subprocess.Popen(['bar.py'], cwd=self.fake_root_dir,
stderr=None, stdout=None).AndReturn(proc2)
proc2.returncode = 1
proc2.communicate().AndReturn(['bouz', None])
self.mox.ReplayAll()
results = presubmit_canned_checks.RunUnitTests(
input_api,
presubmit.OutputApi,
unit_tests,
verbose=True)
self.assertEqual(1, len(results))
self.assertEqual(
presubmit.OutputApi.PresubmitPromptWarning, results[0].__class__)
self.checkstdout('Running allo\nRunning bar.py\n')
def testCannedRunUnitTestsInDirectory(self):
change = presubmit.Change(
'foo1', 'description1', self.fake_root_dir, None, 0, 0)
input_api = self.MockInputApi(change, False)
input_api.PresubmitLocalPath().AndReturn(self.fake_root_dir)
input_api.PresubmitLocalPath().AndReturn(self.fake_root_dir)
path = presubmit.os.path.join(self.fake_root_dir, 'random_directory')
input_api.os_listdir(path).AndReturn(['.', '..', 'a', 'b', 'c'])
input_api.os_path.isfile = lambda x: not x.endswith('.')
proc1 = self.mox.CreateMockAnything()
input_api.subprocess.Popen(['random_directory/b'], cwd=self.fake_root_dir,
stderr=None, stdout=None).AndReturn(proc1)
proc1.returncode = 0
proc1.communicate().AndReturn(['baz', None])
self.mox.ReplayAll()
results = presubmit_canned_checks.RunUnitTestsInDirectory(
input_api,
presubmit.OutputApi,
'random_directory',
whitelist=['^a$', '^b$'],
blacklist=['a'],
verbose=True)
self.assertEqual(results, [])
self.checkstdout('Running random_directory/b\n')
if __name__ == '__main__': if __name__ == '__main__':

Loading…
Cancel
Save