Loading android/pandora/gen_cov.py +121 −65 Original line number Diff line number Diff line #!/usr/bin/env python import argparse from datetime import datetime import os from pathlib import Path import shutil Loading @@ -8,8 +9,16 @@ import subprocess import sys import xml.etree.ElementTree as ET JAVA_UNIT_TESTS = 'test/mts/tools/mts-tradefed/res/config/mts-bluetooth-tests-list-shard-01.xml' NATIVE_UNIT_TESTS = 'test/mts/tools/mts-tradefed/res/config/mts-bluetooth-tests-list-shard-02.xml' DO_NOT_RETRY_TESTS = { 'CtsBluetoothTestCases', 'GoogleBluetoothInstrumentationTests', } MAX_TRIES = 3 def run_pts_bot(): def run_pts_bot(logs_out): run_pts_bot_cmd = [ # atest command with verbose mode. 'atest', Loading @@ -24,28 +33,32 @@ def run_pts_bot(): '--coverage-toolchain CLANG', '--coverage-flush', ] subprocess.run(run_pts_bot_cmd).returncode with open(f'{logs_out}/pts_bot.txt', 'w') as f: subprocess.run(run_pts_bot_cmd, stdout=f, stderr=subprocess.STDOUT) def run_unit_tests(): # Output logs directory logs_out = Path('logs_bt_tests') logs_out.mkdir(exist_ok=True) mts_tests = [] def list_unit_tests(): android_build_top = os.getenv('ANDROID_BUILD_TOP') mts_xml = ET.parse( f'{android_build_top}/test/mts/tools/mts-tradefed/res/config/mts-bluetooth-tests-list.xml' ) for child in mts_xml.getroot(): unit_tests = [] java_unit_xml = ET.parse(f'{android_build_top}/{JAVA_UNIT_TESTS}') for child in java_unit_xml.getroot(): value = child.attrib['value'] if 'enable:true' in value: test = value.replace(':enable:true', '') unit_tests.append(test) native_unit_xml = ET.parse(f'{android_build_top}/{NATIVE_UNIT_TESTS}') for child in native_unit_xml.getroot(): value = child.attrib['value'] if 'enable:true' in value: test = value.replace(':enable:true', '') mts_tests.append(test) unit_tests.append(test) for test in mts_tests: return unit_tests def run_unit_test(test, logs_out): print(f'Test started: {test}') # Env variables necessary for native unit tests. Loading Loading @@ -76,13 +89,30 @@ def run_unit_tests(): '--skip-system-status-check ', 'com.android.tradefed.suite.checker.ShellStatusChecker', ] with open(f'{logs_out}/{test}.txt', 'w') as f: try_count = 1 while (try_count == 1 or test not in DO_NOT_RETRY_TESTS) and try_count <= MAX_TRIES: with open(f'{logs_out}/{test}_{try_count}.txt', 'w') as f: if try_count > 1: print(f'Retrying {test}: count = {try_count}') returncode = subprocess.run( run_test_cmd, env=env, stdout=f, stderr=subprocess.STDOUT).returncode if returncode == 0: break try_count += 1 print( f'Test ended [{"Success" if returncode == 0 else "Failed"}]: {test}') def pull_and_rename_trace_for_test(test, trace): date = datetime.now().strftime("%Y%m%d") temp_trace = Path('temp_trace') subprocess.run(['adb', 'pull', '/data/misc/trace', temp_trace]) for child in temp_trace.iterdir(): child = child.rename(f'{child.parent}/{date}_{test}_{child.name}') shutil.copy(child, trace) shutil.rmtree(temp_trace, ignore_errors=True) def generate_java_coverage(bt_apex_name, trace_path, coverage_out): out = os.getenv('OUT') Loading Loading @@ -127,6 +157,7 @@ def generate_java_coverage(bt_apex_name, trace_path, coverage_out): '**/com/android/internal/annotations/**/*.class', '**/android/annotation/**/*.class', '**/android/net/**/*.class', '**/com/google/**/*.class', # Added ] app_exclude_classes = [ '**/*Test$*.class', Loading Loading @@ -298,25 +329,50 @@ if __name__ == '__main__': generate_native_coverage(args.apex_name, trace_path, coverage_out) else: # Compute Pandora coverage. run_pts_bot() # Output logs directory logs_out = Path('logs_bt_tests') logs_out.mkdir(exist_ok=True) # Compute Pandora tests coverage coverage_out_pandora = Path(f'{coverage_out}/pandora') coverage_out_pandora.mkdir() trace_pandora = Path('trace_pandora') shutil.rmtree(trace_pandora, ignore_errors=True) subprocess.run(['adb', 'pull', '/data/misc/trace', trace_pandora]) generate_java_coverage(args.apex_name, trace_pandora, coverage_out_pandora) generate_native_coverage(args.apex_name, trace_pandora, coverage_out_pandora) # # Compute all coverage. run_unit_tests() trace_pandora.mkdir() subprocess.run(['adb', 'shell', 'rm', '/data/misc/trace/*']) run_pts_bot(logs_out) pull_and_rename_trace_for_test('pts_bot', trace_pandora) generate_java_coverage(args.apex_name, trace_pandora, coverage_out_pandora) generate_native_coverage(args.apex_name, trace_pandora, coverage_out_pandora) # Compute unit tests coverage coverage_out_unit = Path(f'{coverage_out}/unit') coverage_out_unit.mkdir() trace_unit = Path('trace_unit') shutil.rmtree(trace_unit, ignore_errors=True) trace_unit.mkdir() unit_tests = list_unit_tests() for test in unit_tests: subprocess.run(['adb', 'shell', 'rm', '/data/misc/trace/*']) run_unit_test(test, logs_out) pull_and_rename_trace_for_test(test, trace_unit) generate_java_coverage(args.apex_name, trace_unit, coverage_out_unit) generate_native_coverage(args.apex_name, trace_unit, coverage_out_unit) # Compute all tests coverage coverage_out_mainline = Path(f'{coverage_out}/mainline') coverage_out_mainline.mkdir() trace_all = Path('trace_all') shutil.rmtree(trace_all, ignore_errors=True) subprocess.run(['adb', 'pull', '/data/misc/trace', trace_all]) generate_java_coverage(args.apex_name, trace_all, coverage_out_mainline) generate_native_coverage(args.apex_name, trace_all, coverage_out_mainline) trace_mainline = Path('trace_mainline') shutil.rmtree(trace_mainline, ignore_errors=True) trace_mainline.mkdir() for child in trace_pandora.iterdir(): shutil.copy(child, trace_mainline) for child in trace_unit.iterdir(): shutil.copy(child, trace_mainline) generate_java_coverage(args.apex_name, trace_mainline, coverage_out_mainline) generate_native_coverage(args.apex_name, trace_mainline, coverage_out_mainline) Loading
android/pandora/gen_cov.py +121 −65 Original line number Diff line number Diff line #!/usr/bin/env python import argparse from datetime import datetime import os from pathlib import Path import shutil Loading @@ -8,8 +9,16 @@ import subprocess import sys import xml.etree.ElementTree as ET JAVA_UNIT_TESTS = 'test/mts/tools/mts-tradefed/res/config/mts-bluetooth-tests-list-shard-01.xml' NATIVE_UNIT_TESTS = 'test/mts/tools/mts-tradefed/res/config/mts-bluetooth-tests-list-shard-02.xml' DO_NOT_RETRY_TESTS = { 'CtsBluetoothTestCases', 'GoogleBluetoothInstrumentationTests', } MAX_TRIES = 3 def run_pts_bot(): def run_pts_bot(logs_out): run_pts_bot_cmd = [ # atest command with verbose mode. 'atest', Loading @@ -24,28 +33,32 @@ def run_pts_bot(): '--coverage-toolchain CLANG', '--coverage-flush', ] subprocess.run(run_pts_bot_cmd).returncode with open(f'{logs_out}/pts_bot.txt', 'w') as f: subprocess.run(run_pts_bot_cmd, stdout=f, stderr=subprocess.STDOUT) def run_unit_tests(): # Output logs directory logs_out = Path('logs_bt_tests') logs_out.mkdir(exist_ok=True) mts_tests = [] def list_unit_tests(): android_build_top = os.getenv('ANDROID_BUILD_TOP') mts_xml = ET.parse( f'{android_build_top}/test/mts/tools/mts-tradefed/res/config/mts-bluetooth-tests-list.xml' ) for child in mts_xml.getroot(): unit_tests = [] java_unit_xml = ET.parse(f'{android_build_top}/{JAVA_UNIT_TESTS}') for child in java_unit_xml.getroot(): value = child.attrib['value'] if 'enable:true' in value: test = value.replace(':enable:true', '') unit_tests.append(test) native_unit_xml = ET.parse(f'{android_build_top}/{NATIVE_UNIT_TESTS}') for child in native_unit_xml.getroot(): value = child.attrib['value'] if 'enable:true' in value: test = value.replace(':enable:true', '') mts_tests.append(test) unit_tests.append(test) for test in mts_tests: return unit_tests def run_unit_test(test, logs_out): print(f'Test started: {test}') # Env variables necessary for native unit tests. Loading Loading @@ -76,13 +89,30 @@ def run_unit_tests(): '--skip-system-status-check ', 'com.android.tradefed.suite.checker.ShellStatusChecker', ] with open(f'{logs_out}/{test}.txt', 'w') as f: try_count = 1 while (try_count == 1 or test not in DO_NOT_RETRY_TESTS) and try_count <= MAX_TRIES: with open(f'{logs_out}/{test}_{try_count}.txt', 'w') as f: if try_count > 1: print(f'Retrying {test}: count = {try_count}') returncode = subprocess.run( run_test_cmd, env=env, stdout=f, stderr=subprocess.STDOUT).returncode if returncode == 0: break try_count += 1 print( f'Test ended [{"Success" if returncode == 0 else "Failed"}]: {test}') def pull_and_rename_trace_for_test(test, trace): date = datetime.now().strftime("%Y%m%d") temp_trace = Path('temp_trace') subprocess.run(['adb', 'pull', '/data/misc/trace', temp_trace]) for child in temp_trace.iterdir(): child = child.rename(f'{child.parent}/{date}_{test}_{child.name}') shutil.copy(child, trace) shutil.rmtree(temp_trace, ignore_errors=True) def generate_java_coverage(bt_apex_name, trace_path, coverage_out): out = os.getenv('OUT') Loading Loading @@ -127,6 +157,7 @@ def generate_java_coverage(bt_apex_name, trace_path, coverage_out): '**/com/android/internal/annotations/**/*.class', '**/android/annotation/**/*.class', '**/android/net/**/*.class', '**/com/google/**/*.class', # Added ] app_exclude_classes = [ '**/*Test$*.class', Loading Loading @@ -298,25 +329,50 @@ if __name__ == '__main__': generate_native_coverage(args.apex_name, trace_path, coverage_out) else: # Compute Pandora coverage. run_pts_bot() # Output logs directory logs_out = Path('logs_bt_tests') logs_out.mkdir(exist_ok=True) # Compute Pandora tests coverage coverage_out_pandora = Path(f'{coverage_out}/pandora') coverage_out_pandora.mkdir() trace_pandora = Path('trace_pandora') shutil.rmtree(trace_pandora, ignore_errors=True) subprocess.run(['adb', 'pull', '/data/misc/trace', trace_pandora]) generate_java_coverage(args.apex_name, trace_pandora, coverage_out_pandora) generate_native_coverage(args.apex_name, trace_pandora, coverage_out_pandora) # # Compute all coverage. run_unit_tests() trace_pandora.mkdir() subprocess.run(['adb', 'shell', 'rm', '/data/misc/trace/*']) run_pts_bot(logs_out) pull_and_rename_trace_for_test('pts_bot', trace_pandora) generate_java_coverage(args.apex_name, trace_pandora, coverage_out_pandora) generate_native_coverage(args.apex_name, trace_pandora, coverage_out_pandora) # Compute unit tests coverage coverage_out_unit = Path(f'{coverage_out}/unit') coverage_out_unit.mkdir() trace_unit = Path('trace_unit') shutil.rmtree(trace_unit, ignore_errors=True) trace_unit.mkdir() unit_tests = list_unit_tests() for test in unit_tests: subprocess.run(['adb', 'shell', 'rm', '/data/misc/trace/*']) run_unit_test(test, logs_out) pull_and_rename_trace_for_test(test, trace_unit) generate_java_coverage(args.apex_name, trace_unit, coverage_out_unit) generate_native_coverage(args.apex_name, trace_unit, coverage_out_unit) # Compute all tests coverage coverage_out_mainline = Path(f'{coverage_out}/mainline') coverage_out_mainline.mkdir() trace_all = Path('trace_all') shutil.rmtree(trace_all, ignore_errors=True) subprocess.run(['adb', 'pull', '/data/misc/trace', trace_all]) generate_java_coverage(args.apex_name, trace_all, coverage_out_mainline) generate_native_coverage(args.apex_name, trace_all, coverage_out_mainline) trace_mainline = Path('trace_mainline') shutil.rmtree(trace_mainline, ignore_errors=True) trace_mainline.mkdir() for child in trace_pandora.iterdir(): shutil.copy(child, trace_mainline) for child in trace_unit.iterdir(): shutil.copy(child, trace_mainline) generate_java_coverage(args.apex_name, trace_mainline, coverage_out_mainline) generate_native_coverage(args.apex_name, trace_mainline, coverage_out_mainline)