#!/usr/bin/env python3 # # Copyright 2021, 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. import sys import subprocess import os import argparse TEST_SUITES = [ "blueberry.tests.gd.rust.topshim.facade.adapter_test", "blueberry.tests.gd.rust.topshim.facade.suspend_test" ] SOONG_UI_BASH = 'build/soong/soong_ui.bash' def check_dir_exists(dir, dirname): if not os.path.isdir(dir): print("Couldn't find %s (%s)!" % (dirname, dir)) sys.exit(0) def get_output_from_command(cmd): try: return subprocess.check_output(cmd).strip() except subprocess.CalledProcessError as e: print('Failed to call {cmd}, return code {code}'.format(cmd=cmd, code=e.returncode)) print(e) return None def get_android_root_or_die(): value = os.environ.get('ANDROID_BUILD_TOP') if not value: # Try to find build/soong/soong_ui.bash upwards until root directory current_path = os.path.abspath(os.getcwd()) while current_path and os.path.isdir(current_path): soong_ui_bash_path = os.path.join(current_path, SOONG_UI_BASH) if os.path.isfile(soong_ui_bash_path): # Use value returned from Soong UI instead in case definition to TOP # changes in the future value = get_output_from_command((soong_ui_bash_path, '--dumpvar-mode', '--abs', 'TOP')) break parent_path = os.path.abspath(os.path.join(current_path, os.pardir)) if parent_path == current_path: current_path = None else: current_path = parent_path if not value: print('Cannot determine ANDROID_BUILD_TOP') sys.exit(1) check_dir_exists(value, '$ANDROID_BUILD_TOP') return value def get_android_host_out_or_die(): value = os.environ.get('ANDROID_HOST_OUT') if not value: ANDROID_BUILD_TOP = get_android_root_or_die() value = get_output_from_command((os.path.join(ANDROID_BUILD_TOP, SOONG_UI_BASH), '--dumpvar-mode', '--abs', 'HOST_OUT')) if not value: print('Cannot determine ANDROID_HOST_OUT') sys.exit(1) check_dir_exists(value, '$ANDROID_HOST_OUT') return value def get_android_dist_dir_or_die(): # Check if $DIST_DIR is predefined as environment variable value = os.environ.get('DIST_DIR') if not value: # If not use the default path ANDROID_BUILD_TOP = get_android_root_or_die() value = os.path.join(os.path.join(ANDROID_BUILD_TOP, 'out'), 'dist') if not os.path.isdir(value): if os.path.exists(value): print('%s is not a directory!' % (value)) sys.exit(1) os.makedirs(value) return value def get_test_cmd_or_die(suite_name, config_path): config_file_path = os.path.join(os.path.join(get_android_root_or_die(), 'out/dist'), config_path) if not os.path.isfile(config_file_path): print('Cannot find: ' + config_file_path) sys.exit(1) cmd = ["python3", "-m", suite_name, "-c", config_path] return cmd # path is relative to Android build top def build_dist_target(target): ANDROID_BUILD_TOP = get_android_root_or_die() build_cmd = [SOONG_UI_BASH, '--make-mode', 'dist', target] build_cmd.append(target) p = subprocess.Popen(build_cmd, cwd=ANDROID_BUILD_TOP, env=os.environ.copy()) return_code = p.wait() if return_code != 0: print('BUILD FAILED, return code: {0}'.format(str(return_code))) sys.exit(1) return def main(): """ run_topshim - Run registered host based topshim tests """ parser = argparse.ArgumentParser(description='Run host based topshim tests.') parser.add_argument( '--config', type=str, dest='config_path', nargs='?', const=True, default='blueberry/tests/gd/host_config.yaml', help='Test config for mobly topshim test') args = parser.parse_args() build_dist_target('bluetooth_stack_with_facade') test_results = [] dist_path = os.path.join(get_android_root_or_die(), "out/dist") subprocess.call(['unzip', '-o', 'bluetooth_cert_tests.zip'], cwd=dist_path) for test in TEST_SUITES: test_cmd = get_test_cmd_or_die(test, args.config_path) if subprocess.call(test_cmd, cwd=dist_path) != 0: test_results.append(False) else: test_results.append(True) if not all(test_results): failures = [i for i, x in enumerate(test_results) if not x] for index in failures: print('TEST FAILED: ' + TEST_SUITES[index]) sys.exit(0) print('TEST PASSED ' + str(len(test_results)) + ' tests were run') if __name__ == '__main__': main()