aboutsummaryrefslogtreecommitdiff
path: root/tests/mobly
diff options
context:
space:
mode:
authorchuanhsiao <49941275+chuanhsiao@users.noreply.github.com>2021-01-11 13:06:56 +0800
committerericth <ericth@google.com>2021-01-13 13:51:37 +0800
commitfecc70f0e1ed63dd44b88f262ee3384c8135587c (patch)
tree383475e65973fd070341386a1310dc5af5dfc73f /tests/mobly
parent0d063ee53ec322434fea5cbb705a6551e1431d3b (diff)
downloadmobly-fecc70f0e1ed63dd44b88f262ee3384c8135587c.tar.gz
Add a retry mechanism for the ADB command "root”. (#690)
Error "adb: unable to connect for root: closed" often occurs if `adb root` is called right after `adb reboot`. Add a retry for `adb root` to avoid this.
Diffstat (limited to 'tests/mobly')
-rwxr-xr-xtests/mobly/controllers/android_device_lib/adb_test.py54
1 files changed, 54 insertions, 0 deletions
diff --git a/tests/mobly/controllers/android_device_lib/adb_test.py b/tests/mobly/controllers/android_device_lib/adb_test.py
index e4180cf..e920bbd 100755
--- a/tests/mobly/controllers/android_device_lib/adb_test.py
+++ b/tests/mobly/controllers/android_device_lib/adb_test.py
@@ -40,6 +40,12 @@ MOCK_OPTIONS_INSTRUMENTATION_COMMAND = ('am instrument -r -w -e option1 value1'
'.instrumentation.tests/com.android'
'.common.support.test.runner'
'.AndroidJUnitRunner')
+
+# Mock root command outputs.
+MOCK_ROOT_SUCCESS_OUTPUT = 'adbd is already running as root'
+MOCK_ROOT_ERROR_OUTPUT = (
+ 'adb: unable to connect for root: closed'.encode('utf-8'))
+
# Mock Shell Command
MOCK_SHELL_COMMAND = 'ls'
MOCK_COMMAND_OUTPUT = '/system/bin/ls'.encode('utf-8')
@@ -712,6 +718,54 @@ class AdbTest(unittest.TestCase):
self.assertEqual(stderr,
mock_execute_and_process_stdout.return_value)
+ @mock.patch.object(adb.AdbProxy, '_exec_cmd')
+ def test_root_success(self, mock_exec_cmd):
+ mock_exec_cmd.return_value = MOCK_ROOT_SUCCESS_OUTPUT
+ output = adb.AdbProxy().root()
+ mock_exec_cmd.assert_called_once_with(
+ ['adb', 'root'],
+ shell=False,
+ timeout=None,
+ stderr=None)
+ self.assertEqual(output, MOCK_ROOT_SUCCESS_OUTPUT)
+
+ @mock.patch('time.sleep', return_value=mock.MagicMock())
+ @mock.patch.object(adb.AdbProxy, '_exec_cmd')
+ def test_root_success_with_retry(self, mock_exec_cmd, mock_sleep):
+ mock_exec_cmd.side_effect = [
+ adb.AdbError('adb root', '', MOCK_ROOT_ERROR_OUTPUT, 1),
+ MOCK_ROOT_SUCCESS_OUTPUT]
+ output = adb.AdbProxy().root()
+ mock_exec_cmd.assert_called_with(
+ ['adb', 'root'],
+ shell=False,
+ timeout=None,
+ stderr=None)
+ self.assertEqual(output, MOCK_ROOT_SUCCESS_OUTPUT)
+ self.assertEqual(mock_sleep.call_count, 1)
+ mock_sleep.assert_called_with(10)
+
+ @mock.patch('time.sleep', return_value=mock.MagicMock())
+ @mock.patch.object(adb.AdbProxy, '_exec_cmd')
+ def test_root_raises_adb_error_when_all_retries_failed(self, mock_exec_cmd,
+ mock_sleep):
+ mock_exec_cmd.side_effect = adb.AdbError('adb root',
+ '',
+ MOCK_ROOT_ERROR_OUTPUT,
+ 1)
+ expected_msg = ('Error executing adb cmd "adb root". '
+ 'ret: 1, stdout: , stderr: %s' %
+ MOCK_ROOT_ERROR_OUTPUT)
+ with self.assertRaisesRegex(adb.AdbError, expected_msg):
+ adb.AdbProxy().root()
+ mock_exec_cmd.assert_called_with(
+ ['adb', 'root'],
+ shell=False,
+ timeout=None,
+ stderr=None)
+ self.assertEqual(mock_sleep.call_count, 2)
+ mock_sleep.assert_called_with(10)
+
def test_has_shell_command_called_correctly(self):
with mock.patch.object(adb.AdbProxy, '_exec_cmd') as mock_exec_cmd:
mock_exec_cmd.return_value = MOCK_DEFAULT_COMMAND_OUTPUT