123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- #! /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)
- def get_results_for_commit(commit, jobs):
- sys.stderr.write('%s\n' % commit)
- sys.stderr.flush()
- CONFIGS = ['gles', 'vk']
- passing_tests_for_all_jobs = []
- def process(url):
- testResults = json.load(urllib2.urlopen(url))
- sys.stderr.write('.')
- sys.stderr.flush()
- 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)
- sys.stderr.flush()
- 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
- def generate_commit_list(args):
- return subprocess.check_output(['git', 'log', '--format=%H'] + args).splitlines()
- def main(args):
- os.chdir(skia_directory)
- subprocess.check_call(['git', 'fetch', 'origin'])
- 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:])
|