Make TestRoot into a class
This is easier to type annotate than a TypedDict, and overall slightly
nicer design.
diff --git a/tools/wpt/update.py b/tools/wpt/update.py
index 41faeac..4dba7e6 100644
--- a/tools/wpt/update.py
+++ b/tools/wpt/update.py
@@ -13,8 +13,8 @@
from manifest import manifest # type: ignore
for url_base, paths in test_paths.items():
manifest.load_and_update(
- paths["tests_path"],
- paths["manifest_path"],
+ paths.tests_path,
+ paths.manifest_path,
url_base)
diff --git a/tools/wptrunner/wptrunner/config.py b/tools/wptrunner/wptrunner/config.py
index ba51fbb..d78efbf 100644
--- a/tools/wptrunner/wptrunner/config.py
+++ b/tools/wptrunner/wptrunner/config.py
@@ -4,17 +4,17 @@
import os
import sys
from collections import OrderedDict
-from typing import Any, Dict, Mapping
+from typing import Dict, Mapping, Optional
here = os.path.dirname(__file__)
-class ConfigDict(Dict[str, Any]):
- def __init__(self, base_path: str, *args: Any, **kwargs: Any):
+class ConfigDict(Dict[str, str]):
+ def __init__(self, base_path: str, *args: str, **kwargs: str):
self.base_path = base_path
dict.__init__(self, *args, **kwargs)
- def get_path(self, key: str, default:Any = None) -> Any:
+ def get_path(self, key: str, default:Optional[str] = None) -> Optional[str]:
if key not in self:
return default
path = self[key]
diff --git a/tools/wptrunner/wptrunner/environment.py b/tools/wptrunner/wptrunner/environment.py
index de96f79..e206e42 100644
--- a/tools/wptrunner/wptrunner/environment.py
+++ b/tools/wptrunner/wptrunner/environment.py
@@ -45,7 +45,7 @@
def serve_path(test_paths):
- return test_paths["/"]["tests_path"]
+ return test_paths["/"].tests_path
def webtranport_h3_server_is_running(host, port, timeout):
@@ -249,10 +249,10 @@
route_builder.add_handler("GET", "/resources/testdriver.js", TestdriverLoader())
- for url_base, paths in self.test_paths.items():
+ for url_base, test_root in self.test_paths.items():
if url_base == "/":
continue
- route_builder.add_mount_point(url_base, paths["tests_path"])
+ route_builder.add_mount_point(url_base, test_root.tests_path)
if "/" not in self.test_paths:
del route_builder.mountpoint_routes["/"]
diff --git a/tools/wptrunner/wptrunner/testloader.py b/tools/wptrunner/wptrunner/testloader.py
index bfa553e..aa26654 100644
--- a/tools/wptrunner/wptrunner/testloader.py
+++ b/tools/wptrunner/wptrunner/testloader.py
@@ -326,19 +326,20 @@
def load(self):
rv = {}
- for url_base, paths in self.test_paths.items():
- manifest_file = self.load_manifest(url_base=url_base,
- **paths)
- path_data = {"url_base": url_base}
- path_data.update(paths)
+ for url_base, test_root in self.test_paths.items():
+ manifest_file = self.load_manifest(url_base, test_root)
+ path_data = {"url_base": url_base,
+ "tests_path": test_root.tests_path,
+ "metadata_path": test_root.metadata_path,
+ "manifest_path": test_root.manifest_path}
rv[manifest_file] = path_data
return rv
- def load_manifest(self, tests_path, manifest_path, metadata_path, url_base="/", **kwargs):
- cache_root = os.path.join(metadata_path, ".cache")
+ def load_manifest(self, url_base, test_root):
+ cache_root = os.path.join(test_root.metadata_path, ".cache")
if self.manifest_download:
- download_from_github(manifest_path, tests_path)
- return manifest.load_and_update(tests_path, manifest_path, url_base,
+ download_from_github(test_root.manifest_path, test_root.tests_path)
+ return manifest.load_and_update(test_root.tests_path, test_root.manifest_path, url_base,
cache_root=cache_root, update=self.force_manifest_update,
types=self.types)
diff --git a/tools/wptrunner/wptrunner/tests/browsers/test_webkitgtk.py b/tools/wptrunner/wptrunner/tests/browsers/test_webkitgtk.py
index 324142c..b5fc5fc 100644
--- a/tools/wptrunner/wptrunner/tests/browsers/test_webkitgtk.py
+++ b/tools/wptrunner/wptrunner/tests/browsers/test_webkitgtk.py
@@ -7,9 +7,11 @@
from wptserve.config import ConfigBuilder
from ..base import active_products
-from wptrunner import environment, products, testloader
+from wptrunner import environment, products, testloader, wptcommandline
-test_paths = {"/": {"tests_path": join(dirname(__file__), "..", "..", "..", "..", "..")}} # repo root
+wpt_root = join(dirname(__file__), "..", "..", "..", "..")
+
+test_paths = {"/": wptcommandline.TestRoot(wpt_root, wpt_root)}
environment.do_delayed_imports(None, test_paths)
logger = logging.getLogger()
diff --git a/tools/wptrunner/wptrunner/tests/test_products.py b/tools/wptrunner/wptrunner/tests/test_products.py
index 4317511..0781ec5 100644
--- a/tools/wptrunner/wptrunner/tests/test_products.py
+++ b/tools/wptrunner/wptrunner/tests/test_products.py
@@ -8,8 +8,11 @@
from .base import all_products, active_products
from .. import environment
from .. import products
+from .. import wptcommandline
-test_paths = {"/": {"tests_path": join(dirname(__file__), "..", "..", "..", "..")}} # repo root
+wpt_root = join(dirname(__file__), "..", "..", "..", "..")
+
+test_paths = {"/": wptcommandline.TestRoot(wpt_root, wpt_root)}
environment.do_delayed_imports(None, test_paths)
diff --git a/tools/wptrunner/wptrunner/tests/test_update.py b/tools/wptrunner/wptrunner/tests/test_update.py
index e569db9..59aaaea 100644
--- a/tools/wptrunner/wptrunner/tests/test_update.py
+++ b/tools/wptrunner/wptrunner/tests/test_update.py
@@ -8,7 +8,7 @@
import pytest
-from .. import metadata, manifestupdate, wptmanifest
+from .. import metadata, manifestupdate, wptcommandline, wptmanifest
from ..update.update import WPTUpdate
from ..update.base import StepRunner, Step
from mozlog import structuredlog, handlers, formatters
@@ -1771,13 +1771,14 @@
def test_update_pickle():
logger = structuredlog.StructuredLogger("expected_test")
+ wpt_root = os.path.abspath(os.path.join(here,
+ os.pardir,
+ os.pardir,
+ os.pardir,
+ os.pardir))
args = {
"test_paths": {
- "/": {"tests_path": os.path.abspath(os.path.join(here,
- os.pardir,
- os.pardir,
- os.pardir,
- os.pardir))},
+ "/": wptcommandline.TestRoot(wpt_root, wpt_root),
},
"abort": False,
"continue": False,
diff --git a/tools/wptrunner/wptrunner/update/update.py b/tools/wptrunner/wptrunner/update/update.py
index 1e9be41..d519c20 100644
--- a/tools/wptrunner/wptrunner/update/update.py
+++ b/tools/wptrunner/wptrunner/update/update.py
@@ -25,8 +25,8 @@
"path": state.kwargs["sync_path"]}
state.paths = state.kwargs["test_paths"]
- state.tests_path = state.paths["/"]["tests_path"]
- state.metadata_path = state.paths["/"]["metadata_path"]
+ state.tests_path = state.paths["/"].tests_path
+ state.metadata_path = state.paths["/"].metadata_path
assert os.path.isabs(state.tests_path)
@@ -108,12 +108,12 @@
return
paths = state.kwargs["test_paths"]
- state.tests_path = state.paths["/"]["tests_path"]
- state.metadata_path = state.paths["/"]["metadata_path"]
+ state.tests_path = state.paths["/"].tests_path
+ state.metadata_path = state.paths["/"].metadata_path
for url_paths in paths.values():
- tests_path = url_paths["tests_path"]
- metadata_path = url_paths["metadata_path"]
+ tests_path = url_paths.tests_path
+ metadata_path = url_paths.metadata_path
for dirpath, dirnames, filenames in os.walk(metadata_path):
for filename in filenames:
if filename == "__dir__.ini":
@@ -144,7 +144,7 @@
:param kwargs: Command line arguments
"""
self.runner_cls = runner_cls
- self.serve_root = kwargs["test_paths"]["/"]["tests_path"]
+ self.serve_root = kwargs["test_paths"]["/"].tests_path
if not kwargs["sync"]:
setup_paths(self.serve_root)
diff --git a/tools/wptrunner/wptrunner/wptcommandline.py b/tools/wptrunner/wptrunner/wptcommandline.py
index fb0dca7..87f51d6 100644
--- a/tools/wptrunner/wptrunner/wptcommandline.py
+++ b/tools/wptrunner/wptrunner/wptcommandline.py
@@ -6,13 +6,7 @@
from collections import OrderedDict
from shutil import which
from datetime import timedelta
-from typing import cast, Mapping
-
-try:
- from typing import TypedDict
-except ImportError:
- # For Python 3.7 we don't have TypedDict do alias it to a generic Mapping
- TypedDict = Mapping
+from typing import Mapping, Optional
from . import config
from . import products
@@ -491,39 +485,34 @@
new_value = kwargs["config"].get(section, config.ConfigDict({})).get_path(config_value)
kwargs[kw_value] = new_value
- kwargs["test_paths"] = get_test_paths(kwargs["config"])
-
- if kwargs["tests_root"]:
- if "/" not in kwargs["test_paths"]:
- kwargs["test_paths"]["/"] = {}
- kwargs["test_paths"]["/"]["tests_path"] = kwargs["tests_root"]
-
- if kwargs["metadata_root"]:
- if "/" not in kwargs["test_paths"]:
- kwargs["test_paths"]["/"] = {}
- kwargs["test_paths"]["/"]["metadata_path"] = kwargs["metadata_root"]
-
- if kwargs.get("manifest_path"):
- if "/" not in kwargs["test_paths"]:
- kwargs["test_paths"]["/"] = {}
- kwargs["test_paths"]["/"]["manifest_path"] = kwargs["manifest_path"]
+ test_paths = get_test_paths(kwargs["config"],
+ kwargs["tests_root"],
+ kwargs["metadata_root"],
+ kwargs["manifest_path"])
+ check_paths(test_paths)
+ kwargs["test_paths"] = test_paths
kwargs["suite_name"] = kwargs["config"].get("web-platform-tests", {}).get("name", "web-platform-tests")
- check_paths(kwargs)
+class TestRoot:
+ def __init__(self, tests_path: str, metadata_path: str, manifest_path: Optional[str] = None):
+ self.tests_path = tests_path
+ self.metadata_path = metadata_path
+ if manifest_path is None:
+ manifest_path = os.path.join(metadata_path, "MANIFEST.json")
-class TestRoot(TypedDict):
- tests_path: str
- metadata_path: str
- manifest_path: str
+ self.manifest_path = manifest_path
TestPaths = Mapping[str, TestRoot]
-def get_test_paths(config: Mapping[str, config.ConfigDict]) -> TestPaths:
+def get_test_paths(config: Mapping[str, config.ConfigDict],
+ tests_path_override: Optional[str] = None,
+ metadata_path_override: Optional[str] = None,
+ manifest_path_override: Optional[str] = None) -> TestPaths:
# Set up test_paths
test_paths = OrderedDict()
@@ -531,35 +520,47 @@
if section.startswith("manifest:"):
manifest_opts = config[section]
url_base = manifest_opts.get("url_base", "/")
- test_root = {
- "tests_path": manifest_opts.get_path("tests"),
- "metadata_path": manifest_opts.get_path("metadata"),
- }
- if "manifest" in manifest_opts:
- test_root["manifest_path"] = manifest_opts.get_path("manifest")
- test_paths[url_base] = cast(TestRoot, test_root)
+ tests_path = manifest_opts.get_path("tests")
+ if tests_path is None:
+ raise ValueError(f"Missing `tests` key in configuration with url_base {url_base}")
+ metadata_path = manifest_opts.get_path("metadata")
+ if metadata_path is None:
+ raise ValueError(f"Missing `metadata` key in configuration with url_base {url_base}")
+ manifest_path = manifest_opts.get_path("manifest")
+
+ if url_base == "/":
+ if tests_path_override is not None:
+ tests_path = tests_path_override
+ if metadata_path_override is not None:
+ metadata_path = metadata_path_override
+ if manifest_path_override is not None:
+ manifest_path = manifest_path_override
+
+ test_paths[url_base] = TestRoot(tests_path, metadata_path, manifest_path)
+
+ if "/" not in test_paths:
+ if tests_path_override is None or metadata_path_override is None:
+ raise ValueError("No ini file configures the root url, "
+ "so --tests and --metadata arguments are mandatory")
+ test_paths["/"] = TestRoot(tests_path_override,
+ metadata_path_override,
+ manifest_path_override)
return test_paths
-def exe_path(name):
+def exe_path(name: Optional[str]) -> Optional[str]:
if name is None:
- return
+ return None
return which(name)
-def check_paths(kwargs):
- for test_paths in kwargs["test_paths"].values():
- if not ("tests_path" in test_paths and
- "metadata_path" in test_paths):
- print("Fatal: must specify both a test path and metadata path")
- sys.exit(1)
- if "manifest_path" not in test_paths:
- test_paths["manifest_path"] = os.path.join(test_paths["metadata_path"],
- "MANIFEST.json")
- for key, path in test_paths.items():
+def check_paths(test_paths: TestPaths) -> None:
+ for test_root in test_paths.values():
+ for key in ["tests_path", "metadata_path", "manifest_path"]:
name = key.split("_", 1)[0]
+ path = getattr(test_root, key)
if name == "manifest":
# For the manifest we can create it later, so just check the path
@@ -712,7 +713,7 @@
sys.exit(1)
if kwargs["properties_file"] is None and not kwargs["no_properties_file"]:
- default_file = os.path.join(kwargs["test_paths"]["/"]["metadata_path"],
+ default_file = os.path.join(kwargs["test_paths"]["/"].metadata_path,
"update_properties.json")
if os.path.exists(default_file):
kwargs["properties_file"] = default_file
diff --git a/tools/wptrunner/wptrunner/wptrunner.py b/tools/wptrunner/wptrunner/wptrunner.py
index 0658b58..a4ad268 100644
--- a/tools/wptrunner/wptrunner/wptrunner.py
+++ b/tools/wptrunner/wptrunner/wptrunner.py
@@ -390,7 +390,7 @@
env_extras.append(FontInstaller(
logger,
font_dir=kwargs["font_dir"],
- ahem=os.path.join(test_paths["/"]["tests_path"], "fonts/Ahem.ttf")
+ ahem=os.path.join(test_paths["/"].tests_path, "fonts/Ahem.ttf")
))
recording.set(["startup", "load_tests"])