1cb93a386Sopenharmony_ci#! /usr/bin/env python 2cb93a386Sopenharmony_ci# Copyright 2018 Google LLC. 3cb93a386Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 4cb93a386Sopenharmony_ci 5cb93a386Sopenharmony_ciimport json 6cb93a386Sopenharmony_ciimport md5 7cb93a386Sopenharmony_ciimport multiprocessing 8cb93a386Sopenharmony_ciimport os 9cb93a386Sopenharmony_ciimport shutil 10cb93a386Sopenharmony_ciimport sys 11cb93a386Sopenharmony_ciimport tempfile 12cb93a386Sopenharmony_ciimport urllib 13cb93a386Sopenharmony_ciimport urllib2 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_cifrom subprocess import check_call, check_output 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ciassert '/' in [os.sep, os.altsep] and os.pardir == '..' 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ciASSETS = 'platform_tools/android/apps/skqp/src/main/assets' 20cb93a386Sopenharmony_ciBUCKET = 'skia-skqp-assets' 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_cidef urlopen(url): 23cb93a386Sopenharmony_ci cookie = os.environ.get('SKIA_GOLD_COOKIE', '') 24cb93a386Sopenharmony_ci return urllib2.urlopen(urllib2.Request(url, headers={'Cookie': cookie})) 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_cidef make_skqp_model(arg): 27cb93a386Sopenharmony_ci name, urls, exe = arg 28cb93a386Sopenharmony_ci tmp = tempfile.mkdtemp() 29cb93a386Sopenharmony_ci for url in urls: 30cb93a386Sopenharmony_ci urllib.urlretrieve(url, tmp + '/' + url[url.rindex('/') + 1:]) 31cb93a386Sopenharmony_ci check_call([exe, tmp, ASSETS + '/gmkb/' + name]) 32cb93a386Sopenharmony_ci shutil.rmtree(tmp) 33cb93a386Sopenharmony_ci sys.stdout.write(name + ' ') 34cb93a386Sopenharmony_ci sys.stdout.flush() 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_cidef goldgetter(meta, exe): 37cb93a386Sopenharmony_ci assert os.path.exists(exe) 38cb93a386Sopenharmony_ci jobs = [] 39cb93a386Sopenharmony_ci for rec in meta: 40cb93a386Sopenharmony_ci urls = [d['URL'] for d in rec['digests'] 41cb93a386Sopenharmony_ci if d['status'] == 'positive' and 42cb93a386Sopenharmony_ci (set(d['paramset']['config']) & set(['vk', 'gles']))] 43cb93a386Sopenharmony_ci if urls: 44cb93a386Sopenharmony_ci jobs.append((rec['testName'], urls, exe)) 45cb93a386Sopenharmony_ci pool = multiprocessing.Pool(processes=20) 46cb93a386Sopenharmony_ci pool.map(make_skqp_model, jobs) 47cb93a386Sopenharmony_ci sys.stdout.write('\n') 48cb93a386Sopenharmony_ci return set((n for n, _, _ in jobs)) 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_cidef gold(first_commit, last_commit): 51cb93a386Sopenharmony_ci c1, c2 = (check_output(['git', 'rev-parse', c]).strip() 52cb93a386Sopenharmony_ci for c in (first_commit, last_commit)) 53cb93a386Sopenharmony_ci f = urlopen('https://public-gold.skia.org/json/export?' + urllib.urlencode([ 54cb93a386Sopenharmony_ci ('fbegin', c1), 55cb93a386Sopenharmony_ci ('fend', c2), 56cb93a386Sopenharmony_ci ('query', 'config=gles&config=vk&source_type=gm'), 57cb93a386Sopenharmony_ci ('pos', 'true'), 58cb93a386Sopenharmony_ci ('neg', 'false'), 59cb93a386Sopenharmony_ci ('unt', 'false') 60cb93a386Sopenharmony_ci ])) 61cb93a386Sopenharmony_ci j = json.load(f) 62cb93a386Sopenharmony_ci f.close() 63cb93a386Sopenharmony_ci return j 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_cidef gset(path): 66cb93a386Sopenharmony_ci s = set() 67cb93a386Sopenharmony_ci if os.path.isfile(path): 68cb93a386Sopenharmony_ci with open(path, 'r') as f: 69cb93a386Sopenharmony_ci for line in f: 70cb93a386Sopenharmony_ci s.add(line.strip()) 71cb93a386Sopenharmony_ci return s 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_cidef make_rendertest_list(models, good, bad): 74cb93a386Sopenharmony_ci assert good.isdisjoint(bad) 75cb93a386Sopenharmony_ci do_score = good & models 76cb93a386Sopenharmony_ci no_score = bad | (good - models) 77cb93a386Sopenharmony_ci to_delete = models & bad 78cb93a386Sopenharmony_ci for d in to_delete: 79cb93a386Sopenharmony_ci path = ASSETS + '/gmkb/' + d 80cb93a386Sopenharmony_ci if os.path.isdir(path): 81cb93a386Sopenharmony_ci shutil.rmtree(path) 82cb93a386Sopenharmony_ci results = dict() 83cb93a386Sopenharmony_ci for n in do_score: 84cb93a386Sopenharmony_ci results[n] = 0 85cb93a386Sopenharmony_ci for n in no_score: 86cb93a386Sopenharmony_ci results[n] = -1 87cb93a386Sopenharmony_ci return ''.join('%s,%d\n' % (n, results[n]) for n in sorted(results)) 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_cidef get_digest(path): 90cb93a386Sopenharmony_ci m = md5.new() 91cb93a386Sopenharmony_ci with open(path, 'r') as f: 92cb93a386Sopenharmony_ci m.update(f.read()) 93cb93a386Sopenharmony_ci return m.hexdigest() 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_cidef upload_cmd(path, digest): 96cb93a386Sopenharmony_ci return ['gsutil', 'cp', path, 'gs://%s/%s' % (BUCKET, digest)] 97cb93a386Sopenharmony_ci 98cb93a386Sopenharmony_cidef upload_model(): 99cb93a386Sopenharmony_ci bucket_url = 'gs://%s/' % BUCKET 100cb93a386Sopenharmony_ci extant = set((u.replace(bucket_url, '', 1) 101cb93a386Sopenharmony_ci for u in check_output(['gsutil', 'ls', bucket_url]).splitlines() if u)) 102cb93a386Sopenharmony_ci cmds = [] 103cb93a386Sopenharmony_ci filelist = [] 104cb93a386Sopenharmony_ci for dirpath, _, filenames in os.walk(ASSETS + '/gmkb'): 105cb93a386Sopenharmony_ci for filename in filenames: 106cb93a386Sopenharmony_ci path = os.path.join(dirpath, filename) 107cb93a386Sopenharmony_ci digest = get_digest(path) 108cb93a386Sopenharmony_ci if digest not in extant: 109cb93a386Sopenharmony_ci cmds.append(upload_cmd(path, digest)) 110cb93a386Sopenharmony_ci filelist.append('%s;%s\n' % (digest, os.path.relpath(path, ASSETS))) 111cb93a386Sopenharmony_ci tmp = tempfile.mkdtemp() 112cb93a386Sopenharmony_ci filelist_path = tmp + '/x' 113cb93a386Sopenharmony_ci with open(filelist_path, 'w') as o: 114cb93a386Sopenharmony_ci for l in filelist: 115cb93a386Sopenharmony_ci o.write(l) 116cb93a386Sopenharmony_ci filelist_digest = get_digest(filelist_path) 117cb93a386Sopenharmony_ci if filelist_digest not in extant: 118cb93a386Sopenharmony_ci cmds.append(upload_cmd(filelist_path, filelist_digest)) 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_ci pool = multiprocessing.Pool(processes=20) 121cb93a386Sopenharmony_ci pool.map(check_call, cmds) 122cb93a386Sopenharmony_ci shutil.rmtree(tmp) 123cb93a386Sopenharmony_ci return filelist_digest 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_cidef remove(x): 126cb93a386Sopenharmony_ci if os.path.isdir(x) and not os.path.islink(x): 127cb93a386Sopenharmony_ci shutil.rmtree(x) 128cb93a386Sopenharmony_ci if os.path.exists(x): 129cb93a386Sopenharmony_ci os.remove(x) 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_cidef main(first_commit, last_commit): 132cb93a386Sopenharmony_ci check_call(upload_cmd('/dev/null', get_digest('/dev/null'))) 133cb93a386Sopenharmony_ci 134cb93a386Sopenharmony_ci os.chdir(os.path.dirname(__file__) + '/../..') 135cb93a386Sopenharmony_ci remove(ASSETS + '/files.checksum') 136cb93a386Sopenharmony_ci for d in [ASSETS + '/gmkb', ASSETS + '/skqp', ]: 137cb93a386Sopenharmony_ci remove(d) 138cb93a386Sopenharmony_ci os.mkdir(d) 139cb93a386Sopenharmony_ci 140cb93a386Sopenharmony_ci check_call([sys.executable, 'tools/git-sync-deps'], 141cb93a386Sopenharmony_ci env=dict(os.environ, GIT_SYNC_DEPS_QUIET='T')) 142cb93a386Sopenharmony_ci build = 'out/ndebug' 143cb93a386Sopenharmony_ci check_call(['bin/gn', 'gen', build, 144cb93a386Sopenharmony_ci '--args=cc="clang" cxx="clang++" is_debug=false']) 145cb93a386Sopenharmony_ci check_call(['ninja', '-C', build, 146cb93a386Sopenharmony_ci 'jitter_gms', 'list_gpu_unit_tests', 'make_skqp_model']) 147cb93a386Sopenharmony_ci 148cb93a386Sopenharmony_ci models = goldgetter(gold(first_commit, last_commit), build + '/make_skqp_model') 149cb93a386Sopenharmony_ci 150cb93a386Sopenharmony_ci check_call([build + '/jitter_gms', 'tools/skqp/bad_gms.txt']) 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_ci with open(ASSETS + '/skqp/rendertests.txt', 'w') as o: 153cb93a386Sopenharmony_ci o.write(make_rendertest_list(models, gset('good.txt'), gset('bad.txt'))) 154cb93a386Sopenharmony_ci 155cb93a386Sopenharmony_ci remove('good.txt') 156cb93a386Sopenharmony_ci remove('bad.txt') 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci with open(ASSETS + '/skqp/unittests.txt', 'w') as o: 159cb93a386Sopenharmony_ci o.write(check_output([build + '/list_gpu_unit_tests'])) 160cb93a386Sopenharmony_ci 161cb93a386Sopenharmony_ci with open(ASSETS + '/files.checksum', 'w') as o: 162cb93a386Sopenharmony_ci o.write(upload_model() + '\n') 163cb93a386Sopenharmony_ci 164cb93a386Sopenharmony_ci sys.stdout.write(ASSETS + '/files.checksum\n') 165cb93a386Sopenharmony_ci sys.stdout.write(ASSETS + '/skqp/rendertests.txt\n') 166cb93a386Sopenharmony_ci sys.stdout.write(ASSETS + '/skqp/unittests.txt\n') 167cb93a386Sopenharmony_ci 168cb93a386Sopenharmony_ciif __name__ == '__main__': 169cb93a386Sopenharmony_ci if len(sys.argv) != 3: 170cb93a386Sopenharmony_ci sys.stderr.write('Usage:\n %s C1 C2\n\n' % sys.argv[0]) 171cb93a386Sopenharmony_ci sys.exit(1) 172cb93a386Sopenharmony_ci main(sys.argv[1], sys.argv[2]) 173