skia2/tools/skqp/cut_release.py
Hal Canary 572d9bba64 SkQP: consolidate cut_release scripts
replace the following scripts: cut_release, get_gold_results.py,
goldgetter.py, make_rendertests_list.py, and upload_model with a single
program: cut_release.  Still depends on three C++ programs: jitter_gms,
list_gpu_unit_tests, and make_skqp_model.

Change-Id: I28f59bc1f0caedc05d6ce2c4cc11bbd66cfb9784
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/209171
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
2019-04-18 19:40:50 +00:00

169 lines
5.2 KiB
Python
Executable File

#! /usr/bin/env python
# Copyright 2018 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 md5
import multiprocessing
import os
import shutil
import sys
import tempfile
import urllib
import urllib2
from subprocess import check_call, check_output
assert '/' in [os.sep, os.altsep] and os.pardir == '..'
ASSETS = 'platform_tools/android/apps/skqp/src/main/assets'
BUCKET = 'skia-skqp-assets'
def make_skqp_model(arg):
name, urls, exe = arg
tmp = tempfile.mkdtemp()
for url in urls:
urllib.urlretrieve(url, tmp + '/' + url[url.rindex('/') + 1:])
check_call([exe, tmp, ASSETS + '/gmkb/' + name])
shutil.rmtree(tmp)
sys.stdout.write(name + ' ')
sys.stdout.flush()
def goldgetter(meta, exe):
assert os.path.exists(exe)
jobs = []
for rec in meta:
urls = [d['URL'] for d in rec['digests']
if d['status'] == 'positive' and
(set(d['paramset']['config']) & set(['vk', 'gles']))]
if urls:
jobs.append((rec['testName'], urls, exe))
pool = multiprocessing.Pool(processes=20)
pool.map(make_skqp_model, jobs)
sys.stdout.write('\n')
return set((n for n, _, _ in jobs))
def gold(first_commit, last_commit):
c1, c2 = (check_output(['git', 'rev-parse', c]).strip()
for c in (first_commit, last_commit))
f = urllib2.urlopen('https://public-gold.skia.org/json/export?' + urllib.urlencode([
('fbegin', c1),
('fend', c2),
('query', 'config=gles&config=vk&source_type=gm'),
('pos', 'true'),
('neg', 'false'),
('unt', 'false')
]))
j = json.load(f)
f.close()
return j
def gset(path):
s = set()
if os.path.isfile(path):
with open(path, 'r') as f:
for line in f:
s.add(line.strip())
return s
def make_rendertest_list(models, good, bad):
assert good.isdisjoint(bad)
do_score = good & models
no_score = bad | (good - models)
to_delete = models & bad
for d in to_delete:
path = ASSETS + '/gmkb/' + d
if os.path.isdir(path):
shutil.rmtree(path)
results = dict()
for n in do_score:
results[n] = 0
for n in no_score:
results[n] = -1
return ''.join('%s,%d\n' % (n, results[n]) for n in sorted(results))
def get_digest(path):
m = md5.new()
with open(path, 'r') as f:
m.update(f.read())
return m.hexdigest()
def upload_cmd(path, digest):
return ['gsutil', 'cp', path, 'gs://%s/%s' % (BUCKET, digest)]
def upload_model():
bucket_url = 'gs://%s/' % BUCKET
extant = set((u.replace(bucket_url, '', 1)
for u in check_output(['gsutil', 'ls', bucket_url]).splitlines() if u))
cmds = []
filelist = []
for dirpath, _, filenames in os.walk(ASSETS + '/gmkb'):
for filename in filenames:
path = os.path.join(dirpath, filename)
digest = get_digest(path)
if digest not in extant:
cmds.append(upload_cmd(path, digest))
filelist.append('%s;%s\n' % (digest, os.path.relpath(path, ASSETS)))
tmp = tempfile.mkdtemp()
filelist_path = tmp + '/x'
with open(filelist_path, 'w') as o:
for l in filelist:
o.write(l)
filelist_digest = get_digest(filelist_path)
if filelist_digest not in extant:
cmds.append(upload_cmd(filelist_path, filelist_digest))
pool = multiprocessing.Pool(processes=20)
pool.map(check_call, cmds)
shutil.rmtree(tmp)
return filelist_digest
def remove(x):
if os.path.isdir(x) and not os.path.islink(x):
shutil.rmtree(x)
if os.path.exists(x):
os.remove(x)
def main(first_commit, last_commit):
check_call(upload_cmd('/dev/null', get_digest('/dev/null')))
os.chdir(os.path.dirname(__file__) + '/../..')
remove(ASSETS + '/files.checksum')
for d in [ASSETS + '/gmkb', ASSETS + '/skqp', ]:
remove(d)
os.mkdir(d)
check_call([sys.executable, 'tools/git-sync-deps'],
env=dict(os.environ, GIT_SYNC_DEPS_QUIET='T'))
build = 'out/ndebug'
check_call(['bin/gn', 'gen', build,
'--args=cc="clang" cxx="clang++" is_debug=false'])
check_call(['ninja', '-C', build,
'jitter_gms', 'list_gpu_unit_tests', 'make_skqp_model'])
models = goldgetter(gold(first_commit, last_commit), build + '/make_skqp_model')
check_call([build + '/jitter_gms', 'tools/skqp/bad_gms.txt'])
with open(ASSETS + '/skqp/rendertests.txt', 'w') as o:
o.write(make_rendertest_list(models, gset('good.txt'), gset('bad.txt')))
remove('good.txt')
remove('bad.txt')
with open(ASSETS + '/skqp/unittests.txt', 'w') as o:
o.write(check_output([build + '/list_gpu_unit_tests']))
with open(ASSETS + '/files.checksum', 'w') as o:
o.write(upload_model() + '\n')
sys.stdout.write(ASSETS + '/files.checksum\n')
sys.stdout.write(ASSETS + '/skqp/rendertests.txt\n')
sys.stdout.write(ASSETS + '/skqp/unittests.txt\n')
if __name__ == '__main__':
if len(sys.argv) != 3:
sys.stderr.write('Usage:\n %s C1 C2\n\n' % sys.argv[0])
sys.exit(1)
main(sys.argv[1], sys.argv[2])