2019-01-18 22:01:05 +00:00
|
|
|
#! /usr/bin/env python
|
|
|
|
# Copyright 2019 Google LLC.
|
|
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
|
|
# found in the LICENSE file.
|
|
|
|
|
|
|
|
import json
|
|
|
|
import os
|
|
|
|
import re
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import threading
|
|
|
|
import urllib
|
|
|
|
import urllib2
|
|
|
|
|
|
|
|
|
|
|
|
assert '/' in [os.sep, os.altsep]
|
|
|
|
|
|
|
|
|
|
|
|
skia_directory = os.path.abspath(os.path.dirname(__file__) + '/../..')
|
|
|
|
|
|
|
|
|
|
|
|
def get_jobs():
|
|
|
|
path = skia_directory + '/infra/bots/jobs.json'
|
|
|
|
reg = re.compile('Test-(?P<os>[A-Za-z0-9_]+)-'
|
|
|
|
'(?P<compiler>[A-Za-z0-9_]+)-'
|
|
|
|
'(?P<model>[A-Za-z0-9_]+)-GPU-'
|
|
|
|
'(?P<cpu_or_gpu_value>[A-Za-z0-9_]+)-'
|
|
|
|
'(?P<arch>[A-Za-z0-9_]+)-'
|
|
|
|
'(?P<configuration>[A-Za-z0-9_]+)-'
|
|
|
|
'All(-(?P<extra_config>[A-Za-z0-9_]+)|)')
|
|
|
|
keys = ['os', 'compiler', 'model', 'cpu_or_gpu_value', 'arch',
|
|
|
|
'configuration', 'extra_config']
|
|
|
|
def fmt(s):
|
|
|
|
return s.encode('utf-8') if s is not None else ''
|
|
|
|
with open(path) as f:
|
|
|
|
jobs = json.load(f)
|
|
|
|
for job in jobs:
|
|
|
|
m = reg.match(job)
|
|
|
|
if m is not None:
|
|
|
|
yield [(k, fmt(m.group(k))) for k in keys]
|
|
|
|
|
|
|
|
|
|
|
|
def gold_export_url(job, config, first_commit, last_commit):
|
|
|
|
qq = [('source_type', 'gm'), ('config', config)] + job
|
|
|
|
query = [
|
|
|
|
('fbegin', first_commit),
|
|
|
|
('fend', last_commit),
|
|
|
|
('query', urllib.urlencode(qq)),
|
|
|
|
('pos', 'true'),
|
|
|
|
('neg', 'false'),
|
|
|
|
('unt', 'false'),
|
|
|
|
('head', 'true')
|
|
|
|
]
|
|
|
|
return 'https://public-gold.skia.org/json/export?' + urllib.urlencode(query)
|
|
|
|
|
|
|
|
|
2019-12-03 19:27:04 +00:00
|
|
|
def urlopen(url):
|
|
|
|
cookie = os.environ.get('SKIA_GOLD_COOKIE', '')
|
|
|
|
return urllib2.urlopen(urllib2.Request(url, headers={'Cookie': cookie}))
|
|
|
|
|
|
|
|
|
2019-01-18 22:01:05 +00:00
|
|
|
def get_results_for_commit(commit, jobs):
|
|
|
|
sys.stderr.write('%s\n' % commit)
|
2019-02-11 14:41:37 +00:00
|
|
|
sys.stderr.flush()
|
2019-01-18 22:01:05 +00:00
|
|
|
CONFIGS = ['gles', 'vk']
|
|
|
|
passing_tests_for_all_jobs = []
|
|
|
|
def process(url):
|
2019-12-03 19:27:04 +00:00
|
|
|
try:
|
|
|
|
testResults = json.load(urlopen(url))
|
|
|
|
except urllib2.URLError:
|
|
|
|
sys.stderr.write('\nerror "%s":\n' % url)
|
|
|
|
return
|
2019-01-18 22:01:05 +00:00
|
|
|
sys.stderr.write('.')
|
2019-02-11 14:41:37 +00:00
|
|
|
sys.stderr.flush()
|
2019-01-18 22:01:05 +00:00
|
|
|
passing_tests = 0
|
|
|
|
for t in testResults:
|
|
|
|
assert t['digests']
|
|
|
|
passing_tests += 1
|
|
|
|
passing_tests_for_all_jobs.append(passing_tests)
|
|
|
|
all_urls = [gold_export_url(job, config, commit, commit)
|
|
|
|
for job in jobs for config in CONFIGS]
|
|
|
|
threads = [threading.Thread(target=process, args=(url,)) for url in all_urls]
|
|
|
|
for t in threads:
|
|
|
|
t.start()
|
|
|
|
for t in threads:
|
|
|
|
t.join()
|
|
|
|
result = sum(passing_tests_for_all_jobs)
|
|
|
|
sys.stderr.write('\n%d\n' % result)
|
2019-02-11 14:41:37 +00:00
|
|
|
sys.stderr.flush()
|
2019-01-18 22:01:05 +00:00
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
def find_best_commit(commits):
|
|
|
|
jobs = [j for j in get_jobs()]
|
|
|
|
results = []
|
|
|
|
for commit_name in commits:
|
|
|
|
commit_hash = subprocess.check_output(['git', 'rev-parse', commit_name]).strip()
|
|
|
|
results.append((commit_hash, get_results_for_commit(commit_hash, jobs)))
|
|
|
|
|
|
|
|
best_result = max(r for h, r in results)
|
|
|
|
for h, r in results:
|
|
|
|
if r == best_result:
|
|
|
|
return h
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2019-02-11 14:41:37 +00:00
|
|
|
def generate_commit_list(args):
|
|
|
|
return subprocess.check_output(['git', 'log', '--format=%H'] + args).splitlines()
|
|
|
|
|
|
|
|
|
|
|
|
def main(args):
|
2019-01-18 22:01:05 +00:00
|
|
|
os.chdir(skia_directory)
|
|
|
|
subprocess.check_call(['git', 'fetch', 'origin'])
|
2019-02-11 14:41:37 +00:00
|
|
|
sys.stderr.write('%s\n' % ' '.join(args))
|
|
|
|
commits = generate_commit_list(args)
|
|
|
|
sys.stderr.write('%d\n' % len(commits))
|
|
|
|
best = find_best_commit(commits)
|
|
|
|
sys.stderr.write('DONE:\n')
|
|
|
|
sys.stderr.flush()
|
|
|
|
sys.stdout.write('%s\n' % best)
|
|
|
|
|
|
|
|
|
|
|
|
usage = '''Example usage:
|
|
|
|
python %s origin/master ^origin/skqp/dev < /dev/null > LOG 2>&1 & disown
|
|
|
|
'''
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
if len(sys.argv) < 2:
|
|
|
|
sys.stderr.write(usage % sys.argv[0])
|
|
|
|
sys.exit(1)
|
|
|
|
main(sys.argv[1:])
|