Home | History | Annotate | Download | only in tests
      1 #!/usr/bin/env python3
      2 #
      3 #   Copyright 2016 - The Android Open Source Project
      4 #
      5 #   Licensed under the Apache License, Version 2.0 (the "License");
      6 #   you may not use this file except in compliance with the License.
      7 #   You may obtain a copy of the License at
      8 #
      9 #       http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 #   Unless required by applicable law or agreed to in writing, software
     12 #   distributed under the License is distributed on an "AS IS" BASIS,
     13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 #   See the License for the specific language governing permissions and
     15 #   limitations under the License.
     16 
     17 import mock
     18 import shutil
     19 import tempfile
     20 import unittest
     21 
     22 from acts import keys
     23 from acts import signals
     24 from acts import test_runner
     25 
     26 import acts_android_device_test
     27 import mock_controller
     28 
     29 
     30 class ActsTestRunnerTest(unittest.TestCase):
     31     """This test class has unit tests for the implementation of everything
     32     under acts.test_runner.
     33     """
     34 
     35     def setUp(self):
     36         self.tmp_dir = tempfile.mkdtemp()
     37         self.base_mock_test_config = {
     38             "testbed": {
     39                 "name": "SampleTestBed",
     40             },
     41             "logpath": self.tmp_dir,
     42             "cli_args": None,
     43             "testpaths": ["./"],
     44             "icecream": 42,
     45             "extra_param": "haha"
     46         }
     47         self.mock_run_list = [('SampleTest', None)]
     48 
     49     def tearDown(self):
     50         shutil.rmtree(self.tmp_dir)
     51 
     52     def test_register_controller_no_config(self):
     53         tr = test_runner.TestRunner(self.base_mock_test_config,
     54                                     self.mock_run_list)
     55         with self.assertRaisesRegexp(signals.ControllerError,
     56                                      "No corresponding config found for"):
     57             tr.register_controller(mock_controller)
     58 
     59     def test_register_optional_controller_no_config(self):
     60         tr = test_runner.TestRunner(self.base_mock_test_config,
     61                                     self.mock_run_list)
     62         self.assertIsNone(
     63             tr.register_controller(mock_controller, required=False))
     64 
     65     def test_register_controller_third_party_dup_register(self):
     66         """Verifies correctness of registration, internal tally of controllers
     67         objects, and the right error happen when a controller module is
     68         registered twice.
     69         """
     70         mock_test_config = dict(self.base_mock_test_config)
     71         tb_key = keys.Config.key_testbed.value
     72         mock_ctrlr_config_name = mock_controller.ACTS_CONTROLLER_CONFIG_NAME
     73         mock_test_config[tb_key][mock_ctrlr_config_name] = ["magic1", "magic2"]
     74         tr = test_runner.TestRunner(mock_test_config, self.mock_run_list)
     75         tr.register_controller(mock_controller)
     76         registered_name = "mock_controller"
     77         self.assertTrue(mock_controller in tr.controller_registry)
     78         mock_ctrlrs = tr.controller_registry[mock_controller]
     79         self.assertEqual(mock_ctrlrs[0].magic, "magic1")
     80         self.assertEqual(mock_ctrlrs[1].magic, "magic2")
     81         expected_msg = "Controller module .* has already been registered."
     82         with self.assertRaisesRegexp(signals.ControllerError, expected_msg):
     83             tr.register_controller(mock_controller)
     84 
     85     def test_register_optional_controller_third_party_dup_register(self):
     86         """Verifies correctness of registration, internal tally of controllers
     87         objects, and the right error happen when an optional controller module
     88         is registered twice.
     89         """
     90         mock_test_config = dict(self.base_mock_test_config)
     91         tb_key = keys.Config.key_testbed.value
     92         mock_ctrlr_config_name = mock_controller.ACTS_CONTROLLER_CONFIG_NAME
     93         mock_test_config[tb_key][mock_ctrlr_config_name] = ["magic1", "magic2"]
     94         tr = test_runner.TestRunner(mock_test_config, self.mock_run_list)
     95         tr.register_controller(mock_controller, required=False)
     96         expected_msg = "Controller module .* has already been registered."
     97         with self.assertRaisesRegexp(signals.ControllerError, expected_msg):
     98             tr.register_controller(mock_controller, required=False)
     99 
    100     def test_register_controller_builtin_dup_register(self):
    101         """Same as test_register_controller_third_party_dup_register, except
    102         this is for a builtin controller module.
    103         """
    104         mock_test_config = dict(self.base_mock_test_config)
    105         tb_key = keys.Config.key_testbed.value
    106         mock_ctrlr_config_name = mock_controller.ACTS_CONTROLLER_CONFIG_NAME
    107         mock_ref_name = "haha"
    108         setattr(mock_controller, "ACTS_CONTROLLER_REFERENCE_NAME",
    109                 mock_ref_name)
    110         try:
    111             mock_ctrlr_ref_name = mock_controller.ACTS_CONTROLLER_REFERENCE_NAME
    112             mock_test_config[tb_key][mock_ctrlr_config_name] = [
    113                 "magic1", "magic2"
    114             ]
    115             tr = test_runner.TestRunner(mock_test_config, self.mock_run_list)
    116             tr.register_controller(mock_controller, builtin=True)
    117             self.assertTrue(mock_ref_name in tr.test_run_info)
    118             self.assertTrue(mock_controller in tr.controller_registry)
    119             mock_ctrlrs = tr.test_run_info[mock_ctrlr_ref_name]
    120             self.assertEqual(mock_ctrlrs[0].magic, "magic1")
    121             self.assertEqual(mock_ctrlrs[1].magic, "magic2")
    122             expected_msg = "Controller module .* has already been registered."
    123             with self.assertRaisesRegexp(signals.ControllerError,
    124                                          expected_msg):
    125                 tr.register_controller(mock_controller, builtin=True)
    126         finally:
    127             delattr(mock_controller, "ACTS_CONTROLLER_REFERENCE_NAME")
    128 
    129     def test_register_controller_no_get_info(self):
    130         mock_test_config = dict(self.base_mock_test_config)
    131         tb_key = keys.Config.key_testbed.value
    132         mock_ctrlr_config_name = mock_controller.ACTS_CONTROLLER_CONFIG_NAME
    133         mock_ref_name = "haha"
    134         get_info = getattr(mock_controller, "get_info")
    135         delattr(mock_controller, "get_info")
    136         try:
    137             mock_test_config[tb_key][mock_ctrlr_config_name] = [
    138                 "magic1", "magic2"
    139             ]
    140             tr = test_runner.TestRunner(mock_test_config, self.mock_run_list)
    141             tr.register_controller(mock_controller)
    142             self.assertEqual(tr.results.controller_info, {})
    143         finally:
    144             setattr(mock_controller, "get_info", get_info)
    145 
    146     def test_register_controller_return_value(self):
    147         mock_test_config = dict(self.base_mock_test_config)
    148         tb_key = keys.Config.key_testbed.value
    149         mock_ctrlr_config_name = mock_controller.ACTS_CONTROLLER_CONFIG_NAME
    150         mock_test_config[tb_key][mock_ctrlr_config_name] = ["magic1", "magic2"]
    151         tr = test_runner.TestRunner(mock_test_config, self.mock_run_list)
    152         magic_devices = tr.register_controller(mock_controller)
    153         self.assertEqual(magic_devices[0].magic, "magic1")
    154         self.assertEqual(magic_devices[1].magic, "magic2")
    155 
    156     def test_run_twice(self):
    157         """Verifies that:
    158         1. Repeated run works properly.
    159         2. The original configuration is not altered if a test controller
    160            module modifies configuration.
    161         """
    162         mock_test_config = dict(self.base_mock_test_config)
    163         tb_key = keys.Config.key_testbed.value
    164         mock_ctrlr_config_name = mock_controller.ACTS_CONTROLLER_CONFIG_NAME
    165         my_config = [{
    166             "serial": "xxxx",
    167             "magic": "Magic1"
    168         }, {
    169             "serial": "xxxx",
    170             "magic": "Magic2"
    171         }]
    172         mock_test_config[tb_key][mock_ctrlr_config_name] = my_config
    173         tr = test_runner.TestRunner(mock_test_config,
    174                                     [('IntegrationTest', None)])
    175         tr.run()
    176         self.assertFalse(tr.controller_registry)
    177         self.assertTrue(mock_test_config[tb_key][mock_ctrlr_config_name][0])
    178         tr.run()
    179         tr.stop()
    180         self.assertFalse(tr.controller_registry)
    181         results = tr.results.summary_dict()
    182         self.assertEqual(results["Requested"], 2)
    183         self.assertEqual(results["Executed"], 2)
    184         self.assertEqual(results["Passed"], 2)
    185         expected_info = {
    186             'MagicDevice': [{
    187                 'MyMagic': {
    188                     'magic': 'Magic1'
    189                 }
    190             }, {
    191                 'MyMagic': {
    192                     'magic': 'Magic2'
    193                 }
    194             }]
    195         }
    196         self.assertEqual(tr.results.controller_info, expected_info)
    197 
    198     @mock.patch(
    199         'acts.controllers.adb.AdbProxy',
    200         return_value=acts_android_device_test.MockAdbProxy(1))
    201     @mock.patch(
    202         'acts.controllers.fastboot.FastbootProxy',
    203         return_value=acts_android_device_test.MockFastbootProxy(1))
    204     @mock.patch(
    205         'acts.controllers.android_device.list_adb_devices', return_value=["1"])
    206     @mock.patch(
    207         'acts.controllers.android_device.get_all_instances',
    208         return_value=acts_android_device_test.get_mock_ads(1))
    209     @mock.patch(
    210         'acts.controllers.android_device.AndroidDevice.ensure_screen_on',
    211         return_value=True)
    212     @mock.patch(
    213         'acts.controllers.android_device.AndroidDevice.exit_setup_wizard',
    214         return_value=True)
    215     def test_run_two_test_classes(self, mock_exit_setup_wizard,
    216                                   mock_ensure_screen_on, mock_get_all,
    217                                   mock_list_adb, mock_fastboot, mock_adb):
    218         """Verifies that runing more than one test class in one test run works
    219         proerly.
    220 
    221         This requires using a built-in controller module. Using AndroidDevice
    222         module since it has all the mocks needed already.
    223         """
    224         mock_test_config = dict(self.base_mock_test_config)
    225         tb_key = keys.Config.key_testbed.value
    226         mock_ctrlr_config_name = mock_controller.ACTS_CONTROLLER_CONFIG_NAME
    227         my_config = [{
    228             "serial": "xxxx",
    229             "magic": "Magic1"
    230         }, {
    231             "serial": "xxxx",
    232             "magic": "Magic2"
    233         }]
    234         mock_test_config[tb_key][mock_ctrlr_config_name] = my_config
    235         mock_test_config[tb_key]["AndroidDevice"] = [{
    236             "serial": "1",
    237             "skip_sl4a": True
    238         }]
    239         tr = test_runner.TestRunner(mock_test_config,
    240                                     [('IntegrationTest', None),
    241                                      ('IntegrationTest', None)])
    242         tr.run()
    243         tr.stop()
    244         self.assertFalse(tr.controller_registry)
    245         results = tr.results.summary_dict()
    246         self.assertEqual(results["Requested"], 2)
    247         self.assertEqual(results["Executed"], 2)
    248         self.assertEqual(results["Passed"], 2)
    249 
    250     def test_verify_controller_module(self):
    251         test_runner.TestRunner.verify_controller_module(mock_controller)
    252 
    253     def test_verify_controller_module_null_attr(self):
    254         try:
    255             tmp = mock_controller.ACTS_CONTROLLER_CONFIG_NAME
    256             mock_controller.ACTS_CONTROLLER_CONFIG_NAME = None
    257             msg = "Controller interface .* in .* cannot be null."
    258             with self.assertRaisesRegexp(signals.ControllerError, msg):
    259                 test_runner.TestRunner.verify_controller_module(
    260                     mock_controller)
    261         finally:
    262             mock_controller.ACTS_CONTROLLER_CONFIG_NAME = tmp
    263 
    264     def test_verify_controller_module_missing_attr(self):
    265         try:
    266             tmp = mock_controller.ACTS_CONTROLLER_CONFIG_NAME
    267             delattr(mock_controller, "ACTS_CONTROLLER_CONFIG_NAME")
    268             msg = "Module .* missing required controller module attribute"
    269             with self.assertRaisesRegexp(signals.ControllerError, msg):
    270                 test_runner.TestRunner.verify_controller_module(
    271                     mock_controller)
    272         finally:
    273             setattr(mock_controller, "ACTS_CONTROLLER_CONFIG_NAME", tmp)
    274 
    275 
    276 if __name__ == "__main__":
    277     unittest.main()
    278