| Index: third_party/WebKit/LayoutTests/external/wpt/check_stability.py
|
| diff --git a/third_party/WebKit/LayoutTests/external/wpt/check_stability.py b/third_party/WebKit/LayoutTests/external/wpt/check_stability.py
|
| index a7431c8a1c661b3835e57b09a2e7e02d3081cc30..611be00028e46c45fcf1de202894bc355194eeb4 100644
|
| --- a/third_party/WebKit/LayoutTests/external/wpt/check_stability.py
|
| +++ b/third_party/WebKit/LayoutTests/external/wpt/check_stability.py
|
| @@ -13,6 +13,8 @@ import traceback
|
| import zipfile
|
| from cStringIO import StringIO
|
| from collections import defaultdict
|
| +from ConfigParser import RawConfigParser
|
| +from io import BytesIO
|
| from urlparse import urljoin
|
| from tools.manifest import manifest
|
|
|
| @@ -27,6 +29,8 @@ TbplFormatter = None
|
| reader = None
|
| wptcommandline = None
|
| wptrunner = None
|
| +wpt_root = None
|
| +wptrunner_root = None
|
|
|
| logger = logging.getLogger(os.path.splitext(__file__)[0])
|
|
|
| @@ -178,6 +182,7 @@ class GitHubCommentHandler(logging.Handler):
|
|
|
| class Browser(object):
|
| product = None
|
| + binary = None
|
|
|
| def __init__(self, github_token):
|
| self.github_token = github_token
|
| @@ -185,9 +190,11 @@ class Browser(object):
|
|
|
| class Firefox(Browser):
|
| product = "firefox"
|
| + binary = "%s/firefox/firefox"
|
| + platform_ini = "%s/firefox/platform.ini"
|
|
|
| def install(self):
|
| - call("pip", "install", "-r", "w3c/wptrunner/requirements_firefox.txt")
|
| + call("pip", "install", "-r", os.path.join(wptrunner_root, "requirements_firefox.txt"))
|
| resp = get("https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/firefox-53.0a1.en-US.linux-x86_64.tar.bz2")
|
| untar(resp.raw)
|
|
|
| @@ -196,7 +203,7 @@ class Firefox(Browser):
|
| with open(os.path.join("profiles", "prefs_general.js"), "wb") as f:
|
| resp = get("https://hg.mozilla.org/mozilla-central/raw-file/tip/testing/profiles/prefs_general.js")
|
| f.write(resp.content)
|
| - call("pip", "install", "-r", os.path.join("w3c", "wptrunner", "requirements_firefox.txt"))
|
| + call("pip", "install", "-r", os.path.join(wptrunner_root, "requirements_firefox.txt"))
|
|
|
| def _latest_geckodriver_version(self):
|
| # This is used rather than an API call to avoid rate limits
|
| @@ -219,10 +226,20 @@ class Firefox(Browser):
|
| url = "https://github.com/mozilla/geckodriver/releases/download/%s/geckodriver-%s-linux64.tar.gz" % (version, version)
|
| untar(get(url).raw)
|
|
|
| + def version(self, root):
|
| + """Retrieve the release version of the installed browser."""
|
| + platform_info = RawConfigParser()
|
| +
|
| + with open(self.platform_ini % root, "r") as fp:
|
| + platform_info.readfp(BytesIO(fp.read()))
|
| + return "BuildID %s; SourceStamp %s" % (
|
| + platform_info.get("Build", "BuildID"),
|
| + platform_info.get("Build", "SourceStamp"))
|
| +
|
| def wptrunner_args(self, root):
|
| return {
|
| "product": "firefox",
|
| - "binary": "%s/firefox/firefox" % root,
|
| + "binary": self.binary % root,
|
| "certutil_binary": "certutil",
|
| "webdriver_binary": "%s/geckodriver" % root,
|
| "prefs_root": "%s/profiles" % root,
|
| @@ -231,12 +248,13 @@ class Firefox(Browser):
|
|
|
| class Chrome(Browser):
|
| product = "chrome"
|
| + binary = "/usr/bin/google-chrome"
|
|
|
| def install(self):
|
| # Installing the Google Chrome browser requires administrative
|
| # privileges, so that installation is handled by the invoking script.
|
|
|
| - call("pip", "install", "-r", os.path.join("w3c", "wptrunner", "requirements_chrome.txt"))
|
| + call("pip", "install", "-r", os.path.join(wptrunner_root, "requirements_chrome.txt"))
|
|
|
| def install_webdriver(self):
|
| latest = get("http://chromedriver.storage.googleapis.com/LATEST_RELEASE").text.strip()
|
| @@ -245,10 +263,15 @@ class Chrome(Browser):
|
| st = os.stat('chromedriver')
|
| os.chmod('chromedriver', st.st_mode | stat.S_IEXEC)
|
|
|
| + def version(self, root):
|
| + """Retrieve the release version of the installed browser."""
|
| + output = call(self.binary, "--version")
|
| + return re.search(r"[0-9a-z\.]+$", output.strip()).group(0)
|
| +
|
| def wptrunner_args(self, root):
|
| return {
|
| "product": "chrome",
|
| - "binary": "/usr/bin/google-chrome",
|
| + "binary": self.binary,
|
| # Chrome's "sandbox" security feature must be disabled in order to
|
| # run the browser in OpenVZ environments such as the one provided
|
| # by TravisCI.
|
| @@ -319,7 +342,7 @@ def unzip(fileobj):
|
| def setup_github_logging(args):
|
| gh_handler = None
|
| if args.comment_pr:
|
| - github = GitHub("w3c", "web-platform-tests", args.gh_token, args.product)
|
| + github = GitHub(args.user, "web-platform-tests", args.gh_token, args.product)
|
| try:
|
| pr_number = int(args.comment_pr)
|
| except ValueError:
|
| @@ -348,32 +371,32 @@ class pwd(object):
|
| self.old_dir = None
|
|
|
|
|
| -def fetch_wpt_master():
|
| - git = get_git_cmd(os.path.join(os.path.abspath(os.curdir), "w3c", "web-platform-tests"))
|
| - git("fetch", "https://github.com/w3c/web-platform-tests.git", "master:master")
|
| +def fetch_wpt_master(user):
|
| + git = get_git_cmd(wpt_root)
|
| + git("fetch", "https://github.com/%s/web-platform-tests.git" % user, "master:master")
|
|
|
|
|
| def get_sha1():
|
| - git = get_git_cmd(os.path.join(os.path.abspath(os.curdir), "w3c", "web-platform-tests"))
|
| + git = get_git_cmd(wpt_root)
|
| return git("rev-parse", "HEAD").strip()
|
|
|
|
|
| def build_manifest():
|
| - with pwd(os.path.join(os.path.abspath(os.curdir), "w3c", "web-platform-tests")):
|
| + with pwd(wpt_root):
|
| # TODO: Call the manifest code directly
|
| call("python", "manifest")
|
|
|
|
|
| def install_wptrunner():
|
| - call("git", "clone", "--depth=1", "https://github.com/w3c/wptrunner.git", "w3c/wptrunner")
|
| - git = get_git_cmd(os.path.join(os.path.abspath(os.curdir), "w3c", "wptrunner"))
|
| + call("git", "clone", "--depth=1", "https://github.com/w3c/wptrunner.git", wptrunner_root)
|
| + git = get_git_cmd(wptrunner_root)
|
| git("submodule", "update", "--init", "--recursive")
|
| - call("pip", "install", os.path.join("w3c", "wptrunner"))
|
| + call("pip", "install", wptrunner_root)
|
|
|
|
|
| def get_files_changed():
|
| root = os.path.abspath(os.curdir)
|
| - git = get_git_cmd("%s/w3c/web-platform-tests" % root)
|
| + git = get_git_cmd(wpt_root)
|
| branch_point = git("merge-base", "HEAD", "master").strip()
|
| logger.debug("Branch point from master: %s" % branch_point)
|
| logger.debug(git("log", "--oneline", "%s.." % branch_point))
|
| @@ -381,7 +404,7 @@ def get_files_changed():
|
| if not files:
|
| return []
|
| assert files[-1] == "\0"
|
| - return ["%s/w3c/web-platform-tests/%s" % (root, item)
|
| + return ["%s/%s" % (wpt_root, item)
|
| for item in files[:-1].split("\0")]
|
|
|
|
|
| @@ -389,16 +412,15 @@ def get_affected_testfiles(files_changed):
|
| affected_testfiles = []
|
| all_tests = set()
|
| nontests_changed = set(files_changed)
|
| - repo_root = os.path.abspath(os.path.join(os.path.abspath(os.curdir), "w3c", "web-platform-tests"))
|
| - manifest_file = os.path.join(repo_root, "MANIFEST.json")
|
| - for test, _ in manifest.load(repo_root, manifest_file):
|
| - test_full_path = os.path.join(repo_root, test)
|
| + manifest_file = os.path.join(wpt_root, "MANIFEST.json")
|
| + for _, test, _ in manifest.load(wpt_root, manifest_file):
|
| + test_full_path = os.path.join(wpt_root, test)
|
| all_tests.add(test_full_path)
|
| if test_full_path in nontests_changed:
|
| # Reduce the set of changed files to only non-tests.
|
| nontests_changed.remove(test_full_path)
|
| for changedfile_pathname in nontests_changed:
|
| - changed_file_repo_path = os.path.join(os.path.sep, os.path.relpath(changedfile_pathname, repo_root))
|
| + changed_file_repo_path = os.path.join(os.path.sep, os.path.relpath(changedfile_pathname, wpt_root))
|
| os.path.normpath(changed_file_repo_path)
|
| path_components = changed_file_repo_path.split(os.sep)[1:]
|
| if len(path_components) < 2:
|
| @@ -412,7 +434,7 @@ def get_affected_testfiles(files_changed):
|
| # other than a test (e.g., it's a .js or .json file), and it's
|
| # somewhere down beneath one of the top-level "spec" directories.
|
| # So now we try to find any tests that reference it.
|
| - for root, dirs, fnames in os.walk(os.path.join(repo_root, top_level_subdir)):
|
| + for root, dirs, fnames in os.walk(os.path.join(wpt_root, top_level_subdir)):
|
| # Walk top_level_subdir looking for test files containing either the
|
| # relative filepath or absolute filepatch to the changed file.
|
| for fname in fnames:
|
| @@ -434,13 +456,12 @@ def get_affected_testfiles(files_changed):
|
| def wptrunner_args(root, files_changed, iterations, browser):
|
| parser = wptcommandline.create_parser([browser.product])
|
| args = vars(parser.parse_args([]))
|
| - wpt_root = os.path.join(root, "w3c", "web-platform-tests")
|
| args.update(browser.wptrunner_args(root))
|
| args.update({
|
| "tests_root": wpt_root,
|
| "metadata_root": wpt_root,
|
| "repeat": iterations,
|
| - "config": "%s/w3c/wptrunner/wptrunner.default.ini" % root,
|
| + "config": "%s//wptrunner.default.ini" % (wptrunner_root),
|
| "test_list": files_changed,
|
| "restart_on_unexpected": False,
|
| "pause_after_test": False
|
| @@ -586,6 +607,12 @@ def get_parser():
|
| action="store",
|
| default=os.environ.get("TRAVIS_PULL_REQUEST"),
|
| help="PR to comment on with stability results")
|
| + parser.add_argument("--user",
|
| + action="store",
|
| + # Travis docs say do not depend on USER env variable.
|
| + # This is a workaround to get what should be the same value
|
| + default=os.environ.get("TRAVIS_REPO_SLUG").split('/')[0],
|
| + help="Travis user name")
|
| parser.add_argument("product",
|
| action="store",
|
| help="Product to run against (`browser-name` or 'browser-name:channel')")
|
| @@ -593,10 +620,16 @@ def get_parser():
|
|
|
|
|
| def main():
|
| + global wpt_root
|
| + global wptrunner_root
|
| +
|
| retcode = 0
|
| parser = get_parser()
|
| args = parser.parse_args()
|
|
|
| + wpt_root = os.path.abspath(os.curdir)
|
| + wptrunner_root = os.path.normpath(os.path.join(wpt_root, "..", "wptrunner"))
|
| +
|
| if not os.path.exists(args.root):
|
| logger.critical("Root directory %s does not exist" % args.root)
|
| return 1
|
| @@ -620,10 +653,10 @@ def main():
|
| logger.critical("Unrecognised browser %s" % browser_name)
|
| return 1
|
|
|
| - fetch_wpt_master()
|
| + fetch_wpt_master(args.user)
|
|
|
| head_sha1 = get_sha1()
|
| - logger.info("Testing revision %s" % head_sha1)
|
| + logger.info("Testing web-platform-tests at revision %s" % head_sha1)
|
|
|
| # For now just pass the whole list of changed files to wptrunner and
|
| # assume that it will run everything that's actually a test
|
| @@ -637,6 +670,16 @@ def main():
|
| install_wptrunner()
|
| do_delayed_imports()
|
|
|
| + browser = browser_cls(args.gh_token)
|
| + browser.install()
|
| + browser.install_webdriver()
|
| +
|
| + try:
|
| + version = browser.version(args.root)
|
| + except Exception, e:
|
| + version = "unknown (error: %s)" % e
|
| + logger.info("Using browser at version %s", version)
|
| +
|
| logger.debug("Files changed:\n%s" % "".join(" * %s\n" % item for item in files_changed))
|
|
|
| affected_testfiles = get_affected_testfiles(files_changed)
|
| @@ -645,11 +688,6 @@ def main():
|
|
|
| files_changed.extend(affected_testfiles)
|
|
|
| - browser = browser_cls(args.gh_token)
|
| -
|
| - browser.install()
|
| - browser.install_webdriver()
|
| -
|
| kwargs = wptrunner_args(args.root,
|
| files_changed,
|
| args.iterations,
|
|
|