Add an arg to check the number of controller objects (#10)
Add an arg in TestRunner.register_controller to check the number of controller objects meets minimum requirement.
Also clean up unit tests for register_controller:
* Add a test for the new arg
* Remove an old test for the now-removed builtin controller code path
* Rename some tests to match removing the builtin controller code path
* Remove an implementation leftover check.
diff --git a/mobly/test_runner.py b/mobly/test_runner.py
index a05ba2a..dba02d2 100644
--- a/mobly/test_runner.py
+++ b/mobly/test_runner.py
@@ -283,7 +283,7 @@
("Controller interface %s in %s cannot be null.") % (
attr, module.__name__))
- def register_controller(self, module, required=True):
+ def register_controller(self, module, required=True, min_number=1):
"""Registers an Mobly controller module for a test run.
An Mobly controller module is a Python lib that can be used to control
@@ -329,8 +329,12 @@
Args:
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.
+ controller module raises exceptions. If False, the objects
+ failed to instantiate will be skipped.
+ min_number: An integer that is the minimum number of controller
+ objects to be created. Default is one, since you should
+ not register a controller module without expecting at
+ least one object.
Returns:
A list of controller objects instantiated from controller_module, or
@@ -342,6 +346,8 @@
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.
+ If the actual number of objects instantiated is less than the
+ min_number, ControllerError is raised.
"""
TestRunner.verify_controller_module(module)
# Use the module's name as the ref name
@@ -377,6 +383,13 @@
raise signals.ControllerError(
"Controller module %s did not return a list of objects, abort."
% module_ref_name)
+ # Check we got enough controller objects to continue.
+ actual_number = len(objects)
+ if actual_number < min_number:
+ module.destroy(objects)
+ raise signals.ControllerError(
+ "Expected to get at least %d controller objects, got %d." %
+ (min_number, actual_number))
self.controller_registry[module_ref_name] = objects
# Collect controller information and write to test result.
# Implementation of "get_info" is optional for a controller module.
diff --git a/tests/mobly_test_runner_test.py b/tests/mobly_test_runner_test.py
index 37ee373..6e25f81 100755
--- a/tests/mobly_test_runner_test.py
+++ b/tests/mobly_test_runner_test.py
@@ -56,13 +56,13 @@
"No corresponding config found for"):
tr.register_controller(mock_controller)
- def test_register_optional_controller_no_config(self):
+ def test_register_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):
+ def test_register_controller_dup_register(self):
"""Verifies correctness of registration, internal tally of controllers
objects, and the right error happen when a controller module is
registered twice.
@@ -83,21 +83,6 @@
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.MOBLY_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_no_get_info(self):
mock_test_config = dict(self.base_mock_test_config)
tb_key = keys.Config.key_testbed.value
@@ -124,6 +109,16 @@
self.assertEqual(magic_devices[0].magic, "magic1")
self.assertEqual(magic_devices[1].magic, "magic2")
+ def test_register_controller_less_than_min_number(self):
+ mock_test_config = dict(self.base_mock_test_config)
+ tb_key = keys.Config.key_testbed.value
+ mock_ctrlr_config_name = mock_controller.MOBLY_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)
+ expected_msg = "Expected to get at least 3 controller objects, got 2."
+ with self.assertRaisesRegexp(signals.ControllerError, expected_msg):
+ tr.register_controller(mock_controller, min_number=3)
+
def test_run_twice(self):
"""Verifies that:
1. Repeated run works properly.