1#!/usr/bin/env python3 2 3# Step to run: 4# 1. run . build/envsetup.sh; lunch ... 5# 2. Run this script from inside a terminal in sysui studio, as it needs JAVA_HOME to be setup. 6 7import argparse, itertools, os, re, subprocess 8from collections.abc import Generator 9from modules_config import Config, ModuleConfig, TestModuleMapping 10 11def runGradleCommand(outputFile: str, cfg: Config, mc: ModuleConfig) -> int: 12 gradlew_dir: String = os.path.join(cfg.build_top, mc.gradlew_location) 13 with open(os.path.expanduser(outputFile), "w") as of: 14 ret = subprocess.run([os.path.join(gradlew_dir, "gradlew"), f"{mc.gradlew_target}"], 15 stdout=of, stderr=of, cwd=gradlew_dir) 16 return ret.returncode 17 18def check_java(): 19 expected_versions = ['17.0', '1.7', '21.0'] 20 java_home = os.environ.get('JAVA_HOME') 21 if not java_home: 22 print('JAVA_HOME is not set, exiting ...') 23 exit (-2) 24 java_binary = os.path.join(java_home, 'bin/java') 25 print('Checking version for java binary:', java_binary) 26 out = subprocess.check_output([java_binary, '-version'], stderr=subprocess.STDOUT).decode('utf-8') 27 version = re.search(' version \"(\d+\.\d+).*\"', out).groups()[0] 28 if not version in expected_versions: 29 print('Your java version, version', version, ' does not match any of the expected versions', expected_versions) 30 exit (-3) 31 32def walkDir(dirname: str) -> Generator[str, None, None]: 33 print("Processing dir:", dirname) 34 for root, _, files in os.walk(dirname, topdown=False): 35 for name in files: 36 if not (name.endswith('.java') or name.endswith('.kt')): 37 continue 38 yield os.path.join(root, name) 39 40def processFile(filename: str, cfg: Config, mc: ModuleConfig) -> None: 41 print("Attempting roboify on: " , filename) 42 43 # Move to multivalentTests 44 new_filename = filename.replace("/tests/", "/tests/multivalentTests/") 45 dirname = os.path.dirname(new_filename) 46 basename = os.path.basename(new_filename) 47 outputFile = f"{cfg.output_dir}/{basename}.err" 48 os.makedirs(dirname, exist_ok=True) 49 os.rename(filename, new_filename) 50 51 # Attempt run 52 exitValue = runGradleCommand(outputFile, cfg, mc) 53 54 # Log and restore state if needed 55 print("Test run ", "succeeded" if exitValue == 0 else "failed", " with exitValue: ", exitValue) 56 if exitValue != 0 : 57 os.rename(new_filename, filename) 58 59 return exitValue == 0 60 61def init(): 62 parser = argparse.ArgumentParser( 63 description='This script attempts to convert device based unit tests to deviceless.') 64 parser.add_argument('-m', '--module_pattern', required=True) 65 check_java() 66 return parser.parse_args() 67 68def process(cfg: Config, successful: list[str], failed: list[str]): 69 for mc in cfg.module_configs: 70 for d in mc.dirs: 71 for f in walkDir(os.path.join(cfg.build_top, d)): 72 if any(excl in f for excl in mc.excludes): 73 print("Ignore file:", f) 74 continue 75 ret = processFile(f, cfg, mc) 76 (successful if ret else failed).append(f) 77 78def main(): 79 args = init() 80 successful: list[str] = [] 81 failed: list[str] = [] 82 83 module_configs = [] 84 85 for k, mc in TestModuleMapping.items(): 86 if not (args.module_pattern in k): 87 continue 88 print(f"Processing module:{k}, module_config:{mc}") 89 module_configs.append(mc) 90 91 if not module_configs: 92 print(f"Could not match any modules that match: [{args.module_pattern}], exiting ...") 93 exit(-5) 94 95 cfg = Config(module_configs) 96 if not cfg.build_top: 97 print("ANDROID_BUILD_TOP env variable is not set, plase run lunch before invoking this script") 98 exit(-1) 99 100 process(cfg, successful, failed) 101 102 print(f"Successes:\n{successful[:3]} ...") 103 print(f"Failures:\n{failed}") 104 return 0 105 106if __name__ == "__main__": 107 ret = main() 108 exit(ret) 109