# Copyright 2016 Google Inc.
#
# 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 collections
import contextlib
import copy
import functools
import inspect
import logging
import os

from future.utils import raise_with_traceback

from mobly import controller_manager
from mobly import expects
from mobly import records
from mobly import runtime_test_info
from mobly import signals
from mobly import utils

# Macro strings for test result reporting.
TEST_CASE_TOKEN = '[Test]'
RESULT_LINE_TEMPLATE = TEST_CASE_TOKEN + ' %s %s'

TEST_STAGE_BEGIN_LOG_TEMPLATE = '[{parent_token}]#{child_token} >>> BEGIN >>>'
TEST_STAGE_END_LOG_TEMPLATE = '[{parent_token}]#{child_token} <<< END <<<'

# Names of execution stages, in the order they happen during test runs.
STAGE_NAME_SETUP_GENERATED_TESTS = 'setup_generated_tests'
STAGE_NAME_SETUP_CLASS = 'setup_class'
STAGE_NAME_SETUP_TEST = 'setup_test'
STAGE_NAME_TEARDOWN_TEST = 'teardown_test'
STAGE_NAME_TEARDOWN_CLASS = 'teardown_class'
STAGE_NAME_CLEAN_UP = 'clean_up'


class Error(Exception):
    """Raised for exceptions that occurred in BaseTestClass."""


class BaseTestClass(object):
    """Base class for all test classes to inherit from.

    This class gets all the controller objects from test_runner and executes
    the tests requested within itself.

    Most attributes of this class are set at runtime based on the configuration
    provided.

    The default logger in logging module is set up for each test run. If you
    want to log info to the test run output file, use `logging` directly, like
    `logging.info`.

    Attributes:
        tests: A list of strings, each representing a test method name.
        TAG: A string used to refer to a test class. Default is the test class
            name.
        results: A records.TestResult object for aggregating test results from
            the execution of tests.
        controller_configs: dict, controller configs provided by the user via
            test bed config.
        current_test_info: RuntimeTestInfo, runtime information on the test
            currently being executed.
        root_output_path: string, storage path for output files associated with
            the entire test run. A test run can have multiple test class
            executions. This includes the test summary and Mobly log files.
        log_path: string, storage path for files specific to a single test
            class execution.
        test_bed_name: [Deprecated, use 'testbed_name' instead]
            string, the name of the test bed used by a test run.
        testbed_name: string, the name of the test bed used by a test run.
        user_params: dict, custom parameters from user, to be consumed by
            the test logic.
    """

    TAG = None

    def __init__(self, configs):
        """Constructor of BaseTestClass.

        The constructor takes a config_parser.TestRunConfig object and which has
        all the information needed to execute this test class, like log_path
        and controller configurations. For details, see the definition of class
        config_parser.TestRunConfig.

        Args:
            configs: A config_parser.TestRunConfig object.
        """
        self.tests = []
        class_identifier = self.__class__.__name__
        if configs.test_class_name_suffix:
            class_identifier = '%s_%s' % (class_identifier,
                                          configs.test_class_name_suffix)
        if self.TAG is None:
            self.TAG = class_identifier
        # Set params.
        self.root_output_path = configs.log_path
        self.log_path = os.path.join(self.root_output_path, class_identifier)
        utils.create_dir(self.log_path)
        # Deprecated, use 'testbed_name'
        self.test_bed_name = configs.test_bed_name
        self.testbed_name = configs.testbed_name
        self.user_params = configs.user_params
        self.results = records.TestResult()
        self.summary_writer = configs.summary_writer
        self._generated_test_table = collections.OrderedDict()
        self._controller_manager = controller_manager.ControllerManager(
            class_name=self.TAG, controller_configs=configs.controller_configs)
        self.controller_configs = self._controller_manager.controller_configs

    def unpack_userparams(self,
                          req_param_names=None,
                          opt_param_names=None,
                          **kwargs):
        """An optional function that unpacks user defined parameters into
        individual variables.

        After unpacking, the params can be directly accessed with self.xxx.

        If a required param is not provided, an exception is raised. If an
        optional param is not provided, a warning line will be logged.

        To provide a param, add it in the config file or pass it in as a kwarg.
        If a param appears in both the config file and kwarg, the value in the
        config file is used.

        User params from the config file can also be directly accessed in
        self.user_params.

        Args:
            req_param_names: A list of names of the required user params.
            opt_param_names: A list of names of the optional user params.
            **kwargs: Arguments that provide default values.
                e.g. unpack_userparams(required_list, opt_list, arg_a='hello')
                self.arg_a will be 'hello' unless it is specified again in
                required_list or opt_list.

        Raises:
            Error: A required user params is not provided.
        """
        req_param_names = req_param_names or []
        opt_param_names = opt_param_names or []
        for k, v in kwargs.items():
            if k in self.user_params:
                v = self.user_params[k]
            setattr(self, k, v)
        for name in req_param_names:
            if hasattr(self, name):
                continue
            if name not in self.user_params:
                raise Error('Missing required user param "%s" in test '
                            'configuration.' % name)
            setattr(self, name, self.user_params[name])
        for name in opt_param_names:
            if hasattr(self, name):
                continue
            if name in self.user_params:
                setattr(self, name, self.user_params[name])
            else:
                logging.warning(
                    'Missing optional user param "%s" in '
                    'configuration, continue.', name)

    def register_controller(self, module, required=True, min_number=1):
        """Loads a controller module and returns its loaded devices.

        A Mobly controller module is a Python lib that can be used to control
        a device, service, or equipment. To be Mobly compatible, a controller
        module needs to have the following members:

        .. code-block:: python

            def create(configs):
                [Required] Creates controller objects from configurations.

                Args:
                    configs: A list of serialized data like string/dict. Each
                        element of the list is a configuration for a controller
                        object.

                Returns:
                    A list of objects.

            def destroy(objects):
                [Required] Destroys controller objects created by the create
                function. Each controller object shall be properly cleaned up
                and all the resources held should be released, e.g. memory
                allocation, sockets, file handlers etc.

                Args:
                    A list of controller objects created by the create function.

            def get_info(objects):
                [Optional] Gets info from the controller objects used in a test
                run. The info will be included in test_summary.yaml under
                the key 'ControllerInfo'. Such information could include unique
                ID, version, or anything that could be useful for describing the
                test bed and debugging.

                Args:
                    objects: A list of controller objects created by the create
                        function.

                Returns:
                    A list of json serializable objects: each represents the
                        info of a controller object. The order of the info
                        object should follow that of the input objects.

        Registering a controller module declares a test class's dependency the
        controller. If the module config exists and the module matches the
        controller interface, controller objects will be instantiated with
        corresponding configs. The module should be imported first.

        Args:
            module: A module that follows the controller module interface.
            required: A bool. If True, failing to register the specified
                controller module raises exceptions. If False, the objects
                failed to instantiate will be skipped.
            min_number: An integer that is the minimum number of controller
                objects to be created. Default is one, since you should not
                register a controller module without expecting at least one
                object.

        Returns:
            A list of controller objects instantiated from controller_module, or
            None if no config existed for this controller and it was not a
            required controller.

        Raises:
            ControllerError:
                * The controller module has already been registered.
                * The actual number of objects instantiated is less than the
                * `min_number`.
                * `required` is True and no corresponding config can be found.
                * Any other error occurred in the registration process.
        """
        return self._controller_manager.register_controller(
            module, required, min_number)

    def _record_controller_info(self):
        # Collect controller information and write to test result.
        for record in self._controller_manager.get_controller_info_records():
            self.results.add_controller_info_record(record)
            self.summary_writer.dump(
                record.to_dict(), records.TestSummaryEntryType.CONTROLLER_INFO)

    def _setup_generated_tests(self):
        """Proxy function to guarantee the base implementation of
        setup_generated_tests is called.

        Returns:
            True if setup is successful, False otherwise.
        """
        stage_name = STAGE_NAME_SETUP_GENERATED_TESTS
        record = records.TestResultRecord(stage_name, self.TAG)
        record.test_begin()
        self.current_test_info = runtime_test_info.RuntimeTestInfo(
            stage_name, self.log_path, record)
        try:
            with self._log_test_stage(stage_name):
                self.setup_generated_tests()
                return True
        except Exception as e:
            logging.exception('%s failed for %s.', stage_name, self.TAG)
            record.test_error(e)
            self.results.add_class_error(record)
            self.summary_writer.dump(record.to_dict(),
                                     records.TestSummaryEntryType.RECORD)
            return False

    def setup_generated_tests(self):
        """Preprocesses that need to be done before setup_class.

        This phase is used to do pre-test processes like generating tests.
        This is the only place `self.generate_tests` should be called.

        If this function throws an error, the test class will be marked failure
        and the "Requested" field will be 0 because the number of tests
        requested is unknown at this point.
        """

    def _setup_class(self):
        """Proxy function to guarantee the base implementation of setup_class
        is called.

        Returns:
            If `self.results` is returned instead of None, this means something
            has gone wrong, and the rest of the test class should not execute.
        """
        # Setup for the class.
        class_record = records.TestResultRecord(STAGE_NAME_SETUP_CLASS,
                                                self.TAG)
        class_record.test_begin()
        self.current_test_info = runtime_test_info.RuntimeTestInfo(
            STAGE_NAME_SETUP_CLASS, self.log_path, class_record)
        expects.recorder.reset_internal_states(class_record)
        try:
            with self._log_test_stage(STAGE_NAME_SETUP_CLASS):
                self.setup_class()
        except signals.TestAbortSignal:
            # Throw abort signals to outer try block for handling.
            raise
        except Exception as e:
            # Setup class failed for unknown reasons.
            # Fail the class and skip all tests.
            logging.exception('Error in %s#setup_class.', self.TAG)
            class_record.test_error(e)
            self.results.add_class_error(class_record)
            self._exec_procedure_func(self._on_fail, class_record)
            class_record.update_record()
            self.summary_writer.dump(class_record.to_dict(),
                                     records.TestSummaryEntryType.RECORD)
            self._skip_remaining_tests(e)
            return self.results
        if expects.recorder.has_error:
            self._exec_procedure_func(self._on_fail, class_record)
            class_record.test_error()
            class_record.update_record()
            self.summary_writer.dump(class_record.to_dict(),
                                     records.TestSummaryEntryType.RECORD)
            self.results.add_class_error(class_record)
            self._skip_remaining_tests(
                class_record.termination_signal.exception)
            return self.results

    def setup_class(self):
        """Setup function that will be called before executing any test in the
        class.

        To signal setup failure, use asserts or raise your own exception.

        Errors raised from `setup_class` will trigger `on_fail`.

        Implementation is optional.
        """

    def _teardown_class(self):
        """Proxy function to guarantee the base implementation of
        teardown_class is called.
        """
        stage_name = STAGE_NAME_TEARDOWN_CLASS
        record = records.TestResultRecord(stage_name, self.TAG)
        record.test_begin()
        self.current_test_info = runtime_test_info.RuntimeTestInfo(
            stage_name, self.log_path, record)
        expects.recorder.reset_internal_states(record)
        try:
            with self._log_test_stage(stage_name):
                self.teardown_class()
        except signals.TestAbortAll as e:
            setattr(e, 'results', self.results)
            raise
        except Exception as e:
            logging.exception('Error encountered in %s.', stage_name)
            record.test_error(e)
            record.update_record()
            self.results.add_class_error(record)
            self.summary_writer.dump(record.to_dict(),
                                     records.TestSummaryEntryType.RECORD)
        else:
            if expects.recorder.has_error:
                record.update_record()
                self.results.add_class_error(record)
                self.summary_writer.dump(record.to_dict(),
                                         records.TestSummaryEntryType.RECORD)
        finally:
            self._clean_up()

    def teardown_class(self):
        """Teardown function that will be called after all the selected tests in
        the test class have been executed.

        Errors raised from `teardown_class` do not trigger `on_fail`.

        Implementation is optional.
        """

    @contextlib.contextmanager
    def _log_test_stage(self, stage_name):
        """Logs the begin and end of a test stage.

        This context adds two log lines meant for clarifying the boundary of
        each execution stage in Mobly log.

        Args:
            stage_name: string, name of the stage to log.
        """
        parent_token = self.current_test_info.name
        # If the name of the stage is the same as the test name, in which case
        # the stage is class-level instead of test-level, use the class's
        # reference tag as the parent token instead.
        if parent_token == stage_name:
            parent_token = self.TAG
        logging.debug(
            TEST_STAGE_BEGIN_LOG_TEMPLATE.format(parent_token=parent_token,
                                                 child_token=stage_name))
        try:
            yield
        finally:
            logging.debug(
                TEST_STAGE_END_LOG_TEMPLATE.format(parent_token=parent_token,
                                                   child_token=stage_name))

    def _setup_test(self, test_name):
        """Proxy function to guarantee the base implementation of setup_test is
        called.
        """
        with self._log_test_stage(STAGE_NAME_SETUP_TEST):
            self.setup_test()

    def setup_test(self):
        """Setup function that will be called every time before executing each
        test method in the test class.

        To signal setup failure, use asserts or raise your own exception.

        Implementation is optional.
        """

    def _teardown_test(self, test_name):
        """Proxy function to guarantee the base implementation of teardown_test
        is called.
        """
        with self._log_test_stage(STAGE_NAME_TEARDOWN_TEST):
            self.teardown_test()

    def teardown_test(self):
        """Teardown function that will be called every time a test method has
        been executed.

        Implementation is optional.
        """

    def _on_fail(self, record):
        """Proxy function to guarantee the base implementation of on_fail is
        called.

        Args:
            record: records.TestResultRecord, a copy of the test record for
                    this test, containing all information of the test execution
                    including exception objects.
        """
        self.on_fail(record)

    def on_fail(self, record):
        """A function that is executed upon a test failure.

        User implementation is optional.

        Args:
            record: records.TestResultRecord, a copy of the test record for
                this test, containing all information of the test execution
                including exception objects.
        """

    def _on_pass(self, record):
        """Proxy function to guarantee the base implementation of on_pass is
        called.

        Args:
            record: records.TestResultRecord, a copy of the test record for
                this test, containing all information of the test execution
                including exception objects.
        """
        msg = record.details
        if msg:
            logging.info(msg)
        self.on_pass(record)

    def on_pass(self, record):
        """A function that is executed upon a test passing.

        Implementation is optional.

        Args:
            record: records.TestResultRecord, a copy of the test record for
                this test, containing all information of the test execution
                including exception objects.
        """

    def _on_skip(self, record):
        """Proxy function to guarantee the base implementation of on_skip is
        called.

        Args:
            record: records.TestResultRecord, a copy of the test record for
                this test, containing all information of the test execution
                including exception objects.
        """
        logging.info('Reason to skip: %s', record.details)
        logging.info(RESULT_LINE_TEMPLATE, record.test_name, record.result)
        self.on_skip(record)

    def on_skip(self, record):
        """A function that is executed upon a test being skipped.

        Implementation is optional.

        Args:
            record: records.TestResultRecord, a copy of the test record for
                this test, containing all information of the test execution
                including exception objects.
        """

    def _exec_procedure_func(self, func, tr_record):
        """Executes a procedure function like on_pass, on_fail etc.

        This function will alter the 'Result' of the test's record if
        exceptions happened when executing the procedure function, but
        prevents procedure functions from altering test records themselves
        by only passing in a copy.

        This will let signals.TestAbortAll through so abort_all works in all
        procedure functions.

        Args:
            func: The procedure function to be executed.
            tr_record: The TestResultRecord object associated with the test
                executed.
        """
        func_name = func.__name__
        procedure_name = func_name[1:] if func_name[0] == '_' else func_name
        with self._log_test_stage(procedure_name):
            try:
                # Pass a copy of the record instead of the actual object so that it
                # will not be modified.
                func(copy.deepcopy(tr_record))
            except signals.TestAbortSignal:
                raise
            except Exception as e:
                logging.exception(
                    'Exception happened when executing %s for %s.',
                    procedure_name, self.current_test_info.name)
                tr_record.add_error(procedure_name, e)

    def record_data(self, content):
        """Record an entry in test summary file.

        Sometimes additional data need to be recorded in summary file for
        debugging or post-test analysis.

        Each call adds a new entry to the summary file, with no guarantee of
        its position among the summary file entries.

        The content should be a dict. If absent, timestamp field is added for
        ease of parsing later.

        Args:
            content: dict, the data to add to summary file.
        """
        if 'timestamp' not in content:
            content['timestamp'] = utils.get_current_epoch_time()
        self.summary_writer.dump(content,
                                 records.TestSummaryEntryType.USER_DATA)

    def exec_one_test(self, test_name, test_method):
        """Executes one test and update test results.

        Executes setup_test, the test method, and teardown_test; then creates a
        records.TestResultRecord object with the execution information and adds
        the record to the test class's test results.

        Args:
            test_name: string, Name of the test.
            test_method: function, The test method to execute.
        """
        tr_record = records.TestResultRecord(test_name, self.TAG)
        tr_record.uid = getattr(test_method, 'uid', None)
        tr_record.test_begin()
        self.current_test_info = runtime_test_info.RuntimeTestInfo(
            test_name, self.log_path, tr_record)
        expects.recorder.reset_internal_states(tr_record)
        logging.info('%s %s', TEST_CASE_TOKEN, test_name)
        # Did teardown_test throw an error.
        teardown_test_failed = False
        try:
            try:
                try:
                    self._setup_test(test_name)
                except signals.TestFailure as e:
                    raise_with_traceback(signals.TestError(
                        e.details, e.extras))
                test_method()
            except (signals.TestPass, signals.TestAbortSignal):
                raise
            except Exception:
                logging.exception('Exception occurred in %s.',
                                  self.current_test_info.name)
                raise
            finally:
                before_count = expects.recorder.error_count
                try:
                    self._teardown_test(test_name)
                except signals.TestAbortSignal:
                    raise
                except Exception as e:
                    logging.exception(e)
                    tr_record.test_error()
                    tr_record.add_error(STAGE_NAME_TEARDOWN_TEST, e)
                    teardown_test_failed = True
                else:
                    # Check if anything failed by `expects`.
                    if before_count < expects.recorder.error_count:
                        teardown_test_failed = True
        except (signals.TestFailure, AssertionError) as e:
            tr_record.test_fail(e)
        except signals.TestSkip as e:
            # Test skipped.
            tr_record.test_skip(e)
        except signals.TestAbortSignal as e:
            # Abort signals, pass along.
            tr_record.test_fail(e)
            raise
        except signals.TestPass as e:
            # Explicit test pass.
            tr_record.test_pass(e)
        except Exception as e:
            # Exception happened during test.
            tr_record.test_error(e)
        else:
            # No exception is thrown from test and teardown, if `expects` has
            # error, the test should fail with the first error in `expects`.
            if expects.recorder.has_error and not teardown_test_failed:
                tr_record.test_fail()
            # Otherwise the test passed.
            elif not teardown_test_failed:
                tr_record.test_pass()
        finally:
            tr_record.update_record()
            try:
                if tr_record.result in (
                        records.TestResultEnums.TEST_RESULT_ERROR,
                        records.TestResultEnums.TEST_RESULT_FAIL):
                    self._exec_procedure_func(self._on_fail, tr_record)
                elif tr_record.result == records.TestResultEnums.TEST_RESULT_PASS:
                    self._exec_procedure_func(self._on_pass, tr_record)
                elif tr_record.result == records.TestResultEnums.TEST_RESULT_SKIP:
                    self._exec_procedure_func(self._on_skip, tr_record)
            finally:
                logging.info(RESULT_LINE_TEMPLATE, tr_record.test_name,
                             tr_record.result)
                self.results.add_record(tr_record)
                self.summary_writer.dump(tr_record.to_dict(),
                                         records.TestSummaryEntryType.RECORD)
                self.current_test_info = None

    def _assert_function_name_in_stack(self, expected_func_name):
        """Asserts that the current stack contains the given function name."""
        current_frame = inspect.currentframe()
        caller_frames = inspect.getouterframes(current_frame, 2)
        for caller_frame in caller_frames[2:]:
            if caller_frame[3] == expected_func_name:
                return
        raise Error('"%s" cannot be called outside of %s' %
                    (caller_frames[1][3], expected_func_name))

    def generate_tests(self, test_logic, name_func, arg_sets, uid_func=None):
        """Generates tests in the test class.

        This function has to be called inside a test class's
        `self.setup_generated_tests` function.

        Generated tests are not written down as methods, but as a list of
        parameter sets. This way we reduce code repetition and improve test
        scalability.

        Users can provide an optional function to specify the UID of each test.
        Not all generated tests are required to have UID.

        Args:
            test_logic: function, the common logic shared by all the generated
                tests.
            name_func: function, generate a test name according to a set of
                test arguments. This function should take the same arguments as
                the test logic function.
            arg_sets: a list of tuples, each tuple is a set of arguments to be
                passed to the test logic function and name function.
            uid_func: function, an optional function that takes the same
                arguments as the test logic function and returns a string that
                is the corresponding UID.
        """
        self._assert_function_name_in_stack(STAGE_NAME_SETUP_GENERATED_TESTS)
        root_msg = 'During test generation of "%s":' % test_logic.__name__
        for args in arg_sets:
            test_name = name_func(*args)
            if test_name in self.get_existing_test_names():
                raise Error(
                    '%s Test name "%s" already exists, cannot be duplicated!' %
                    (root_msg, test_name))
            test_func = functools.partial(test_logic, *args)
            if uid_func is not None:
                uid = uid_func(*args)
                if uid is None:
                    logging.warning('%s UID for arg set %s is None.', root_msg,
                                    args)
                else:
                    setattr(test_func, 'uid', uid)
            self._generated_test_table[test_name] = test_func

    def _safe_exec_func(self, func, *args):
        """Executes a function with exception safeguard.

        This will let signals.TestAbortAll through so abort_all works in all
        procedure functions.

        Args:
            func: Function to be executed.
            args: Arguments to be passed to the function.

        Returns:
            Whatever the function returns.
        """
        try:
            return func(*args)
        except signals.TestAbortAll:
            raise
        except:
            logging.exception('Exception happened when executing %s in %s.',
                              func.__name__, self.TAG)

    def get_existing_test_names(self):
        """Gets the names of existing tests in the class.

        A method in the class is considered a test if its name starts with
        'test_*'.

        Note this only gets the names of tests that already exist. If
        `setup_generated_test` has not happened when this was called, the
        generated tests won't be listed.

        Returns:
            A list of strings, each is a test method name.
        """
        test_names = []
        for name, _ in inspect.getmembers(self, callable):
            if name.startswith('test_'):
                test_names.append(name)
        return test_names + list(self._generated_test_table.keys())

    def _get_test_methods(self, test_names):
        """Resolves test method names to bound test methods.

        Args:
            test_names: A list of strings, each string is a test method name.

        Returns:
            A list of tuples of (string, function). String is the test method
            name, function is the actual python method implementing its logic.

        Raises:
            Error: The test name does not follow naming convention 'test_*'.
                This can only be caused by user input.
        """
        test_methods = []
        for test_name in test_names:
            if not test_name.startswith('test_'):
                raise Error('Test method name %s does not follow naming '
                            'convention test_*, abort.' % test_name)
            if hasattr(self, test_name):
                test_method = getattr(self, test_name)
            elif test_name in self._generated_test_table:
                test_method = self._generated_test_table[test_name]
            else:
                raise Error('%s does not have test method %s.' %
                            (self.TAG, test_name))
            test_methods.append((test_name, test_method))
        return test_methods

    def _skip_remaining_tests(self, exception):
        """Marks any requested test that has not been executed in a class as
        skipped.

        This is useful for handling abort class signal.

        Args:
            exception: The exception object that was thrown to trigger the
                skip.
        """
        for test_name in self.results.requested:
            if not self.results.is_test_executed(test_name):
                test_record = records.TestResultRecord(test_name, self.TAG)
                test_record.test_skip(exception)
                self.results.add_record(test_record)
                self.summary_writer.dump(test_record.to_dict(),
                                         records.TestSummaryEntryType.RECORD)

    def run(self, test_names=None):
        """Runs tests within a test class.

        One of these test method lists will be executed, shown here in priority
        order:

        1. The test_names list, which is passed from cmd line. Invalid names
           are guarded by cmd line arg parsing.
        2. The self.tests list defined in test class. Invalid names are
           ignored.
        3. All function that matches test method naming convention in the test
           class.

        Args:
            test_names: A list of string that are test method names requested in
                cmd line.

        Returns:
            The test results object of this class.
        """
        logging.log_path = self.log_path
        # Executes pre-setup procedures, like generating test methods.
        if not self._setup_generated_tests():
            return self.results
        logging.info('==========> %s <==========', self.TAG)
        # Devise the actual test methods to run in the test class.
        if not test_names:
            if self.tests:
                # Specified by run list in class.
                test_names = list(self.tests)
            else:
                # No test method specified by user, execute all in test class.
                test_names = self.get_existing_test_names()
        self.results.requested = test_names
        self.summary_writer.dump(self.results.requested_test_names_dict(),
                                 records.TestSummaryEntryType.TEST_NAME_LIST)
        tests = self._get_test_methods(test_names)
        try:
            setup_class_result = self._setup_class()
            if setup_class_result:
                return setup_class_result
            # Run tests in order.
            for test_name, test_method in tests:
                self.exec_one_test(test_name, test_method)
            return self.results
        except signals.TestAbortClass as e:
            e.details = 'Test class aborted due to: %s' % e.details
            self._skip_remaining_tests(e)
            return self.results
        except signals.TestAbortAll as e:
            e.details = 'All remaining tests aborted due to: %s' % e.details
            self._skip_remaining_tests(e)
            # Piggy-back test results on this exception object so we don't lose
            # results from this test class.
            setattr(e, 'results', self.results)
            raise e
        finally:
            self._teardown_class()
            logging.info('Summary for test class %s: %s', self.TAG,
                         self.results.summary_str())

    def _clean_up(self):
        """The final stage of a test class execution."""
        stage_name = STAGE_NAME_CLEAN_UP
        record = records.TestResultRecord(stage_name, self.TAG)
        record.test_begin()
        self.current_test_info = runtime_test_info.RuntimeTestInfo(
            stage_name, self.log_path, record)
        expects.recorder.reset_internal_states(record)
        with self._log_test_stage(stage_name):
            # Write controller info and summary to summary file.
            self._record_controller_info()
            self._controller_manager.unregister_controllers()
            if expects.recorder.has_error:
                record.test_error()
                record.update_record()
                self.results.add_class_error(record)
                self.summary_writer.dump(record.to_dict(),
                                         records.TestSummaryEntryType.RECORD)
