# 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 copy
import functools
import io
import os
import mock
import shutil
import tempfile
import unittest
import yaml

from mobly import asserts
from mobly import base_test
from mobly import config_parser
from mobly import expects
from mobly import records
from mobly import signals

from tests.lib import utils
from tests.lib import mock_controller
from tests.lib import mock_second_controller

MSG_EXPECTED_EXCEPTION = "This is an expected exception."
MSG_EXPECTED_TEST_FAILURE = "This is an expected test failure."
MSG_UNEXPECTED_EXCEPTION = "Unexpected exception!"

MOCK_EXTRA = {"key": "value", "answer_to_everything": 42}


def never_call():
  raise Exception(MSG_UNEXPECTED_EXCEPTION)


class SomeError(Exception):
  """A custom exception class used for tests in this module."""


class BaseTestTest(unittest.TestCase):

  def setUp(self):
    self.tmp_dir = tempfile.mkdtemp()
    self.mock_test_cls_configs = config_parser.TestRunConfig()
    self.summary_file = os.path.join(self.tmp_dir, 'summary.yaml')
    self.mock_test_cls_configs.summary_writer = records.TestSummaryWriter(
        self.summary_file)
    self.mock_test_cls_configs.controller_configs = {}
    self.mock_test_cls_configs.log_path = self.tmp_dir
    self.mock_test_cls_configs.user_params = {"some_param": "hahaha"}
    self.mock_test_cls_configs.reporter = mock.MagicMock()
    self.mock_test_name = "test_something"

  def tearDown(self):
    shutil.rmtree(self.tmp_dir)

  def test_paths(self):
    '''Checks the output paths set in `BaseTestClass`.'''
    path_checker = mock.MagicMock()

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        path_checker.log_path = self.log_path
        path_checker.root_output_path = self.root_output_path

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_func"])
    self.assertEqual(path_checker.root_output_path, self.tmp_dir)
    self.assertTrue(os.path.exists(path_checker.root_output_path))
    expected_log_path = os.path.join(self.tmp_dir, 'MockBaseTest')
    self.assertEqual(path_checker.log_path, expected_log_path)
    self.assertTrue(os.path.exists(path_checker.log_path))

  def test_current_test_name(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        asserts.assert_true(self.current_test_info.name == "test_func",
                            ("Got "
                             "unexpected test name %s.") %
                            self.current_test_info.name)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_func"])
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertIsNone(actual_record.details)
    self.assertIsNone(actual_record.extras)

  def test_current_test_info(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        asserts.assert_true(
            self.current_test_info.name == 'test_func',
            'Got unexpected test name %s.' % self.current_test_info.name)
        output_path = self.current_test_info.output_path
        asserts.assert_true(os.path.exists(output_path),
                            'test output path missing')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=['test_func'])
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.test_name, 'test_func')
    self.assertIsNone(actual_record.details)
    self.assertIsNone(actual_record.extras)

  def test_current_test_info_in_setup_class(self):

    class MockBaseTest(base_test.BaseTestClass):

      def setup_class(self):
        asserts.assert_true(
            self.current_test_info.name == 'setup_class',
            'Got unexpected test name %s.' % self.current_test_info.name)
        output_path = self.current_test_info.output_path
        asserts.assert_true(os.path.exists(output_path),
                            'test output path missing')
        raise Exception(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, 'setup_class')
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)

  def test_self_tests_list(self):

    class MockBaseTest(base_test.BaseTestClass):

      def __init__(self, controllers):
        super().__init__(controllers)
        self.tests = ("test_something",)

      def test_something(self):
        pass

      def test_never(self):
        # This should not execute it's not on default test list.
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.test_name, "test_something")

  def test_self_tests_list_fail_by_convention(self):

    class MockBaseTest(base_test.BaseTestClass):

      def __init__(self, controllers):
        super().__init__(controllers)
        self.tests = ("not_a_test_something",)

      def not_a_test_something(self):
        pass

      def test_never(self):
        # This should not execute it's not on default test list.
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    expected_msg = (r'Test method name not_a_test_something does not follow '
                    r'naming convention test_\*, abort.')
    with self.assertRaisesRegex(base_test.Error, expected_msg):
      bt_cls.run()

  def test_cli_test_selection_override_self_tests_list(self):

    class MockBaseTest(base_test.BaseTestClass):

      def __init__(self, controllers):
        super().__init__(controllers)
        self.tests = ("test_never",)

      def test_something(self):
        pass

      def test_never(self):
        # This should not execute it's not selected by cmd line input.
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_something"])
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.test_name, "test_something")

  def test_cli_test_selection_fail_by_convention(self):

    class MockBaseTest(base_test.BaseTestClass):

      def __init__(self, controllers):
        super().__init__(controllers)
        self.tests = ("not_a_test_something",)

      def not_a_test_something(self):
        pass

      def test_never(self):
        # This should not execute it's not selected by cmd line input.
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    expected_msg = (r'Test method name not_a_test_something does not follow '
                    r'naming convention test_\*, abort.')
    with self.assertRaisesRegex(base_test.Error, expected_msg):
      bt_cls.run(test_names=["not_a_test_something"])

  def test_default_execution_of_all_tests(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_something(self):
        pass

      def not_a_test(self):
        # This should not execute its name doesn't follow test method
        # naming convention.
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.test_name, "test_something")

  def test_default_execution_skip_noncallable_tests(self):
    mock_decorated = mock.MagicMock()
    mock_undecorated = mock.MagicMock()

    class TestDecorator:

      def __init__(self, func):
        self.func = func

      def __call__(self, *args, **kwargs):
        return self.func(*args, **kwargs)

      def __get__(self, instance, owner):
        return functools.partial(self.__call__, instance)

    class MockBaseTest(base_test.BaseTestClass):

      def __init__(self, controllers):
        super().__init__(controllers)
        self.test_noncallable = None

      @TestDecorator
      def test_decorated(self):
        mock_decorated('test_decorated')

      def test_undecorated(self):
        mock_undecorated('test_undecorated')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    self.assertNotIn('test_noncallable',
                     [test.test_name for test in bt_cls.results.executed])
    mock_decorated.assert_called_once_with('test_decorated')
    mock_undecorated.assert_called_once_with('test_undecorated')

  def test_missing_requested_test_func(self):

    class MockBaseTest(base_test.BaseTestClass):
      pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    expected_msg = ".* does not have test method test_something"
    with self.assertRaisesRegex(base_test.Error, expected_msg):
      bt_cls.run(test_names=["test_something"])
    self.assertFalse(bt_cls.results.executed)

  def test_setup_class_fail_by_exception(self):
    teardown_class_call_check = mock.MagicMock()
    on_fail_call_check = mock.MagicMock()

    class MockBaseTest(base_test.BaseTestClass):

      def setup_class(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)

      def test_something(self):
        # This should not execute because setup_class failed.
        never_call()

      def test_something2(self):
        # This should not execute because setup_class failed.
        never_call()

      def teardown_class(self):
        # This should execute because the setup_class failure should
        # have already been recorded.
        if not self.results.is_all_pass:
          teardown_class_call_check("heehee")

      def on_fail(self, record):
        on_fail_call_check("haha")

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    skipped_record = bt_cls.results.skipped[0]
    self.assertIsNone(skipped_record.begin_time)
    self.assertIsNone(skipped_record.end_time)
    utils.validate_test_result(bt_cls.results)
    self.assertEqual(actual_record.test_name, "setup_class")
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)
    expected_summary = ("Error 1, Executed 0, Failed 0, Passed 0, "
                        "Requested 2, Skipped 2")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)
    teardown_class_call_check.assert_called_once_with("heehee")
    on_fail_call_check.assert_called_once_with("haha")

  def test_teardown_class_fail_by_exception(self):
    mock_test_config = self.mock_test_cls_configs.copy()
    mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
    mock_ctrlr_2_config_name = mock_second_controller.MOBLY_CONTROLLER_CONFIG_NAME
    my_config = [{'serial': 'xxxx', 'magic': 'Magic'}]
    mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
    mock_test_config.controller_configs[mock_ctrlr_2_config_name] = copy.copy(
        my_config)

    class MockBaseTest(base_test.BaseTestClass):

      def setup_class(self):
        self.register_controller(mock_controller)

      def test_something(self):
        pass

      def teardown_class(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(mock_test_config)
    bt_cls.run()
    test_record = bt_cls.results.passed[0]
    class_record = bt_cls.results.error[0]
    self.assertFalse(bt_cls.results.is_all_pass)
    self.assertEqual(class_record.test_name, 'teardown_class')
    self.assertEqual(class_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNotNone(class_record.begin_time)
    self.assertIsNotNone(class_record.end_time)
    self.assertIsNone(class_record.extras)
    expected_summary = ('Error 1, Executed 1, Failed 0, Passed 1, '
                        'Requested 1, Skipped 0')
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)
    # Verify the controller info is recorded correctly.
    info = bt_cls.results.controller_info[0]
    self.assertEqual(info.test_class, 'MockBaseTest')
    self.assertEqual(info.controller_name, 'MagicDevice')
    self.assertEqual(info.controller_info, [{'MyMagic': {'magic': 'Magic'}}])

  def test_teardown_class_raise_abort_all(self):
    mock_test_config = self.mock_test_cls_configs.copy()
    mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
    mock_ctrlr_2_config_name = mock_second_controller.MOBLY_CONTROLLER_CONFIG_NAME
    my_config = [{'serial': 'xxxx', 'magic': 'Magic'}]
    mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
    mock_test_config.controller_configs[mock_ctrlr_2_config_name] = copy.copy(
        my_config)

    class MockBaseTest(base_test.BaseTestClass):

      def setup_class(self):
        self.register_controller(mock_controller)

      def test_something(self):
        pass

      def teardown_class(self):
        raise asserts.abort_all(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(mock_test_config)
    with self.assertRaisesRegex(signals.TestAbortAll, MSG_EXPECTED_EXCEPTION):
      bt_cls.run()
    test_record = bt_cls.results.passed[0]
    self.assertTrue(bt_cls.results.is_all_pass)
    expected_summary = ('Error 0, Executed 1, Failed 0, Passed 1, '
                        'Requested 1, Skipped 0')
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)
    # Verify the controller info is recorded correctly.
    info = bt_cls.results.controller_info[0]
    self.assertEqual(info.test_class, 'MockBaseTest')
    self.assertEqual(info.controller_name, 'MagicDevice')
    self.assertEqual(info.controller_info, [{'MyMagic': {'magic': 'Magic'}}])

  def test_setup_test_fail_by_exception(self):
    mock_on_fail = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def on_fail(self, *args):
        mock_on_fail('on_fail')

      def setup_test(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)

      def test_something(self):
        # This should not execute because setup_test failed.
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_something"])
    mock_on_fail.assert_called_once_with('on_fail')
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIn(
        'in setup_test\n    '
        'raise Exception(MSG_EXPECTED_EXCEPTION)\n'
        'Exception: This is an expected exception.\n', actual_record.stacktrace)
    self.assertIsNone(actual_record.extras)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_setup_test_fail_by_test_signal(self):

    class MockBaseTest(base_test.BaseTestClass):

      def setup_test(self):
        raise signals.TestFailure(MSG_EXPECTED_EXCEPTION)

      def test_something(self):
        # This should not execute because setup_test failed.
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_something"])
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    # Make sure the full stacktrace of `setup_test` is preserved.
    self.assertTrue('self.setup_test()' in actual_record.stacktrace)
    self.assertIsNone(actual_record.extras)
    self.assertTrue(actual_record.end_time)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_teardown_test_assert_fail(self):

    class MockBaseTest(base_test.BaseTestClass):

      def teardown_test(self):
        asserts.fail(MSG_EXPECTED_EXCEPTION)

      def test_something(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertTrue(actual_record.end_time)
    self.assertIsNone(actual_record.extras)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_teardown_test_raise_exception(self):

    class MockBaseTest(base_test.BaseTestClass):

      def teardown_test(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)

      def test_something(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)
    self.assertFalse(actual_record.extra_errors)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_teardown_test_executed_if_test_pass(self):
    my_mock = mock.MagicMock()

    class MockBaseTest(base_test.BaseTestClass):

      def teardown_test(self):
        my_mock("teardown_test")

      def test_something(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.passed[0]
    my_mock.assert_called_once_with("teardown_test")
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertIsNone(actual_record.details)
    self.assertIsNone(actual_record.extras)
    self.assertTrue(actual_record.end_time)
    expected_summary = ("Error 0, Executed 1, Failed 0, Passed 1, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_teardown_test_executed_if_setup_test_fails(self):
    my_mock = mock.MagicMock()

    class MockBaseTest(base_test.BaseTestClass):

      def setup_test(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)

      def teardown_test(self):
        my_mock("teardown_test")

      def test_something(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    my_mock.assert_called_once_with("teardown_test")
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)
    self.assertTrue(actual_record.end_time)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_teardown_test_executed_if_test_fails(self):
    my_mock = mock.MagicMock()

    class MockBaseTest(base_test.BaseTestClass):

      def teardown_test(self):
        my_mock("teardown_test")

      def on_pass(self, record):
        never_call()

      def test_something(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    my_mock.assert_called_once_with("teardown_test")
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_on_fail_executed_if_teardown_test_fails(self):
    my_mock = mock.MagicMock()

    class MockBaseTest(base_test.BaseTestClass):

      def on_fail(self, record):
        my_mock("on_fail")

      def on_pass(self, record):
        never_call()

      def teardown_test(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)

      def test_something(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    my_mock.assert_called_once_with('on_fail')
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_on_fail_executed_if_test_fails(self):
    my_mock = mock.MagicMock()

    class MockBaseTest(base_test.BaseTestClass):

      def on_fail(self, record):
        assert self.current_test_info.name == 'test_something'
        my_mock("on_fail")

      def on_pass(self, record):
        never_call()

      def test_something(self):
        asserts.assert_true(False, MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    my_mock.assert_called_once_with("on_fail")
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)
    expected_summary = ("Error 0, Executed 1, Failed 1, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_procedure_function_gets_correct_record(self):
    on_fail_mock = mock.MagicMock()

    class MockBaseTest(base_test.BaseTestClass):

      def on_fail(self, record):
        on_fail_mock.record = record

      def test_something(self):
        asserts.fail(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, 'test_something')
    self.assertEqual(on_fail_mock.record.test_name, actual_record.test_name)
    self.assertEqual(on_fail_mock.record.begin_time, actual_record.begin_time)
    self.assertEqual(on_fail_mock.record.end_time, actual_record.end_time)
    self.assertEqual(on_fail_mock.record.stacktrace, actual_record.stacktrace)
    self.assertEqual(on_fail_mock.record.extras, actual_record.extras)
    self.assertEqual(on_fail_mock.record.extra_errors,
                     actual_record.extra_errors)
    # But they are not the same object.
    self.assertIsNot(on_fail_mock.record, actual_record)

  def test_on_fail_cannot_modify_original_record(self):

    class MockBaseTest(base_test.BaseTestClass):

      def on_fail(self, record):
        record.test_name = 'blah'

      def test_something(self):
        asserts.assert_true(False, MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, 'test_something')

  def test_on_fail_executed_if_both_test_and_teardown_test_fails(self):
    on_fail_mock = mock.MagicMock()

    class MockBaseTest(base_test.BaseTestClass):

      def on_fail(self, record):
        on_fail_mock("on_fail")

      def on_pass(self, record):
        never_call()

      def teardown_test(self):
        raise Exception(MSG_EXPECTED_EXCEPTION + 'ha')

      def test_something(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    on_fail_mock.assert_called_once_with("on_fail")
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extra_errors['teardown_test'].details,
                     'This is an expected exception.ha')
    self.assertIsNone(actual_record.extras)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_on_fail_executed_if_setup_test_fails_by_exception(self):
    my_mock = mock.MagicMock()

    class MockBaseTest(base_test.BaseTestClass):

      def setup_test(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)

      def on_fail(self, record):
        my_mock("on_fail")

      def test_something(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    my_mock.assert_called_once_with("on_fail")
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_on_fail_executed_if_setup_class_fails_by_exception(self):
    my_mock = mock.MagicMock()

    class MockBaseTest(base_test.BaseTestClass):

      def setup_class(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)

      def on_fail(self, record):
        my_mock("on_fail")

      def test_something(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    my_mock.assert_called_once_with("on_fail")
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, 'setup_class')
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)
    expected_summary = ("Error 1, Executed 0, Failed 0, Passed 0, "
                        "Requested 1, Skipped 1")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_on_fail_triggered_by_setup_class_failure_then_fail_too(self):
    """Errors thrown from on_fail should be captured."""

    class MockBaseTest(base_test.BaseTestClass):

      def setup_class(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)

      def on_fail(self, record):
        raise Exception('Failure in on_fail.')

      def test_something(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    setup_class_record = bt_cls.results.error[0]
    self.assertEqual(setup_class_record.test_name, 'setup_class')
    self.assertEqual(setup_class_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(setup_class_record.extra_errors['on_fail'].details,
                     'Failure in on_fail.')
    expected_summary = ("Error 1, Executed 0, Failed 0, Passed 0, "
                        "Requested 1, Skipped 1")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_failure_to_call_procedure_function_is_recorded(self):

    class MockBaseTest(base_test.BaseTestClass):

      def on_fail(self):
        pass

      def test_something(self):
        asserts.assert_true(False, MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.failed[0]
    self.assertIn('on_fail', actual_record.extra_errors)
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)
    expected_summary = ("Error 0, Executed 1, Failed 1, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_failure_in_procedure_functions_is_recorded(self):
    expected_msg = "Something failed in on_pass."

    class MockBaseTest(base_test.BaseTestClass):

      def on_pass(self, record):
        raise Exception(expected_msg)

      def test_something(self):
        asserts.explicit_pass(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.extra_errors['on_pass'].details,
                     expected_msg)
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_both_teardown_and_test_body_raise_exceptions(self):

    class MockBaseTest(base_test.BaseTestClass):

      def teardown_test(self):
        asserts.assert_true(False, MSG_EXPECTED_EXCEPTION)

      def test_something(self):
        raise Exception("Test Body Exception.")

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, "Test Body Exception.")
    self.assertIsNone(actual_record.extras)
    self.assertEqual(actual_record.extra_errors['teardown_test'].details,
                     MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extra_errors['teardown_test'].extras)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_exception_objects_in_record(self):
    """Checks that the exception objects are correctly tallied.
    """
    expected_termination_signal = Exception('Test Body Exception.')
    expected_extra_error = Exception('teardown_test Exception.')

    class MockBaseTest(base_test.BaseTestClass):

      def teardown_test(self):
        raise expected_extra_error

      def test_something(self):
        raise expected_termination_signal

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    self.assertIs(actual_record.termination_signal.exception,
                  expected_termination_signal)
    self.assertIsNotNone(actual_record.termination_signal.stacktrace)
    self.assertEqual(len(actual_record.extra_errors), 1)
    extra_error = actual_record.extra_errors['teardown_test']
    self.assertIs(extra_error.exception, expected_extra_error)
    self.assertIsNotNone(extra_error.stacktrace)
    self.assertIsNone(actual_record.extras)

  def test_promote_extra_errors_to_termination_signal(self):
    """If no termination signal is specified, use the first extra error as
    the termination signal.
    """
    expected_extra_error = Exception('teardown_test Exception.')

    class MockBaseTest(base_test.BaseTestClass):

      def teardown_test(self):
        raise expected_extra_error

      def test_something(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    self.assertFalse(actual_record.extra_errors)
    self.assertEqual(actual_record.details, 'teardown_test Exception.')
    self.assertIsNotNone(actual_record.stacktrace)

  def test_explicit_pass_but_teardown_test_raises_an_exception(self):
    """Test record result should be marked as ERROR as opposed to PASS.
    """

    class MockBaseTest(base_test.BaseTestClass):

      def teardown_test(self):
        asserts.assert_true(False, MSG_EXPECTED_EXCEPTION)

      def test_something(self):
        asserts.explicit_pass('Test Passed!')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, 'Test Passed!')
    self.assertIsNone(actual_record.extras)
    self.assertEqual(actual_record.extra_errors['teardown_test'].details,
                     MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extra_errors['teardown_test'].extras)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_on_pass_cannot_modify_original_record(self):

    class MockBaseTest(base_test.BaseTestClass):

      def on_pass(self, record):
        record.test_name = 'blah'

      def test_something(self):
        asserts.explicit_pass('Extra pass!')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.test_name, 'test_something')

  def test_on_pass_raise_exception(self):

    class MockBaseTest(base_test.BaseTestClass):

      def on_pass(self, record):
        raise Exception(MSG_EXPECTED_EXCEPTION)

      def test_something(self):
        asserts.explicit_pass(MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)
    self.assertEqual(actual_record.extra_errors['on_pass'].details,
                     MSG_EXPECTED_EXCEPTION)
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_on_fail_raise_exception(self):

    class MockBaseTest(base_test.BaseTestClass):

      def on_fail(self, record):
        raise Exception(MSG_EXPECTED_EXCEPTION)

      def test_something(self):
        asserts.fail(MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, self.mock_test_name)
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)
    self.assertEqual(actual_record.extra_errors['on_fail'].details,
                     MSG_EXPECTED_EXCEPTION)
    expected_summary = ("Error 0, Executed 1, Failed 1, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_abort_class_setup_class(self):
    """A class was intentionally aborted by the test.

    This is not considered an error as the abort class is used as a skip
    signal for the entire class, which is different from raising other
    exceptions in `setup_class`.
    """

    class MockBaseTest(base_test.BaseTestClass):

      def setup_class(self):
        asserts.abort_class(MSG_EXPECTED_EXCEPTION)

      def test_1(self):
        never_call()

      def test_2(self):
        never_call()

      def test_3(self):
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_1", "test_2", "test_3"])
    self.assertEqual(len(bt_cls.results.skipped), 3)
    self.assertEqual(bt_cls.results.summary_str(),
                     ("Error 0, Executed 0, Failed 0, Passed 0, "
                      "Requested 3, Skipped 3"))

  def test_abort_class_in_setup_test(self):

    class MockBaseTest(base_test.BaseTestClass):

      def setup_test(self):
        asserts.abort_class(MSG_EXPECTED_EXCEPTION)

      def test_1(self):
        never_call()

      def test_2(self):
        never_call()

      def test_3(self):
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_1", "test_2", "test_3"])
    self.assertEqual(len(bt_cls.results.skipped), 2)
    self.assertEqual(bt_cls.results.summary_str(),
                     ("Error 0, Executed 1, Failed 1, Passed 0, "
                      "Requested 3, Skipped 2"))

  def test_abort_class_in_on_fail(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_1(self):
        asserts.fail(MSG_EXPECTED_EXCEPTION)

      def test_2(self):
        never_call()

      def test_3(self):
        never_call()

      def on_fail(self, record):
        asserts.abort_class(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_1", "test_2", "test_3"])
    self.assertEqual(len(bt_cls.results.skipped), 2)
    self.assertEqual(bt_cls.results.summary_str(),
                     ("Error 0, Executed 1, Failed 1, Passed 0, "
                      "Requested 3, Skipped 2"))

  def test_setup_and_teardown_execution_count(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        pass

      def test_func2(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.setup_class = mock.Mock()
    bt_cls.teardown_class = mock.Mock()
    bt_cls.setup_test = mock.Mock()
    bt_cls.teardown_test = mock.Mock()
    bt_cls.run()
    self.assertEqual(bt_cls.setup_class.call_count, 1)
    self.assertEqual(bt_cls.teardown_class.call_count, 1)
    self.assertEqual(bt_cls.setup_test.call_count, 2)
    self.assertEqual(bt_cls.teardown_test.call_count, 2)

  def test_abort_class_in_test(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_1(self):
        pass

      def test_2(self):
        asserts.abort_class(MSG_EXPECTED_EXCEPTION)
        never_call()

      def test_3(self):
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_1", "test_2", "test_3"])
    self.assertEqual(bt_cls.results.passed[0].test_name, "test_1")
    self.assertEqual(bt_cls.results.failed[0].details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(bt_cls.results.summary_str(),
                     ("Error 0, Executed 2, Failed 1, Passed 1, "
                      "Requested 3, Skipped 1"))

  def test_abort_all_in_setup_class(self):

    class MockBaseTest(base_test.BaseTestClass):

      def setup_class(self):
        asserts.abort_all(MSG_EXPECTED_EXCEPTION)

      def test_1(self):
        never_call()

      def test_2(self):
        never_call()

      def test_3(self):
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    with self.assertRaisesRegex(signals.TestAbortAll,
                                MSG_EXPECTED_EXCEPTION) as context:
      bt_cls.run(test_names=["test_1", "test_2", "test_3"])
    self.assertTrue(hasattr(context.exception, 'results'))
    self.assertEqual(bt_cls.results.summary_str(),
                     ("Error 0, Executed 0, Failed 0, Passed 0, "
                      "Requested 3, Skipped 3"))

  def test_abort_all_in_teardown_class(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_1(self):
        pass

      def test_2(self):
        pass

      def teardown_class(self):
        asserts.abort_all(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    with self.assertRaisesRegex(signals.TestAbortAll,
                                MSG_EXPECTED_EXCEPTION) as context:
      bt_cls.run(test_names=["test_1", "test_2"])
    self.assertTrue(hasattr(context.exception, 'results'))
    self.assertEqual(bt_cls.results.summary_str(),
                     ("Error 0, Executed 2, Failed 0, Passed 2, "
                      "Requested 2, Skipped 0"))

  def test_abort_all_in_setup_test(self):

    class MockBaseTest(base_test.BaseTestClass):

      def setup_test(self):
        asserts.abort_all(MSG_EXPECTED_EXCEPTION)

      def test_1(self):
        never_call()

      def test_2(self):
        never_call()

      def test_3(self):
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    with self.assertRaisesRegex(signals.TestAbortAll,
                                MSG_EXPECTED_EXCEPTION) as context:
      bt_cls.run(test_names=["test_1", "test_2", "test_3"])
    self.assertTrue(hasattr(context.exception, 'results'))
    self.assertEqual(bt_cls.results.summary_str(),
                     ("Error 0, Executed 1, Failed 1, Passed 0, "
                      "Requested 3, Skipped 2"))

  def test_abort_all_in_on_fail(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_1(self):
        asserts.fail(MSG_EXPECTED_EXCEPTION)

      def test_2(self):
        never_call()

      def test_3(self):
        never_call()

      def on_fail(self, record):
        asserts.abort_all(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    with self.assertRaisesRegex(signals.TestAbortAll,
                                MSG_EXPECTED_EXCEPTION) as context:
      bt_cls.run(test_names=["test_1", "test_2", "test_3"])
    self.assertTrue(hasattr(context.exception, 'results'))
    self.assertEqual(bt_cls.results.summary_str(),
                     ("Error 0, Executed 1, Failed 1, Passed 0, "
                      "Requested 3, Skipped 2"))

  def test_abort_all_in_on_fail_from_setup_class(self):

    class MockBaseTest(base_test.BaseTestClass):

      def setup_class(self):
        asserts.fail(MSG_UNEXPECTED_EXCEPTION)

      def test_1(self):
        never_call()

      def test_2(self):
        never_call()

      def test_3(self):
        never_call()

      def on_fail(self, record):
        asserts.abort_all(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    with self.assertRaisesRegex(signals.TestAbortAll,
                                MSG_EXPECTED_EXCEPTION) as context:
      bt_cls.run(test_names=["test_1", "test_2", "test_3"])
    setup_class_record = bt_cls.results.error[0]
    self.assertEqual(setup_class_record.test_name, 'setup_class')
    self.assertTrue(hasattr(context.exception, 'results'))
    self.assertEqual(bt_cls.results.summary_str(),
                     ("Error 1, Executed 0, Failed 0, Passed 0, "
                      "Requested 3, Skipped 3"))

  def test_abort_all_in_test(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_1(self):
        pass

      def test_2(self):
        asserts.abort_all(MSG_EXPECTED_EXCEPTION)
        never_call()

      def test_3(self):
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    with self.assertRaisesRegex(signals.TestAbortAll,
                                MSG_EXPECTED_EXCEPTION) as context:
      bt_cls.run(test_names=["test_1", "test_2", "test_3"])
    self.assertTrue(hasattr(context.exception, 'results'))
    self.assertEqual(bt_cls.results.passed[0].test_name, "test_1")
    self.assertEqual(bt_cls.results.failed[0].details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(bt_cls.results.summary_str(),
                     ("Error 0, Executed 2, Failed 1, Passed 1, "
                      "Requested 3, Skipped 1"))

  def test_uncaught_exception(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_func"])
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)
    # Stacktraces can vary. Just check for key words
    self.assertIn('test_method()', actual_record.stacktrace)
    self.assertIn('raise Exception(MSG_EXPECTED_EXCEPTION)',
                  actual_record.stacktrace)
    self.assertIn('Exception: This is an expected exception.',
                  actual_record.stacktrace)

  def test_fail(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        asserts.fail(MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_func"])
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_assert_true(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        asserts.assert_true(False, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_func"])
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_assert_equal_pass(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        asserts.assert_equal(1, 1, extras=MOCK_EXTRA)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertIsNone(actual_record.details)
    self.assertIsNone(actual_record.extras)

  def test_assert_equal_fail(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        asserts.assert_equal(1, 2, extras=MOCK_EXTRA)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertEqual(actual_record.details, "1 != 2")
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_assert_equal_fail_with_msg(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        asserts.assert_equal(1,
                             2,
                             msg=MSG_EXPECTED_EXCEPTION,
                             extras=MOCK_EXTRA)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    expected_msg = "1 != 2 " + MSG_EXPECTED_EXCEPTION
    self.assertEqual(actual_record.details, expected_msg)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_assert_raises_pass(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        with asserts.assert_raises(SomeError, extras=MOCK_EXTRA):
          raise SomeError(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertIsNone(actual_record.details)
    self.assertIsNone(actual_record.extras)

  def test_assert_raises_fail_with_noop(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        with asserts.assert_raises(SomeError, extras=MOCK_EXTRA):
          pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertEqual(actual_record.details, "SomeError not raised")
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_assert_raises_fail_with_wrong_error(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        with asserts.assert_raises(SomeError, extras=MOCK_EXTRA):
          raise AttributeError(MSG_UNEXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertEqual(actual_record.details, MSG_UNEXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)

  def test_assert_raises_regex_pass(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        with asserts.assert_raises_regex(SomeError,
                                         expected_regex=MSG_EXPECTED_EXCEPTION,
                                         extras=MOCK_EXTRA):
          raise SomeError(MSG_EXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertIsNone(actual_record.details)
    self.assertIsNone(actual_record.extras)

  def test_assert_raises_regex_fail_with_noop(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        with asserts.assert_raises_regex(SomeError,
                                         expected_regex=MSG_EXPECTED_EXCEPTION,
                                         extras=MOCK_EXTRA):
          pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertEqual(actual_record.details, "SomeError not raised")
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_assert_raises_fail_with_wrong_regex(self):
    wrong_msg = "ha"

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        with asserts.assert_raises_regex(SomeError,
                                         expected_regex=MSG_EXPECTED_EXCEPTION,
                                         extras=MOCK_EXTRA):
          raise SomeError(wrong_msg)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    expected_details = ('"This is an expected exception." does not match '
                        '"%s"') % wrong_msg
    self.assertEqual(actual_record.details, expected_details)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_assert_raises_regex_fail_with_wrong_error(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        with asserts.assert_raises_regex(SomeError,
                                         expected_regex=MSG_EXPECTED_EXCEPTION,
                                         extras=MOCK_EXTRA):
          raise AttributeError(MSG_UNEXPECTED_EXCEPTION)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertEqual(actual_record.details, MSG_UNEXPECTED_EXCEPTION)
    self.assertIsNone(actual_record.extras)

  def test_explicit_pass(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        asserts.explicit_pass(MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_func"])
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_implicit_pass(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_func"])
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertIsNone(actual_record.details)
    self.assertIsNone(actual_record.extras)

  def test_skip(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        asserts.skip(MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_func"])
    actual_record = bt_cls.results.skipped[0]
    self.assertIsNotNone(actual_record.begin_time)
    self.assertIsNotNone(actual_record.end_time)
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_skip_if(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        asserts.skip_if(False, MSG_UNEXPECTED_EXCEPTION)
        asserts.skip_if(True, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_func"])
    actual_record = bt_cls.results.skipped[0]
    self.assertIsNotNone(actual_record.begin_time)
    self.assertIsNotNone(actual_record.end_time)
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_skip_in_setup_test(self):

    class MockBaseTest(base_test.BaseTestClass):

      def setup_test(self):
        asserts.skip(MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)

      def test_func(self):
        never_call()

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_func"])
    actual_record = bt_cls.results.skipped[0]
    self.assertIsNotNone(actual_record.begin_time)
    self.assertIsNotNone(actual_record.end_time)
    self.assertEqual(actual_record.test_name, "test_func")
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_expect_true(self):
    must_call = mock.Mock()
    must_call2 = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        expects.expect_true(False, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        must_call('ha')

      def on_fail(self, record):
        must_call2('on_fail')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=['test_func'])
    must_call.assert_called_once_with('ha')
    must_call2.assert_called_once_with('on_fail')
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, 'test_func')
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_expect_multiple_fails(self):
    must_call = mock.Mock()
    must_call2 = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        expects.expect_true(False, 'msg 1', extras='1')
        expects.expect_true(False, 'msg 2', extras='2')
        must_call('ha')

      def on_fail(self, record):
        must_call2('on_fail')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=['test_func'])
    must_call.assert_called_once_with('ha')
    must_call2.assert_called_once_with('on_fail')
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, 'test_func')
    self.assertEqual(actual_record.details, 'msg 1')
    self.assertEqual(actual_record.extras, '1')
    self.assertEqual(len(actual_record.extra_errors), 1)
    second_error = list(actual_record.extra_errors.values())[0]
    self.assertEqual(second_error.details, 'msg 2')
    self.assertEqual(second_error.extras, '2')

  def test_expect_two_tests(self):
    """Errors in `expect` should not leak across tests.
    """
    must_call = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def test_1(self):
        expects.expect_true(False, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        must_call('ha')

      def test_2(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=['test_1', 'test_2'])
    must_call.assert_called_once_with('ha')
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, 'test_1')
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)
    another_record = bt_cls.results.passed[0]
    self.assertEqual(another_record.test_name, 'test_2')

  def test_expect_no_op(self):
    """Tests don't fail when expect is not triggered.
    """
    must_call = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def test_1(self):
        expects.expect_true(True, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        must_call('ha')

      def test_2(self):
        expects.expect_false(False, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        must_call('ha')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=['test_1', 'test_2'])
    must_call.assert_called_with('ha')
    self.assertEqual(len(bt_cls.results.passed), 2)

  @mock.patch('mobly.records.TestSummaryWriter.dump')
  def test_expect_in_setup_class(self, mock_dump):
    must_call = mock.Mock()
    must_call2 = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def setup_class(self):
        expects.expect_true(False, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        must_call('ha')

      def test_func(self):
        pass

      def on_fail(self, record):
        must_call2('on_fail')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    must_call.assert_called_once_with('ha')
    must_call2.assert_called_once_with('on_fail')
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, 'setup_class')
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)
    # Verify the class record is written out correctly.
    setup_class_dict = mock_dump.call_args_list[1][0][0]
    self.assertIsNotNone(setup_class_dict['Begin Time'])
    self.assertIsNotNone(setup_class_dict['End Time'])
    self.assertEqual(setup_class_dict['Test Name'], 'setup_class')

  @mock.patch('mobly.records.TestSummaryWriter.dump')
  def test_expect_in_setup_class_and_on_fail(self, mock_dump):
    must_call = mock.Mock()
    must_call2 = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def setup_class(self):
        expects.expect_true(False, 'Failure in setup_class', extras=MOCK_EXTRA)
        must_call('ha')

      def test_func(self):
        pass

      def on_fail(self, record):
        expects.expect_true(False, 'Failure in on_fail', extras=MOCK_EXTRA)
        must_call2('on_fail')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    must_call.assert_called_once_with('ha')
    must_call2.assert_called_once_with('on_fail')
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, 'setup_class')
    self.assertEqual(actual_record.details, 'Failure in setup_class')
    self.assertEqual(actual_record.extras, MOCK_EXTRA)
    on_fail_error = next(iter(actual_record.extra_errors.values()))
    self.assertEqual(on_fail_error.details, 'Failure in on_fail')
    self.assertEqual(on_fail_error.extras, MOCK_EXTRA)
    # Verify the class record is written out correctly.
    setup_class_dict = mock_dump.call_args_list[1][0][0]
    self.assertIsNotNone(setup_class_dict['Begin Time'])
    self.assertIsNotNone(setup_class_dict['End Time'])
    self.assertEqual(setup_class_dict['Test Name'], 'setup_class')
    # Verify the on_fail error is recorded in summary result.
    extra_error_dict = next(iter(setup_class_dict['Extra Errors'].values()))
    self.assertEqual(extra_error_dict['Details'], 'Failure in on_fail')

  def test_expect_in_teardown_class(self):
    must_call = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        pass

      def teardown_class(self):
        expects.expect_true(False, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        must_call('ha')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    must_call.assert_called_once_with('ha')
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, 'teardown_class')
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_expect_in_setup_test(self):
    must_call = mock.Mock()
    must_call2 = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def setup_test(self):
        expects.expect_true(False, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        must_call('ha')

      def test_func(self):
        pass

      def on_fail(self, record):
        must_call2('on_fail')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    must_call.assert_called_once_with('ha')
    must_call2.assert_called_once_with('on_fail')
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, 'test_func')
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_expect_in_teardown_test(self):
    must_call = mock.Mock()
    must_call2 = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        pass

      def teardown_test(self):
        expects.expect_true(False, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        must_call('ha')

      def on_fail(self, record):
        must_call2('on_fail')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=['test_func'])
    must_call.assert_called_once_with('ha')
    must_call2.assert_called_once_with('on_fail')
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, 'test_func')
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_expect_false(self):
    must_call = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        expects.expect_false(True, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        must_call('ha')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=['test_func'])
    must_call.assert_called_once_with('ha')
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, 'test_func')
    self.assertEqual(actual_record.details, MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_expect_equal(self):
    must_call = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        expects.expect_equal(1, 2, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        must_call('ha')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=['test_func'])
    must_call.assert_called_once_with('ha')
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, 'test_func')
    self.assertEqual(actual_record.details, '1 != 2 ' + MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_expect_no_raises_default_msg(self):
    must_call = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        with expects.expect_no_raises(extras=MOCK_EXTRA):
          raise Exception(MSG_EXPECTED_EXCEPTION)
        must_call('ha')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=['test_func'])
    must_call.assert_called_once_with('ha')
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, 'test_func')
    self.assertEqual(actual_record.details,
                     'Got an unexpected exception: %s' % MSG_EXPECTED_EXCEPTION)
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_expect_no_raises_custom_msg(self):
    must_call = mock.Mock()
    msg = 'Some step unexpected failed'

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        with expects.expect_no_raises(message=msg, extras=MOCK_EXTRA):
          raise Exception(MSG_EXPECTED_EXCEPTION)
        must_call('ha')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=['test_func'])
    must_call.assert_called_once_with('ha')
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, 'test_func')
    self.assertEqual(actual_record.details,
                     '%s: %s' % (msg, MSG_EXPECTED_EXCEPTION))
    self.assertEqual(actual_record.extras, MOCK_EXTRA)

  def test_expect_true_and_assert_true(self):
    """Error thrown by assert_true should be considered the termination.
    """
    must_call = mock.Mock()

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        expects.expect_true(False, MSG_EXPECTED_EXCEPTION, extras=MOCK_EXTRA)
        must_call('ha')
        asserts.assert_true(False, 'failed from assert_true')

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=['test_func'])
    must_call.assert_called_once_with('ha')
    actual_record = bt_cls.results.failed[0]
    self.assertEqual(actual_record.test_name, 'test_func')
    self.assertEqual(actual_record.details, 'failed from assert_true')
    self.assertIsNone(actual_record.extras)

  def test_unpack_userparams_required(self):
    """Missing a required param should raise an error."""
    required = ["some_param"]
    bc = base_test.BaseTestClass(self.mock_test_cls_configs)
    bc.unpack_userparams(required)
    expected_value = self.mock_test_cls_configs.user_params["some_param"]
    self.assertEqual(bc.some_param, expected_value)

  def test_unpack_userparams_required_missing(self):
    """Missing a required param should raise an error."""
    required = ["something"]
    bc = base_test.BaseTestClass(self.mock_test_cls_configs)
    expected_msg = ('Missing required user param "%s" in test '
                    'configuration.') % required[0]
    with self.assertRaisesRegex(base_test.Error, expected_msg):
      bc.unpack_userparams(required)

  def test_unpack_userparams_optional(self):
    """If an optional param is specified, the value should be what's in the
    config.
    """
    opt = ["some_param"]
    bc = base_test.BaseTestClass(self.mock_test_cls_configs)
    bc.unpack_userparams(opt_param_names=opt)
    expected_value = self.mock_test_cls_configs.user_params["some_param"]
    self.assertEqual(bc.some_param, expected_value)

  def test_unpack_userparams_optional_with_default(self):
    """If an optional param is specified with a default value, and the
    param is not in the config, the value should be the default value.
    """
    bc = base_test.BaseTestClass(self.mock_test_cls_configs)
    bc.unpack_userparams(optional_thing="whatever")
    self.assertEqual(bc.optional_thing, "whatever")

  def test_unpack_userparams_default_overwrite_by_optional_param_list(self):
    """If an optional param is specified in kwargs, and the param is in the
    config, the value should be the one in the config.
    """
    bc = base_test.BaseTestClass(self.mock_test_cls_configs)
    bc.unpack_userparams(some_param="whatever")
    expected_value = self.mock_test_cls_configs.user_params["some_param"]
    self.assertEqual(bc.some_param, expected_value)

  def test_unpack_userparams_default_overwrite_by_required_param_list(self):
    """If an optional param is specified in kwargs, the param is in the
    required param list, and the param is not specified in the config, the
    param's alue should be the default value and there should be no error
    thrown.
    """
    bc = base_test.BaseTestClass(self.mock_test_cls_configs)
    bc.unpack_userparams(req_param_names=['a_kwarg_param'],
                         a_kwarg_param="whatever")
    self.assertEqual(bc.a_kwarg_param, "whatever")

  def test_unpack_userparams_optional_missing(self):
    """Missing an optional param should not raise an error."""
    opt = ["something"]
    bc = base_test.BaseTestClass(self.mock_test_cls_configs)
    bc.unpack_userparams(opt_param_names=opt)

  def test_unpack_userparams_basic(self):
    """Required and optional params are unpacked properly."""
    required = ["something"]
    optional = ["something_else"]
    configs = self.mock_test_cls_configs.copy()
    configs.user_params["something"] = 42
    configs.user_params["something_else"] = 53
    bc = base_test.BaseTestClass(configs)
    bc.unpack_userparams(req_param_names=required, opt_param_names=optional)
    self.assertEqual(bc.something, 42)
    self.assertEqual(bc.something_else, 53)

  def test_unpack_userparams_default_overwrite(self):
    default_arg_val = "haha"
    actual_arg_val = "wawa"
    arg_name = "arg1"
    configs = self.mock_test_cls_configs.copy()
    configs.user_params[arg_name] = actual_arg_val
    bc = base_test.BaseTestClass(configs)
    bc.unpack_userparams(opt_param_names=[arg_name], arg1=default_arg_val)
    self.assertEqual(bc.arg1, actual_arg_val)

  def test_unpack_userparams_default_None(self):
    bc = base_test.BaseTestClass(self.mock_test_cls_configs)
    bc.unpack_userparams(arg1="haha")
    self.assertEqual(bc.arg1, "haha")

  def test_setup_generated_tests_failure(self):
    """Test code path for setup_generated_tests failure.

    When setup_generated_tests fails, pre-execution calculation is
    incomplete and the number of tests requested is unknown. This is a
    fatal issue that blocks any test execution in a class.

    A class level error record is generated.
    Unlike `setup_class` failure, no test is considered "skipped" in this
    case as execution stage never started.
    """

    class MockBaseTest(base_test.BaseTestClass):

      def setup_generated_tests(self):
        raise Exception(MSG_EXPECTED_EXCEPTION)

      def logic(self, a, b):
        pass

      def test_foo(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    self.assertEqual(len(bt_cls.results.requested), 0)
    class_record = bt_cls.results.error[0]
    self.assertEqual(class_record.test_name, 'setup_generated_tests')
    self.assertEqual(bt_cls.results.skipped, [])

  def test_generate_tests_run(self):

    class MockBaseTest(base_test.BaseTestClass):

      def setup_generated_tests(self):
        self.generate_tests(test_logic=self.logic,
                            name_func=self.name_gen,
                            arg_sets=[(1, 2), (3, 4)])

      def name_gen(self, a, b):
        return 'test_%s_%s' % (a, b)

      def logic(self, a, b):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    self.assertEqual(len(bt_cls.results.requested), 2)
    self.assertEqual(len(bt_cls.results.passed), 2)
    self.assertIsNone(bt_cls.results.passed[0].uid)
    self.assertIsNone(bt_cls.results.passed[1].uid)
    self.assertEqual(bt_cls.results.passed[0].test_name, 'test_1_2')
    self.assertEqual(bt_cls.results.passed[1].test_name, 'test_3_4')

  def test_generate_tests_with_uid(self):

    class MockBaseTest(base_test.BaseTestClass):

      def setup_generated_tests(self):
        self.generate_tests(test_logic=self.logic,
                            name_func=self.name_gen,
                            uid_func=self.uid_logic,
                            arg_sets=[(1, 2), (3, 4)])

      def name_gen(self, a, b):
        return 'test_%s_%s' % (a, b)

      def uid_logic(self, a, b):
        return 'uid-%s-%s' % (a, b)

      def logic(self, a, b):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    self.assertEqual(bt_cls.results.passed[0].uid, 'uid-1-2')
    self.assertEqual(bt_cls.results.passed[1].uid, 'uid-3-4')

  def test_generate_tests_with_none_uid(self):

    class MockBaseTest(base_test.BaseTestClass):

      def setup_generated_tests(self):
        self.generate_tests(test_logic=self.logic,
                            name_func=self.name_gen,
                            uid_func=self.uid_logic,
                            arg_sets=[(1, 2), (3, 4)])

      def name_gen(self, a, b):
        return 'test_%s_%s' % (a, b)

      def uid_logic(self, a, b):
        if a == 1:
          return None
        return 'uid-3-4'

      def logic(self, a, b):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    self.assertIsNone(bt_cls.results.passed[0].uid)
    self.assertEqual(bt_cls.results.passed[1].uid, 'uid-3-4')

  def test_generate_tests_selected_run(self):

    class MockBaseTest(base_test.BaseTestClass):

      def setup_generated_tests(self):
        self.generate_tests(test_logic=self.logic,
                            name_func=self.name_gen,
                            arg_sets=[(1, 2), (3, 4)])

      def name_gen(self, a, b):
        return 'test_%s_%s' % (a, b)

      def logic(self, a, b):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=['test_3_4'])
    self.assertEqual(len(bt_cls.results.requested), 1)
    self.assertEqual(len(bt_cls.results.passed), 1)
    self.assertEqual(bt_cls.results.passed[0].test_name, 'test_3_4')

  def test_generate_tests_call_outside_of_setup_generated_tests(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_ha(self):
        self.generate_tests(test_logic=self.logic,
                            name_func=self.name_gen,
                            arg_sets=[(1, 2), (3, 4)])

      def name_gen(self, a, b):
        return 'test_%s_%s' % (a, b)

      def logic(self, a, b):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    utils.validate_test_result(bt_cls.results)
    self.assertEqual(actual_record.test_name, "test_ha")
    self.assertEqual(
        actual_record.details,
        '"generate_tests" cannot be called outside of setup_generated_tests')
    expected_summary = ("Error 1, Executed 1, Failed 0, Passed 0, "
                        "Requested 1, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_generate_tests_dup_test_name(self):

    class MockBaseTest(base_test.BaseTestClass):

      def setup_generated_tests(self):
        self.generate_tests(test_logic=self.logic,
                            name_func=self.name_gen,
                            arg_sets=[(1, 2), (3, 4)])

      def name_gen(self, a, b):
        return 'ha'

      def logic(self, a, b):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.error[0]
    self.assertEqual(actual_record.test_name, "setup_generated_tests")
    self.assertEqual(
        actual_record.details,
        'During test generation of "logic": Test name "ha" already exists'
        ', cannot be duplicated!')
    expected_summary = ("Error 1, Executed 0, Failed 0, Passed 0, "
                        "Requested 0, Skipped 0")
    self.assertEqual(bt_cls.results.summary_str(), expected_summary)

  def test_write_user_data(self):
    content = {'a': 1}

    class MockBaseTest(base_test.BaseTestClass):

      def test_something(self):
        self.record_data(content)

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run(test_names=["test_something"])
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.test_name, "test_something")
    hit = False
    with io.open(self.summary_file, 'r', encoding='utf-8') as f:
      for c in yaml.safe_load_all(f):
        if c['Type'] != records.TestSummaryEntryType.USER_DATA.value:
          continue
        hit = True
        self.assertEqual(c['a'], content['a'])
        self.assertIsNotNone(c['timestamp'])
    self.assertTrue(hit)

  def test_record_controller_info(self):
    """Verifies that controller info is correctly recorded.

    1. Info added in test is recorded.
    2. Info of multiple controller types are recorded.
    """
    mock_test_config = self.mock_test_cls_configs.copy()
    mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
    mock_ctrlr_2_config_name = mock_second_controller.MOBLY_CONTROLLER_CONFIG_NAME
    my_config = [{'serial': 'xxxx', 'magic': 'Magic'}]
    mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
    mock_test_config.controller_configs[mock_ctrlr_2_config_name] = copy.copy(
        my_config)

    class ControllerInfoTest(base_test.BaseTestClass):
      """Registers two different controller types and modifies controller
      info at runtime.
      """

      def setup_class(self):
        self.register_controller(mock_controller)
        second_controller = self.register_controller(mock_second_controller)[0]
        # This should appear in recorded controller info.
        second_controller.set_magic('haha')

      def test_func(self):
        pass

    bt_cls = ControllerInfoTest(mock_test_config)
    bt_cls.run()
    info1 = bt_cls.results.controller_info[0]
    info2 = bt_cls.results.controller_info[1]
    self.assertNotEqual(info1, info2)
    self.assertEqual(info1.test_class, 'ControllerInfoTest')
    self.assertEqual(info1.controller_name, 'MagicDevice')
    self.assertEqual(info1.controller_info, [{'MyMagic': {'magic': 'Magic'}}])
    self.assertEqual(info2.test_class, 'ControllerInfoTest')
    self.assertEqual(info2.controller_name, 'AnotherMagicDevice')
    self.assertEqual(info2.controller_info, [{
        'MyOtherMagic': {
            'magic': 'Magic',
            'extra_magic': 'haha'
        }
    }])

  def test_record_controller_info_fail(self):
    mock_test_config = self.mock_test_cls_configs.copy()
    mock_ctrlr_config_name = mock_controller.MOBLY_CONTROLLER_CONFIG_NAME
    mock_ctrlr_2_config_name = mock_second_controller.MOBLY_CONTROLLER_CONFIG_NAME
    my_config = [{'serial': 'xxxx', 'magic': 'Magic'}]
    mock_test_config.controller_configs[mock_ctrlr_config_name] = my_config
    mock_test_config.controller_configs[mock_ctrlr_2_config_name] = copy.copy(
        my_config)

    class ControllerInfoTest(base_test.BaseTestClass):
      """Registers two different controller types and modifies controller
      info at runtime.
      """

      def setup_class(self):
        device = self.register_controller(mock_controller)[0]
        device.who_am_i = mock.MagicMock()
        device.who_am_i.side_effect = Exception('Some failure')
        second_controller = self.register_controller(mock_second_controller)[0]
        # This should appear in recorded controller info.
        second_controller.set_magic('haha')

      def test_func(self):
        pass

    bt_cls = ControllerInfoTest(mock_test_config)
    bt_cls.run()
    info = bt_cls.results.controller_info[0]
    self.assertEqual(len(bt_cls.results.controller_info), 1)
    self.assertEqual(info.test_class, 'ControllerInfoTest')
    self.assertEqual(info.controller_name, 'AnotherMagicDevice')
    self.assertEqual(info.controller_info, [{
        'MyOtherMagic': {
            'magic': 'Magic',
            'extra_magic': 'haha'
        }
    }])
    record = bt_cls.results.error[0]
    print(record.to_dict())
    self.assertEqual(record.test_name, 'clean_up')
    self.assertIsNotNone(record.begin_time)
    self.assertIsNotNone(record.end_time)
    expected_msg = ('Failed to collect controller info from '
                    'mock_controller: Some failure')
    self.assertEqual(record.details, expected_msg)

  def test_uid(self):

    class MockBaseTest(base_test.BaseTestClass):

      @records.uid('some-uid')
      def test_func(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.passed[0]
    self.assertEqual(actual_record.uid, 'some-uid')

  def test_uid_not_specified(self):

    class MockBaseTest(base_test.BaseTestClass):

      def test_func(self):
        pass

    bt_cls = MockBaseTest(self.mock_test_cls_configs)
    bt_cls.run()
    actual_record = bt_cls.results.passed[0]
    self.assertIsNone(actual_record.uid)

  def test_uid_is_none(self):
    with self.assertRaisesRegex(ValueError, 'UID cannot be None.'):

      class MockBaseTest(base_test.BaseTestClass):

        @records.uid(None)
        def not_a_test(self):
          pass

  def test_log_stage_always_logs_end_statement(self):
    instance = base_test.BaseTestClass(self.mock_test_cls_configs)
    instance.current_test_info = mock.Mock()
    instance.current_test_info.name = 'TestClass'

    class RecoverableError(Exception):
      pass

    with mock.patch('mobly.base_test.logging') as logging_patch:
      try:
        with instance._log_test_stage('stage'):
          raise RecoverableError('Force stage to fail.')
      except RecoverableError:
        pass

    logging_patch.debug.assert_called_with('[TestClass]#stage <<< END <<<')


if __name__ == "__main__":
  unittest.main()
