aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAng Li <angli@google.com>2024-01-22 17:32:57 -0800
committerGitHub <noreply@github.com>2024-01-22 17:32:57 -0800
commit68724d8fa39e779c7d6f960a7f4d4822ae26903c (patch)
treec09659d8e1a0828fb0567eaaf5f1753ef6694b01
parent3da49fa2dd58da889ac9673ef055d74ea2497dd7 (diff)
downloadmobly-68724d8fa39e779c7d6f960a7f4d4822ae26903c.tar.gz
Cache `AndroidDevice#model` to reduce fastboot calls (#910)
fastboot calls are expensive and can increase USB flakiness when issued in large amount. So we should reduce fastboot calls whenever possible
-rw-r--r--mobly/controllers/android_device.py3
-rwxr-xr-xtests/mobly/controllers/android_device_test.py24
2 files changed, 26 insertions, 1 deletions
diff --git a/mobly/controllers/android_device.py b/mobly/controllers/android_device.py
index 981af27..20c5762 100644
--- a/mobly/controllers/android_device.py
+++ b/mobly/controllers/android_device.py
@@ -14,6 +14,7 @@
import contextlib
import enum
+import functools
import logging
import os
import re
@@ -845,7 +846,7 @@ class AndroidDevice:
def is_rootable(self):
return not self.is_bootloader and self.build_info['debuggable'] == '1'
- @property
+ @functools.cached_property
def model(self):
"""The Android code name for the device."""
# If device is in bootloader mode, get mode name from fastboot.
diff --git a/tests/mobly/controllers/android_device_test.py b/tests/mobly/controllers/android_device_test.py
index fc939db..81c2965 100755
--- a/tests/mobly/controllers/android_device_test.py
+++ b/tests/mobly/controllers/android_device_test.py
@@ -495,6 +495,30 @@ class AndroidDeviceTest(unittest.TestCase):
@mock.patch(
'mobly.controllers.android_device_lib.adb.AdbProxy',
+ return_value=mock_android_device.MockAdbProxy('1'),
+ )
+ @mock.patch(
+ 'mobly.controllers.android_device.list_fastboot_devices',
+ return_value=mock.MagicMock(),
+ )
+ def test_AndroidDevice_model_property_is_cached(
+ self, mock_list_fastboot_devices, _
+ ):
+ """Accessing `model` a second time shouldn't invoke all the fastboot/adb
+ calls again.
+ """
+ mock_serial = 1
+ # mock returns '2' so the device is not considered in bootloader mode.
+ mock_list_fastboot_devices.return_value = ['2']
+ ad = android_device.AndroidDevice(serial=mock_serial)
+ ad.model
+ mock_count_first = mock_list_fastboot_devices.call_count
+ ad.model # access `model` again.
+ mock_count_second = mock_list_fastboot_devices.call_count
+ self.assertEqual(mock_count_first, mock_count_second)
+
+ @mock.patch(
+ 'mobly.controllers.android_device_lib.adb.AdbProxy',
return_value=mock_android_device.MockAdbProxy(
'1',
mock_properties={