blob: da0ab005d3660edbbeab5c80f47f0c995683a0b4 [file] [log] [blame]
# Copyright (c) 2013 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.
"""LayoutTests/ presubmit script for Blink.
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""
import filecmp
def _CheckTestharnessResults(input_api, output_api):
"""Checks for all-PASS generic baselines for testharness.js tests.
These files are unnecessary because for testharness.js tests, if there is no
baseline file then the test is considered to pass when the output is all
PASS. Note that only generic baselines are checked because platform specific
and virtual baselines might be needed to prevent fallback.
"""
baseline_files = _TestharnessGenericBaselinesToCheck(input_api)
if not baseline_files:
return []
checker_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
'..', 'Tools', 'Scripts', 'check-testharness-expected-pass')
args = [input_api.python_executable, checker_path]
args.extend(baseline_files)
_, errs = input_api.subprocess.Popen(args,
stdout=input_api.subprocess.PIPE,
stderr=input_api.subprocess.PIPE).communicate()
if errs:
return [output_api.PresubmitError(errs)]
return []
def _TestharnessGenericBaselinesToCheck(input_api):
"""Returns a list of paths of generic baselines for testharness.js tests."""
baseline_files = []
for f in input_api.AffectedFiles():
if f.Action() == 'D':
continue
path = f.AbsoluteLocalPath()
if not path.endswith('-expected.txt'):
continue
if (input_api.os_path.join('LayoutTests', 'platform') in path or
input_api.os_path.join('LayoutTests', 'virtual') in path):
continue
baseline_files.append(path)
return baseline_files
def _CheckFilesUsingEventSender(input_api, output_api):
"""Check if any new layout tests still use eventSender. If they do, we encourage replacing them with
chrome.gpuBenchmarking.pointerActionSequence.
"""
results = []
actions = ["eventSender.touch", "eventSender.mouse", "eventSender.gesture"]
for f in input_api.AffectedFiles():
if f.Action() == 'A':
for line_num, line in f.ChangedContents():
if any(action in line for action in actions):
results.append(output_api.PresubmitPromptWarning(
'eventSender is deprecated, please use chrome.gpuBenchmarking.pointerActionSequence instead ' +
'(see https://crbug.com/711340 and http://goo.gl/BND75q).\n' +
'Files: %s:%d %s ' % (f.LocalPath(), line_num, line)))
return results
def _CheckTestExpectations(input_api, output_api):
local_paths = [f.LocalPath() for f in input_api.AffectedFiles()]
if any('LayoutTests' in path for path in local_paths):
lint_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
'..', 'Tools', 'Scripts', 'lint-test-expectations')
_, errs = input_api.subprocess.Popen(
[input_api.python_executable, lint_path],
stdout=input_api.subprocess.PIPE,
stderr=input_api.subprocess.PIPE).communicate()
if not errs:
return [output_api.PresubmitError(
"lint-test-expectations failed "
"to produce output; check by hand. ")]
if errs.strip() != 'Lint succeeded.':
return [output_api.PresubmitError(errs)]
return []
def _CheckForJSTest(input_api, output_api):
"""'js-test.js' is the past, 'testharness.js' is our glorious future"""
jstest_re = input_api.re.compile(r'resources/js-test.js')
def source_file_filter(path):
return input_api.FilterSourceFile(path,
white_list=[r'third_party/WebKit/LayoutTests/.*\.(html|js|php|pl|svg)$'])
errors = input_api.canned_checks._FindNewViolationsOfRule(
lambda _, x: not jstest_re.search(x), input_api, source_file_filter)
errors = [' * %s' % violation for violation in errors]
if errors:
return [output_api.PresubmitPromptOrNotify(
'"resources/js-test.js" is deprecated; please write new layout '
'tests using the assertions in "resources/testharness.js" '
'instead, as these can be more easily upstreamed to Web Platform '
'Tests for cross-vendor compatibility testing. If you\'re not '
'already familiar with this framework, a tutorial is available at '
'https://darobin.github.io/test-harness-tutorial/docs/using-testharness.html'
'\n\n%s' % '\n'.join(errors))]
return []
def _CheckForInvalidPreferenceError(input_api, output_api):
pattern = input_api.re.compile('Invalid name for preference: (.+)')
results = []
for f in input_api.AffectedFiles():
if not f.LocalPath().endswith('-expected.txt'):
continue
for line_num, line in f.ChangedContents():
error = pattern.search(line)
if error:
results.append(output_api.PresubmitError('Found an invalid preference %s in expected result %s:%s' % (error.group(1), f, line_num)))
return results
def CheckChangeOnUpload(input_api, output_api):
results = []
results.extend(_CheckTestharnessResults(input_api, output_api))
results.extend(_CheckFilesUsingEventSender(input_api, output_api))
results.extend(_CheckTestExpectations(input_api, output_api))
results.extend(_CheckForJSTest(input_api, output_api))
results.extend(_CheckForInvalidPreferenceError(input_api, output_api))
return results
def CheckChangeOnCommit(input_api, output_api):
results = []
results.extend(_CheckTestharnessResults(input_api, output_api))
results.extend(_CheckFilesUsingEventSender(input_api, output_api))
results.extend(_CheckTestExpectations(input_api, output_api))
return results