1#!/usr/bin/python3 2# 3# Copyright 2023 The ANGLE Project Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6# 7# angle_deqp_bundle.py: 8# Makes a zip bundle allowing to run deqp tests, similarly to mb.py but 9# - trims most of the dependencies 10# - includes run_tests.sh (see below) 11# - lib.unstripped only included if --include-unstripped-libs 12# - does not depend on vpython 13# - just adds files to the zip instead of "isolate remap" with a temp dir 14# 15# Example usage: 16# % scripts/angle_deqp_bundle.py out/Android angle_deqp_gles31_rotate90_tests angle_deqp_bundle.zip 17# 18# (transfer the zip elsewhere) 19# % unzip angle_deqp_bundle.zip -d angle_deqp_bundle 20# % angle_deqp_bundle/run_tests.sh --list-tests 21# % angle_deqp_bundle/run_tests.sh --gtest_filter='dEQP-GLES31.functional.primitive_bounding_box.triangles.*' 22 23import argparse 24import json 25import os 26import subprocess 27import sys 28import zipfile 29 30RUN_TESTS_TEMPLATE = r'''#!/bin/bash 31cd "$(dirname "$0")" 32python3 src/tests/angle_android_test_runner.py gtest --suite={suite} --output-directory={gn_dir} "$@" 33''' 34 35 36def main(): 37 parser = argparse.ArgumentParser() 38 parser.add_argument('gn_dir', help='path to GN. (e.g. out/Android)') 39 parser.add_argument('suite', help='dEQP suite (e.g. angle_deqp_gles31_rotate90_tests)') 40 parser.add_argument('output_zip_file', help='output zip file') 41 parser.add_argument( 42 '--include-unstripped-libs', action='store_true', help='include lib.unstripped') 43 args, _ = parser.parse_known_args() 44 45 gn_dir = os.path.join(os.path.normpath(args.gn_dir), '') 46 suite = args.suite 47 assert os.path.sep == '/' and gn_dir.endswith('/') 48 assert gn_dir[0] not in ('.', '/') # expecting relative to angle root 49 50 subprocess.check_call([ 51 'python3', 'tools/mb/mb.py', 'isolate', gn_dir, suite, '-i', 52 'infra/specs/gn_isolate_map.pyl' 53 ]) 54 55 with open(os.path.join(args.gn_dir, '%s.isolate' % suite)) as f: 56 isolate_file_paths = json.load(f)['variables']['files'] 57 58 # Currently not in deps, add manually 59 isolate_file_paths.append('../../src/tests/angle_android_test_runner.py') 60 61 skipped_prefixes = [ 62 'build/', 63 'third_party/catapult/', 64 'third_party/colorama/', 65 'third_party/jdk/', 66 'third_party/jinja2/', 67 'third_party/logdog/', 68 'third_party/r8/', 69 'third_party/requests/', 70 os.path.join(gn_dir, 'lib.java/'), 71 os.path.join(gn_dir, 'obj/'), 72 ] 73 74 if not args.include_unstripped_libs: 75 skipped_prefixes.append(os.path.join(gn_dir, 'lib.unstripped/')) 76 77 with zipfile.ZipFile(args.output_zip_file, 'w', zipfile.ZIP_DEFLATED, allowZip64=True) as fzip: 78 for fn in isolate_file_paths: 79 path = os.path.normpath(os.path.join(gn_dir, fn)) 80 if any(path.startswith(p) for p in skipped_prefixes): 81 continue 82 83 fzip.write(path) 84 85 # Create a script directly inside the zip file 86 info = zipfile.ZipInfo('run_tests.sh') 87 info.external_attr = 0o755 << 16 # unnecessarily obscure way to chmod 755... 88 fzip.writestr(info, RUN_TESTS_TEMPLATE.format(gn_dir=gn_dir, suite=suite)) 89 90 return 0 91 92 93if __name__ == '__main__': 94 sys.exit(main()) 95