From 872983a1d8f39889356bf0f931818799b5a9896c Mon Sep 17 00:00:00 2001 From: Thomas Girardier <girardier@google.com> Date: Sat, 5 Nov 2022 00:15:56 +0000 Subject: [PATCH] [Pandora] Few improvements on coverage script Test: NA Change-Id: Ifffacac7a34022b6c04ceaaf332a0f73fac3ea12 --- android/pandora/gen_cov.py | 186 ++++++++++++++++++++++++------------- 1 file changed, 121 insertions(+), 65 deletions(-) diff --git a/android/pandora/gen_cov.py b/android/pandora/gen_cov.py index 3943341b06d..5365f465358 100755 --- a/android/pandora/gen_cov.py +++ b/android/pandora/gen_cov.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import argparse +from datetime import datetime import os from pathlib import Path import shutil @@ -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', @@ -24,63 +33,84 @@ 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) - - for test in mts_tests: - print(f'Test started: {test}') - - # Env variables necessary for native unit tests. - env = os.environ.copy() - env['CLANG_COVERAGE_CONTINUOUS_MODE'] = 'true' - env['CLANG_COVERAGE'] = 'true' - env['NATIVE_COVERAGE_PATHS'] = 'packages/modules/Bluetooth' - run_test_cmd = [ - # atest command with verbose mode. - 'atest', - '-d', - '-v', - test, - # Coverage tool chains and specify that coverage should be flush to the - # disk between each tests. - '--', - '--coverage', - '--coverage-toolchain JACOCO', - '--coverage-toolchain CLANG', - '--coverage-flush', - # Allows tests to use hidden APIs. - '--test-arg ', - 'com.android.compatibility.testtype.LibcoreTest:hidden-api-checks:false', - '--test-arg ', - 'com.android.tradefed.testtype.AndroidJUnitTest:hidden-api-checks:false', - '--test-arg ', - 'com.android.tradefed.testtype.InstrumentationTest:hidden-api-checks:false', - '--skip-system-status-check ', - 'com.android.tradefed.suite.checker.ShellStatusChecker', - ] - with open(f'{logs_out}/{test}.txt', 'w') as f: + unit_tests.append(test) + + return unit_tests + + +def run_unit_test(test, logs_out): + print(f'Test started: {test}') + + # Env variables necessary for native unit tests. + env = os.environ.copy() + env['CLANG_COVERAGE_CONTINUOUS_MODE'] = 'true' + env['CLANG_COVERAGE'] = 'true' + env['NATIVE_COVERAGE_PATHS'] = 'packages/modules/Bluetooth' + run_test_cmd = [ + # atest command with verbose mode. + 'atest', + '-d', + '-v', + test, + # Coverage tool chains and specify that coverage should be flush to the + # disk between each tests. + '--', + '--coverage', + '--coverage-toolchain JACOCO', + '--coverage-toolchain CLANG', + '--coverage-flush', + # Allows tests to use hidden APIs. + '--test-arg ', + 'com.android.compatibility.testtype.LibcoreTest:hidden-api-checks:false', + '--test-arg ', + 'com.android.tradefed.testtype.AndroidJUnitTest:hidden-api-checks:false', + '--test-arg ', + 'com.android.tradefed.testtype.InstrumentationTest:hidden-api-checks:false', + '--skip-system-status-check ', + 'com.android.tradefed.suite.checker.ShellStatusChecker', + ] + + 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 - print( - f'Test ended [{"Success" if returncode == 0 else "Failed"}]: {test}') + 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): @@ -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', @@ -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) -- GitLab