123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- #!/usr/bin/env python
- #
- # Copyright 2017, 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
- # Registered host based unit tests
- # Must have 'host_supported: true'
- HOST_TESTS = [
- 'bluetooth_test_common',
- 'bluetoothtbd_test',
- 'net_test_avrcp',
- 'net_test_btcore',
- 'net_test_types',
- 'net_test_btpackets',
- ]
- SOONG_UI_BASH = 'build/soong/soong_ui.bash'
- def str2bool(argument, default=False):
- """ Convert a string to a booleen value. """
- argument = str(argument)
- if argument.lower() in ['0', 'f', 'false', 'off', 'no', 'n']:
- return False
- elif argument.lower() in ['1', 't', 'true', 'on', 'yes', 'y']:
- return True
- return default
- 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_native_test_root_or_die():
- android_host_out = get_android_host_out_or_die()
- test_root = os.path.join(android_host_out, 'nativetest64')
- if not os.path.isdir(test_root):
- test_root = os.path.join(android_host_out, 'nativetest')
- if not os.path.isdir(test_root):
- print 'Neither nativetest64 nor nativetest directory exist,' \
- ' please compile first'
- sys.exit(1)
- return test_root
- def get_test_cmd_or_die(test_root, test_name, enable_xml, test_filter):
- test_path = os.path.join(os.path.join(test_root, test_name), test_name)
- if not os.path.isfile(test_path):
- print 'Cannot find: ' + test_path
- sys.exit(1)
- cmd = [test_path]
- if enable_xml:
- dist_dir = get_android_dist_dir_or_die()
- log_output_path = os.path.join(dist_dir, 'gtest/{0}_test_details.xml'
- .format(test_name))
- cmd.append('--gtest_output=xml:{0}'.format(log_output_path))
- if test_filter:
- cmd.append('--gtest_filter=%s' % test_filter)
- return cmd
- # path is relative to Android build top
- def build_target(target, num_tasks):
- ANDROID_BUILD_TOP = get_android_root_or_die()
- build_cmd = [SOONG_UI_BASH, '--make-mode']
- if num_tasks > 1:
- build_cmd.append('-j' + str(num_tasks))
- 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_host_unit_tests.py - Run registered host based unit tests
- """
- parser = argparse.ArgumentParser(description='Run host based unit tests.')
- parser.add_argument(
- '--enable_xml',
- type=str2bool,
- dest='enable_xml',
- nargs='?',
- const=True,
- default=False,
- help=
- 'Whether to output structured XML log output in out/dist/gtest directory')
- parser.add_argument(
- '-j',
- type=int,
- nargs='?',
- dest='num_tasks',
- const=-1,
- default=-1,
- help='Number of tasks to run at the same time')
- parser.add_argument(
- 'rest',
- nargs=argparse.REMAINDER,
- help='-- args, other gtest arguments for each individual test')
- args = parser.parse_args()
- build_target('MODULES-IN-system-bt', args.num_tasks)
- TEST_ROOT = get_native_test_root_or_die()
- test_results = []
- for test in HOST_TESTS:
- test_cmd = get_test_cmd_or_die(TEST_ROOT, test, args.enable_xml, args.rest)
- if subprocess.call(test_cmd) != 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: ' + HOST_TESTS[index]
- sys.exit(0)
- print 'TEST PASSED ' + str(len(test_results)) + ' tests were run'
- dist_dir = get_android_dist_dir_or_die()
- log_output_path = os.path.join(dist_dir, 'gtest/coverage')
- cmd_path = os.path.join(get_android_root_or_die(), 'system/bt/test')
- print cmd_path
- cmd = [
- os.path.join(cmd_path, 'gen_coverage.py'),
- '--skip-html',
- '--json-file',
- '-o',
- log_output_path,
- ]
- subprocess.call(cmd)
- sys.exit(0)
- if __name__ == '__main__':
- main()
|