Commit 2b5ce56a authored by maruel@chromium.org's avatar maruel@chromium.org

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
parent e6a4ab30
*.pyc
/git_cl_repo
/tests/pymox
/tests/rietveld
/tests/_trial
/python
/python.bat
......
......@@ -410,9 +410,76 @@ def CheckTreeIsOpen(input_api, output_api,
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):
"""Run the unit tests out of process, capture the output and use the result
code to determine success.
DEPRECATED.
"""
# We don't want to hinder users from uploading incomplete patches.
if input_api.is_committing:
......@@ -477,10 +544,10 @@ def _FetchAllFiles(input_api, white_list, black_list):
return True
return False
import os
files = []
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.
for item in dirnames[:]:
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.
"""
__version__ = '1.4'
__version__ = '1.5'
# TODO(joi) Add caching where appropriate/needed. The API is designed to allow
# caching (between all different invocations of presubmit scripts for a given
......@@ -251,6 +251,8 @@ class InputApi(object):
self.cPickle = cPickle
self.cStringIO = cStringIO
self.json = json
self.os_listdir = os.listdir
self.os_walk = os.walk
self.os_path = os.path
self.pickle = pickle
self.marshal = marshal
......
#!/usr/bin/python
# Copyright (c) 2010 The Chromium Authors. All rights reserved.
#!/usr/bin/env python2.5
# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
......@@ -9,6 +9,7 @@
# pylint: disable=E1101,E1103,W0212,W0403
import StringIO
import sys
# Fixes include path.
from super_mox import mox, SuperMoxTestBase
......@@ -726,8 +727,8 @@ class InputApiUnittest(PresubmitTestsBase):
'LocalToDepotPath',
'PresubmitLocalPath', 'ReadFile', 'RightHandSideLines', 'ServerPaths',
'basename', 'cPickle', 'cStringIO', 'canned_checks', 'change', 'environ',
'host_url', 'is_committing', 'json', 'marshal', 'os_path',
'owners_db', 'pickle', 'platform', 'python_executable', 're',
'host_url', 'is_committing', 'json', 'marshal', 'os_listdir', 'os_walk',
'os_path', 'owners_db', 'pickle', 'platform', 'python_executable', 're',
'subprocess', 'tbr', 'tempfile', 'time', 'traceback', 'unittest',
'urllib2', 'version',
]
......@@ -1237,6 +1238,8 @@ class CannedChecksUnittest(PresubmitTestsBase):
def MockInputApi(self, change, committing):
input_api = self.mox.CreateMock(presubmit.InputApi)
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.re = presubmit.re
input_api.traceback = presubmit.traceback
......@@ -1249,6 +1252,7 @@ class CannedChecksUnittest(PresubmitTestsBase):
input_api.is_committing = committing
input_api.tbr = False
input_api.python_executable = 'pyyyyython'
input_api.platform = sys.platform
return input_api
def testMembersChanged(self):
......@@ -1273,6 +1277,7 @@ class CannedChecksUnittest(PresubmitTestsBase):
'CheckSvnModifiedDirectories',
'CheckSvnForCommonMimeTypes', 'CheckSvnProperty',
'RunPythonUnitTests', 'RunPylint',
'RunUnitTests', 'RunUnitTestsInDirectory',
]
# If this test fails, you should add the relevant test.
self.compareMembers(presubmit_canned_checks, members)
......@@ -2010,6 +2015,60 @@ mac|success|blew
self.AssertOwnersWorks(approvers=set(['ben@example.com']),
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__':
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment