1a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond#!/usr/bin/env python
25bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond
35bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# Copyright (C) 2016 The Android Open Source Project
45bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond#
55bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# Licensed under the Apache License, Version 2.0 (the "License");
65bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# you may not use this file except in compliance with the License.
75bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# You may obtain a copy of the License at
85bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond#
95bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond#      http://www.apache.org/licenses/LICENSE-2.0
105bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond#
115bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# Unless required by applicable law or agreed to in writing, software
125bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# distributed under the License is distributed on an "AS IS" BASIS,
135bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# See the License for the specific language governing permissions and
155bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond# limitations under the License.
165bbcc3861c44435f89481f80946ef5c9c49968f2Luke Drummond
17dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo'''Main test suite execution script.'''
18dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport argparse
19dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport inspect
20dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport logging
21dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport os
22dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport signal
23dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport subprocess
24dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport sys
25dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport time
26a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummondimport collections
27dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoimport xml.etree.ElementTree as ET
28dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
29dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leofrom config import Config
30dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leofrom tests.harness import util_constants
31a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummondfrom tests.harness.exception import TestSuiteException, FailFastException
32dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leofrom tests.harness import UtilAndroid
33dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leofrom tests.harness import UtilBundle
34dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leofrom tests.harness import util_log
35dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leofrom tests.harness.util_functions import load_py_module
36a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummondfrom tests.harness.decorators import deprecated
37dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
38dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo# For some reason pylint is not able to understand the class returned by
39dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo# from util_log.get_logger() and generates a lot of false warnings
40dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo#pylint: disable=maybe-no-member
41dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
42dcecc0c8d22e894525e25a122ce25129b51338f2Dean De LeoEMU_PROC = None
43dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
44dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef _parse_args():
45dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''Parse the command line arguments.
46dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
47dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Returns:
48dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        A namespace object that contains the options specified to run_tests on
49dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        the command line.
50dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''
51dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
52dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    parser = argparse.ArgumentParser(description='Run the test suite.')
53dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
54dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    parser.add_argument('--config', '-c',
55dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        metavar='path',
56dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        help='Path to a custom config file.')
57dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    parser.add_argument('--device', '-d',
58dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        help='Specify the device id of the device to test on.')
59dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    parser.add_argument('--test', '-t',
60dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        metavar='path',
61dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        help='Specify a specific test to run.')
62a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    group = parser.add_mutually_exclusive_group()
63a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    group.add_argument('--wimpy', '-w',
64a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                        action='store_true',
65a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                        default=None,
66a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                        help='Test only a core subset of features.')
67a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    group.add_argument('--app-types',
68a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                        default=['java', 'cpp', 'jni'],
69a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                        nargs='*',
70a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                        help='Specify a list of Android app types against which'
71a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                             ' to run the tests',
72a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                        dest='bundle_types')
73dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    parser.add_argument('--install-only',
74dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        action='store_true',
75dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        default=False,
76dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        help='It only runs the pre-run stage of the test suite.'
77dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                             ' It installs the required APKs but does not '
78dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                             'execute the tests.',
79dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        dest='install_only')
80dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    parser.add_argument('--no-install', '-n',
81dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        action='store_true',
82dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        default=False,
83dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        help='Stop the test suite installing apks to device.',
84dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        dest='noinstall')
85dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    parser.add_argument('--no-uninstall',
86dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        action='store_true',
87dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        default=False,
88dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        help='Stop the test suite uninstalling apks after '
89dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                             'completion.',
90dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        dest='nouninstall')
91dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    parser.add_argument('--print-to-stdout',
92dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        action='store_true',
93dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        default=False,
94dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        help='Print all logging information to standard out.',
95dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        dest='print_to_stdout')
96dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    parser.add_argument('--verbose', '-v',
97dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        action='store_true',
98dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        default=None,
99dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        help='Store extra info in the log.')
100a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    parser.add_argument('--fail-fast',
101dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        action='store_true',
102a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                        default=False,
103a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                        help='Exit the test suite immediately on the first failure.')
104dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    parser.add_argument('--run-emu',
105dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        action='store_true',
106dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        default=None,
107dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        help='Spawn an emulator and run the test suite on that.'
108dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                             ' Specify the emulator command line in the config'
109dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                             ' file or with -emu-cmd.',
110dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        dest='run_emu')
111dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
112dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    # Get the properties of the Config class and add a command line argument
113dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    # for each.
114dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    this_module = sys.modules[__name__]
115dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    for member_name, member_obj in inspect.getmembers(Config):
116dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if (inspect.isdatadescriptor(member_obj) and
117dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            member_name not in ['__weakref__', 'device', 'verbose']):
118dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
119dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            # List type properties can take one or more arguments
120dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            num_args = None
121dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            if (isinstance(member_obj, property)
122dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                and isinstance(member_obj.fget(Config), list)):
123dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                num_args = '+'
124dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
125dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            opt_name = member_name.replace('_', '-')
126dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
127dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            setattr(this_module, opt_name, '')
128dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
129dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            parser.add_argument('--' + opt_name,
130dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                nargs=num_args,
131dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                help=member_obj.__doc__,
132dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                dest=member_name)
133dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
134dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    return parser.parse_args()
135dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
136dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
137dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef _choice(first_choice, second_choice):
138dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''Return first_choice if it is not None otherwise return second_choice.
139dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
140dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Args:
141dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        first_choice: The first choice value.
142dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        second_choice: The alternative value.
143dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
144dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Returns:
145dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        The first argument if it is not None, and the second otherwise.
146dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''
147dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    return first_choice if first_choice else second_choice
148dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
149dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
150dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoclass State(object):
151dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''This class manages all objects required by the test suite.'''
152dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
153dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    # pylint: disable=too-many-instance-attributes
154dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    # Since this is a state class many attributes are expected.
155dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
156dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    def __init__(self):
157dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        '''State constructor.
158dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
159dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        Raises:
160dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            TestSuiteException: When unable to load config file.
161dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
162dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            AssertionError: When assertions fail.
163dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        '''
164dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
165dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # Parse the command line options
166dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        args = _parse_args()
167dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
168dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # create a config instance
169dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if args.config:
170dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            # use the user supplied
171dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            config = State.load_user_configuration(args.config)
172dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        else:
173dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            # use the default configuration
174dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            config = Config()
175dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
176dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # save the test blacklist
177dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.blacklist = _choice(args.blacklist, config.blacklist)
178dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
179dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # Allow any of the command line arguments to override the
180dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # values in the config file.
181dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.adb_path = _choice(args.adb_path, config.adb_path)
182dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
183dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.host_port = int(_choice(args.host_port, config.host_port))
184dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
185dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.device = _choice(args.device, config.device)
186dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
187dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.user_specified_device = self.device
188dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
189dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.device_port = int(_choice(args.device_port, config.device_port))
190dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
191dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.lldb_server_path_device = _choice(args.lldb_server_path_device,
192dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                               config.lldb_server_path_device)
193dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
194dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.lldb_server_path_host = _choice(args.lldb_server_path_host,
195dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                             config.lldb_server_path_host)
196dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
197dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.aosp_product_path = _choice(args.aosp_product_path,
198dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                         config.aosp_product_path)
199dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
200dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.log_file_path = _choice(args.log_file_path, config.log_file_path)
201dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
202dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.results_file_path = _choice(args.results_file_path,
203dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                         config.results_file_path)
204dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
205dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.lldb_path = _choice(args.lldb_path, config.lldb_path)
206dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.print_to_stdout = args.print_to_stdout
207dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.verbose = _choice(args.verbose, config.verbose)
208dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.timeout = int(_choice(args.timeout, config.timeout))
209dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.emu_cmd = _choice(args.emu_cmd, config.emu_cmd)
210dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.run_emu = args.run_emu
211a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        self.wimpy = args.wimpy
212a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        self.bundle_types = args.bundle_types if not self.wimpy else ['java']
213a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        self.fail_fast = args.fail_fast
214dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
215dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # validate the param "verbose"
216dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if not isinstance(self.verbose, bool):
217dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            raise TestSuiteException('The parameter "verbose" should be a '
218dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                     'boolean: {0}'.format(self.verbose))
219dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
220dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # create result array
221dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.results = dict()
222dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.single_test = args.test
223dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
224dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # initialise the logging facility
225dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        log_level = logging.INFO if not self.verbose else logging.DEBUG
226dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        util_log.initialise("driver",
227dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                            print_to_stdout=self.print_to_stdout,
228dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                            level=log_level,
229dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                            file_mode='w', # open for write
230dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                            file_path=self.log_file_path
231dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                            )
232dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        log = util_log.get_logger()
233dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
234dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if self.run_emu and not self.emu_cmd:
235dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log.TestSuiteException('Need to specify --emu-cmd (or specify a'
236dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                ' value in the config file) if using --run-emu.')
237dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
238dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # create a results file
239dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.results_file = open(self.results_file_path, 'w')
240dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
241dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # create an android helper object
242dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.android = UtilAndroid(self.adb_path,
243dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                   self.lldb_server_path_device,
244dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                   self.device)
245dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        assert self.android
246dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
247dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # create a test bundle
248dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.bundle = UtilBundle(self.android,
249dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                 self.aosp_product_path)
250dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        assert self.bundle
251dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
252dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # save the no pushing option
253dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        assert isinstance(args.noinstall, bool)
254dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.noinstall = args.noinstall
255dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
256dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        assert isinstance(args.nouninstall, bool)
257dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.nouninstall = args.nouninstall
258dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
259dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # install only option
260dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        assert type(args.install_only) is bool
261dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.install_only = args.install_only
262dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if self.install_only:
263dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log.log_and_print('Option --install-only set. The test APKs will '
264dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                              'be installed on the device but the tests will '
265dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                              'not be executed.')
266dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            if self.noinstall:
267dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                raise TestSuiteException('Conflicting options given: '
268dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                         '--install-only and --no-install')
269dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
270dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # TCP port modifier which is used to increment the port number used for
271dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # each test case to avoid collisions.
272dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.port_mod = 0
273dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
27474de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond        # total number of test files that have been executed
275dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        self.test_count = 0
276dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
277dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    def get_android(self):
278dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        '''Return the android ADB helper instance.
279dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
280dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        Returns:
281dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            The android ADB helper, instance of UtilAndroid.
282dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        '''
283dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        assert self.android
284dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        return self.android
285dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
286dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    def get_bundle(self):
287dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        '''Return the test executable bundle.
288dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
289dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        Returns:
290dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            The test exectable collection, instance of UtilBundle.
291dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        '''
292dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        return self.bundle
293dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
29474de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond    def add_result(self, name, app_type, result):
295dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        '''Add a test result to the collection.
296dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
297dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        Args:
298dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            name: String name of the test that has executed.
29974de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond            app_type: type of app i.e. java, jni, or cpp
300dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            result: String result of the test, "pass", "fail", "error".
301dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        '''
30274de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond        key = (name, app_type)
30374de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond        assert key not in self.results
30474de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond        self.results[key] = result
305dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
306dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    def get_single_test(self):
307dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        '''Get the name of the single test to run.
308dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
309dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        Returns:
310dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            A string that is the name of the python file containing the test to
311dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            be run. If all tests are to be run this returns None.
312dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        '''
313dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        return self.single_test
314dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
315dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    @staticmethod
316dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    def load_user_configuration(path):
317dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        '''Load the test suite config from the give path.
318dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
319dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        Instantiate the Config class found in the module at the given path.
320dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        If no suitable class is available, it raises a TestSuiteException.
321dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
322dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        Args:
323dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            path: String location of the module.
324dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
325dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        Returns:
326dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            an instance of the Config class, defined in the module.
327dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
328dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        Raises:
329dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            TestSuiteException: when unable to import the module or when a
330dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                subclass of Config is not found inside it.
331dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        '''
332dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
333dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # load the module
334dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        config_module = load_py_module(path)
335dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if not config_module:
336dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            raise TestSuiteException('Unable to import the module from "%s"'
337dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                     % (path))
338dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
339dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # look for a subclass of Config
340dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        for name, value in inspect.getmembers(config_module):
341dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            if (inspect.isclass(value)
342dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                and name != 'Config'
343dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                and issubclass(value, Config)):
344dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                # that's our candidate
345dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                return value()
346dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
347dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # otherwise there are no valid candidates
348dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        raise TestSuiteException('The provided user configuration is not '
349dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                 'valid. The module must define a subclass '
350dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                 'of Config')
351dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
352dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
353dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef _kill_emulator():
354dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    ''' Kill the emulator process. '''
355dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    global EMU_PROC
356dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if EMU_PROC:
357dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        try:
358dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            EMU_PROC.terminate()
359dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        except OSError:
360dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            # can't kill a dead proc
361dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log = util_log.get_logger()
362dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log.debug('Trying to kill an emulator but it is already dead.')
363dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
364dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
365dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef _check_emulator_terminated():
366dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    ''' Throw an exception if the emulator process has ended.
367dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
368dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Raises:
369dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        TestSuiteException: If the emulator process has ended.
370dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''
371dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    global EMU_PROC
372dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    assert EMU_PROC
373dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if EMU_PROC.poll():
374dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        stdout, stderr = EMU_PROC.communicate()
375dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        raise TestSuiteException('The emulator terminated with output:'
376dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            '\nstderr: {0}\nstdout: {1}.'.format(stderr, stdout))
377dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
378dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
379a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond@deprecated()
380dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef _launch_emulator(state):
381dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''Launch the emulator and wait for it to boot.
382dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
383dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Args:
384dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        emu_cmd: The command line to run the emulator.
385dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
386dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Raises:
387dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        TestSuiteException: If an emulator already exists or the emulator
388dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                            process terminated before we could connect to it, or
389dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                            we failed to copy lldb-server to the emulator.
390dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''
391dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    global EMU_PROC
392dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    android = state.android
393dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if state.user_specified_device:
394dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if android.device_with_substring_exists(state.user_specified_device):
395dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            raise TestSuiteException(
396dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                'A device with name {0} already exists.',
397dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                state.user_specified_device)
398dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    else:
399dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if android.device_with_substring_exists('emulator'):
400dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            raise TestSuiteException('An emulator already exists.')
401dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
402dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    assert state.emu_cmd
403dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    EMU_PROC = subprocess.Popen(state.emu_cmd.split(),
404dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                stdout=None,
405dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                stderr=subprocess.STDOUT)
406dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
407dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    log = util_log.get_logger()
408dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    log.info('Launching emulator with command line {0}'.format(state.emu_cmd))
409dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
410dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    tries_number = 180
411dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    tries = tries_number
412dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    found_device = False
413dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    while not found_device:
414dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        try:
415dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            android.validate_device(False, 'emulator')
416dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            found_device = True
417dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        except TestSuiteException as ex:
418dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            tries -= 1
419dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            if tries == 0:
420dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                # Avoid infinitely looping if the emulator won't boot
421dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                log.warning(
422dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                    'Giving up trying to validate device after {0} tries.'
423dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                    .format(tries_number))
424dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                raise ex
425dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            _check_emulator_terminated()
426dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            # wait a bit and try again, maybe it has now booted
427dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            time.sleep(10)
428dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
429dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    tries = 500
430dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    while not android.is_booted():
431dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        tries -= 1
432dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if tries == 0:
433dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            # Avoid infinitely looping if the emulator won't boot
434dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            raise TestSuiteException('The emulator has failed to boot.')
435dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        _check_emulator_terminated()
436dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        time.sleep(5)
437dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
438dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    # Need to be root before we can push lldb-server
439dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    android.adb_root()
440dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    android.wait_for_device()
441dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
442dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    # Push the lldb-server executable to the device.
443dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    output = android.adb('push {0} {1}'.format(state.lldb_server_path_host,
444dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                                               state.lldb_server_path_device))
445dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
446dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if 'failed to copy' in output or 'No such file or directory' in output:
447dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        raise TestSuiteException(
448dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            'unable to push lldb-server to the emulator: {0}.'
449dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            .format(output))
450dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
451dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    output = android.shell('chmod a+x {0}'
452dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                           .format(state.lldb_server_path_device))
453dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
454dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if 'No such file or directory' in output:
455dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        raise TestSuiteException('Failed to copy lldb-server to the emulator.')
456dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
457dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
458dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef _restart_emulator(state):
459dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''Kill the emulator and start a new instance.
460dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
461dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Args:
462dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        state: Test suite state collection, instance of State.
463dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''
464dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    _kill_emulator()
465dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    _launch_emulator(state)
466dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
467dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
468a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummonddef _run_test(state, name, bundle_type):
469dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''Execute a single test case.
470dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
471dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Args:
472dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        state: Test suite state collection, instance of State.
473dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        name: String file name of the test to execute.
474a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        bundle_type: string for the installed app type (cpp|jni|java)
475dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
476dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Raises:
477dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        AssertionError: When assertion fails.
478dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''
479dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    assert isinstance(name, str)
480dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
481dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    try:
482dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        state.android.check_adb_alive()
483dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    except TestSuiteException as expt:
484dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        global EMU_PROC
485dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if EMU_PROC:
486dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            _restart_emulator(state)
487dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        else:
488dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            raise expt
489dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
490dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    log = util_log.get_logger()
491dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    sys.stdout.write('Running {0}\r'.format(name))
492dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    sys.stdout.flush()
493dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    log.info('Running {0}'.format(name))
494dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
495dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    run_tests_dir = os.path.dirname(os.path.realpath(__file__))
496dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    run_test_path = os.path.join(run_tests_dir, 'tests', 'run_test.py')
497dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
498dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    # Forward port for lldb-server on the device to our host
499dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    hport = int(state.host_port) + state.port_mod
500dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    dport = int(state.device_port) + state.port_mod
501dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    state.android.forward_port(hport, dport)
502dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    state.port_mod += 1
503dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
504dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    log.debug('Giving up control to {0}...'.format(name))
505dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
506a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    params = map(str, [
507a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        sys.executable,
508a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        run_test_path,
509a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        name,
510a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        state.log_file_path,
511a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        state.adb_path,
512a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        state.lldb_server_path_device,
513a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        state.aosp_product_path,
514a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        dport,
515a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        state.android.get_device_id(),
516a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        state.print_to_stdout,
517a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        state.verbose,
518a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        state.wimpy,
519a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        state.timeout,
520a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        bundle_type
521a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    ])
522dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
523dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    return_code = subprocess.call(params)
52474de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond    state.test_count += 1
525dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    state.android.remove_port_forwarding()
526dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    log.seek_to_end()
527dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
528dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    # report in sys.stdout the result
52974de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond    success = return_code == util_constants.RC_TEST_OK
53074de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond    status_handlers = collections.defaultdict(lambda: ('error', log.error), (
53174de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond            (util_constants.RC_TEST_OK, ('pass', log.info)),
53274de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond            (util_constants.RC_TEST_TIMEOUT, ('timeout', log.error)),
53374de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond            (util_constants.RC_TEST_IGNORED, ('ignored', log.info)),
53474de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond            (util_constants.RC_TEST_FAIL, ('fail', log.critical))
535a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        )
536a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    )
53774de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond    status_name, status_logger = status_handlers[return_code]
53874de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond    log.info('Running %s: %s', name, status_name.upper())
53974de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond    status_logger("Test %r: %s", name, status_name)
54074de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond
54174de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond    # Special case for ignored tests - just return now
542a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    if return_code == util_constants.RC_TEST_IGNORED:
543a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        return
544a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond
54574de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond    state.add_result(name, bundle_type, status_name)
54674de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond
547a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    if state.fail_fast and not success:
548a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        raise FailFastException(name)
549a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond
550dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    # print a running total pass rate
551a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    passes = sum(1 for key, value in state.results.items() if value == 'pass')
55274de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond    log.info('Current pass rate: %s of %s executed.', passes, len(state.results))
553dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
554dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
555dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef _check_lldbserver_exists(state):
556dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''Check lldb-server exists on the target device and it is executable.
557dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
558dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Raises:
559dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        TestSuiteError: If lldb-server does not exist on the target.
560dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''
561dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    assert state
562dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
563dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    message = 'Unable to verify valid lldb-server on target'
564dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
565dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    android = state.get_android()
566dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    assert android
567dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
568dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    cmd = state.lldb_server_path_device
569dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    out = android.shell(cmd, False)
570dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if not isinstance(out, str):
571dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        raise TestSuiteException(message)
572dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if out.find('Usage:') < 0:
573dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        raise TestSuiteException(message)
574dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
575dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
576dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef _suite_pre_run(state):
577dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''This function is executed before the test cases are run (setup).
578dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
579dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Args:
580dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        state: Test suite state collection, instance of State.
581dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
582dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Return:
583dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        True if the pre_run step completes without error.
584dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        Checks made:
585dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            - Validating that adb exists and runs.
586dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            - Validating that a device is attached.
587dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            - We have root access to the device.
588dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            - All test binaries were pushed to the device.
589dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            - The port for lldb-server was forwarded correctly.
590dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
591dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Raises:
592dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        AssertionError: When assertions fail.
593dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''
594dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    assert state
595dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    log = util_log.get_logger()
596dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
597dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    try:
598dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        android = state.get_android()
599dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        bundle = state.get_bundle()
600dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        assert android
601dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        assert bundle
602dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
603dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # validate ADB helper class
604dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        android.validate_adb()
605dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        log.log_and_print('Located ADB')
606dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
607dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if state.run_emu:
608dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log.log_and_print('Launching emulator...')
609dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            _launch_emulator(state)
610dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log.log_and_print('Started emulator ' + android.device)
611dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        else:
612dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            android.validate_device()
613dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log.log_and_print('Located device ' + android.device)
614dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
615dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if state.noinstall and not state.single_test:
616dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            bundle.check_apps_installed(state.wimpy)
617dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
618dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # elevate to root user
619dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        android.adb_root()
620dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        android.wait_for_device()
621dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # check that lldb-server exists on device
622dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        android.kill_servers()
623dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        _check_lldbserver_exists(state)
624dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
625dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if not state.noinstall:
626dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            # push all tests to the device
627dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log.log_and_print('Pushing all tests...')
628dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            bundle.push_all()
629dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log.log_and_print('Pushed all tests')
630dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        log.log_and_print('Pre run complete')
631dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
632dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    except TestSuiteException as expt:
633dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        log.exception('Test suite pre run failure')
634dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
635dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # Even if we are logging the error, it may be helpful and more
636dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # immediate to find out the error into the terminal
637dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        log.log_and_print('ERROR: Unable to set up the test suite: %s\n'
638dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                          % expt.message, logging.ERROR)
639dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
640dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        return False
641dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    return True
642dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
643dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
644dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef _suite_post_run(state):
645dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''This function is executed after the test cases have run (teardown).
646dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
647dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Args:
648dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        state: Test suite state collection, instance of State.
649a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    Returns:
650a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        Number of failures
651dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''
652dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    log = util_log.get_logger()
653dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
654dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if not state.noinstall and not state.nouninstall:
655dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if state.wimpy:
656dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            state.bundle.uninstall_all_apk()
657dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        else:
658dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            state.bundle.uninstall_all()
659dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        log.log_and_print('Uninstalled/Deleted all tests')
660dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
661dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    total = 0
662dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    passes = 0
663dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    failures = 0
664dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
665dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    results = ET.Element('testsuite')
666dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    results.attrib['name'] = 'LLDB RS Test Suite'
667dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
668a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    for key, value in state.results.items():
669dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        total += 1
670dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if value == 'pass':
671dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            passes += 1
672dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        else:
673dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            failures += 1
674dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
675dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # test case name, followed by pass, failure or error elements
676dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        testcase = ET.Element('testcase')
67774de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond        testcase.attrib['name'] = "%s:%s" % key
678dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        result_element = ET.Element(value)
67974de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond        result_element.text = "%s:%s" % key
680dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        testcase.append(result_element)
681dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        results.append(testcase)
682dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
683dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    assert passes + failures == total, 'Invalid test results status'
684dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if failures:
685dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        log.log_and_print(
6866e319703dbbeb80818f530f6cfe432d8ccf90408David Gross            'The following failures occurred:\n%s\n' %
68774de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond            '\n'.join('failed: %s:%s' % test_spec
68874de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond                for test_spec, result in state.results.items() if result != 'pass'
68974de4db187fc370c9b6625134ae39df6655e7d72Luke Drummond        ))
690dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
691dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    log.log_and_print('{0} of {1} passed'.format(passes, total))
692dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if total:
693dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        log.log_and_print('{0}% rate'.format((passes*100)/total))
694dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
695dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    results.attrib['tests'] = str(total)
696dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    state.results_file.write(ET.tostring(results, encoding='iso-8859-1'))
697dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
698a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    return failures
699a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond
700dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
701dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef _discover_tests(state):
702dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''Discover all tests in the tests directory.
703dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
704dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Returns:
705dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        List of strings, test file names from the 'tests' directory.
706dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''
707dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    tests = []
708dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
709dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    single_test = state.get_single_test()
710dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if single_test is None:
711dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        file_dir = os.path.dirname(os.path.realpath(__file__))
712dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        tests_dir = os.path.join(file_dir, 'tests')
713dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
714dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        for sub_dir in os.listdir(tests_dir):
715dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            current_test_dir = os.path.join(tests_dir, sub_dir)
716dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            if os.path.isdir(current_test_dir):
717dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                dir_name = os.path.basename(current_test_dir)
718dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
719dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                if dir_name == 'harness':
720dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                    continue
721dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
722dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                for item in os.listdir(current_test_dir):
723dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                    if (item.startswith('test')
724dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        and item.endswith('.py')
725dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        and not item in state.blacklist):
726dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                        tests.append(item)
727dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    else:
728dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if single_test.endswith('.py'):
729dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            tests.append(single_test)
730dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        else:
731dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            tests.append(single_test + '.py')
732dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
733dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    return tests
734dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
735dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
736dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef _deduce_python_path(state):
737dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''Try to deduce the PYTHONPATH environment variable via the LLDB binary.
738dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
739dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Args:
740dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        state: Test suite state collection, instance of State.
741dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
742dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Returns:
743dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        True if PYTHONPATH has been updated, False otherwise.
744dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
745dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    Raises:
746dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        TestSuiteException: If lldb path provided in the config or command line
747dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                            is incorrect.
748dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        AssertionError: If an assertion fails.
749dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''
750dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
751dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    lldb_path = state.lldb_path
752dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if not lldb_path:
753dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # lldb may not be provided in preference of a manual $PYTHONPATH
754dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        return False
755dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
756dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    params = [lldb_path, '-P']
757dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
758dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    try:
759dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        proc = subprocess.Popen(params, stdout=subprocess.PIPE)
760dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    except OSError as err:
761dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        error_string = 'Could not run lldb at %s: %s' % (lldb_path, str(err))
762dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        raise TestSuiteException(error_string)
763dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
764dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    stdout = proc.communicate()[0]
765dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    if stdout:
766dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        os.environ['PYTHONPATH'] = stdout.strip()
767dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        return True
768dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
769dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    return False
770dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
771dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
772dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef main():
773dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''The lldb-renderscript test suite entry point.'''
774dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    log = None
775dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
776dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    try:
777dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # parse the command line
778dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        state = State()
779dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        assert state
780dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
781dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # logging is initialised in State()
782dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        log = util_log.get_logger()
783dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
784dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # if we can, set PYTHONPATH for lldb bindings
785dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if not _deduce_python_path(state):
786dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log.log_and_print('Unable to deduce PYTHONPATH', logging.WARN)
787dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
788dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # pre run step
789dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if not _suite_pre_run(state):
790dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            raise TestSuiteException('Test suite pre-run step failed')
791dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        # discover all tests and execute them
792dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        tests = _discover_tests(state)
793dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        log.log_and_print('Found {0} tests'.format(len(tests)))
794dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if state.install_only:
795dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log.log_and_print('Test applications installed. Terminating due to '
796dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo                              '--install-only option')
797dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        else:
798dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            # run the tests
799a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond            for bundle_type in state.bundle_types:
800a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                log.info("Running bundle type '%s'", bundle_type)
801a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                for item in tests:
802a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                    _run_test(state, item, bundle_type)
803a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond                # post run step
804a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond            quit(0 if _suite_post_run(state) == 0 else 1)
805dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
806dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    except AssertionError:
807dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if log:
808dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log.exception('Internal test suite error')
809dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
810a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        print('Internal test suite error')
811a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        quit(1)
812a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond
813a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    except FailFastException:
814a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        log.exception('Early exit after first test failure')
815dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        quit(1)
816dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
817dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    except TestSuiteException as error:
818dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        if log:
819dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo            log.exception('Test suite exception')
820dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
821a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond        print('{0}'.format(str(error)))
822dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        quit(2)
823dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
824dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    finally:
825dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        _kill_emulator()
826dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo        logging.shutdown()
827dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
828dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leodef signal_handler(_, _unused):
829dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    '''Signal handler for SIGINT, caused by the user typing Ctrl-C.'''
830dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    # pylint: disable=unused-argument
831dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    # pylint: disable=protected-access
832a3c6f62775506c95afd556e617f14d7a28839f01Luke Drummond    print('Ctrl+C!')
833dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    os._exit(1)
834dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
835dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo
836dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo# execution trampoline
837dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leoif __name__ == '__main__':
838dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    signal.signal(signal.SIGINT, signal_handler)
839dcecc0c8d22e894525e25a122ce25129b51338f2Dean De Leo    main()
840