Skip to content

Commit

Permalink
Reorganize Servo's WPT Python scripts
Browse files Browse the repository at this point in the history
This change moves all of Servo's WPT Python support scripts into one
directory as they were previously scattered throughout the directory
structure. This should allow more code reuse and make it easier to
understand how everything fits together.

The changes:

- `tests/wpt/update` → `python/wpt/importer`
- `etc/ci/upstream-wpt-changes/wptupstreamer` → `python/wpt/exporter`
- `etc/ci/upstream-wpt-changes/test.py` → `python/wpt/test.py`
- `etc/ci/upstream-wpt-changes/tests` → `python/wpt/tests`
- `tests/wpt/servowpt.py` →
    - `python/wpt/update.py`
    - `python/wpt/run.py`
- `tests/wpt/manifestupdate.py` → `python/wpt/manifestupdate.py`

This change also removes
 - The ability to run the `update-wpt` and `test-wpt` commands without
   using `mach`. These didn't work very well, because it was difficult
   to get all of the wptrunner and mach dependencies installed outside
   of the Python virtualenv. It's simpler if they are always run through
   `mach`.
- The old WPT change upstreaming script that was no longer used.
  • Loading branch information
mrobinson committed Apr 20, 2023
1 parent 9acb9cc commit 1abee12
Show file tree
Hide file tree
Showing 52 changed files with 236 additions and 886 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/pull-request-wpt-export.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ jobs:
# See https://github.com/actions/checkout/issues/162.
token: ${{ secrets.WPT_SYNC_TOKEN }}
- name: Install requirements
run: pip install -r servo/etc/ci/upstream-wpt-changes/requirements.txt
run: pip install -r servo/python/wpt/requirements.txt
- name: Process pull request
run: servo/etc/ci/upstream-wpt-changes/upstream-wpt-changes.py
run: servo/python/wpt/upstream.py
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
WPT_SYNC_TOKEN: ${{ secrets.WPT_SYNC_TOKEN }}
WPT_SYNC_TOKEN: ${{ secrets.WPT_SYNC_TOKEN }}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: WPT exporter test
on:
pull_request:
branches: ["**"]
paths: ["etc/ci/upstream-wpt-changes/**"]
paths: ["python/wpt/exporter/**"]

jobs:
test:
Expand All @@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v3
- name: Install dependencies
run: |
python3 -m pip install --upgrade -r etc/ci/upstream-wpt-changes/requirements-dev.txt
python3 -m pip install --upgrade -r python/wpt/requirements-dev.txt
- name: Running tests
run: |
python3 etc/ci/upstream-wpt-changes/test.py
python3 python/wpt/test.py
2 changes: 1 addition & 1 deletion etc/ci/update-wpt-checkout
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function unsafe_pull_from_upstream() {

# Fetch all changes from upstream WPT and automatically transpose them
# into a single servo commit.
./mach update-wpt --sync --no-upstream --patch || return 2
./mach update-wpt --sync --patch || return 2

# If there was no new commit created, there are no changes that need syncing.
# Skip the remaining steps.
Expand Down
Empty file removed etc/ci/upstream-wpt-changes/README
Empty file.
5 changes: 5 additions & 0 deletions python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ is the canonical repository for this code.

servo-tidy is used to check licenses, line lengths, whitespace, flake8 on
Python files, lock file versions, and more.

# `wpt`
servo-wpt is a module with support scripts for running, importing,
exporting, updating manifests, and updating expectations for WPT
tests.
74 changes: 17 additions & 57 deletions python/servo/testing_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,31 @@
from xml.etree.ElementTree import XML
from six import iteritems

import wpt
import wpt.manifestupdate
import wpt.run
import wpt.update

from mach.registrar import Registrar
from mach.decorators import (
CommandArgument,
CommandProvider,
Command,
)

from servo_tidy import tidy
from servo.command_base import (
CommandBase,
call, check_call, check_output,
)
from servo.util import host_triple

from wptrunner import wptcommandline
from update import updatecommandline
from servo_tidy import tidy
from servo_tidy_tests import test_tidy
from servo.util import host_triple

SCRIPT_PATH = os.path.split(__file__)[0]
PROJECT_TOPLEVEL_PATH = os.path.abspath(os.path.join(SCRIPT_PATH, "..", ".."))
WEB_PLATFORM_TESTS_PATH = os.path.join("tests", "wpt", "web-platform-tests")
SERVO_TESTS_PATH = os.path.join("tests", "wpt", "mozilla", "tests")

sys.path.insert(0, os.path.join(PROJECT_TOPLEVEL_PATH, 'tests', 'wpt'))
import servowpt # noqa: E402

CLANGFMT_CPP_DIRS = ["support/hololens/"]
CLANGFMT_VERSION = "15"

Expand All @@ -67,45 +66,6 @@
TEST_SUITES_BY_PREFIX = {path: k for k, v in iteritems(TEST_SUITES) if "paths" in v for path in v["paths"]}


def create_parser_wpt():
import mozlog.commandline
parser = wptcommandline.create_parser()
parser.add_argument('--release', default=False, action="store_true",
help="Run with a release build of servo")
parser.add_argument('--rr-chaos', default=False, action="store_true",
help="Run under chaos mode in rr until a failure is captured")
parser.add_argument('--pref', default=[], action="append", dest="prefs",
help="Pass preferences to servo")
parser.add_argument('--layout-2020', '--with-layout-2020', default=False,
action="store_true", help="Use expected results for the 2020 layout engine")
parser.add_argument('--log-servojson', action="append", type=mozlog.commandline.log_file,
help="Servo's JSON logger of unexpected results")
parser.add_argument('--always-succeed', default=False, action="store_true",
help="Always yield exit code of zero")
parser.add_argument('--no-default-test-types', default=False, action="store_true",
help="Run all of the test types provided by wptrunner or specified explicitly by --test-types")
parser.add_argument('--filter-intermittents', default=None, action="store",
help="Filter intermittents against known intermittents "
"and save the filtered output to the given file.")
parser.add_argument('--log-raw-unexpected', default=None, action="store",
help="Raw structured log messages for unexpected results."
" '--log-raw' Must also be passed in order to use this.")
return parser


def create_parser_manifest_update():
import manifestupdate
return manifestupdate.create_parser()


def run_update(topdir, check_clean=False, rebuild=False, **kwargs):
import manifestupdate
from wptrunner import wptlogging
logger = wptlogging.setup(kwargs, {"mach": sys.stdout})
wpt_dir = os.path.abspath(os.path.join(topdir, 'tests', 'wpt'))
return manifestupdate.update(logger, wpt_dir, check_clean, rebuild)


@CommandProvider
class MachCommands(CommandBase):
DEFAULT_RENDER_MODE = "cpu"
Expand Down Expand Up @@ -353,7 +313,7 @@ def test_tidy(self, all_files, no_progress, self_test, stylo, force_cpp=False, n
if no_wpt:
manifest_dirty = False
else:
manifest_dirty = run_update(self.context.topdir, check_clean=True)
manifest_dirty = wpt.manifestupdate.update(check_clean=True)
tidy_failed = tidy.scan(not all_files, not no_progress, stylo=stylo, no_wpt=no_wpt)
self.install_rustfmt()
rustfmt_failed = self.call_rustup_run(["cargo", "fmt", "--", "--check"])
Expand Down Expand Up @@ -399,7 +359,7 @@ def test_webidl(self, quiet, tests):
@Command('test-wpt-failure',
description='Run the tests harness that verifies that the test failures are reported correctly',
category='testing',
parser=create_parser_wpt)
parser=wpt.create_parser)
def test_wpt_failure(self, **kwargs):
kwargs["pause_after_test"] = False
kwargs["include"] = ["infrastructure/failing-test.html"]
Expand All @@ -408,7 +368,7 @@ def test_wpt_failure(self, **kwargs):
@Command('test-wpt',
description='Run the regular web platform test suite',
category='testing',
parser=create_parser_wpt)
parser=wpt.create_parser)
def test_wpt(self, **kwargs):
ret = self.run_test_list_or_dispatch(kwargs["test_list"], "wpt", self._test_wpt, **kwargs)
if kwargs["always_succeed"]:
Expand All @@ -419,7 +379,7 @@ def test_wpt(self, **kwargs):
@Command('test-wpt-android',
description='Run the web platform test suite in an Android emulator',
category='testing',
parser=create_parser_wpt)
parser=wpt.create_parser)
def test_wpt_android(self, release=False, dev=False, binary_args=None, **kwargs):
kwargs.update(
release=release,
Expand All @@ -433,7 +393,7 @@ def test_wpt_android(self, release=False, dev=False, binary_args=None, **kwargs)

def _test_wpt(self, android=False, **kwargs):
self.set_run_env(android)
return servowpt.run_tests(**kwargs)
return wpt.run.run_tests(**kwargs)

# Helper to ensure all specified paths are handled, otherwise dispatch to appropriate test suite.
def run_test_list_or_dispatch(self, requested_paths, correct_suite, correct_function, **kwargs):
Expand All @@ -454,9 +414,9 @@ def run_test_list_or_dispatch(self, requested_paths, correct_suite, correct_func
@Command('update-manifest',
description='Run test-wpt --manifest-update SKIP_TESTS to regenerate MANIFEST.json',
category='testing',
parser=create_parser_manifest_update)
parser=wpt.manifestupdate.create_parser)
def update_manifest(self, **kwargs):
return run_update(self.context.topdir, **kwargs)
return wpt.manifestupdate.update(check_clean=False)

@Command('fmt',
description='Format the Rust and CPP source files with rustfmt and clang-format',
Expand All @@ -474,13 +434,13 @@ def format_code(self):
@Command('update-wpt',
description='Update the web platform tests',
category='testing',
parser=updatecommandline.create_parser())
parser=wpt.update.create_parser)
def update_wpt(self, **kwargs):
patch = kwargs.get("patch", False)
if not patch and kwargs["sync"]:
print("Are you sure you don't want a patch?")
return 1
return servowpt.update_tests(**kwargs)
return wpt.update.update_tests(**kwargs)

@Command('test-android-startup',
description='Extremely minimal testing of Servo for Android',
Expand Down Expand Up @@ -826,7 +786,7 @@ def run_create(self, **kwargs):
proc = subprocess.Popen("%s %s" % (editor, test_path), shell=True)

if not kwargs["no_run"]:
p = create_parser_wpt()
p = wpt.create_parser()
args = []
if kwargs["release"]:
args.append("--release")
Expand Down
61 changes: 61 additions & 0 deletions python/wpt/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Copyright 2023 The Servo Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.

import os
import sys

import mozlog.commandline

SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__))
SERVO_ROOT = os.path.abspath(os.path.join(SCRIPT_PATH, "..", ".."))
WPT_PATH = os.path.join(SERVO_ROOT, "tests", "wpt")
WPT_TOOLS_PATH = os.path.join(WPT_PATH, "web-platform-tests", "tools")
CERTS_PATH = os.path.join(WPT_TOOLS_PATH, "certs")

sys.path.insert(0, WPT_TOOLS_PATH)
import localpaths # noqa: F401,E402
import wptrunner.wptcommandline # noqa: E402


def create_parser():
parser = wptrunner.wptcommandline.create_parser()
parser.add_argument('--release', default=False, action="store_true",
help="Run with a release build of servo")
parser.add_argument('--rr-chaos', default=False, action="store_true",
help="Run under chaos mode in rr until a failure is captured")
parser.add_argument('--pref', default=[], action="append", dest="prefs",
help="Pass preferences to servo")
parser.add_argument('--layout-2020', '--with-layout-2020', default=False,
action="store_true", help="Use expected results for the 2020 layout engine")
parser.add_argument('--log-servojson', action="append", type=mozlog.commandline.log_file,
help="Servo's JSON logger of unexpected results")
parser.add_argument('--always-succeed', default=False, action="store_true",
help="Always yield exit code of zero")
parser.add_argument('--no-default-test-types', default=False, action="store_true",
help="Run all of the test types provided by wptrunner or specified explicitly by --test-types")
parser.add_argument('--filter-intermittents', default=None, action="store",
help="Filter intermittents against known intermittents "
"and save the filtered output to the given file.")
parser.add_argument('--log-raw-unexpected', default=None, action="store",
help="Raw structured log messages for unexpected results."
" '--log-raw' Must also be passed in order to use this.")
return parser


def update_args_for_layout_2020(kwargs: dict):
if kwargs.pop("layout_2020"):
kwargs["test_paths"]["/"]["metadata_path"] = os.path.join(
WPT_PATH, "metadata-layout-2020"
)
kwargs["test_paths"]["/_mozilla/"]["metadata_path"] = os.path.join(
WPT_PATH, "mozilla", "meta-layout-2020"
)
kwargs["include_manifest"] = os.path.join(
WPT_PATH, "include-layout-2020.ini"
)
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import os
import sys

from wptupstreamer import WPTSync
from exporter import WPTSync


def main() -> int:
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
57 changes: 57 additions & 0 deletions python/wpt/importer/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

import os
import sys

from .tree import GitTree, GeckoCommit

from wptrunner.update import setup_logging, WPTUpdate # noqa: F401
from wptrunner.update.base import Step, StepRunner, exit_unclean # noqa: F401
from wptrunner.update.update import LoadConfig, SyncFromUpstream, UpdateMetadata # noqa: F401
from wptrunner import wptcommandline # noqa: F401


class LoadTrees(Step):
"""Load gecko tree and sync tree containing web-platform-tests"""

provides = ["local_tree", "sync_tree"]

def create(self, state):
if os.path.exists(state.sync["path"]):
sync_tree = GitTree(root=state.sync["path"])
else:
sync_tree = None

assert GitTree.is_type()
state.update({"local_tree": GitTree(commit_cls=GeckoCommit),
"sync_tree": sync_tree})


class UpdateRunner(StepRunner):
"""Overall runner for updating web-platform-tests in Gecko."""
steps = [LoadConfig,
LoadTrees,
SyncFromUpstream,
UpdateMetadata]


def run_update(**kwargs):
logger = setup_logging(kwargs, {"mach": sys.stdout})
updater = WPTUpdate(logger, runner_cls=UpdateRunner, **kwargs)
return updater.run() != exit_unclean


def create_parser():
parser = wptcommandline.create_parser_update()
parser.add_argument("--layout-2020", "--with-layout-2020", default=False, action="store_true",
help="Use expected results for the 2020 layout engine")
return parser


def check_args(kwargs):
wptcommandline.set_from_config(kwargs)
if hasattr(wptcommandline, 'check_paths'):
wptcommandline.check_paths(kwargs)
return kwargs
Loading

0 comments on commit 1abee12

Please sign in to comment.