Commit 99e5157e authored by Robert Ma's avatar Robert Ma Committed by Commit Bot

Roll WPT internal tools to 358439343c2878d6a3784964a11e43644d49c452

Due to https://github.com/web-platform-tests/wpt/pull/25471,
wpt/tools/ci/tc/github_checks_output.py is now included in the internal
tools even though it is not used.

Change-Id: I1b29dadd07243a6156489c44db4b49611ef99501
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2419575
Auto-Submit: Robert Ma <robertma@chromium.org>
Commit-Queue: Stephen McGruer <smcgruer@chromium.org>
Reviewed-by: default avatarStephen McGruer <smcgruer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#808682}
parent 818f45b6
...@@ -22,7 +22,7 @@ Local Modifications: None ...@@ -22,7 +22,7 @@ Local Modifications: None
Name: web-platform-tests - Test Suites for Web Platform specifications Name: web-platform-tests - Test Suites for Web Platform specifications
Short Name: wpt Short Name: wpt
URL: https://github.com/web-platform-tests/wpt/ URL: https://github.com/web-platform-tests/wpt/
Version: d7d965cb51cb8a87ff9f87668f00b242e597d499 Version: 358439343c2878d6a3784964a11e43644d49c452
License: LICENSES FOR W3C TEST SUITES (https://www.w3.org/Consortium/Legal/2008/03-bsd-license.html) License: LICENSES FOR W3C TEST SUITES (https://www.w3.org/Consortium/Legal/2008/03-bsd-license.html)
License File: wpt/wpt/LICENSE.md License File: wpt/wpt/LICENSE.md
Security Critical: no Security Critical: no
......
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
./LICENSE.md ./LICENSE.md
./serve.py ./serve.py
./tools/__init__.py ./tools/__init__.py
./tools/ci/__init__.py
./tools/ci/commands.json ./tools/ci/commands.json
./tools/ci/tc/__init__.py
./tools/ci/tc/github_checks_output.py
./tools/conftest.py ./tools/conftest.py
./tools/docker/commands.json ./tools/docker/commands.json
./tools/gitignore/__init__.py ./tools/gitignore/__init__.py
......
...@@ -9,7 +9,7 @@ cd $DIR ...@@ -9,7 +9,7 @@ cd $DIR
TARGET_DIR=$DIR/wpt TARGET_DIR=$DIR/wpt
REMOTE_REPO="https://github.com/web-platform-tests/wpt.git" REMOTE_REPO="https://github.com/web-platform-tests/wpt.git"
WPT_HEAD=d7d965cb51cb8a87ff9f87668f00b242e597d499 WPT_HEAD=358439343c2878d6a3784964a11e43644d49c452
function clone { function clone {
# Remove existing repo if already exists. # Remove existing repo if already exists.
......
...@@ -13,6 +13,13 @@ ...@@ -13,6 +13,13 @@
"help": "Output a hosts file to stdout", "help": "Output a hosts file to stdout",
"virtualenv": false "virtualenv": false
}, },
"regen-certs": {
"path": "regen_certs.py",
"script": "run",
"parser": "get_parser",
"help": "Regenerate the WPT certificates",
"virtualenv": false
},
"tc-download": { "tc-download": {
"path": "tc/download.py", "path": "tc/download.py",
"script": "run", "script": "run",
......
MYPY = False
if MYPY:
# MYPY is set to True when run under Mypy.
from typing import Any
from typing import Optional
from typing import Text
class GitHubChecksOutputter(object):
"""Provides a method to output data to be shown in the GitHub Checks UI.
This can be useful to provide a summary of a given check (e.g. the lint)
to enable developers to quickly understand what has gone wrong. The output
supports markdown format.
See https://docs.taskcluster.net/docs/reference/integrations/github/checks#custom-text-output-in-checks
"""
def __init__(self, path):
# type: (Text) -> None
self.path = path
def output(self, line):
# type: (Any) -> None
# TODO(stephenmcgruer): Once mypy 0.790 is released, we can change this
# to AnyStr, as that release teaches mypy about the mode flags of open.
# See https://github.com/python/typeshed/pull/4146
with open(self.path, 'a') as f:
f.write(line)
f.write('\n')
__outputter = None
def get_gh_checks_outputter(filepath):
# type: (Optional[Text]) -> Optional[GitHubChecksOutputter]
"""Return the outputter for GitHub Checks output, if enabled.
:param filepath: The filepath to write GitHub Check output information to,
or None if not enabled.
"""
global __outputter
if filepath and __outputter is None:
__outputter = GitHubChecksOutputter(filepath)
return __outputter
...@@ -17,6 +17,7 @@ from collections import defaultdict ...@@ -17,6 +17,7 @@ from collections import defaultdict
from . import fnmatch from . import fnmatch
from . import rules from . import rules
from .. import localpaths from .. import localpaths
from ..ci.tc.github_checks_output import get_gh_checks_outputter, GitHubChecksOutputter
from ..gitignore.gitignore import PathFilter from ..gitignore.gitignore import PathFilter
from ..wpt import testfiles from ..wpt import testfiles
from ..manifest.vcs import walk from ..manifest.vcs import walk
...@@ -30,6 +31,7 @@ MYPY = False ...@@ -30,6 +31,7 @@ MYPY = False
if MYPY: if MYPY:
# MYPY is set to True when run under Mypy. # MYPY is set to True when run under Mypy.
from typing import Any from typing import Any
from typing import Callable
from typing import Dict from typing import Dict
from typing import IO from typing import IO
from typing import Iterable from typing import Iterable
...@@ -809,41 +811,61 @@ def check_file_contents(repo_root, path, f): ...@@ -809,41 +811,61 @@ def check_file_contents(repo_root, path, f):
return errors return errors
def output_errors_text(errors): def output_errors_text(log, errors):
# type: (List[rules.Error]) -> None # type: (Callable[[Any], None], List[rules.Error]) -> None
assert logger is not None
for error_type, description, path, line_number in errors: for error_type, description, path, line_number in errors:
pos_string = path pos_string = path
if line_number: if line_number:
pos_string += ":%s" % line_number pos_string += ":%s" % line_number
logger.error("%s: %s (%s)" % (pos_string, description, error_type)) log("%s: %s (%s)" % (pos_string, description, error_type))
def output_errors_markdown(errors): def output_errors_markdown(log, errors):
# type: (List[rules.Error]) -> None # type: (Callable[[Any], None], List[rules.Error]) -> None
if not errors: if not errors:
return return
assert logger is not None
heading = """Got lint errors: heading = """Got lint errors:
| Error Type | Position | Message | | Error Type | Position | Message |
|------------|----------|---------|""" |------------|----------|---------|"""
for line in heading.split("\n"): for line in heading.split("\n"):
logger.error(line) log(line)
for error_type, description, path, line_number in errors: for error_type, description, path, line_number in errors:
pos_string = path pos_string = path
if line_number: if line_number:
pos_string += ":%s" % line_number pos_string += ":%s" % line_number
logger.error("%s | %s | %s |" % (error_type, pos_string, description)) log("%s | %s | %s |" % (error_type, pos_string, description))
def output_errors_json(errors): def output_errors_json(log, errors):
# type: (List[rules.Error]) -> None # type: (Callable[[Any], None], List[rules.Error]) -> None
for error_type, error, path, line_number in errors: for error_type, error, path, line_number in errors:
# We use 'print' rather than the log function to ensure that the output
# is valid JSON (e.g. with no logger preamble).
print(json.dumps({"path": path, "lineno": line_number, print(json.dumps({"path": path, "lineno": line_number,
"rule": error_type, "message": error})) "rule": error_type, "message": error}))
def output_errors_github_checks(outputter, errors, first_reported):
# type: (GitHubChecksOutputter, List[rules.Error], bool) -> None
"""Output errors to the GitHub Checks output markdown format.
:param outputter: the GitHub Checks outputter
:param errors: a list of error tuples (error type, message, path, line number)
:param first_reported: True if these are the first reported errors
"""
if first_reported:
outputter.output(
"\nChanges in this PR contain lint errors, listed below. These "
"errors must either be fixed or added to the list of ignored "
"errors; see [the documentation]("
"https://web-platform-tests.org/writing-tests/lint-tool.html). "
"For help, please tag `@web-platform-tests/wpt-core-team` in a "
"comment.\n")
outputter.output("```")
output_errors_text(outputter.output, errors)
def output_error_count(error_count): def output_error_count(error_count):
# type: (Dict[Text, int]) -> None # type: (Dict[Text, int]) -> None
if not error_count: if not error_count:
...@@ -910,6 +932,8 @@ def create_parser(): ...@@ -910,6 +932,8 @@ def create_parser():
"using fnmatch, except that path separators are normalized.") "using fnmatch, except that path separators are normalized.")
parser.add_argument("--all", action="store_true", help="If no paths are passed, try to lint the whole " parser.add_argument("--all", action="store_true", help="If no paths are passed, try to lint the whole "
"working directory, not just files that changed") "working directory, not just files that changed")
parser.add_argument("--github-checks-text-file", type=ensure_text,
help="Path to GitHub checks output file for Taskcluster runs")
return parser return parser
...@@ -935,11 +959,13 @@ def main(**kwargs_str): ...@@ -935,11 +959,13 @@ def main(**kwargs_str):
ignore_glob = kwargs.get("ignore_glob", []) ignore_glob = kwargs.get("ignore_glob", [])
return lint(repo_root, paths, output_format, ignore_glob) github_checks_outputter = get_gh_checks_outputter(kwargs["github_checks_text_file"])
return lint(repo_root, paths, output_format, ignore_glob, github_checks_outputter)
def lint(repo_root, paths, output_format, ignore_glob=None):
# type: (Text, List[Text], Text, Optional[List[Text]]) -> int def lint(repo_root, paths, output_format, ignore_glob=None, github_checks_outputter=None):
# type: (Text, List[Text], Text, Optional[List[Text]], Optional[GitHubChecksOutputter]) -> int
error_count = defaultdict(int) # type: Dict[Text, int] error_count = defaultdict(int) # type: Dict[Text, int]
last = None last = None
...@@ -964,11 +990,16 @@ def lint(repo_root, paths, output_format, ignore_glob=None): ...@@ -964,11 +990,16 @@ def lint(repo_root, paths, output_format, ignore_glob=None):
""" """
errors = filter_ignorelist_errors(ignorelist, errors) errors = filter_ignorelist_errors(ignorelist, errors)
if not errors: if not errors:
return None return None
output_errors(errors) assert logger is not None
output_errors(logger.error, errors)
if github_checks_outputter:
first_output = len(error_count) == 0
output_errors_github_checks(github_checks_outputter, errors, first_output)
for error_type, error, path, line in errors: for error_type, error, path, line in errors:
error_count[error_type] += 1 error_count[error_type] += 1
...@@ -1002,6 +1033,10 @@ def lint(repo_root, paths, output_format, ignore_glob=None): ...@@ -1002,6 +1033,10 @@ def lint(repo_root, paths, output_format, ignore_glob=None):
assert logger is not None assert logger is not None
for line in (ERROR_MSG % (last[0], last[1], last[0], last[1])).split("\n"): for line in (ERROR_MSG % (last[0], last[1], last[0], last[1])).split("\n"):
logger.info(line) logger.info(line)
if error_count and github_checks_outputter:
github_checks_outputter.output("```")
return sum(itervalues(error_count)) return sum(itervalues(error_count))
......
...@@ -940,6 +940,7 @@ def get_parser(): ...@@ -940,6 +940,7 @@ def get_parser():
parser.add_argument("--no-h2", action="store_false", dest="h2", default=None, parser.add_argument("--no-h2", action="store_false", dest="h2", default=None,
help="Disable the HTTP/2.0 server") help="Disable the HTTP/2.0 server")
parser.add_argument("--quic-transport", action="store_true", help="Enable QUIC server for WebTransport") parser.add_argument("--quic-transport", action="store_true", help="Enable QUIC server for WebTransport")
parser.add_argument("--exit-after-start", action="store_true", help="Exit after starting servers")
parser.set_defaults(report=False) parser.set_defaults(report=False)
parser.set_defaults(is_wave=False) parser.set_defaults(is_wave=False)
return parser return parser
...@@ -990,7 +991,7 @@ def run(config_cls=ConfigBuilder, route_builder=None, **kwargs): ...@@ -990,7 +991,7 @@ def run(config_cls=ConfigBuilder, route_builder=None, **kwargs):
signal.signal(signal.SIGINT, handle_signal) signal.signal(signal.SIGINT, handle_signal)
while (all(subproc.is_alive() for subproc in iter_procs(servers)) and while (all(subproc.is_alive() for subproc in iter_procs(servers)) and
not received_signal.is_set()): not received_signal.is_set() and not kwargs["exit_after_start"]):
for subproc in iter_procs(servers): for subproc in iter_procs(servers):
subproc.join(1) subproc.join(1)
......
...@@ -649,7 +649,10 @@ class Chrome(Browser): ...@@ -649,7 +649,10 @@ class Chrome(Browser):
# All other channels share the same path on macOS. # All other channels share the same path on macOS.
return "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" return "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
if uname[0] == "Windows": if uname[0] == "Windows":
return os.path.expandvars(r"$SYSTEMDRIVE\Program Files (x86)\Google\Chrome\Application\chrome.exe") path = os.path.expandvars(r"$SYSTEMDRIVE\Program Files (x86)\Google\Chrome\Application\chrome.exe")
if not os.path.exists(path):
path = os.path.expandvars(r"$SYSTEMDRIVE\Program Files\Google\Chrome\Application\chrome.exe")
return path
self.logger.warning("Unable to find the browser binary.") self.logger.warning("Unable to find the browser binary.")
return None return None
......
...@@ -407,7 +407,7 @@ class AsIsHandler(object): ...@@ -407,7 +407,7 @@ class AsIsHandler(object):
path = filesystem_path(self.base_path, request, self.url_base) path = filesystem_path(self.base_path, request, self.url_base)
try: try:
with open(path) as f: with open(path, 'rb') as f:
response.writer.write_raw_content(f.read()) response.writer.write_raw_content(f.read())
wrap_pipeline(path, request, response) wrap_pipeline(path, request, response)
response.close_connection = True response.close_connection = True
......
...@@ -169,6 +169,10 @@ class Request(object): ...@@ -169,6 +169,10 @@ class Request(object):
Regexp match object from matching the request path to the route Regexp match object from matching the request path to the route
selected for the request. selected for the request.
.. attribute:: client_address
Contains a tuple of the form (host, port) representing the client's address.
.. attribute:: protocol_version .. attribute:: protocol_version
HTTP version specified in the request. HTTP version specified in the request.
...@@ -245,6 +249,7 @@ class Request(object): ...@@ -245,6 +249,7 @@ class Request(object):
def __init__(self, request_handler): def __init__(self, request_handler):
self.doc_root = request_handler.server.router.doc_root self.doc_root = request_handler.server.router.doc_root
self.route_match = None # Set by the router self.route_match = None # Set by the router
self.client_address = request_handler.client_address
self.protocol_version = request_handler.protocol_version self.protocol_version = request_handler.protocol_version
self.method = request_handler.command self.method = request_handler.command
......
...@@ -528,6 +528,7 @@ class H2HandlerCopy(object): ...@@ -528,6 +528,7 @@ class H2HandlerCopy(object):
self.h2_stream_id = req_frame.stream_id self.h2_stream_id = req_frame.stream_id
self.server = handler.server self.server = handler.server
self.protocol_version = handler.protocol_version self.protocol_version = handler.protocol_version
self.client_address = handler.client_address
self.raw_requestline = '' self.raw_requestline = ''
self.rfile = rfile self.rfile = rfile
self.request = handler.request self.request = handler.request
......
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