Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1349)

Side by Side Diff: third_party/WebKit/LayoutTests/external/wpt/check_stability.py

Issue 2645553002: Import wpt@fd6560f225668e933bfb147ee0e20d5971a0d21f (Closed)
Patch Set: Modify TestExpectations or download new baselines for tests. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 self.name = name 82 self.name = name
83 83
84 def __enter__(self): 84 def __enter__(self):
85 print("travis_fold:start:%s" % self.name, file=sys.stderr) 85 print("travis_fold:start:%s" % self.name, file=sys.stderr)
86 86
87 def __exit__(self, type, value, traceback): 87 def __exit__(self, type, value, traceback):
88 print("travis_fold:end:%s" % self.name, file=sys.stderr) 88 print("travis_fold:end:%s" % self.name, file=sys.stderr)
89 89
90 90
91 class GitHub(object): 91 class GitHub(object):
92 def __init__(self, org, repo, token, browser): 92 def __init__(self, org, repo, token, product):
93 self.token = token 93 self.token = token
94 self.headers = {"Accept": "application/vnd.github.v3+json"} 94 self.headers = {"Accept": "application/vnd.github.v3+json"}
95 self.auth = (self.token, "x-oauth-basic") 95 self.auth = (self.token, "x-oauth-basic")
96 self.org = org 96 self.org = org
97 self.repo = repo 97 self.repo = repo
98 self.base_url = "https://api.github.com/repos/%s/%s/" % (org, repo) 98 self.base_url = "https://api.github.com/repos/%s/%s/" % (org, repo)
99 self.browser = browser 99 self.product = product
100 100
101 def _headers(self, headers): 101 def _headers(self, headers):
102 if headers is None: 102 if headers is None:
103 headers = {} 103 headers = {}
104 rv = self.headers.copy() 104 rv = self.headers.copy()
105 rv.update(headers) 105 rv.update(headers)
106 return rv 106 return rv
107 107
108 def post(self, url, data, headers=None): 108 def post(self, url, data, headers=None):
109 logger.debug("POST %s" % url) 109 logger.debug("POST %s" % url)
(...skipping 28 matching lines...) Expand all
138 headers=self._headers(headers), 138 headers=self._headers(headers),
139 auth=self.auth 139 auth=self.auth
140 ) 140 )
141 resp.raise_for_status() 141 resp.raise_for_status()
142 return resp 142 return resp
143 143
144 def post_comment(self, issue_number, body): 144 def post_comment(self, issue_number, body):
145 user = self.get(urljoin(self.base_url, "/user")).json() 145 user = self.get(urljoin(self.base_url, "/user")).json()
146 issue_comments_url = urljoin(self.base_url, "issues/%s/comments" % issue _number) 146 issue_comments_url = urljoin(self.base_url, "issues/%s/comments" % issue _number)
147 comments = self.get(issue_comments_url).json() 147 comments = self.get(issue_comments_url).json()
148 title_line = "# %s #" % self.browser.title() 148 title_line = format_comment_title(self.product)
149 data = {"body": body} 149 data = {"body": body}
150 for comment in comments: 150 for comment in comments:
151 if (comment["user"]["login"] == user["login"] and 151 if (comment["user"]["login"] == user["login"] and
152 comment["body"].startswith(title_line)): 152 comment["body"].startswith(title_line)):
153 comment_url = urljoin(self.base_url, "issues/comments/%s" % comm ent["id"]) 153 comment_url = urljoin(self.base_url, "issues/comments/%s" % comm ent["id"])
154 self.patch(comment_url, data) 154 self.patch(comment_url, data)
155 break 155 break
156 else: 156 else:
157 self.post(issue_comments_url, data) 157 self.post(issue_comments_url, data)
158 158
159 def releases(self):
160 url = urljoin(self.base_url, "releases/latest")
161 return self.get(url)
162
163 159
164 class GitHubCommentHandler(logging.Handler): 160 class GitHubCommentHandler(logging.Handler):
165 def __init__(self, github, pull_number): 161 def __init__(self, github, pull_number):
166 logging.Handler.__init__(self) 162 logging.Handler.__init__(self)
167 self.github = github 163 self.github = github
168 self.pull_number = pull_number 164 self.pull_number = pull_number
169 self.log_data = [] 165 self.log_data = []
170 166
171 def emit(self, record): 167 def emit(self, record):
172 try: 168 try:
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 "certutil_binary": "certutil", 226 "certutil_binary": "certutil",
231 "webdriver_binary": "%s/geckodriver" % root, 227 "webdriver_binary": "%s/geckodriver" % root,
232 "prefs_root": "%s/profiles" % root, 228 "prefs_root": "%s/profiles" % root,
233 } 229 }
234 230
235 231
236 class Chrome(Browser): 232 class Chrome(Browser):
237 product = "chrome" 233 product = "chrome"
238 234
239 def install(self): 235 def install(self):
240 latest = get("https://www.googleapis.com/download/storage/v1/b/chromium- browser-snapshots/o/Linux_x64%2FLAST_CHANGE?alt=media").text.strip() 236 # Installing the Google Chrome browser requires administrative
241 url = "https://www.googleapis.com/download/storage/v1/b/chromium-browser -snapshots/o/Linux_x64%%2F%s%%2Fchrome-linux.zip?alt=media" % latest 237 # privileges, so that installation is handled by the invoking script.
242 unzip(get(url).raw) 238
243 logger.debug(call("ls", "-lhrt", "chrome-linux"))
244 call("pip", "install", "-r", os.path.join("w3c", "wptrunner", "requireme nts_chrome.txt")) 239 call("pip", "install", "-r", os.path.join("w3c", "wptrunner", "requireme nts_chrome.txt"))
245 240
246 def install_webdriver(self): 241 def install_webdriver(self):
247 latest = get("http://chromedriver.storage.googleapis.com/LATEST_RELEASE" ).text.strip() 242 latest = get("http://chromedriver.storage.googleapis.com/LATEST_RELEASE" ).text.strip()
248 url = "http://chromedriver.storage.googleapis.com/%s/chromedriver_linux6 4.zip" % latest 243 url = "http://chromedriver.storage.googleapis.com/%s/chromedriver_linux6 4.zip" % latest
249 unzip(get(url).raw) 244 unzip(get(url).raw)
250 st = os.stat('chromedriver') 245 st = os.stat('chromedriver')
251 os.chmod('chromedriver', st.st_mode | stat.S_IEXEC) 246 os.chmod('chromedriver', st.st_mode | stat.S_IEXEC)
252 247
253 def wptrunner_args(self, root): 248 def wptrunner_args(self, root):
254 return { 249 return {
255 "product": "chrome", 250 "product": "chrome",
256 "binary": "%s/chrome-linux/chrome" % root, 251 "binary": "/usr/bin/google-chrome",
252 # Chrome's "sandbox" security feature must be disabled in order to
253 # run the browser in OpenVZ environments such as the one provided
254 # by TravisCI.
255 #
256 # Reference: https://github.com/travis-ci/travis-ci/issues/938
257 "binary_arg": "--no-sandbox",
257 "webdriver_binary": "%s/chromedriver" % root, 258 "webdriver_binary": "%s/chromedriver" % root,
258 "test_types": ["testharness", "reftest"] 259 "test_types": ["testharness", "reftest"]
259 } 260 }
260 261
261 262
262 def get(url): 263 def get(url):
263 logger.debug("GET %s" % url) 264 logger.debug("GET %s" % url)
264 resp = requests.get(url, stream=True) 265 resp = requests.get(url, stream=True)
265 resp.raise_for_status() 266 resp.raise_for_status()
266 return resp 267 return resp
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 with zipfile.ZipFile(fileobj) as zip_data: 312 with zipfile.ZipFile(fileobj) as zip_data:
312 for info in zip_data.infolist(): 313 for info in zip_data.infolist():
313 zip_data.extract(info) 314 zip_data.extract(info)
314 perm = info.external_attr >> 16 & 0x1FF 315 perm = info.external_attr >> 16 & 0x1FF
315 os.chmod(info.filename, perm) 316 os.chmod(info.filename, perm)
316 317
317 318
318 def setup_github_logging(args): 319 def setup_github_logging(args):
319 gh_handler = None 320 gh_handler = None
320 if args.comment_pr: 321 if args.comment_pr:
321 github = GitHub("w3c", "web-platform-tests", args.gh_token, args.browser ) 322 github = GitHub("w3c", "web-platform-tests", args.gh_token, args.product )
322 try: 323 try:
323 pr_number = int(args.comment_pr) 324 pr_number = int(args.comment_pr)
324 except ValueError: 325 except ValueError:
325 pass 326 pass
326 else: 327 else:
327 gh_handler = GitHubCommentHandler(github, pr_number) 328 gh_handler = GitHubCommentHandler(github, pr_number)
328 gh_handler.setLevel(logging.INFO) 329 gh_handler.setLevel(logging.INFO)
329 logger.debug("Setting up GitHub logging") 330 logger.debug("Setting up GitHub logging")
330 logger.addHandler(gh_handler) 331 logger.addHandler(gh_handler)
331 else: 332 else:
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 handler = LogHandler() 486 handler = LogHandler()
486 reader.handle_log(reader.read(log), handler) 487 reader.handle_log(reader.read(log), handler)
487 results = handler.results 488 results = handler.results
488 for test, test_results in results.iteritems(): 489 for test, test_results in results.iteritems():
489 for subtest, result in test_results.iteritems(): 490 for subtest, result in test_results.iteritems():
490 if is_inconsistent(result, iterations): 491 if is_inconsistent(result, iterations):
491 inconsistent.append((test, subtest, result)) 492 inconsistent.append((test, subtest, result))
492 return results, inconsistent 493 return results, inconsistent
493 494
494 495
496 def format_comment_title(product):
497 """Produce a Markdown-formatted string based on a given "product"--a string
498 containing a browser identifier optionally followed by a colon and a
499 release channel. (For example: "firefox" or "chrome:dev".) The generated
500 title string is used both to create new comments and to locate (and
501 subsequently update) previously-submitted comments."""
502 parts = product.split(":")
503 title = parts[0].title()
504
505 if len(parts) > 1:
506 title += " (%s channel)" % parts[1]
507
508 return "# %s #" % title
509
510
495 def markdown_adjust(s): 511 def markdown_adjust(s):
496 s = s.replace('\t', u'\\t') 512 s = s.replace('\t', u'\\t')
497 s = s.replace('\n', u'\\n') 513 s = s.replace('\n', u'\\n')
498 s = s.replace('\r', u'\\r') 514 s = s.replace('\r', u'\\r')
499 s = s.replace('`', u'\\`') 515 s = s.replace('`', u'\\`')
500 return s 516 return s
501 517
502 518
503 def table(headings, data, log): 519 def table(headings, data, log):
504 cols = range(len(headings)) 520 cols = range(len(headings))
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 type=int, 579 type=int,
564 help="Number of times to run tests") 580 help="Number of times to run tests")
565 parser.add_argument("--gh-token", 581 parser.add_argument("--gh-token",
566 action="store", 582 action="store",
567 default=os.environ.get("GH_TOKEN"), 583 default=os.environ.get("GH_TOKEN"),
568 help="OAuth token to use for accessing GitHub api") 584 help="OAuth token to use for accessing GitHub api")
569 parser.add_argument("--comment-pr", 585 parser.add_argument("--comment-pr",
570 action="store", 586 action="store",
571 default=os.environ.get("TRAVIS_PULL_REQUEST"), 587 default=os.environ.get("TRAVIS_PULL_REQUEST"),
572 help="PR to comment on with stability results") 588 help="PR to comment on with stability results")
573 parser.add_argument("browser", 589 parser.add_argument("product",
574 action="store", 590 action="store",
575 help="Browser to run against") 591 help="Product to run against (`browser-name` or 'browser -name:channel')")
576 return parser 592 return parser
577 593
578 594
579 def main(): 595 def main():
580 retcode = 0 596 retcode = 0
581 parser = get_parser() 597 parser = get_parser()
582 args = parser.parse_args() 598 args = parser.parse_args()
583 599
584 if not os.path.exists(args.root): 600 if not os.path.exists(args.root):
585 logger.critical("Root directory %s does not exist" % args.root) 601 logger.critical("Root directory %s does not exist" % args.root)
586 return 1 602 return 1
587 603
588 os.chdir(args.root) 604 os.chdir(args.root)
589 605
590 if args.gh_token: 606 if args.gh_token:
591 gh_handler = setup_github_logging(args) 607 gh_handler = setup_github_logging(args)
592 else: 608 else:
593 logger.warning("Can't log to GitHub") 609 logger.warning("Can't log to GitHub")
594 gh_handler = None 610 gh_handler = None
595 611
612 browser_name = args.product.split(":")[0]
613
596 with TravisFold("browser_setup"): 614 with TravisFold("browser_setup"):
597 logger.info("# %s #" % args.browser.title()) 615 logger.info(format_comment_title(args.product))
598 616
599 browser_cls = {"firefox": Firefox, 617 browser_cls = {"firefox": Firefox,
600 "chrome": Chrome}.get(args.browser) 618 "chrome": Chrome}.get(browser_name)
601 if browser_cls is None: 619 if browser_cls is None:
602 logger.critical("Unrecognised browser %s" % args.browser) 620 logger.critical("Unrecognised browser %s" % browser_name)
603 return 1 621 return 1
604 622
605 fetch_wpt_master() 623 fetch_wpt_master()
606 624
607 head_sha1 = get_sha1() 625 head_sha1 = get_sha1()
608 logger.info("Testing revision %s" % head_sha1) 626 logger.info("Testing revision %s" % head_sha1)
609 627
610 # For now just pass the whole list of changed files to wptrunner and 628 # For now just pass the whole list of changed files to wptrunner and
611 # assume that it will run everything that's actually a test 629 # assume that it will run everything that's actually a test
612 files_changed = get_files_changed() 630 files_changed = get_files_changed()
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 return retcode 696 return retcode
679 697
680 698
681 if __name__ == "__main__": 699 if __name__ == "__main__":
682 try: 700 try:
683 retcode = main() 701 retcode = main()
684 except: 702 except:
685 raise 703 raise
686 else: 704 else:
687 sys.exit(retcode) 705 sys.exit(retcode)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698