OSDN Git Service

Return after removing sample LTK device am: 7c86810c44 am: e8ba00c87c am: a326247710
[android-x86/system-bt.git] / test / run_host_unit_tests.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2017, The Android Open Source Project
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #     http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 import sys
17 import subprocess
18 import os
19 import argparse
20
21 # Registered host based unit tests
22 # Must have 'host_supported: true'
23 HOST_TESTS = [
24     'bluetooth_test_common',
25     'bluetoothtbd_test',
26     'net_test_avrcp',
27     'net_test_btcore',
28     'net_test_types',
29     'net_test_btpackets',
30 ]
31
32 SOONG_UI_BASH = 'build/soong/soong_ui.bash'
33
34
35 def str2bool(argument, default=False):
36     """ Convert a string to a booleen value. """
37     argument = str(argument)
38     if argument.lower() in ['0', 'f', 'false', 'off', 'no', 'n']:
39         return False
40     elif argument.lower() in ['1', 't', 'true', 'on', 'yes', 'y']:
41         return True
42     return default
43
44
45 def check_dir_exists(dir, dirname):
46     if not os.path.isdir(dir):
47         print "Couldn't find %s (%s)!" % (dirname, dir)
48         sys.exit(0)
49
50
51 def get_output_from_command(cmd):
52     try:
53         return subprocess.check_output(cmd).strip()
54     except subprocess.CalledProcessError as e:
55         print 'Failed to call {cmd}, return code {code}'.format(
56             cmd=cmd, code=e.returncode)
57         print e
58         return None
59
60
61 def get_android_root_or_die():
62     value = os.environ.get('ANDROID_BUILD_TOP')
63     if not value:
64         # Try to find build/soong/soong_ui.bash upwards until root directory
65         current_path = os.path.abspath(os.getcwd())
66         while current_path and os.path.isdir(current_path):
67             soong_ui_bash_path = os.path.join(current_path, SOONG_UI_BASH)
68             if os.path.isfile(soong_ui_bash_path):
69                 # Use value returned from Soong UI instead in case definition to TOP
70                 # changes in the future
71                 value = get_output_from_command(
72                     (soong_ui_bash_path, '--dumpvar-mode', '--abs', 'TOP'))
73                 break
74             parent_path = os.path.abspath(os.path.join(current_path, os.pardir))
75             if parent_path == current_path:
76                 current_path = None
77             else:
78                 current_path = parent_path
79         if not value:
80             print 'Cannot determine ANDROID_BUILD_TOP'
81             sys.exit(1)
82     check_dir_exists(value, '$ANDROID_BUILD_TOP')
83     return value
84
85
86 def get_android_host_out_or_die():
87     value = os.environ.get('ANDROID_HOST_OUT')
88     if not value:
89         ANDROID_BUILD_TOP = get_android_root_or_die()
90         value = get_output_from_command(
91             (os.path.join(ANDROID_BUILD_TOP, SOONG_UI_BASH), '--dumpvar-mode',
92              '--abs', 'HOST_OUT'))
93         if not value:
94             print 'Cannot determine ANDROID_HOST_OUT'
95             sys.exit(1)
96     check_dir_exists(value, '$ANDROID_HOST_OUT')
97     return value
98
99
100 def get_android_dist_dir_or_die():
101     # Check if $DIST_DIR is predefined as environment variable
102     value = os.environ.get('DIST_DIR')
103     if not value:
104         # If not use the default path
105         ANDROID_BUILD_TOP = get_android_root_or_die()
106         value = os.path.join(os.path.join(ANDROID_BUILD_TOP, 'out'), 'dist')
107     if not os.path.isdir(value):
108         if os.path.exists(value):
109             print '%s is not a directory!' % (value)
110             sys.exit(1)
111         os.makedirs(value)
112     return value
113
114
115 def get_native_test_root_or_die():
116     android_host_out = get_android_host_out_or_die()
117     test_root = os.path.join(android_host_out, 'nativetest64')
118     if not os.path.isdir(test_root):
119         test_root = os.path.join(android_host_out, 'nativetest')
120         if not os.path.isdir(test_root):
121             print 'Neither nativetest64 nor nativetest directory exist,' \
122                   ' please compile first'
123             sys.exit(1)
124     return test_root
125
126
127 def get_test_cmd_or_die(test_root, test_name, enable_xml, test_filter):
128     test_path = os.path.join(os.path.join(test_root, test_name), test_name)
129     if not os.path.isfile(test_path):
130         print 'Cannot find: ' + test_path
131         sys.exit(1)
132     cmd = [test_path]
133     if enable_xml:
134         dist_dir = get_android_dist_dir_or_die()
135         log_output_path = os.path.join(
136             dist_dir, 'gtest/{0}_test_details.xml'.format(test_name))
137         cmd.append('--gtest_output=xml:{0}'.format(log_output_path))
138     if test_filter:
139         cmd.append('--gtest_filter=%s' % test_filter)
140     return cmd
141
142
143 # path is relative to Android build top
144 def build_target(target, num_tasks):
145     ANDROID_BUILD_TOP = get_android_root_or_die()
146     build_cmd = [SOONG_UI_BASH, '--make-mode']
147     if num_tasks > 1:
148         build_cmd.append('-j' + str(num_tasks))
149     build_cmd.append(target)
150     p = subprocess.Popen(
151         build_cmd, cwd=ANDROID_BUILD_TOP, env=os.environ.copy())
152     return_code = p.wait()
153     if return_code != 0:
154         print 'BUILD FAILED, return code: {0}'.format(str(return_code))
155         sys.exit(1)
156     return
157
158
159 def main():
160     """ run_host_unit_tests.py - Run registered host based unit tests
161   """
162     parser = argparse.ArgumentParser(description='Run host based unit tests.')
163     parser.add_argument(
164         '--enable_xml',
165         type=str2bool,
166         dest='enable_xml',
167         nargs='?',
168         const=True,
169         default=False,
170         help=
171         'Whether to output structured XML log output in out/dist/gtest directory'
172     )
173     parser.add_argument(
174         '-j',
175         type=int,
176         nargs='?',
177         dest='num_tasks',
178         const=-1,
179         default=-1,
180         help='Number of tasks to run at the same time')
181     parser.add_argument(
182         'rest',
183         nargs=argparse.REMAINDER,
184         help='-- args, other gtest arguments for each individual test')
185     args = parser.parse_args()
186
187     build_target('MODULES-IN-system-bt', args.num_tasks)
188     TEST_ROOT = get_native_test_root_or_die()
189     test_results = []
190     for test in HOST_TESTS:
191         test_cmd = get_test_cmd_or_die(TEST_ROOT, test, args.enable_xml,
192                                        args.rest)
193         if subprocess.call(test_cmd) != 0:
194             test_results.append(False)
195         else:
196             test_results.append(True)
197     if not all(test_results):
198         failures = [i for i, x in enumerate(test_results) if not x]
199         for index in failures:
200             print 'TEST FAILLED: ' + HOST_TESTS[index]
201         sys.exit(0)
202     print 'TEST PASSED ' + str(len(test_results)) + ' tests were run'
203
204     dist_dir = get_android_dist_dir_or_die()
205     log_output_path = os.path.join(dist_dir, 'gtest/coverage')
206     cmd_path = os.path.join(get_android_root_or_die(), 'system/bt/test')
207     print cmd_path
208     cmd = [
209         os.path.join(cmd_path, 'gen_coverage.py'),
210         '--skip-html',
211         '--json-file',
212         '-o',
213         log_output_path,
214     ]
215     subprocess.call(cmd)
216
217     sys.exit(0)
218
219
220 if __name__ == '__main__':
221     main()