| #!/usr/bin/python3 |
| |
| # Copyright (C) 2023 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """Script to automatically populate TEST_MAPPING""" |
| |
| if __name__ != "__main__": |
| print("This is a script, not a library.") |
| exit(1) |
| |
| import argparse |
| import json |
| import os |
| import textwrap |
| |
| from pathlib import Path |
| |
| # some other things we might consider adding: |
| # - support for other classes of tests, besides 'presubmit' |
| # - use bpmodify to add tests to 'general-tests' or 'device-tests' automatically |
| |
| parser = argparse.ArgumentParser( |
| epilog=textwrap.dedent("""For example, |
| `map_tests --dir system/libhidl --tests-in system/libhidl/transport -w` would add the |
| tests in the `transport` subdirectory into system/libhidl/TEST_MAPPING`. In general, |
| it's expected to be used by `map_tests.py -w` in the directory where you want to add |
| tests.""")) |
| parser.add_argument("-i", "--module-info", action="store", help="Default is $ANDROID_PRODUCT_OUT/module-info.json. If this is out of date, run `refreshmod`.") |
| parser.add_argument("-w", "--write", action="store_true", help="Write over the TEST_MAPPING file.") |
| parser.add_argument("-d", "--dir", action="store", help="Directory where TEST_MAPPING file should exist, defaults to current directory.") |
| parser.add_argument("-t", "--tests-in", action="store", help="Directory to pull tests from, defaults to test mapping '--dir'") |
| parser.add_argument("-p", "--print", action="store", help="Also print the module-info.json entry for this module, or '-' to print everything") |
| args = parser.parse_args() |
| |
| INFO_PATH = args.module_info or (os.environ["ANDROID_PRODUCT_OUT"] + "/module-info.json") |
| MAP_DIR = args.dir or os.getcwd() |
| TESTS_IN_DIR = args.tests_in or MAP_DIR |
| PRINT = args.print |
| WRITE = args.write |
| del args |
| |
| MAP_PATH = MAP_DIR + "/TEST_MAPPING" |
| TOP = os.environ["ANDROID_BUILD_TOP"] |
| |
| ################################################################################ |
| # READ THE CURRENT TEST MAPPING |
| ################################################################################ |
| if os.path.exists(MAP_PATH): |
| with open(MAP_PATH, "r", encoding="utf-8") as f: |
| test_mapping = json.loads("".join(f.readlines())) |
| else: |
| test_mapping = {} |
| |
| ################################################################################ |
| # READ THE MODULE INFO |
| ################################################################################ |
| with open(INFO_PATH, "r", encoding="utf-8") as module_info_file: |
| info = json.load(module_info_file) |
| |
| ################################################################################ |
| # UPDATE TEST MAPPING BASED ON MODULE INFO |
| ################################################################################ |
| tests_dir = os.path.relpath(TESTS_IN_DIR, TOP) |
| |
| for name,k in info.items(): |
| if PRINT == '-' or name == PRINT: print(name, k) |
| |
| # skip 32-bit tests, which show up in module-info.json, but they aren't present |
| # at the atest level |
| if name.endswith("_32"): continue |
| |
| is_in_path = any(Path(p).is_relative_to(tests_dir) for p in k['path']) |
| if not is_in_path: continue |
| |
| # these are the test_suites that TEST_MAPPING can currently pull tests from |
| is_built = any(ts in k['compatibility_suites'] for ts in ['device-tests', 'general-tests']) |
| if not is_built: continue |
| |
| # automatically runs using other infrastructure |
| if k['is_unit_test'] == 'true': continue |
| |
| has_test_config = len(k['test_config']) |
| is_native_test = 'NATIVE_TESTS' in k['class'] |
| if not has_test_config and not is_native_test: continue |
| |
| if "presubmit" not in test_mapping: test_mapping["presubmit"] = [] |
| |
| already_there = any(i["name"] == name for i in test_mapping["presubmit"]) |
| if already_there: continue |
| |
| test_mapping["presubmit"] += [{ "name": name }] |
| |
| out = json.dumps(test_mapping, indent=2) |
| |
| ################################################################################ |
| # WRITE THE OUTPUT |
| ################################################################################ |
| if WRITE: |
| with open(MAP_PATH, "w+", encoding="utf-8") as f: |
| f.write(out + "\n") |
| else: |
| print(out) |