blob: a807b210fbdc290cd802e06bc1b5ab8b94d89f94 [file]
# Copyright 2015 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Top-level presubmit script for content/test/gpu.
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into depot_tools.
"""
PRESUBMIT_VERSION = '2.0.0'
EXTRA_PATHS_COMPONENTS = [
('build',),
('build', 'fuchsia', 'test'),
('build', 'util'),
('testing',),
('third_party', 'blink', 'tools'),
('third_party', 'catapult', 'common', 'py_utils'),
('third_party', 'catapult', 'devil'),
('third_party', 'catapult', 'telemetry'),
('third_party', 'catapult', 'third_party', 'typ'),
('third_party', 'catapult', 'tracing'),
('tools', 'perf'),
]
def _GetChromiumSrcPath(input_api):
"""Returns the path to the Chromium src directory."""
return input_api.os_path.realpath(
input_api.os_path.join(input_api.PresubmitLocalPath(), '..', '..', '..')
)
def _GetGpuEnv(input_api):
"""Gets the common environment for running GPU tests."""
gpu_env = dict(input_api.environ)
current_path = input_api.PresubmitLocalPath()
chromium_src_path = _GetChromiumSrcPath(input_api)
testing_path = input_api.os_path.join(chromium_src_path, 'testing')
gpu_env.update(
{
'PYTHONPATH': input_api.os_path.pathsep.join(
[testing_path, current_path]
),
'PYTHONDONTWRITEBYTECODE': '1',
}
)
return gpu_env
def CheckGpuTestsUnittests(input_api, output_api):
"""Runs the unittests for the gpu_tests directory."""
gpu_env = _GetGpuEnv(input_api)
command = input_api.Command(
name='run_content_test_gpu_unittests',
cmd=[input_api.python3_executable, 'run_unittests.py', 'gpu_tests'],
kwargs={'env': gpu_env},
message=output_api.PresubmitError,
python3=True,
)
return input_api.RunTests([command])
def CheckMachineTimesUnittests(input_api, output_api):
"""Runs the unittests for the machine_times directory."""
return input_api.canned_checks.RunUnitTestsInDirectory(
input_api,
output_api,
input_api.os_path.join(input_api.PresubmitLocalPath(), 'machine_times'),
[r'^.+_unittest\.py$'],
env=_GetGpuEnv(input_api),
run_on_python2=False,
run_on_python3=True,
skip_shebang_check=True,
)
def CheckUnexpectedPassesUnittests(input_api, output_api):
"""Runs the unittests for the unexpected_passes directory."""
return input_api.canned_checks.RunUnitTestsInDirectory(
input_api,
output_api,
input_api.os_path.join(input_api.PresubmitLocalPath(), 'unexpected_passes'),
[r'^.+_unittest\.py$'],
env=_GetGpuEnv(input_api),
)
def CheckFlakeSuppressorUnittests(input_api, output_api):
"""Runs the unittests for the flake_suppressor directory."""
return input_api.canned_checks.RunUnitTestsInDirectory(
input_api,
output_api,
input_api.os_path.join(input_api.PresubmitLocalPath(), 'flake_suppressor'),
[r'^.+_unittest\.py$'],
env=_GetGpuEnv(input_api),
)
def CheckValidateTagConsistency(input_api, output_api):
"""Checks that GPU expectation tags are consistent across all files."""
command = input_api.Command(
name='validate_tag_consistency',
cmd=[
input_api.python3_executable,
'validate_tag_consistency.py',
'validate',
],
kwargs={},
message=output_api.PresubmitError,
)
return input_api.RunTests([command])
def CheckForNewSkipExpectations(input_api, output_api):
"""Checks for and dissuades the addition of new Skip expectations."""
new_skips = []
expectation_file_dir = input_api.os_path.join(
input_api.PresubmitLocalPath(), 'gpu_tests', 'test_expectations'
)
def file_filter(f):
return f.AbsoluteLocalPath().startswith(expectation_file_dir)
for affected_file in input_api.AffectedFiles(file_filter=file_filter):
for _, line in affected_file.ChangedContents():
if input_api.re.search(r'\[\s*Skip\s*\]', line):
new_skips.append((affected_file, line))
result = []
if new_skips:
warnings = []
for affected_file, line in new_skips:
warnings.append(f' Line "{line}" in file {affected_file.LocalPath()}')
warnings_str = '\n'.join(warnings)
result.append(
output_api.PresubmitPromptWarning(
f'Suspected new Skip expectations found:\n'
f'{warnings_str}\n'
f'Please only use such expectations when they are strictly '
f'necessary, e.g. the test is impacting other tests. Otherwise, '
f'opt for a Failure/RetryOnFailure expectation.'
)
)
return result
def CheckPatchFormatted(input_api, output_api):
return input_api.canned_checks.CheckPatchFormatted(
input_api,
output_api,
result_factory=output_api.PresubmitError,
bypass_warnings=False,
)
def CheckPytypePathsInSync(input_api, output_api):
"""Checks that run_pytype.py's paths are in sync with PRESUBMIT.py's"""
filepath = input_api.os_path.join(
input_api.PresubmitLocalPath(), 'run_pytype.py'
)
with open(filepath, encoding='utf-8') as infile:
contents = infile.read()
# Grab the EXTRA_PATHS_COMPONENTS = [...] portion as a string.
match = input_api.re.search(
r'(EXTRA_PATHS_COMPONENTS\s*=\s*[^=]*\]\n)', contents, input_api.re.DOTALL
)
if not match:
return [
output_api.PresubmitError(
'Unable to find EXTRA_PATHS_COMPONENTS in run_pytype.py. Maybe '
'the code in PRESUBMIT.py needs to be updated?'
)
]
expression = match.group(0)
expression = expression.split('=', 1)[1]
expression = expression.lstrip()
pytype_path_components = input_api.ast.literal_eval(expression)
if EXTRA_PATHS_COMPONENTS != pytype_path_components:
return [
output_api.PresubmitError(
'EXTRA_PATHS_COMPONENTS is not synced between PRESUBMIT.py and '
'run_pytype.py, please ensure they are identical.'
)
]
return []