| OLD | NEW |
| 1 from __future__ import print_function | 1 from __future__ import print_function |
| 2 | 2 |
| 3 import argparse | 3 import argparse |
| 4 import json | 4 import json |
| 5 import logging | 5 import logging |
| 6 import os | 6 import os |
| 7 import re | 7 import re |
| 8 import stat | 8 import stat |
| 9 import subprocess | 9 import subprocess |
| 10 import sys | 10 import sys |
| 11 import tarfile | 11 import tarfile |
| 12 import traceback | 12 import traceback |
| 13 import zipfile | 13 import zipfile |
| 14 from cStringIO import StringIO | 14 from cStringIO import StringIO |
| 15 from collections import defaultdict | 15 from collections import defaultdict |
| 16 from ConfigParser import RawConfigParser |
| 17 from io import BytesIO |
| 16 from urlparse import urljoin | 18 from urlparse import urljoin |
| 17 from tools.manifest import manifest | 19 from tools.manifest import manifest |
| 18 | 20 |
| 19 import requests | 21 import requests |
| 20 | 22 |
| 21 BaseHandler = None | 23 BaseHandler = None |
| 22 LogActionFilter = None | 24 LogActionFilter = None |
| 23 LogHandler = None | 25 LogHandler = None |
| 24 LogLevelFilter = None | 26 LogLevelFilter = None |
| 25 StreamHandler = None | 27 StreamHandler = None |
| 26 TbplFormatter = None | 28 TbplFormatter = None |
| 27 reader = None | 29 reader = None |
| 28 wptcommandline = None | 30 wptcommandline = None |
| 29 wptrunner = None | 31 wptrunner = None |
| 32 wpt_root = None |
| 33 wptrunner_root = None |
| 30 | 34 |
| 31 logger = logging.getLogger(os.path.splitext(__file__)[0]) | 35 logger = logging.getLogger(os.path.splitext(__file__)[0]) |
| 32 | 36 |
| 33 | 37 |
| 34 def do_delayed_imports(): | 38 def do_delayed_imports(): |
| 35 global BaseHandler | 39 global BaseHandler |
| 36 global LogLevelFilter | 40 global LogLevelFilter |
| 37 global StreamHandler | 41 global StreamHandler |
| 38 global TbplFormatter | 42 global TbplFormatter |
| 39 global reader | 43 global reader |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 except Exception: | 175 except Exception: |
| 172 self.handleError(record) | 176 self.handleError(record) |
| 173 | 177 |
| 174 def send(self): | 178 def send(self): |
| 175 self.github.post_comment(self.pull_number, "\n".join(self.log_data)) | 179 self.github.post_comment(self.pull_number, "\n".join(self.log_data)) |
| 176 self.log_data = [] | 180 self.log_data = [] |
| 177 | 181 |
| 178 | 182 |
| 179 class Browser(object): | 183 class Browser(object): |
| 180 product = None | 184 product = None |
| 185 binary = None |
| 181 | 186 |
| 182 def __init__(self, github_token): | 187 def __init__(self, github_token): |
| 183 self.github_token = github_token | 188 self.github_token = github_token |
| 184 | 189 |
| 185 | 190 |
| 186 class Firefox(Browser): | 191 class Firefox(Browser): |
| 187 product = "firefox" | 192 product = "firefox" |
| 193 binary = "%s/firefox/firefox" |
| 194 platform_ini = "%s/firefox/platform.ini" |
| 188 | 195 |
| 189 def install(self): | 196 def install(self): |
| 190 call("pip", "install", "-r", "w3c/wptrunner/requirements_firefox.txt") | 197 call("pip", "install", "-r", os.path.join(wptrunner_root, "requirements_
firefox.txt")) |
| 191 resp = get("https://archive.mozilla.org/pub/firefox/nightly/latest-mozil
la-central/firefox-53.0a1.en-US.linux-x86_64.tar.bz2") | 198 resp = get("https://archive.mozilla.org/pub/firefox/nightly/latest-mozil
la-central/firefox-53.0a1.en-US.linux-x86_64.tar.bz2") |
| 192 untar(resp.raw) | 199 untar(resp.raw) |
| 193 | 200 |
| 194 if not os.path.exists("profiles"): | 201 if not os.path.exists("profiles"): |
| 195 os.mkdir("profiles") | 202 os.mkdir("profiles") |
| 196 with open(os.path.join("profiles", "prefs_general.js"), "wb") as f: | 203 with open(os.path.join("profiles", "prefs_general.js"), "wb") as f: |
| 197 resp = get("https://hg.mozilla.org/mozilla-central/raw-file/tip/test
ing/profiles/prefs_general.js") | 204 resp = get("https://hg.mozilla.org/mozilla-central/raw-file/tip/test
ing/profiles/prefs_general.js") |
| 198 f.write(resp.content) | 205 f.write(resp.content) |
| 199 call("pip", "install", "-r", os.path.join("w3c", "wptrunner", "requireme
nts_firefox.txt")) | 206 call("pip", "install", "-r", os.path.join(wptrunner_root, "requirements_
firefox.txt")) |
| 200 | 207 |
| 201 def _latest_geckodriver_version(self): | 208 def _latest_geckodriver_version(self): |
| 202 # This is used rather than an API call to avoid rate limits | 209 # This is used rather than an API call to avoid rate limits |
| 203 tags = call("git", "ls-remote", "--tags", "--refs", | 210 tags = call("git", "ls-remote", "--tags", "--refs", |
| 204 "https://github.com/mozilla/geckodriver.git") | 211 "https://github.com/mozilla/geckodriver.git") |
| 205 release_re = re.compile(".*refs/tags/v(\d+)\.(\d+)\.(\d+)") | 212 release_re = re.compile(".*refs/tags/v(\d+)\.(\d+)\.(\d+)") |
| 206 latest_release = 0 | 213 latest_release = 0 |
| 207 for item in tags.split("\n"): | 214 for item in tags.split("\n"): |
| 208 m = release_re.match(item) | 215 m = release_re.match(item) |
| 209 if m: | 216 if m: |
| 210 version = [int(item) for item in m.groups()] | 217 version = [int(item) for item in m.groups()] |
| 211 if version > latest_release: | 218 if version > latest_release: |
| 212 latest_release = version | 219 latest_release = version |
| 213 assert latest_release != 0 | 220 assert latest_release != 0 |
| 214 return "v%s.%s.%s" % tuple(str(item) for item in latest_release) | 221 return "v%s.%s.%s" % tuple(str(item) for item in latest_release) |
| 215 | 222 |
| 216 def install_webdriver(self): | 223 def install_webdriver(self): |
| 217 version = self._latest_geckodriver_version() | 224 version = self._latest_geckodriver_version() |
| 218 logger.debug("Latest geckodriver release %s" % version) | 225 logger.debug("Latest geckodriver release %s" % version) |
| 219 url = "https://github.com/mozilla/geckodriver/releases/download/%s/gecko
driver-%s-linux64.tar.gz" % (version, version) | 226 url = "https://github.com/mozilla/geckodriver/releases/download/%s/gecko
driver-%s-linux64.tar.gz" % (version, version) |
| 220 untar(get(url).raw) | 227 untar(get(url).raw) |
| 221 | 228 |
| 229 def version(self, root): |
| 230 """Retrieve the release version of the installed browser.""" |
| 231 platform_info = RawConfigParser() |
| 232 |
| 233 with open(self.platform_ini % root, "r") as fp: |
| 234 platform_info.readfp(BytesIO(fp.read())) |
| 235 return "BuildID %s; SourceStamp %s" % ( |
| 236 platform_info.get("Build", "BuildID"), |
| 237 platform_info.get("Build", "SourceStamp")) |
| 238 |
| 222 def wptrunner_args(self, root): | 239 def wptrunner_args(self, root): |
| 223 return { | 240 return { |
| 224 "product": "firefox", | 241 "product": "firefox", |
| 225 "binary": "%s/firefox/firefox" % root, | 242 "binary": self.binary % root, |
| 226 "certutil_binary": "certutil", | 243 "certutil_binary": "certutil", |
| 227 "webdriver_binary": "%s/geckodriver" % root, | 244 "webdriver_binary": "%s/geckodriver" % root, |
| 228 "prefs_root": "%s/profiles" % root, | 245 "prefs_root": "%s/profiles" % root, |
| 229 } | 246 } |
| 230 | 247 |
| 231 | 248 |
| 232 class Chrome(Browser): | 249 class Chrome(Browser): |
| 233 product = "chrome" | 250 product = "chrome" |
| 251 binary = "/usr/bin/google-chrome" |
| 234 | 252 |
| 235 def install(self): | 253 def install(self): |
| 236 # Installing the Google Chrome browser requires administrative | 254 # Installing the Google Chrome browser requires administrative |
| 237 # privileges, so that installation is handled by the invoking script. | 255 # privileges, so that installation is handled by the invoking script. |
| 238 | 256 |
| 239 call("pip", "install", "-r", os.path.join("w3c", "wptrunner", "requireme
nts_chrome.txt")) | 257 call("pip", "install", "-r", os.path.join(wptrunner_root, "requirements_
chrome.txt")) |
| 240 | 258 |
| 241 def install_webdriver(self): | 259 def install_webdriver(self): |
| 242 latest = get("http://chromedriver.storage.googleapis.com/LATEST_RELEASE"
).text.strip() | 260 latest = get("http://chromedriver.storage.googleapis.com/LATEST_RELEASE"
).text.strip() |
| 243 url = "http://chromedriver.storage.googleapis.com/%s/chromedriver_linux6
4.zip" % latest | 261 url = "http://chromedriver.storage.googleapis.com/%s/chromedriver_linux6
4.zip" % latest |
| 244 unzip(get(url).raw) | 262 unzip(get(url).raw) |
| 245 st = os.stat('chromedriver') | 263 st = os.stat('chromedriver') |
| 246 os.chmod('chromedriver', st.st_mode | stat.S_IEXEC) | 264 os.chmod('chromedriver', st.st_mode | stat.S_IEXEC) |
| 247 | 265 |
| 266 def version(self, root): |
| 267 """Retrieve the release version of the installed browser.""" |
| 268 output = call(self.binary, "--version") |
| 269 return re.search(r"[0-9a-z\.]+$", output.strip()).group(0) |
| 270 |
| 248 def wptrunner_args(self, root): | 271 def wptrunner_args(self, root): |
| 249 return { | 272 return { |
| 250 "product": "chrome", | 273 "product": "chrome", |
| 251 "binary": "/usr/bin/google-chrome", | 274 "binary": self.binary, |
| 252 # Chrome's "sandbox" security feature must be disabled in order to | 275 # Chrome's "sandbox" security feature must be disabled in order to |
| 253 # run the browser in OpenVZ environments such as the one provided | 276 # run the browser in OpenVZ environments such as the one provided |
| 254 # by TravisCI. | 277 # by TravisCI. |
| 255 # | 278 # |
| 256 # Reference: https://github.com/travis-ci/travis-ci/issues/938 | 279 # Reference: https://github.com/travis-ci/travis-ci/issues/938 |
| 257 "binary_arg": "--no-sandbox", | 280 "binary_arg": "--no-sandbox", |
| 258 "webdriver_binary": "%s/chromedriver" % root, | 281 "webdriver_binary": "%s/chromedriver" % root, |
| 259 "test_types": ["testharness", "reftest"] | 282 "test_types": ["testharness", "reftest"] |
| 260 } | 283 } |
| 261 | 284 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 with zipfile.ZipFile(fileobj) as zip_data: | 335 with zipfile.ZipFile(fileobj) as zip_data: |
| 313 for info in zip_data.infolist(): | 336 for info in zip_data.infolist(): |
| 314 zip_data.extract(info) | 337 zip_data.extract(info) |
| 315 perm = info.external_attr >> 16 & 0x1FF | 338 perm = info.external_attr >> 16 & 0x1FF |
| 316 os.chmod(info.filename, perm) | 339 os.chmod(info.filename, perm) |
| 317 | 340 |
| 318 | 341 |
| 319 def setup_github_logging(args): | 342 def setup_github_logging(args): |
| 320 gh_handler = None | 343 gh_handler = None |
| 321 if args.comment_pr: | 344 if args.comment_pr: |
| 322 github = GitHub("w3c", "web-platform-tests", args.gh_token, args.product
) | 345 github = GitHub(args.user, "web-platform-tests", args.gh_token, args.pro
duct) |
| 323 try: | 346 try: |
| 324 pr_number = int(args.comment_pr) | 347 pr_number = int(args.comment_pr) |
| 325 except ValueError: | 348 except ValueError: |
| 326 pass | 349 pass |
| 327 else: | 350 else: |
| 328 gh_handler = GitHubCommentHandler(github, pr_number) | 351 gh_handler = GitHubCommentHandler(github, pr_number) |
| 329 gh_handler.setLevel(logging.INFO) | 352 gh_handler.setLevel(logging.INFO) |
| 330 logger.debug("Setting up GitHub logging") | 353 logger.debug("Setting up GitHub logging") |
| 331 logger.addHandler(gh_handler) | 354 logger.addHandler(gh_handler) |
| 332 else: | 355 else: |
| 333 logger.warning("No PR number found; not posting to GitHub") | 356 logger.warning("No PR number found; not posting to GitHub") |
| 334 return gh_handler | 357 return gh_handler |
| 335 | 358 |
| 336 | 359 |
| 337 class pwd(object): | 360 class pwd(object): |
| 338 def __init__(self, dir): | 361 def __init__(self, dir): |
| 339 self.dir = dir | 362 self.dir = dir |
| 340 self.old_dir = None | 363 self.old_dir = None |
| 341 | 364 |
| 342 def __enter__(self): | 365 def __enter__(self): |
| 343 self.old_dir = os.path.abspath(os.curdir) | 366 self.old_dir = os.path.abspath(os.curdir) |
| 344 os.chdir(self.dir) | 367 os.chdir(self.dir) |
| 345 | 368 |
| 346 def __exit__(self, *args, **kwargs): | 369 def __exit__(self, *args, **kwargs): |
| 347 os.chdir(self.old_dir) | 370 os.chdir(self.old_dir) |
| 348 self.old_dir = None | 371 self.old_dir = None |
| 349 | 372 |
| 350 | 373 |
| 351 def fetch_wpt_master(): | 374 def fetch_wpt_master(user): |
| 352 git = get_git_cmd(os.path.join(os.path.abspath(os.curdir), "w3c", "web-platf
orm-tests")) | 375 git = get_git_cmd(wpt_root) |
| 353 git("fetch", "https://github.com/w3c/web-platform-tests.git", "master:master
") | 376 git("fetch", "https://github.com/%s/web-platform-tests.git" % user, "master:
master") |
| 354 | 377 |
| 355 | 378 |
| 356 def get_sha1(): | 379 def get_sha1(): |
| 357 git = get_git_cmd(os.path.join(os.path.abspath(os.curdir), "w3c", "web-platf
orm-tests")) | 380 git = get_git_cmd(wpt_root) |
| 358 return git("rev-parse", "HEAD").strip() | 381 return git("rev-parse", "HEAD").strip() |
| 359 | 382 |
| 360 | 383 |
| 361 def build_manifest(): | 384 def build_manifest(): |
| 362 with pwd(os.path.join(os.path.abspath(os.curdir), "w3c", "web-platform-tests
")): | 385 with pwd(wpt_root): |
| 363 # TODO: Call the manifest code directly | 386 # TODO: Call the manifest code directly |
| 364 call("python", "manifest") | 387 call("python", "manifest") |
| 365 | 388 |
| 366 | 389 |
| 367 def install_wptrunner(): | 390 def install_wptrunner(): |
| 368 call("git", "clone", "--depth=1", "https://github.com/w3c/wptrunner.git", "w
3c/wptrunner") | 391 call("git", "clone", "--depth=1", "https://github.com/w3c/wptrunner.git", wp
trunner_root) |
| 369 git = get_git_cmd(os.path.join(os.path.abspath(os.curdir), "w3c", "wptrunner
")) | 392 git = get_git_cmd(wptrunner_root) |
| 370 git("submodule", "update", "--init", "--recursive") | 393 git("submodule", "update", "--init", "--recursive") |
| 371 call("pip", "install", os.path.join("w3c", "wptrunner")) | 394 call("pip", "install", wptrunner_root) |
| 372 | 395 |
| 373 | 396 |
| 374 def get_files_changed(): | 397 def get_files_changed(): |
| 375 root = os.path.abspath(os.curdir) | 398 root = os.path.abspath(os.curdir) |
| 376 git = get_git_cmd("%s/w3c/web-platform-tests" % root) | 399 git = get_git_cmd(wpt_root) |
| 377 branch_point = git("merge-base", "HEAD", "master").strip() | 400 branch_point = git("merge-base", "HEAD", "master").strip() |
| 378 logger.debug("Branch point from master: %s" % branch_point) | 401 logger.debug("Branch point from master: %s" % branch_point) |
| 379 logger.debug(git("log", "--oneline", "%s.." % branch_point)) | 402 logger.debug(git("log", "--oneline", "%s.." % branch_point)) |
| 380 files = git("diff", "--name-only", "-z", "%s.." % branch_point) | 403 files = git("diff", "--name-only", "-z", "%s.." % branch_point) |
| 381 if not files: | 404 if not files: |
| 382 return [] | 405 return [] |
| 383 assert files[-1] == "\0" | 406 assert files[-1] == "\0" |
| 384 return ["%s/w3c/web-platform-tests/%s" % (root, item) | 407 return ["%s/%s" % (wpt_root, item) |
| 385 for item in files[:-1].split("\0")] | 408 for item in files[:-1].split("\0")] |
| 386 | 409 |
| 387 | 410 |
| 388 def get_affected_testfiles(files_changed): | 411 def get_affected_testfiles(files_changed): |
| 389 affected_testfiles = [] | 412 affected_testfiles = [] |
| 390 all_tests = set() | 413 all_tests = set() |
| 391 nontests_changed = set(files_changed) | 414 nontests_changed = set(files_changed) |
| 392 repo_root = os.path.abspath(os.path.join(os.path.abspath(os.curdir), "w3c",
"web-platform-tests")) | 415 manifest_file = os.path.join(wpt_root, "MANIFEST.json") |
| 393 manifest_file = os.path.join(repo_root, "MANIFEST.json") | 416 for _, test, _ in manifest.load(wpt_root, manifest_file): |
| 394 for test, _ in manifest.load(repo_root, manifest_file): | 417 test_full_path = os.path.join(wpt_root, test) |
| 395 test_full_path = os.path.join(repo_root, test) | |
| 396 all_tests.add(test_full_path) | 418 all_tests.add(test_full_path) |
| 397 if test_full_path in nontests_changed: | 419 if test_full_path in nontests_changed: |
| 398 # Reduce the set of changed files to only non-tests. | 420 # Reduce the set of changed files to only non-tests. |
| 399 nontests_changed.remove(test_full_path) | 421 nontests_changed.remove(test_full_path) |
| 400 for changedfile_pathname in nontests_changed: | 422 for changedfile_pathname in nontests_changed: |
| 401 changed_file_repo_path = os.path.join(os.path.sep, os.path.relpath(chang
edfile_pathname, repo_root)) | 423 changed_file_repo_path = os.path.join(os.path.sep, os.path.relpath(chang
edfile_pathname, wpt_root)) |
| 402 os.path.normpath(changed_file_repo_path) | 424 os.path.normpath(changed_file_repo_path) |
| 403 path_components = changed_file_repo_path.split(os.sep)[1:] | 425 path_components = changed_file_repo_path.split(os.sep)[1:] |
| 404 if len(path_components) < 2: | 426 if len(path_components) < 2: |
| 405 # This changed file is in the repo root, so skip it | 427 # This changed file is in the repo root, so skip it |
| 406 # (because it's not part of any test). | 428 # (because it's not part of any test). |
| 407 continue | 429 continue |
| 408 top_level_subdir = path_components[0] | 430 top_level_subdir = path_components[0] |
| 409 if top_level_subdir in ["conformance-checkers", "docs"]: | 431 if top_level_subdir in ["conformance-checkers", "docs"]: |
| 410 continue | 432 continue |
| 411 # OK, this changed file is the kind we care about: It's something | 433 # OK, this changed file is the kind we care about: It's something |
| 412 # other than a test (e.g., it's a .js or .json file), and it's | 434 # other than a test (e.g., it's a .js or .json file), and it's |
| 413 # somewhere down beneath one of the top-level "spec" directories. | 435 # somewhere down beneath one of the top-level "spec" directories. |
| 414 # So now we try to find any tests that reference it. | 436 # So now we try to find any tests that reference it. |
| 415 for root, dirs, fnames in os.walk(os.path.join(repo_root, top_level_subd
ir)): | 437 for root, dirs, fnames in os.walk(os.path.join(wpt_root, top_level_subdi
r)): |
| 416 # Walk top_level_subdir looking for test files containing either the | 438 # Walk top_level_subdir looking for test files containing either the |
| 417 # relative filepath or absolute filepatch to the changed file. | 439 # relative filepath or absolute filepatch to the changed file. |
| 418 for fname in fnames: | 440 for fname in fnames: |
| 419 testfile_full_path = os.path.join(root, fname) | 441 testfile_full_path = os.path.join(root, fname) |
| 420 # Skip any test file that's already in files_changed. | 442 # Skip any test file that's already in files_changed. |
| 421 if testfile_full_path in files_changed: | 443 if testfile_full_path in files_changed: |
| 422 continue | 444 continue |
| 423 # Skip any file that's not a test file. | 445 # Skip any file that's not a test file. |
| 424 if testfile_full_path not in all_tests: | 446 if testfile_full_path not in all_tests: |
| 425 continue | 447 continue |
| 426 with open(testfile_full_path, "r") as fh: | 448 with open(testfile_full_path, "r") as fh: |
| 427 file_contents = fh.read() | 449 file_contents = fh.read() |
| 428 changed_file_relpath = os.path.relpath(changedfile_pathname,
root).replace(os.path.sep, "/") | 450 changed_file_relpath = os.path.relpath(changedfile_pathname,
root).replace(os.path.sep, "/") |
| 429 if changed_file_relpath in file_contents or changed_file_rep
o_path.replace(os.path.sep, "/") in file_contents: | 451 if changed_file_relpath in file_contents or changed_file_rep
o_path.replace(os.path.sep, "/") in file_contents: |
| 430 affected_testfiles.append(testfile_full_path) | 452 affected_testfiles.append(testfile_full_path) |
| 431 return affected_testfiles | 453 return affected_testfiles |
| 432 | 454 |
| 433 | 455 |
| 434 def wptrunner_args(root, files_changed, iterations, browser): | 456 def wptrunner_args(root, files_changed, iterations, browser): |
| 435 parser = wptcommandline.create_parser([browser.product]) | 457 parser = wptcommandline.create_parser([browser.product]) |
| 436 args = vars(parser.parse_args([])) | 458 args = vars(parser.parse_args([])) |
| 437 wpt_root = os.path.join(root, "w3c", "web-platform-tests") | |
| 438 args.update(browser.wptrunner_args(root)) | 459 args.update(browser.wptrunner_args(root)) |
| 439 args.update({ | 460 args.update({ |
| 440 "tests_root": wpt_root, | 461 "tests_root": wpt_root, |
| 441 "metadata_root": wpt_root, | 462 "metadata_root": wpt_root, |
| 442 "repeat": iterations, | 463 "repeat": iterations, |
| 443 "config": "%s/w3c/wptrunner/wptrunner.default.ini" % root, | 464 "config": "%s//wptrunner.default.ini" % (wptrunner_root), |
| 444 "test_list": files_changed, | 465 "test_list": files_changed, |
| 445 "restart_on_unexpected": False, | 466 "restart_on_unexpected": False, |
| 446 "pause_after_test": False | 467 "pause_after_test": False |
| 447 }) | 468 }) |
| 448 wptcommandline.check_args(args) | 469 wptcommandline.check_args(args) |
| 449 return args | 470 return args |
| 450 | 471 |
| 451 | 472 |
| 452 def setup_log_handler(): | 473 def setup_log_handler(): |
| 453 global LogHandler | 474 global LogHandler |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 type=int, | 600 type=int, |
| 580 help="Number of times to run tests") | 601 help="Number of times to run tests") |
| 581 parser.add_argument("--gh-token", | 602 parser.add_argument("--gh-token", |
| 582 action="store", | 603 action="store", |
| 583 default=os.environ.get("GH_TOKEN"), | 604 default=os.environ.get("GH_TOKEN"), |
| 584 help="OAuth token to use for accessing GitHub api") | 605 help="OAuth token to use for accessing GitHub api") |
| 585 parser.add_argument("--comment-pr", | 606 parser.add_argument("--comment-pr", |
| 586 action="store", | 607 action="store", |
| 587 default=os.environ.get("TRAVIS_PULL_REQUEST"), | 608 default=os.environ.get("TRAVIS_PULL_REQUEST"), |
| 588 help="PR to comment on with stability results") | 609 help="PR to comment on with stability results") |
| 610 parser.add_argument("--user", |
| 611 action="store", |
| 612 # Travis docs say do not depend on USER env variable. |
| 613 # This is a workaround to get what should be the same va
lue |
| 614 default=os.environ.get("TRAVIS_REPO_SLUG").split('/')[0]
, |
| 615 help="Travis user name") |
| 589 parser.add_argument("product", | 616 parser.add_argument("product", |
| 590 action="store", | 617 action="store", |
| 591 help="Product to run against (`browser-name` or 'browser
-name:channel')") | 618 help="Product to run against (`browser-name` or 'browser
-name:channel')") |
| 592 return parser | 619 return parser |
| 593 | 620 |
| 594 | 621 |
| 595 def main(): | 622 def main(): |
| 623 global wpt_root |
| 624 global wptrunner_root |
| 625 |
| 596 retcode = 0 | 626 retcode = 0 |
| 597 parser = get_parser() | 627 parser = get_parser() |
| 598 args = parser.parse_args() | 628 args = parser.parse_args() |
| 599 | 629 |
| 630 wpt_root = os.path.abspath(os.curdir) |
| 631 wptrunner_root = os.path.normpath(os.path.join(wpt_root, "..", "wptrunner")) |
| 632 |
| 600 if not os.path.exists(args.root): | 633 if not os.path.exists(args.root): |
| 601 logger.critical("Root directory %s does not exist" % args.root) | 634 logger.critical("Root directory %s does not exist" % args.root) |
| 602 return 1 | 635 return 1 |
| 603 | 636 |
| 604 os.chdir(args.root) | 637 os.chdir(args.root) |
| 605 | 638 |
| 606 if args.gh_token: | 639 if args.gh_token: |
| 607 gh_handler = setup_github_logging(args) | 640 gh_handler = setup_github_logging(args) |
| 608 else: | 641 else: |
| 609 logger.warning("Can't log to GitHub") | 642 logger.warning("Can't log to GitHub") |
| 610 gh_handler = None | 643 gh_handler = None |
| 611 | 644 |
| 612 browser_name = args.product.split(":")[0] | 645 browser_name = args.product.split(":")[0] |
| 613 | 646 |
| 614 with TravisFold("browser_setup"): | 647 with TravisFold("browser_setup"): |
| 615 logger.info(format_comment_title(args.product)) | 648 logger.info(format_comment_title(args.product)) |
| 616 | 649 |
| 617 browser_cls = {"firefox": Firefox, | 650 browser_cls = {"firefox": Firefox, |
| 618 "chrome": Chrome}.get(browser_name) | 651 "chrome": Chrome}.get(browser_name) |
| 619 if browser_cls is None: | 652 if browser_cls is None: |
| 620 logger.critical("Unrecognised browser %s" % browser_name) | 653 logger.critical("Unrecognised browser %s" % browser_name) |
| 621 return 1 | 654 return 1 |
| 622 | 655 |
| 623 fetch_wpt_master() | 656 fetch_wpt_master(args.user) |
| 624 | 657 |
| 625 head_sha1 = get_sha1() | 658 head_sha1 = get_sha1() |
| 626 logger.info("Testing revision %s" % head_sha1) | 659 logger.info("Testing web-platform-tests at revision %s" % head_sha1) |
| 627 | 660 |
| 628 # For now just pass the whole list of changed files to wptrunner and | 661 # For now just pass the whole list of changed files to wptrunner and |
| 629 # assume that it will run everything that's actually a test | 662 # assume that it will run everything that's actually a test |
| 630 files_changed = get_files_changed() | 663 files_changed = get_files_changed() |
| 631 | 664 |
| 632 if not files_changed: | 665 if not files_changed: |
| 633 logger.info("No files changed") | 666 logger.info("No files changed") |
| 634 return 0 | 667 return 0 |
| 635 | 668 |
| 636 build_manifest() | 669 build_manifest() |
| 637 install_wptrunner() | 670 install_wptrunner() |
| 638 do_delayed_imports() | 671 do_delayed_imports() |
| 639 | 672 |
| 673 browser = browser_cls(args.gh_token) |
| 674 browser.install() |
| 675 browser.install_webdriver() |
| 676 |
| 677 try: |
| 678 version = browser.version(args.root) |
| 679 except Exception, e: |
| 680 version = "unknown (error: %s)" % e |
| 681 logger.info("Using browser at version %s", version) |
| 682 |
| 640 logger.debug("Files changed:\n%s" % "".join(" * %s\n" % item for item in
files_changed)) | 683 logger.debug("Files changed:\n%s" % "".join(" * %s\n" % item for item in
files_changed)) |
| 641 | 684 |
| 642 affected_testfiles = get_affected_testfiles(files_changed) | 685 affected_testfiles = get_affected_testfiles(files_changed) |
| 643 | 686 |
| 644 logger.debug("Affected tests:\n%s" % "".join(" * %s\n" % item for item i
n affected_testfiles)) | 687 logger.debug("Affected tests:\n%s" % "".join(" * %s\n" % item for item i
n affected_testfiles)) |
| 645 | 688 |
| 646 files_changed.extend(affected_testfiles) | 689 files_changed.extend(affected_testfiles) |
| 647 | 690 |
| 648 browser = browser_cls(args.gh_token) | |
| 649 | |
| 650 browser.install() | |
| 651 browser.install_webdriver() | |
| 652 | |
| 653 kwargs = wptrunner_args(args.root, | 691 kwargs = wptrunner_args(args.root, |
| 654 files_changed, | 692 files_changed, |
| 655 args.iterations, | 693 args.iterations, |
| 656 browser) | 694 browser) |
| 657 | 695 |
| 658 with TravisFold("running_tests"): | 696 with TravisFold("running_tests"): |
| 659 logger.info("Starting %i test iterations" % args.iterations) | 697 logger.info("Starting %i test iterations" % args.iterations) |
| 660 with open("raw.log", "wb") as log: | 698 with open("raw.log", "wb") as log: |
| 661 wptrunner.setup_logging(kwargs, | 699 wptrunner.setup_logging(kwargs, |
| 662 {"raw": log}) | 700 {"raw": log}) |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 696 return retcode | 734 return retcode |
| 697 | 735 |
| 698 | 736 |
| 699 if __name__ == "__main__": | 737 if __name__ == "__main__": |
| 700 try: | 738 try: |
| 701 retcode = main() | 739 retcode = main() |
| 702 except: | 740 except: |
| 703 raise | 741 raise |
| 704 else: | 742 else: |
| 705 sys.exit(retcode) | 743 sys.exit(retcode) |
| OLD | NEW |