Hash :
8e744e9f
        
        Author :
  
        
        Date :
2023-08-14T14:40:41
        
      
Android: support dEQP in android_helper and add bundle script
Example:
    autoninja -C out/Android angle_deqp_gles31_tests && (cd out/Android; ../../src/tests/run_angle_android_test.py --suite=angle_deqp_gles31_tests --gtest_filter='dEQP-GLES31.functional.image_load_store.3d.*')
For angle_deqp_bundle.py example usage see comments at the top of the
file.
Note: this change is not supposed to have any impact on CI. dEQP tests
are still ran using Chromium's test runner, not android_helper.
Bug: b/293590167
Change-Id: I605102ebea8b135f3239ffac012ce5dc13e84943
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4776109
Commit-Queue: Roman Lavrov <romanl@google.com>
Reviewed-by: Yuxin Hu <yuxinhu@google.com>
Auto-Submit: Roman Lavrov <romanl@google.com>
Reviewed-by: Cody Northrop <cnorthrop@google.com>
      
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
#!/usr/bin/python3
#
# Copyright 2023 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# angle_trace_bundle.py:
#   Makes a zip bundle allowing to run angle traces, similarly to mb.py but
#    - trims most of the dependencies
#    - includes list_traces.sh and run_trace.sh (see --trace-name)
#    - lib.unstripped only included if --include-unstripped-libs
#    - does not depend on vpython
#    - just adds files to the zip instead of "isolate remap" with a temp dir
#
#  Example usage:
#    % gn args out/Android  # angle_restricted_traces=["among_us"]
#    (note: explicit build isn't necessary as it is invoked by mb isolate this script runs)
#    % scripts/angle_trace_bundle.py out/Android angle_trace.zip --trace-name=among_us
#
#    (transfer the zip elsewhere)
#    % unzip angle_trace.zip -d angle_trace
#    % angle_trace/list_traces.sh
#    % angle_trace/run_trace.sh  # only included if --trace-name, runs that trace
import argparse
import json
import os
import subprocess
import sys
import zipfile
# {gn_dir}/angle_trace_tests has vpython in wrapper shebangs, call our runner directly
RUN_TESTS_TEMPLATE = r'''#!/bin/bash
cd "$(dirname "$0")"
python3 src/tests/angle_android_test_runner.py gtest --suite=angle_trace_tests --output-directory={gn_dir} "$@"
'''
LIST_TRACES_TEMPLATE = r'''#!/bin/bash
cd "$(dirname "$0")"
./_run_tests.sh --list-tests
'''
RUN_TRACE_TEMPLATE = r'''#!/bin/bash
cd "$(dirname "$0")"
./_run_tests.sh --filter='TraceTest.{trace_name}' --verbose --fixed-test-time-with-warmup 10
'''
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('gn_dir', help='path to GN. (e.g. out/Android)')
    parser.add_argument('output_zip_file', help='output zip file')
    parser.add_argument(
        '--include-unstripped-libs', action='store_true', help='include lib.unstripped')
    parser.add_argument('--trace-name', help='trace to run from run_script.sh')
    args, _ = parser.parse_known_args()
    gn_dir = os.path.join(os.path.normpath(args.gn_dir), '')
    assert os.path.sep == '/' and gn_dir.endswith('/')
    assert gn_dir[0] not in ('.', '/')  # expecting relative to angle root
    subprocess.check_call([
        'python3', 'tools/mb/mb.py', 'isolate', gn_dir, 'angle_trace_perf_tests', '-i',
        'infra/specs/gn_isolate_map.pyl'
    ])
    with open(os.path.join(args.gn_dir, 'angle_trace_perf_tests.isolate')) as f:
        isolate_file_paths = json.load(f)['variables']['files']
    skipped_prefixes = [
        'build/',
        'src/tests/run_perf_tests.py',  # won't work as it depends on catapult
        'third_party/catapult/',
        'third_party/colorama/',
        'third_party/jdk/',
        'third_party/jinja2/',
        'third_party/logdog/',
        'third_party/r8/',
        'third_party/requests/',
        os.path.join(gn_dir, 'lib.java/'),
        os.path.join(gn_dir, 'obj/'),
    ]
    if not args.include_unstripped_libs:
        skipped_prefixes.append(os.path.join(gn_dir, 'lib.unstripped/'))
    with zipfile.ZipFile(args.output_zip_file, 'w', zipfile.ZIP_DEFLATED, allowZip64=True) as fzip:
        for fn in isolate_file_paths:
            path = os.path.normpath(os.path.join(gn_dir, fn))
            if any(path.startswith(p) for p in skipped_prefixes):
                continue
            fzip.write(path)
        def addScript(path_in_zip, contents):
            # Creates a script directly inside the zip file
            info = zipfile.ZipInfo(path_in_zip)
            info.external_attr = 0o755 << 16  # unnecessarily obscure way to chmod 755...
            fzip.writestr(info, contents)
        addScript('_run_tests.sh', RUN_TESTS_TEMPLATE.format(gn_dir=gn_dir))
        addScript('list_traces.sh', LIST_TRACES_TEMPLATE.format(gn_dir=gn_dir))
        if args.trace_name:
            addScript('run_trace.sh',
                      RUN_TRACE_TEMPLATE.format(gn_dir=gn_dir, trace_name=args.trace_name))
    return 0
if __name__ == '__main__':
    sys.exit(main())