blob: d7bc12d1ea31c68477cb73d60a14773fecf7b077 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright 2022 The Fuchsia Authors
#
# 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 mock
import shutil
import tempfile
import unittest
import mock
from mobly import config_parser as mobly_config_parser
from antlion import base_test
from antlion import signals
from antlion import test_decorators
from antlion import test_runner
from antlion.controllers.sl4a_lib import rpc_client
def return_true():
return True
def return_false():
return False
def raise_pass():
raise signals.TestPass('')
def raise_failure():
raise signals.TestFailure('')
def raise_sl4a():
raise rpc_client.Sl4aException('')
def raise_generic():
raise Exception('')
class MockTest(base_test.BaseTestClass):
TEST_CASE_LIST = 'test_run_mock_test'
TEST_LOGIC_ATTR = 'test_logic'
def test_run_mock_test(self):
getattr(MockTest, MockTest.TEST_LOGIC_ATTR, None)()
class TestDecoratorIntegrationTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.tmp_dir = tempfile.mkdtemp()
cls.MOCK_CONFIG = mobly_config_parser.TestRunConfig()
cls.MOCK_CONFIG.testbed_name = 'SampleTestBed'
cls.MOCK_CONFIG.log_path = cls.tmp_dir
cls.MOCK_TEST_RUN_LIST = [(MockTest.__name__,
[MockTest.TEST_CASE_LIST])]
@classmethod
def tearDownClass(cls):
shutil.rmtree(cls.tmp_dir)
def _run_with_test_logic(self, func):
if hasattr(MockTest, MockTest.TEST_LOGIC_ATTR):
delattr(MockTest, MockTest.TEST_LOGIC_ATTR)
setattr(MockTest, MockTest.TEST_LOGIC_ATTR, func)
self.test_runner = test_runner.TestRunner(self.MOCK_CONFIG,
self.MOCK_TEST_RUN_LIST)
self.test_runner.run(MockTest)
def _validate_results_has_extra(self, result, extra_key, extra_value):
results = self.test_runner.results
self.assertGreaterEqual(len(results.executed), 1,
'Expected at least one executed test.')
record = results.executed[0]
self.assertIsNotNone(record.extras,
'Expected the test record to have extras.')
self.assertEqual(record.extras[extra_key], extra_value)
def test_mock_test_with_raise_pass(self):
self._run_with_test_logic(raise_pass)
def test_mock_test_with_raise_generic(self):
self._run_with_test_logic(raise_generic)
class RepeatedTestTests(unittest.TestCase):
def test_all_error_types_count_toward_failures(self):
def result_selector(results, _):
self.assertIsInstance(results[0], AssertionError)
self.assertIsInstance(results[1], signals.TestFailure)
self.assertIsInstance(results[2], signals.TestError)
self.assertIsInstance(results[3], IndexError)
raise signals.TestPass('Expected failures occurred')
@test_decorators.repeated_test(1, 3, result_selector)
def test_case(_, attempt_number):
if attempt_number == 1:
raise AssertionError()
elif attempt_number == 2:
raise signals.TestFailure('Failed')
elif attempt_number == 3:
raise signals.TestError('Error')
else:
# Note that any Exception that does not fall into another bucket
# is also considered a failure
raise IndexError('Bad index')
with self.assertRaises(signals.TestPass):
test_case(mock.Mock())
def test_passes_stop_repeating_the_test_case(self):
def result_selector(results, _):
self.assertEqual(len(results), 3)
for result in results:
self.assertIsInstance(result, signals.TestPass)
raise signals.TestPass('Expected passes occurred')
@test_decorators.repeated_test(3, 0, result_selector)
def test_case(*_):
raise signals.TestPass('Passed')
with self.assertRaises(signals.TestPass):
test_case(mock.Mock())
def test_abort_signals_are_uncaught(self):
@test_decorators.repeated_test(3, 0)
def test_case(*_):
raise signals.TestAbortClass('Abort All')
with self.assertRaises(signals.TestAbortClass):
test_case(mock.Mock())
def test_keyboard_interrupt_is_uncaught(self):
@test_decorators.repeated_test(3, 0)
def test_case(*_):
raise KeyboardInterrupt()
with self.assertRaises(KeyboardInterrupt):
test_case(mock.Mock())
def test_teardown_and_setup_are_called_between_test_cases(self):
mock_test_class = mock.Mock()
@test_decorators.repeated_test(1, 1)
def test_case(*_):
raise signals.TestFailure('Failed')
with self.assertRaises(signals.TestFailure):
test_case(mock_test_class)
self.assertTrue(mock_test_class.setup_test.called)
self.assertTrue(mock_test_class.teardown_test.called)
def test_result_selector_returned_value_gets_raised(self):
def result_selector(*_):
return signals.TestPass('Expect this to be raised.')
@test_decorators.repeated_test(3, 0, result_selector=result_selector)
def test_case(*_):
raise signals.TestFailure('Result selector ignores this.')
with self.assertRaises(signals.TestPass):
test_case(mock.Mock())
if __name__ == '__main__':
unittest.main()