summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAng Li <angli@google.com>2016-06-21 18:29:06 -0700
committerNathan Harold <nharold@google.com>2016-06-22 13:43:03 -0700
commit4848c64c31516d8802a8b9ea33f8b896ef19fd7e (patch)
treeb611228861d854c72224bba0edf3a58806e2a0ad
parent0f2874db69d7bf42e1d02bdf555412e8093737d0 (diff)
downloadplatform_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.py27
-rwxr-xr-xacts/framework/tests/acts_test_runner_test.py85
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()