xref: /aosp_15_r20/external/angle/scripts/angle_trace_bundle.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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_trace_bundle.py:
8#   Makes a zip bundle allowing to run angle traces, similarly to mb.py but
9#    - trims most of the dependencies
10#    - includes list_traces.sh and run_trace.sh (see --trace-name)
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#    % gn args out/Android  # angle_restricted_traces=["among_us"]
17#    (note: explicit build isn't necessary as it is invoked by mb isolate this script runs)
18#    % scripts/angle_trace_bundle.py out/Android angle_trace.zip --trace-name=among_us
19#
20#    (transfer the zip elsewhere)
21#    % unzip angle_trace.zip -d angle_trace
22#    % angle_trace/list_traces.sh
23#    % angle_trace/run_trace.sh  # only included if --trace-name, runs that trace
24
25import argparse
26import json
27import os
28import subprocess
29import sys
30import zipfile
31
32# {gn_dir}/angle_trace_tests has vpython in wrapper shebangs, call our runner directly
33RUN_TESTS_TEMPLATE = r'''#!/bin/bash
34cd "$(dirname "$0")"
35python3 src/tests/angle_android_test_runner.py gtest --suite=angle_trace_tests --output-directory={gn_dir} "$@"
36'''
37
38LIST_TRACES_TEMPLATE = r'''#!/bin/bash
39cd "$(dirname "$0")"
40./_run_tests.sh --list-tests
41'''
42
43RUN_TRACE_TEMPLATE = r'''#!/bin/bash
44cd "$(dirname "$0")"
45./_run_tests.sh --filter='TraceTest.{trace_name}' --verbose --fixed-test-time-with-warmup 10
46'''
47
48
49def main():
50    parser = argparse.ArgumentParser()
51    parser.add_argument('gn_dir', help='path to GN. (e.g. out/Android)')
52    parser.add_argument('output_zip_file', help='output zip file')
53    parser.add_argument(
54        '--include-unstripped-libs', action='store_true', help='include lib.unstripped')
55    parser.add_argument('--trace-name', help='trace to run from run_script.sh')
56    args, _ = parser.parse_known_args()
57
58    gn_dir = os.path.join(os.path.normpath(args.gn_dir), '')
59    assert os.path.sep == '/' and gn_dir.endswith('/')
60    assert gn_dir[0] not in ('.', '/')  # expecting relative to angle root
61
62    subprocess.check_call([
63        'python3', 'tools/mb/mb.py', 'isolate', gn_dir, 'angle_trace_perf_tests', '-i',
64        'infra/specs/gn_isolate_map.pyl'
65    ])
66
67    with open(os.path.join(args.gn_dir, 'angle_trace_perf_tests.isolate')) as f:
68        isolate_file_paths = json.load(f)['variables']['files']
69
70    skipped_prefixes = [
71        'build/',
72        'src/tests/run_perf_tests.py',  # won't work as it depends on catapult
73        'third_party/catapult/',
74        'third_party/colorama/',
75        'third_party/jdk/',
76        'third_party/jinja2/',
77        'third_party/logdog/',
78        'third_party/r8/',
79        'third_party/requests/',
80        os.path.join(gn_dir, 'lib.java/'),
81        os.path.join(gn_dir, 'obj/'),
82    ]
83
84    if not args.include_unstripped_libs:
85        skipped_prefixes.append(os.path.join(gn_dir, 'lib.unstripped/'))
86
87    with zipfile.ZipFile(args.output_zip_file, 'w', zipfile.ZIP_DEFLATED, allowZip64=True) as fzip:
88        for fn in isolate_file_paths:
89            path = os.path.normpath(os.path.join(gn_dir, fn))
90            if any(path.startswith(p) for p in skipped_prefixes):
91                continue
92
93            fzip.write(path)
94
95        def addScript(path_in_zip, contents):
96            # Creates a script directly inside the zip file
97            info = zipfile.ZipInfo(path_in_zip)
98            info.external_attr = 0o755 << 16  # unnecessarily obscure way to chmod 755...
99            fzip.writestr(info, contents)
100
101        addScript('_run_tests.sh', RUN_TESTS_TEMPLATE.format(gn_dir=gn_dir))
102        addScript('list_traces.sh', LIST_TRACES_TEMPLATE.format(gn_dir=gn_dir))
103
104        if args.trace_name:
105            addScript('run_trace.sh',
106                      RUN_TRACE_TEMPLATE.format(gn_dir=gn_dir, trace_name=args.trace_name))
107
108    return 0
109
110
111if __name__ == '__main__':
112    sys.exit(main())
113