depot_tools: Make it possible to run python3 tests on PRESUBMIT.

Add run_on_python2 and run_on_python3 to allow to be tests on
either only python2, only python3 or both.

Bug: 984182
Change-Id: I87d3b67412129cf3a8e627cd6bc97daa81147657
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/1758849
Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
Reviewed-by: smut <smut@google.com>
Reviewed-by: Robbie Iannucci <iannucci@chromium.org>
changes/49/1758849/6
Edward Lemur 6 years ago committed by Commit Bot
parent 3a96d62052
commit 940c282116

@ -576,7 +576,8 @@ def CheckTreeIsOpen(input_api, output_api,
return []
def GetUnitTestsInDirectory(
input_api, output_api, directory, whitelist=None, blacklist=None, env=None):
input_api, output_api, directory, whitelist=None, blacklist=None, env=None,
run_on_python2=True, run_on_python3=True):
"""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
@ -609,14 +610,24 @@ def GetUnitTestsInDirectory(
'Out of %d files, found none that matched w=%r, b=%r in directory %s'
% (found, whitelist, blacklist, directory))
]
return GetUnitTests(input_api, output_api, unit_tests, env)
return GetUnitTests(
input_api, output_api, unit_tests, env, run_on_python2, run_on_python3)
def GetUnitTests(input_api, output_api, unit_tests, env=None):
def GetUnitTests(
input_api, output_api, unit_tests, env=None, run_on_python2=True,
run_on_python3=True):
"""Runs all unit tests in a directory.
On Windows, sys.executable is used for unit tests ending with ".py".
"""
assert run_on_python3 or run_on_python2, (
'At least one of "run_on_python2" or "run_on_python3" must be set.')
def has_py3_shebang(test):
with open(test) as f:
maybe_shebang = f.readline()
return maybe_shebang.startswith('#!') and 'python3' in maybe_shebang
# We don't want to hinder users from uploading incomplete patches.
if input_api.is_committing:
message_type = output_api.PresubmitError
@ -631,11 +642,26 @@ def GetUnitTests(input_api, output_api, unit_tests, env=None):
kwargs = {'cwd': input_api.PresubmitLocalPath()}
if env:
kwargs['env'] = env
results.append(input_api.Command(
name=unit_test,
cmd=cmd,
kwargs=kwargs,
message=message_type))
if not unit_test.endswith('.py'):
results.append(input_api.Command(
name=unit_test,
cmd=cmd,
kwargs=kwargs,
message=message_type))
else:
if has_py3_shebang(unit_test) and run_on_python3:
results.append(input_api.Command(
name=unit_test,
cmd=cmd,
kwargs=kwargs,
message=message_type,
python3=True))
if run_on_python2:
results.append(input_api.Command(
name=unit_test,
cmd=cmd,
kwargs=kwargs,
message=message_type))
return results

@ -66,7 +66,7 @@ class PresubmitFailure(Exception):
class CommandData(object):
def __init__(self, name, cmd, kwargs, message):
def __init__(self, name, cmd, kwargs, message, python3=False):
self.name = name
self.cmd = cmd
self.stdin = kwargs.get('stdin', None)
@ -76,6 +76,7 @@ class CommandData(object):
self.kwargs['stdin'] = subprocess.PIPE
self.message = message
self.info = None
self.python3 = python3
# Adapted from
@ -152,7 +153,11 @@ class ThreadPool(object):
This function converts invocation of .py files and invocations of "python"
to vpython invocations.
"""
vpython = 'vpython.bat' if sys.platform == 'win32' else 'vpython'
vpython = 'vpython'
if test.python3:
vpython += '3'
if sys.platform == 'win32':
vpython += '.bat'
cmd = test.cmd
if cmd[0] == 'python':

@ -58,6 +58,11 @@ class MockTemporaryFile(object):
pass
class MockProcess(object):
def __init__(self, returncode):
self.returncode = returncode
class PresubmitTestsBase(TestCaseUtils, unittest.TestCase):
"""Sets up and tears down the mocks but doesn't test anything as-is."""
presubmit_text = """
@ -2521,6 +2526,7 @@ the current line as well!
is_committing=False,
uncovered_files=set())
@mock.patch('__builtin__.open', mock.mock_open(read_data=''))
def testCannedRunUnitTests(self):
change = presubmit.Change(
'foo1', 'description1', self.fake_root_dir, None, 0, 0, None)
@ -2563,6 +2569,143 @@ the current line as well!
self.checkstdout('')
@mock.patch('__builtin__.open', mock.mock_open())
def testCannedRunUnitTestsPython3(self):
open().readline.return_value = '#!/usr/bin/env python3'
change = presubmit.Change(
'foo1', 'description1', self.fake_root_dir, None, 0, 0, None)
input_api = self.MockInputApi(change, False)
input_api.verbose = True
input_api.PresubmitLocalPath.return_value = self.fake_root_dir
presubmit.sigint_handler.wait.return_value = ('', None)
subprocess.Popen.side_effect = [
MockProcess(1),
MockProcess(0),
MockProcess(0),
]
unit_tests = ['allo', 'bar.py']
results = presubmit_canned_checks.RunUnitTests(
input_api,
presubmit.OutputApi,
unit_tests)
self.assertEqual([result.__class__ for result in results], [
presubmit.OutputApi.PresubmitPromptWarning,
presubmit.OutputApi.PresubmitNotifyResult,
presubmit.OutputApi.PresubmitNotifyResult,
])
cmd = ['bar.py', '--verbose']
vpython = 'vpython'
vpython3 = 'vpython3'
if input_api.platform == 'win32':
vpython += '.bat'
vpython3 += '.bat'
self.assertEqual(subprocess.Popen.mock_calls, [
mock.call(
[vpython] + cmd, cwd=self.fake_root_dir, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stdin=subprocess.PIPE),
mock.call(
[vpython3] + cmd, cwd=self.fake_root_dir, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stdin=subprocess.PIPE),
mock.call(
['allo', '--verbose'], cwd=self.fake_root_dir,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
stdin=subprocess.PIPE),
])
self.checkstdout('')
@mock.patch('__builtin__.open', mock.mock_open())
def testCannedRunUnitTestsDontRunOnPython2(self):
open().readline.return_value = '#!/usr/bin/env python3'
change = presubmit.Change(
'foo1', 'description1', self.fake_root_dir, None, 0, 0, None)
input_api = self.MockInputApi(change, False)
input_api.verbose = True
input_api.PresubmitLocalPath.return_value = self.fake_root_dir
presubmit.sigint_handler.wait.return_value = ('', None)
subprocess.Popen.side_effect = [
MockProcess(1),
MockProcess(0),
MockProcess(0),
]
unit_tests = ['allo', 'bar.py']
results = presubmit_canned_checks.RunUnitTests(
input_api,
presubmit.OutputApi,
unit_tests,
run_on_python2=False)
self.assertEqual([result.__class__ for result in results], [
presubmit.OutputApi.PresubmitPromptWarning,
presubmit.OutputApi.PresubmitNotifyResult,
])
cmd = ['bar.py', '--verbose']
vpython3 = 'vpython3'
if input_api.platform == 'win32':
vpython3 += '.bat'
self.assertEqual(subprocess.Popen.mock_calls, [
mock.call(
[vpython3] + cmd, cwd=self.fake_root_dir, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stdin=subprocess.PIPE),
mock.call(
['allo', '--verbose'], cwd=self.fake_root_dir,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
stdin=subprocess.PIPE),
])
self.checkstdout('')
@mock.patch('__builtin__.open', mock.mock_open())
def testCannedRunUnitTestsDontRunOnPython3(self):
open().readline.return_value = '#!/usr/bin/env python3'
change = presubmit.Change(
'foo1', 'description1', self.fake_root_dir, None, 0, 0, None)
input_api = self.MockInputApi(change, False)
input_api.verbose = True
input_api.PresubmitLocalPath.return_value = self.fake_root_dir
presubmit.sigint_handler.wait.return_value = ('', None)
subprocess.Popen.side_effect = [
MockProcess(1),
MockProcess(0),
MockProcess(0),
]
unit_tests = ['allo', 'bar.py']
results = presubmit_canned_checks.RunUnitTests(
input_api,
presubmit.OutputApi,
unit_tests,
run_on_python3=False)
self.assertEqual([result.__class__ for result in results], [
presubmit.OutputApi.PresubmitPromptWarning,
presubmit.OutputApi.PresubmitNotifyResult,
])
cmd = ['bar.py', '--verbose']
vpython = 'vpython'
if input_api.platform == 'win32':
vpython += '.bat'
self.assertEqual(subprocess.Popen.mock_calls, [
mock.call(
[vpython] + cmd, cwd=self.fake_root_dir, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stdin=subprocess.PIPE),
mock.call(
['allo', '--verbose'], cwd=self.fake_root_dir,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
stdin=subprocess.PIPE),
])
self.checkstdout('')
def testCannedRunUnitTestsInDirectory(self):
change = presubmit.Change(
'foo1', 'description1', self.fake_root_dir, None, 0, 0, None)

Loading…
Cancel
Save