1#!/usr/bin/env python
2#
3# Copyright (C) 2016 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#
17"""Runs all tests for gtest/gmock."""
18import argparse
19import logging
20import os
21import sys
22
23
24# pylint: disable=design
25
26
27def logger():
28    """Return the default logger for the module."""
29    return logging.getLogger(__name__)
30
31
32def call(cmd, *args, **kwargs):
33    """Proxy for subprocess.call with logging."""
34    import subprocess
35    logger().info('call `%s`', ' '.join(cmd))
36    return subprocess.call(cmd, *args, **kwargs)
37
38
39def parse_args():
40    "Parse and return command line arguments."""
41    parser = argparse.ArgumentParser()
42    parser.add_argument('--host', action='store_true')
43    parser.add_argument('-v', '--verbose', action='store_true')
44    return parser.parse_args()
45
46
47def main():
48    "Program entry point."""
49    args = parse_args()
50    log_level = logging.INFO
51    if args.verbose:
52        log_level = logging.DEBUG
53    logging.basicConfig(level=log_level)
54
55    if args.host:
56        test_location = os.path.join(os.environ['ANDROID_HOST_OUT'], 'bin')
57    else:
58        data_dir = os.path.join(os.environ['OUT'], 'data')
59        test_location = os.path.join(data_dir, 'nativetest64')
60        if not os.path.exists(test_location):
61            test_location = os.path.join(data_dir, 'nativetest')
62
63    num_tests = 0
64    failures = []
65    logger().debug('Scanning %s for tests', test_location)
66    for test in os.listdir(test_location):
67        if not test.startswith('gtest') and not test.startswith('gmock'):
68            logger().debug('Skipping %s', test)
69            continue
70        num_tests += 1
71
72        if args.host:
73            cmd = [os.path.join(test_location, test)]
74            if call(cmd) != 0:
75                failures.append(test)
76        else:
77            device_dir = test_location.replace(os.environ['OUT'], '')
78            cmd = ['adb', 'shell', 'cd {} && ./{}'.format(device_dir, test)]
79            if call(cmd) != 0:
80                failures.append(test)
81
82    if num_tests == 0:
83        logger().error('No tests found!')
84        sys.exit(1)
85
86    num_failures = len(failures)
87    num_passes = num_tests - num_failures
88    logger().info('%d/%d tests passed', num_passes, num_tests)
89    if len(failures) > 0:
90        logger().error('Failures:\n%s', '\n'.join(failures))
91    else:
92        logger().info('All tests passed!')
93    sys.exit(num_failures)
94
95
96if __name__ == '__main__':
97    main()
98