2018-11-16 21:48:50 +03:00
|
|
|
# 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 http://mozilla.org/MPL/2.0/.
|
|
|
|
|
2016-09-13 16:20:20 +03:00
|
|
|
import argparse
|
2020-10-14 13:20:20 +03:00
|
|
|
import errno
|
2018-11-16 21:48:50 +03:00
|
|
|
import hashlib
|
2016-09-13 16:20:20 +03:00
|
|
|
import imp
|
|
|
|
import os
|
2020-03-06 21:07:38 +03:00
|
|
|
import six
|
2016-09-13 16:20:20 +03:00
|
|
|
import sys
|
|
|
|
|
2019-12-09 13:46:50 +03:00
|
|
|
from six.moves import configparser
|
|
|
|
|
2018-11-16 21:48:50 +03:00
|
|
|
from mozboot.util import get_state_dir
|
|
|
|
|
2016-09-13 16:20:20 +03:00
|
|
|
from mozlog.structured import commandline
|
2018-10-02 18:46:42 +03:00
|
|
|
|
|
|
|
import manifestdownload
|
|
|
|
from wptrunner import wptcommandline
|
2017-01-28 11:49:11 +03:00
|
|
|
|
|
|
|
manifest = None
|
|
|
|
|
2018-08-20 15:05:22 +03:00
|
|
|
|
2017-01-28 11:49:11 +03:00
|
|
|
def do_delayed_imports(wpt_dir):
|
|
|
|
global manifest
|
2018-10-02 18:46:42 +03:00
|
|
|
imp.load_source(
|
|
|
|
"localpaths", os.path.join(wpt_dir, "tests", "tools", "localpaths.py")
|
2020-10-26 21:34:53 +03:00
|
|
|
)
|
2017-01-28 11:49:11 +03:00
|
|
|
sys.path.insert(0, os.path.join(wpt_dir, "tools", "manifest"))
|
|
|
|
import manifest
|
2016-09-13 16:20:20 +03:00
|
|
|
|
2018-08-20 15:05:22 +03:00
|
|
|
|
2016-09-13 16:20:20 +03:00
|
|
|
def create_parser():
|
|
|
|
p = argparse.ArgumentParser()
|
2018-10-02 18:46:42 +03:00
|
|
|
p.add_argument(
|
|
|
|
"--rebuild", action="store_true", help="Rebuild manifest from scratch"
|
|
|
|
)
|
|
|
|
download_group = p.add_mutually_exclusive_group()
|
|
|
|
download_group.add_argument(
|
|
|
|
"--download",
|
|
|
|
dest="download",
|
|
|
|
action="store_true",
|
|
|
|
default=None,
|
|
|
|
help="Always download even if the local manifest is recent",
|
|
|
|
)
|
|
|
|
download_group.add_argument(
|
|
|
|
"--no-download",
|
|
|
|
dest="download",
|
|
|
|
action="store_false",
|
|
|
|
help="Don't try to download the manifest",
|
|
|
|
)
|
|
|
|
p.add_argument(
|
|
|
|
"--no-update",
|
|
|
|
action="store_false",
|
|
|
|
dest="update",
|
|
|
|
default=True,
|
|
|
|
help="Just download the manifest, don't update",
|
|
|
|
)
|
|
|
|
p.add_argument(
|
|
|
|
"--config",
|
|
|
|
action="store",
|
|
|
|
dest="config_path",
|
|
|
|
default=None,
|
|
|
|
help="Path to wptrunner config file",
|
|
|
|
)
|
|
|
|
p.add_argument(
|
|
|
|
"--rewrite-config",
|
|
|
|
action="store_true",
|
|
|
|
default=False,
|
|
|
|
help="Force the local configuration to be regenerated",
|
|
|
|
)
|
2018-11-16 21:48:50 +03:00
|
|
|
p.add_argument(
|
2019-02-04 23:52:31 +03:00
|
|
|
"--cache-root",
|
|
|
|
action="store",
|
|
|
|
default=os.path.join(get_state_dir(), "cache", "wpt"),
|
2018-11-16 21:48:50 +03:00
|
|
|
help="Path to use for the metadata cache",
|
|
|
|
)
|
2016-09-13 16:20:20 +03:00
|
|
|
commandline.add_logging_group(p)
|
|
|
|
|
|
|
|
return p
|
|
|
|
|
|
|
|
|
2018-10-02 18:46:42 +03:00
|
|
|
def ensure_kwargs(kwargs):
|
|
|
|
_kwargs = vars(create_parser().parse_args([]))
|
|
|
|
_kwargs.update(kwargs)
|
|
|
|
return _kwargs
|
|
|
|
|
|
|
|
|
|
|
|
def run(src_root, obj_root, logger=None, **kwargs):
|
|
|
|
kwargs = ensure_kwargs(kwargs)
|
|
|
|
|
|
|
|
if logger is None:
|
|
|
|
from wptrunner import wptlogging
|
2020-10-26 21:34:53 +03:00
|
|
|
|
2018-10-02 18:46:42 +03:00
|
|
|
logger = wptlogging.setup(kwargs, {"mach": sys.stdout})
|
2018-09-20 15:07:58 +03:00
|
|
|
|
2018-10-02 18:46:42 +03:00
|
|
|
src_wpt_dir = os.path.join(src_root, "testing", "web-platform")
|
|
|
|
|
|
|
|
do_delayed_imports(src_wpt_dir)
|
|
|
|
|
|
|
|
if not kwargs["config_path"]:
|
|
|
|
config_path = generate_config(
|
|
|
|
logger,
|
|
|
|
src_root,
|
|
|
|
src_wpt_dir,
|
|
|
|
os.path.join(obj_root, "_tests", "web-platform"),
|
|
|
|
kwargs["rewrite_config"],
|
|
|
|
)
|
2018-09-20 15:07:58 +03:00
|
|
|
else:
|
2018-10-02 18:46:42 +03:00
|
|
|
config_path = kwargs["config_path"]
|
|
|
|
|
|
|
|
if not os.path.exists(config_path):
|
|
|
|
logger.critical("Config file %s does not exist" % config_path)
|
|
|
|
return None
|
|
|
|
|
|
|
|
logger.debug("Using config path %s" % config_path)
|
|
|
|
|
|
|
|
test_paths = wptcommandline.get_test_paths(wptcommandline.config.read(config_path))
|
|
|
|
|
2020-03-06 21:07:38 +03:00
|
|
|
for paths in six.itervalues(test_paths):
|
2018-10-02 18:46:42 +03:00
|
|
|
if "manifest_path" not in paths:
|
|
|
|
paths["manifest_path"] = os.path.join(
|
|
|
|
paths["metadata_path"], "MANIFEST.json"
|
|
|
|
)
|
|
|
|
|
|
|
|
ensure_manifest_directories(logger, test_paths)
|
|
|
|
|
|
|
|
local_config = read_local_config(src_wpt_dir)
|
|
|
|
for section in ["manifest:upstream", "manifest:mozilla"]:
|
|
|
|
url_base = local_config.get(section, "url_base")
|
|
|
|
manifest_rel_path = os.path.join(
|
|
|
|
local_config.get(section, "metadata"), "MANIFEST.json"
|
|
|
|
)
|
|
|
|
test_paths[url_base]["manifest_rel_path"] = manifest_rel_path
|
|
|
|
|
|
|
|
if not kwargs["rebuild"] and kwargs["download"] is not False:
|
|
|
|
force_download = False if kwargs["download"] is None else True
|
|
|
|
manifestdownload.download_from_taskcluster(
|
|
|
|
logger, src_root, test_paths, force=force_download
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
logger.debug("Skipping manifest download")
|
|
|
|
|
2019-02-07 16:48:50 +03:00
|
|
|
update = kwargs["update"] or kwargs["rebuild"]
|
|
|
|
manifests = load_and_update(
|
|
|
|
logger,
|
|
|
|
src_wpt_dir,
|
|
|
|
test_paths,
|
|
|
|
update=update,
|
|
|
|
rebuild=kwargs["rebuild"],
|
2019-05-21 00:17:39 +03:00
|
|
|
cache_root=kwargs["cache_root"],
|
|
|
|
)
|
2018-10-02 18:46:42 +03:00
|
|
|
|
|
|
|
return manifests
|
|
|
|
|
2018-09-20 15:07:58 +03:00
|
|
|
|
2018-10-02 18:46:42 +03:00
|
|
|
def ensure_manifest_directories(logger, test_paths):
|
2020-03-06 21:07:38 +03:00
|
|
|
for paths in six.itervalues(test_paths):
|
2018-10-02 18:46:42 +03:00
|
|
|
manifest_dir = os.path.dirname(paths["manifest_path"])
|
|
|
|
if not os.path.exists(manifest_dir):
|
|
|
|
logger.info("Creating directory %s" % manifest_dir)
|
2020-10-14 13:20:20 +03:00
|
|
|
# Even though we just checked the path doesn't exist, there's a chance
|
|
|
|
# of race condition with another process or thread having created it in
|
|
|
|
# between. This happens during tests.
|
|
|
|
try:
|
|
|
|
os.makedirs(manifest_dir)
|
|
|
|
except OSError as e:
|
|
|
|
if e.errno != errno.EEXIST:
|
|
|
|
raise
|
2018-10-02 18:46:42 +03:00
|
|
|
elif not os.path.isdir(manifest_dir):
|
|
|
|
raise IOError("Manifest directory is a file")
|
2016-09-13 16:20:20 +03:00
|
|
|
|
2017-01-28 11:49:11 +03:00
|
|
|
|
2018-10-02 18:46:42 +03:00
|
|
|
def read_local_config(wpt_dir):
|
|
|
|
src_config_path = os.path.join(wpt_dir, "wptrunner.ini")
|
2017-01-28 11:49:11 +03:00
|
|
|
|
2019-12-09 13:46:50 +03:00
|
|
|
parser = configparser.SafeConfigParser()
|
2018-10-02 18:46:42 +03:00
|
|
|
success = parser.read(src_config_path)
|
|
|
|
assert src_config_path in success
|
|
|
|
return parser
|
|
|
|
|
|
|
|
|
|
|
|
def generate_config(logger, repo_root, wpt_dir, dest_path, force_rewrite=False):
|
|
|
|
"""Generate the local wptrunner.ini file to use locally"""
|
|
|
|
if not os.path.exists(dest_path):
|
2020-10-14 13:20:20 +03:00
|
|
|
# Even though we just checked the path doesn't exist, there's a chance
|
|
|
|
# of race condition with another process or thread having created it in
|
|
|
|
# between. This happens during tests.
|
|
|
|
try:
|
|
|
|
os.makedirs(dest_path)
|
|
|
|
except OSError as e:
|
|
|
|
if e.errno != errno.EEXIST:
|
|
|
|
raise
|
2018-10-02 18:46:42 +03:00
|
|
|
|
|
|
|
dest_config_path = os.path.join(dest_path, "wptrunner.local.ini")
|
|
|
|
|
|
|
|
if not force_rewrite and os.path.exists(dest_config_path):
|
|
|
|
logger.debug("Config is up to date, not regenerating")
|
|
|
|
return dest_config_path
|
|
|
|
|
|
|
|
logger.info("Creating config file %s" % dest_config_path)
|
|
|
|
|
|
|
|
parser = read_local_config(wpt_dir)
|
|
|
|
|
|
|
|
for section in ["manifest:upstream", "manifest:mozilla"]:
|
|
|
|
meta_rel_path = parser.get(section, "metadata")
|
|
|
|
tests_rel_path = parser.get(section, "tests")
|
|
|
|
|
|
|
|
parser.set(
|
|
|
|
section, "manifest", os.path.join(dest_path, meta_rel_path, "MANIFEST.json")
|
2020-10-26 21:34:53 +03:00
|
|
|
)
|
2018-10-02 18:46:42 +03:00
|
|
|
parser.set(section, "metadata", os.path.join(wpt_dir, meta_rel_path))
|
|
|
|
parser.set(section, "tests", os.path.join(wpt_dir, tests_rel_path))
|
|
|
|
|
2020-09-29 17:22:49 +03:00
|
|
|
parser.set(
|
|
|
|
"paths",
|
|
|
|
"prefs",
|
|
|
|
os.path.abspath(os.path.join(wpt_dir, parser.get("paths", "prefs"))),
|
|
|
|
)
|
2018-10-02 18:46:42 +03:00
|
|
|
|
2020-03-06 21:07:38 +03:00
|
|
|
with open(dest_config_path, "wt") as config_file:
|
2018-10-02 18:46:42 +03:00
|
|
|
parser.write(config_file)
|
|
|
|
|
|
|
|
return dest_config_path
|
|
|
|
|
|
|
|
|
2019-02-07 16:48:50 +03:00
|
|
|
def load_and_update(
|
|
|
|
logger,
|
|
|
|
wpt_dir,
|
|
|
|
test_paths,
|
|
|
|
rebuild=False,
|
|
|
|
config_dir=None,
|
|
|
|
cache_root=None,
|
2019-05-21 00:17:39 +03:00
|
|
|
update=True,
|
|
|
|
):
|
2018-10-02 18:46:42 +03:00
|
|
|
rv = {}
|
2020-03-18 18:42:58 +03:00
|
|
|
wptdir_hash = hashlib.sha256(os.path.abspath(wpt_dir).encode()).hexdigest()
|
2020-03-06 21:07:38 +03:00
|
|
|
for url_base, paths in six.iteritems(test_paths):
|
2018-10-02 18:46:42 +03:00
|
|
|
manifest_path = paths["manifest_path"]
|
2020-09-29 17:22:49 +03:00
|
|
|
this_cache_root = os.path.join(
|
|
|
|
cache_root, wptdir_hash, os.path.dirname(paths["manifest_rel_path"])
|
2020-10-26 21:34:53 +03:00
|
|
|
)
|
2018-11-16 21:48:50 +03:00
|
|
|
m = manifest.manifest.load_and_update(
|
|
|
|
paths["tests_path"],
|
|
|
|
manifest_path,
|
|
|
|
url_base,
|
2019-02-07 16:48:50 +03:00
|
|
|
update=update,
|
|
|
|
rebuild=rebuild,
|
2018-11-16 21:48:50 +03:00
|
|
|
working_copy=True,
|
2019-05-21 00:17:39 +03:00
|
|
|
cache_root=this_cache_root,
|
|
|
|
)
|
2018-10-02 18:46:42 +03:00
|
|
|
path_data = {"url_base": url_base}
|
|
|
|
path_data.update(paths)
|
|
|
|
rv[m] = path_data
|
|
|
|
|
|
|
|
return rv
|
|
|
|
|
|
|
|
|
2017-01-28 11:49:11 +03:00
|
|
|
def log_error(logger, manifest_path, msg):
|
|
|
|
logger.lint_error(
|
|
|
|
path=manifest_path, message=msg, lineno=0, source="", linter="wpt-manifest"
|
|
|
|
)
|