Jaewoong Jung | e5cd4e1 | 2019-11-22 14:34:55 -0800 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # |
| 3 | # Copyright (C) 2019 The Android Open Source Project |
| 4 | # |
| 5 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | # you may not use this file except in compliance with the License. |
| 7 | # You may obtain a copy of the License at |
| 8 | # |
| 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | # |
| 11 | # Unless required by applicable law or agreed to in writing, software |
| 12 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | # See the License for the specific language governing permissions and |
| 15 | # limitations under the License. |
| 16 | # |
| 17 | """A tool for modifying values in a test config.""" |
| 18 | |
| 19 | from __future__ import print_function |
| 20 | |
| 21 | import argparse |
Ronald Braunstein | fce4316 | 2024-02-02 12:37:20 -0800 | [diff] [blame^] | 22 | import json |
Jaewoong Jung | e5cd4e1 | 2019-11-22 14:34:55 -0800 | [diff] [blame] | 23 | import sys |
| 24 | from xml.dom import minidom |
| 25 | |
| 26 | |
| 27 | from manifest import get_children_with_tag |
| 28 | from manifest import parse_manifest |
| 29 | from manifest import parse_test_config |
| 30 | from manifest import write_xml |
| 31 | |
Rahul Sabnis | 48a8f0d | 2022-04-19 18:00:10 -0700 | [diff] [blame] | 32 | KNOWN_PREPARERS = ['com.android.tradefed.targetprep.TestAppInstallSetup', |
| 33 | 'com.android.tradefed.targetprep.suite.SuiteApkInstaller'] |
Jaewoong Jung | e5cd4e1 | 2019-11-22 14:34:55 -0800 | [diff] [blame] | 34 | |
Ronald Braunstein | fce4316 | 2024-02-02 12:37:20 -0800 | [diff] [blame^] | 35 | KNOWN_TEST_RUNNERS = ['com.android.tradefed.testtype.AndroidJUnitTest'] |
| 36 | |
Seth Moore | c6f4b53 | 2023-02-02 13:22:26 -0800 | [diff] [blame] | 37 | MAINLINE_CONTROLLER = 'com.android.tradefed.testtype.suite.module.MainlineTestModuleController' |
| 38 | |
Jaewoong Jung | e5cd4e1 | 2019-11-22 14:34:55 -0800 | [diff] [blame] | 39 | def parse_args(): |
| 40 | """Parse commandline arguments.""" |
| 41 | |
| 42 | parser = argparse.ArgumentParser() |
| 43 | parser.add_argument('--manifest', default='', dest='manifest', |
| 44 | help=('AndroidManifest.xml that contains the original package name')) |
| 45 | parser.add_argument('--package-name', default='', dest='package_name', |
| 46 | help=('overwrite package fields in the test config')) |
Jaewoong Jung | 3998234 | 2020-01-14 10:27:18 -0800 | [diff] [blame] | 47 | parser.add_argument('--test-file-name', default='', dest='test_file_name', |
| 48 | help=('overwrite test file name in the test config')) |
Ronald Braunstein | fce4316 | 2024-02-02 12:37:20 -0800 | [diff] [blame^] | 49 | parser.add_argument('--orig-test-file-name', default='', dest='orig_test_file_name', |
| 50 | help=('Use with test-file-name to only override a single apk')) |
Seth Moore | c6f4b53 | 2023-02-02 13:22:26 -0800 | [diff] [blame] | 51 | parser.add_argument('--mainline-package-name', default='', dest='mainline_package_name', |
| 52 | help=('overwrite mainline module package name in the test config')) |
Ronald Braunstein | fce4316 | 2024-02-02 12:37:20 -0800 | [diff] [blame^] | 53 | parser.add_argument('--test-runner-options', default='', dest='test_runner_options', |
| 54 | help=('Add test runner options in the test config')) |
Jaewoong Jung | e5cd4e1 | 2019-11-22 14:34:55 -0800 | [diff] [blame] | 55 | parser.add_argument('input', help='input test config file') |
| 56 | parser.add_argument('output', help='output test config file') |
| 57 | return parser.parse_args() |
| 58 | |
| 59 | |
| 60 | def overwrite_package_name(test_config_doc, manifest_doc, package_name): |
| 61 | |
| 62 | manifest = parse_manifest(manifest_doc) |
| 63 | original_package = manifest.getAttribute('package') |
Jaewoong Jung | e5cd4e1 | 2019-11-22 14:34:55 -0800 | [diff] [blame] | 64 | |
| 65 | test_config = parse_test_config(test_config_doc) |
| 66 | tests = get_children_with_tag(test_config, 'test') |
| 67 | |
| 68 | for test in tests: |
| 69 | options = get_children_with_tag(test, 'option') |
| 70 | for option in options: |
| 71 | if option.getAttribute('name') == "package" and option.getAttribute('value') == original_package: |
| 72 | option.setAttribute('value', package_name) |
| 73 | |
Jaewoong Jung | 3998234 | 2020-01-14 10:27:18 -0800 | [diff] [blame] | 74 | def overwrite_test_file_name(test_config_doc, test_file_name): |
| 75 | |
| 76 | test_config = parse_test_config(test_config_doc) |
| 77 | tests = get_children_with_tag(test_config, 'target_preparer') |
| 78 | |
| 79 | for test in tests: |
Rahul Sabnis | 48a8f0d | 2022-04-19 18:00:10 -0700 | [diff] [blame] | 80 | if test.getAttribute('class') in KNOWN_PREPARERS: |
Jaewoong Jung | 3998234 | 2020-01-14 10:27:18 -0800 | [diff] [blame] | 81 | options = get_children_with_tag(test, 'option') |
| 82 | for option in options: |
| 83 | if option.getAttribute('name') == "test-file-name": |
| 84 | option.setAttribute('value', test_file_name) |
| 85 | |
Ronald Braunstein | fce4316 | 2024-02-02 12:37:20 -0800 | [diff] [blame^] | 86 | def overwrite_single_test_file_name(test_config_doc, orig_test_file_name, new_test_file_name): |
| 87 | |
| 88 | test_config = parse_test_config(test_config_doc) |
| 89 | tests = get_children_with_tag(test_config, 'target_preparer') |
| 90 | |
| 91 | for test in tests: |
| 92 | if test.getAttribute('class') in KNOWN_PREPARERS: |
| 93 | options = get_children_with_tag(test, 'option') |
| 94 | for option in options: |
| 95 | if option.getAttribute('name') == "test-file-name" and option.getAttribute('value') == orig_test_file_name: |
| 96 | option.setAttribute('value', new_test_file_name) |
| 97 | |
Seth Moore | c6f4b53 | 2023-02-02 13:22:26 -0800 | [diff] [blame] | 98 | def overwrite_mainline_module_package_name(test_config_doc, mainline_package_name): |
| 99 | |
| 100 | test_config = parse_test_config(test_config_doc) |
| 101 | |
| 102 | for obj in get_children_with_tag(test_config, 'object'): |
| 103 | if obj.getAttribute('class') == MAINLINE_CONTROLLER: |
| 104 | for option in get_children_with_tag(obj, 'option'): |
| 105 | if option.getAttribute('name') == "mainline-module-package-name": |
| 106 | option.setAttribute('value', mainline_package_name) |
| 107 | |
Ronald Braunstein | fce4316 | 2024-02-02 12:37:20 -0800 | [diff] [blame^] | 108 | def add_test_runner_options_toplevel(test_config_doc, test_runner_options): |
| 109 | |
| 110 | test_config = parse_test_config(test_config_doc) |
| 111 | |
| 112 | test_config.appendChild(test_config_doc.createComment("Options from Android.bp")) |
| 113 | test_config.appendChild(test_config_doc.createTextNode("\n")) |
| 114 | for new_option in json.loads(test_runner_options): |
| 115 | option = test_config_doc.createElement("option") |
| 116 | # name and value are mandatory, |
| 117 | name = new_option.get('Name') |
| 118 | if not name: |
| 119 | raise RuntimeError('"name" must set in test_runner_option"') |
| 120 | value = new_option.get('Value') |
| 121 | if not value: |
| 122 | raise RuntimeError('"value" must set in test_runner_option"') |
| 123 | option.setAttribute('name', name) # 'include-filter') |
| 124 | option.setAttribute('value', value) # 'android.test.example.devcodelab.DevCodelabTest#testHelloFail') |
| 125 | key = new_option.get('Key') |
| 126 | if key: |
| 127 | option.setAttribute('key', key) # 'include-filter') |
| 128 | # add tab and newline for readability |
| 129 | test_config.appendChild(test_config_doc.createTextNode(" ")) |
| 130 | test_config.appendChild(option) |
| 131 | test_config.appendChild(test_config_doc.createTextNode("\n")) |
| 132 | |
Jaewoong Jung | e5cd4e1 | 2019-11-22 14:34:55 -0800 | [diff] [blame] | 133 | def main(): |
| 134 | """Program entry point.""" |
| 135 | try: |
| 136 | args = parse_args() |
| 137 | |
| 138 | doc = minidom.parse(args.input) |
| 139 | |
| 140 | if args.package_name: |
| 141 | if not args.manifest: |
| 142 | raise RuntimeError('--manifest flag required for --package-name') |
| 143 | manifest_doc = minidom.parse(args.manifest) |
| 144 | overwrite_package_name(doc, manifest_doc, args.package_name) |
| 145 | |
Jaewoong Jung | 3998234 | 2020-01-14 10:27:18 -0800 | [diff] [blame] | 146 | if args.test_file_name: |
Ronald Braunstein | fce4316 | 2024-02-02 12:37:20 -0800 | [diff] [blame^] | 147 | if args.orig_test_file_name: |
| 148 | overwrite_single_test_file_name(doc, args.orig_test_file_name, args.test_file_name) |
| 149 | else: |
| 150 | # You probably never want to override the test_file_name if there |
| 151 | # are several in the xml, but this is currently only used on generated |
| 152 | # AndroidTest.xml where there is only a single test-file-name (no data) |
| 153 | overwrite_test_file_name(doc, args.test_file_name) |
Jaewoong Jung | 3998234 | 2020-01-14 10:27:18 -0800 | [diff] [blame] | 154 | |
Seth Moore | c6f4b53 | 2023-02-02 13:22:26 -0800 | [diff] [blame] | 155 | if args.mainline_package_name: |
| 156 | overwrite_mainline_module_package_name(doc, args.mainline_package_name) |
| 157 | |
Ronald Braunstein | fce4316 | 2024-02-02 12:37:20 -0800 | [diff] [blame^] | 158 | if args.test_runner_options: |
| 159 | add_test_runner_options_toplevel(doc, args.test_runner_options) |
| 160 | |
Cole Faust | c41dd72 | 2021-11-09 15:08:26 -0800 | [diff] [blame] | 161 | with open(args.output, 'w') as f: |
Jaewoong Jung | e5cd4e1 | 2019-11-22 14:34:55 -0800 | [diff] [blame] | 162 | write_xml(f, doc) |
| 163 | |
| 164 | # pylint: disable=broad-except |
| 165 | except Exception as err: |
| 166 | print('error: ' + str(err), file=sys.stderr) |
| 167 | sys.exit(-1) |
| 168 | |
| 169 | if __name__ == '__main__': |
| 170 | main() |