diff options
author | Ang Li <angli@google.com> | 2016-06-21 18:29:06 -0700 |
---|---|---|
committer | Nathan Harold <nharold@google.com> | 2016-06-22 13:43:03 -0700 |
commit | 4848c64c31516d8802a8b9ea33f8b896ef19fd7e (patch) | |
tree | b611228861d854c72224bba0edf3a58806e2a0ad | |
parent | 0f2874db69d7bf42e1d02bdf555412e8093737d0 (diff) | |
download | platform_tools_test_connectivity-4848c64c31516d8802a8b9ea33f8b896ef19fd7e.tar.gz platform_tools_test_connectivity-4848c64c31516d8802a8b9ea33f8b896ef19fd7e.tar.bz2 platform_tools_test_connectivity-4848c64c31516d8802a8b9ea33f8b896ef19fd7e.zip |
Provide an option to skip certain controller registrations if no
config is provided.
Bug=29335724
Change-Id: I1b10040b264969879067b4d881ca065c8848abc9
(cherry picked from commit 9a52d83212a13c45cf6f6beb865e7aefd4ba4ec0)
-rw-r--r-- | acts/framework/acts/test_runner.py | 27 | ||||
-rwxr-xr-x | acts/framework/tests/acts_test_runner_test.py | 85 |
2 files changed, 95 insertions, 17 deletions
diff --git a/acts/framework/acts/test_runner.py b/acts/framework/acts/test_runner.py index bcf17063ea..bd4c678152 100644 --- a/acts/framework/acts/test_runner.py +++ b/acts/framework/acts/test_runner.py @@ -14,6 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +__author__ = "angli@google.com" + from future import standard_library standard_library.install_aliases() @@ -159,7 +161,7 @@ class TestRunner(object): raise signals.ControllerError(("Controller interface %s in %s " "cannot be null.") % (attr, module.__name__)) - def register_controller(self, module): + def register_controller(self, module, required=True): """Registers a controller module for a test run. This declares a controller dependency of this test class. If the target @@ -169,13 +171,20 @@ class TestRunner(object): Params: module: A module that follows the controller module interface. + required: A bool. If True, failing to register the specified + controller module raises exceptions. If False, returns + None upon failures. Returns: - A list of controller objects instantiated from controller_module. + A list of controller objects instantiated from controller_module, or + None. Raises: - ControllerError is raised if no corresponding config can be found, - or if the controller module has already been registered. + When required is True, ControllerError is raised if no corresponding + config can be found. + Regardless of the value of "required", ControllerError is raised if + the controller module has already been registered or any other error + occurred in the registration process. """ TestRunner.verify_controller_module(module) try: @@ -195,8 +204,14 @@ class TestRunner(object): create = module.create module_config_name = module.ACTS_CONTROLLER_CONFIG_NAME if module_config_name not in self.testbed_configs: - raise signals.ControllerError(("No corresponding config found for" - " %s") % module_config_name) + if required: + raise signals.ControllerError( + "No corresponding config found for %s" % + module_config_name) + self.log.warning( + "No corresponding config found for optional controller %s", + module_config_name) + return None try: # Make a deep copy of the config to pass to the controller module, # in case the controller module modifies the config internally. diff --git a/acts/framework/tests/acts_test_runner_test.py b/acts/framework/tests/acts_test_runner_test.py index f9c7b8e41b..40ff6fee0a 100755 --- a/acts/framework/tests/acts_test_runner_test.py +++ b/acts/framework/tests/acts_test_runner_test.py @@ -15,6 +15,8 @@ # limitations under the License. + +import mock import shutil import tempfile import unittest @@ -33,7 +35,7 @@ class ActsTestRunnerTest(unittest.TestCase): def setUp(self): self.tmp_dir = tempfile.mkdtemp() self.base_mock_test_config = { - "testbed":{ + "testbed": { "name": "SampleTestBed", }, "logpath": self.tmp_dir, @@ -54,6 +56,12 @@ class ActsTestRunnerTest(unittest.TestCase): "No corresponding config found for"): tr.register_controller(mock_controller) + def test_register_optional_controller_no_config(self): + tr = test_runner.TestRunner(self.base_mock_test_config, + self.mock_run_list) + self.assertIsNone(tr.register_controller(mock_controller, + required=False)) + def test_register_controller_third_party_dup_register(self): """Verifies correctness of registration, internal tally of controllers objects, and the right error happen when a controller module is @@ -75,6 +83,21 @@ class ActsTestRunnerTest(unittest.TestCase): with self.assertRaisesRegexp(signals.ControllerError, expected_msg): tr.register_controller(mock_controller) + def test_register_optional_controller_third_party_dup_register(self): + """Verifies correctness of registration, internal tally of controllers + objects, and the right error happen when an optional controller module + is registered twice. + """ + mock_test_config = dict(self.base_mock_test_config) + tb_key = keys.Config.key_testbed.value + mock_ctrlr_config_name = mock_controller.ACTS_CONTROLLER_CONFIG_NAME + mock_test_config[tb_key][mock_ctrlr_config_name] = ["magic1", "magic2"] + tr = test_runner.TestRunner(mock_test_config, self.mock_run_list) + tr.register_controller(mock_controller, required=False) + expected_msg = "Controller module .* has already been registered." + with self.assertRaisesRegexp(signals.ControllerError, expected_msg): + tr.register_controller(mock_controller, required=False) + def test_register_controller_builtin_dup_register(self): """Same as test_register_controller_third_party_dup_register, except this is for a builtin controller module. @@ -83,12 +106,12 @@ class ActsTestRunnerTest(unittest.TestCase): tb_key = keys.Config.key_testbed.value mock_ctrlr_config_name = mock_controller.ACTS_CONTROLLER_CONFIG_NAME mock_ref_name = "haha" - setattr(mock_controller, - "ACTS_CONTROLLER_REFERENCE_NAME", + setattr(mock_controller, "ACTS_CONTROLLER_REFERENCE_NAME", mock_ref_name) try: mock_ctrlr_ref_name = mock_controller.ACTS_CONTROLLER_REFERENCE_NAME - mock_test_config[tb_key][mock_ctrlr_config_name] = ["magic1", "magic2"] + mock_test_config[tb_key][mock_ctrlr_config_name] = ["magic1", + "magic2"] tr = test_runner.TestRunner(mock_test_config, self.mock_run_list) tr.register_controller(mock_controller) self.assertTrue(mock_ref_name in tr.test_run_info) @@ -98,7 +121,8 @@ class ActsTestRunnerTest(unittest.TestCase): self.assertEqual(mock_ctrlrs[1].magic, "magic2") self.assertTrue(tr.controller_destructors[mock_ctrlr_ref_name]) expected_msg = "Controller module .* has already been registered." - with self.assertRaisesRegexp(signals.ControllerError, expected_msg): + with self.assertRaisesRegexp(signals.ControllerError, + expected_msg): tr.register_controller(mock_controller) finally: delattr(mock_controller, "ACTS_CONTROLLER_REFERENCE_NAME") @@ -122,10 +146,12 @@ class ActsTestRunnerTest(unittest.TestCase): mock_test_config = dict(self.base_mock_test_config) tb_key = keys.Config.key_testbed.value mock_ctrlr_config_name = mock_controller.ACTS_CONTROLLER_CONFIG_NAME - my_config = [{"serial": "xxxx", "magic": "Magic1"}, - {"serial": "xxxx", "magic": "Magic2"}] + my_config = [{"serial": "xxxx", + "magic": "Magic1"}, {"serial": "xxxx", + "magic": "Magic2"}] mock_test_config[tb_key][mock_ctrlr_config_name] = my_config - tr = test_runner.TestRunner(mock_test_config, [('IntegrationTest', None)]) + tr = test_runner.TestRunner(mock_test_config, [('IntegrationTest', + None)]) tr.run() self.assertFalse(tr.controller_registry) self.assertFalse(tr.controller_destructors) @@ -139,6 +165,41 @@ class ActsTestRunnerTest(unittest.TestCase): self.assertEqual(results["Executed"], 2) self.assertEqual(results["Passed"], 2) + @mock.patch('acts.controllers.adb.AdbProxy', + return_value=acts_android_device_test.MockAdbProxy(1)) + @mock.patch('acts.controllers.android_device.list_adb_devices', + return_value=["1"]) + @mock.patch('acts.controllers.android_device.get_all_instances', + return_value=acts_android_device_test.get_mock_ads(1)) + def test_run_two_test_classes(self, mock_adb, mock_list_adb, mock_get_all): + """Verifies that runing more than one test class in one test run works + proerly. + + This requires using a built-in controller module. Using AndroidDevice + module since it has all the mocks needed already. + """ + mock_test_config = dict(self.base_mock_test_config) + tb_key = keys.Config.key_testbed.value + mock_ctrlr_config_name = mock_controller.ACTS_CONTROLLER_CONFIG_NAME + my_config = [{"serial": "xxxx", "magic": "Magic1"}, + {"serial": "xxxx", "magic": "Magic2"}] + mock_test_config[tb_key][mock_ctrlr_config_name] = my_config + mock_test_config[tb_key]["AndroidDevice"] = [ + {"serial": "1", + "skip_sl4a": True} + ] + tr = test_runner.TestRunner(mock_test_config, + [('IntegrationTest', None), + ('IntegrationTest', None)]) + tr.run() + tr.stop() + self.assertFalse(tr.controller_registry) + self.assertFalse(tr.controller_destructors) + results = tr.results.summary_dict() + self.assertEqual(results["Requested"], 2) + self.assertEqual(results["Executed"], 2) + self.assertEqual(results["Passed"], 2) + def test_verify_controller_module(self): test_runner.TestRunner.verify_controller_module(mock_controller) @@ -148,7 +209,8 @@ class ActsTestRunnerTest(unittest.TestCase): mock_controller.ACTS_CONTROLLER_CONFIG_NAME = None msg = "Controller interface .* in .* cannot be null." with self.assertRaisesRegexp(signals.ControllerError, msg): - test_runner.TestRunner.verify_controller_module(mock_controller) + test_runner.TestRunner.verify_controller_module( + mock_controller) finally: mock_controller.ACTS_CONTROLLER_CONFIG_NAME = tmp @@ -158,10 +220,11 @@ class ActsTestRunnerTest(unittest.TestCase): delattr(mock_controller, "ACTS_CONTROLLER_CONFIG_NAME") msg = "Module .* missing required controller module attribute" with self.assertRaisesRegexp(signals.ControllerError, msg): - test_runner.TestRunner.verify_controller_module(mock_controller) + test_runner.TestRunner.verify_controller_module( + mock_controller) finally: setattr(mock_controller, "ACTS_CONTROLLER_CONFIG_NAME", tmp) if __name__ == "__main__": - unittest.main()
\ No newline at end of file + unittest.main() |