Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 86abd88a authored by Hansong Zhang's avatar Hansong Zhang
Browse files

Add a helper to run topshim locally

Test: gd/cert/run_topshim
Tag: #floss
Bug: 197316386
Change-Id: I52c23ce556661a811789d566433e21b7d3292b60
parent bf3995a5
Loading
Loading
Loading
Loading
+142 −0
Original line number Diff line number Diff line
#!/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"
]

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', 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")
    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 FAILLED: ' + TEST_SUITES[index])
        sys.exit(0)
    print('TEST PASSED ' + str(len(test_results)) + ' tests were run')

if __name__ == '__main__':
    main()
 No newline at end of file