Source code

Revision control

Copy as Markdown

Other Tools

#!/usr/bin/env python
import pathlib
from unittest import mock
import mozunit
import pytest
from mozperftest.environment import SYSTEM
from mozperftest.system.android import DeviceError
from mozperftest.system.android_perf_tuner import PerformanceTuner
from mozperftest.tests.support import get_running_env, requests_content, temp_file
from mozperftest.utils import silence
class FakeDevice:
def __init__(self, **args):
self.apps = []
self._logger = mock.MagicMock()
self._have_su = True
self._have_android_su = True
self._have_root_shell = True
self.is_rooted = True
def clear_logcat(self, *args, **kwargs):
return True
def shell_output(self, *args, **kwargs):
return "A Fake Device"
def shell_bool(self, *args, **kwargs):
return True
def uninstall_app(self, apk_name):
return True
def install_app(self, apk, replace=True):
if apk not in self.apps:
self.apps.append(apk)
def is_app_installed(self, app_name):
return True
@mock.patch("mozperftest.system.android.ADBLoggedDevice", new=FakeDevice)
def test_android():
args = {
"flavor": "mobile-browser",
"android-install-apk": ["this.apk"],
"android": True,
"android-timeout": 30,
"android-capture-adb": "stdout",
"android-app-name": "org.mozilla.fenix",
}
mach_cmd, metadata, env = get_running_env(**args)
system = env.layers[SYSTEM]
with system as android, silence(system):
android(metadata)
@mock.patch("mozperftest.system.android.ADBLoggedDevice")
def test_android_perf_tuning_rooted(device):
# Check to make sure that performance tuning runs
# on rooted devices correctly
device._have_su = True
device._have_android_su = True
device._have_root_shell = True
device.is_rooted = True
with mock.patch(
"mozperftest.system.android_perf_tuner.PerformanceTuner.set_kernel_performance_parameters"
) as mockfunc:
tuner = PerformanceTuner(device)
tuner.tune_performance()
mockfunc.assert_called()
@mock.patch("mozperftest.system.android.ADBLoggedDevice")
def test_android_perf_tuning_nonrooted(device):
# Check to make sure that performance tuning runs
# on non-rooted devices correctly
device._have_su = False
device._have_android_su = False
device._have_root_shell = False
device.is_rooted = False
with mock.patch(
"mozperftest.system.android_perf_tuner.PerformanceTuner.set_kernel_performance_parameters"
) as mockfunc:
tuner = PerformanceTuner(device)
tuner.tune_performance()
mockfunc.assert_not_called()
class Device:
def __init__(self, name, rooted=True):
self.device_name = name
self.is_rooted = rooted
self.call_counts = 0
@property
def _logger(self):
return self
def noop(self, *args, **kw):
pass
debug = error = info = clear_logcat = noop
def shell_bool(self, *args, **kw):
self.call_counts += 1
return True
def shell_output(self, *args, **kw):
self.call_counts += 1
return self.device_name
def test_android_perf_tuning_all_calls():
# Check without mocking PerformanceTuner functions
for name in ["?"]:
device = Device(name)
tuner = PerformanceTuner(device)
tuner.tune_performance()
assert device.call_counts > 1
@mock.patch("mozperftest.system.android_perf_tuner.PerformanceTuner")
@mock.patch("mozperftest.system.android.ADBLoggedDevice")
def test_android_with_perftuning(device, tuner):
args = {
"flavor": "mobile-browser",
"android-install-apk": ["this.apk"],
"android": True,
"android-timeout": 30,
"android-capture-adb": "stdout",
"android-app-name": "org.mozilla.fenix",
"android-perf-tuning": True,
}
tuner.return_value = tuner
mach_cmd, metadata, env = get_running_env(**args)
system = env.layers[SYSTEM]
with system as android, silence(system):
android(metadata)
# Make sure the tuner was actually called
tuner.tune_performance.assert_called()
def test_android_failure():
# no patching so it'll try for real and fail
args = {
"flavor": "mobile-browser",
"android-install-apk": ["this"],
"android": True,
"android-timeout": 120,
"android-app-name": "org.mozilla.fenix",
"android-capture-adb": "stdout",
}
mach_cmd, metadata, env = get_running_env(**args)
system = env.layers[SYSTEM]
with system as android, silence(system), pytest.raises(DeviceError):
android(metadata)
@mock.patch(
"mozperftest.system.android.AndroidDevice.custom_apk_exists", new=lambda x: False
)
@mock.patch("mozperftest.utils.requests.get", new=requests_content())
@mock.patch("mozperftest.system.android.ADBLoggedDevice")
def test_android_apk_alias(device):
args = {
"flavor": "mobile-browser",
"android-install-apk": ["fenix_nightly_armeabi_v7a"],
"android": True,
"android-app-name": "org.mozilla.fenix",
"android-capture-adb": "stdout",
}
mach_cmd, metadata, env = get_running_env(**args)
system = env.layers[SYSTEM]
with system as android, silence(system):
android(metadata)
assert device.mock_calls[1][1][0] == "org.mozilla.fenix"
assert device.mock_calls[2][1][0].endswith("target.apk")
@mock.patch("mozperftest.utils.requests.get", new=requests_content())
@mock.patch("mozperftest.system.android.ADBLoggedDevice")
def test_android_timeout(device):
args = {
"flavor": "mobile-browser",
"android-install-apk": ["gve_nightly_api16"],
"android": True,
"android-timeout": 60,
"android-app-name": "org.mozilla.geckoview_example",
"android-capture-adb": "stdout",
}
mach_cmd, metadata, env = get_running_env(**args)
system = env.layers[SYSTEM]
with system as android, silence(system):
android(metadata)
options = device.mock_calls[0][-1]
assert options["timeout"] == 60
@mock.patch("mozperftest.utils.requests.get", new=requests_content())
def test_android_log_adb():
with temp_file() as log_adb:
args = {
"flavor": "mobile-browser",
"android-install-apk": ["gve_nightly_api16"],
"android": True,
"android-timeout": 60,
"android-app-name": "org.mozilla.geckoview_example",
"android-capture-adb": log_adb,
}
mach_cmd, metadata, env = get_running_env(**args)
system = env.layers[SYSTEM]
with system as android, silence(system), pytest.raises(DeviceError):
android(metadata)
with open(log_adb) as f:
assert "DEBUG ADBLoggedDevice" in f.read()
@mock.patch("mozperftest.utils.requests.get", new=requests_content())
@mock.patch("mozperftest.system.android.ADBLoggedDevice")
def test_android_log_cat(device):
with temp_file() as log_cat:
args = {
"flavor": "mobile-browser",
"android-install-apk": ["gve_nightly_api16"],
"android": True,
"android-timeout": 60,
"android-app-name": "org.mozilla.geckoview_example",
"android-capture-logcat": log_cat,
"android-clear-logcat": True,
"android-capture-adb": "stdout",
}
mach_cmd, metadata, env = get_running_env(**args)
system = env.layers[SYSTEM]
andro = system.layers[1]
with system as layer, silence(system):
andro.device = device
andro.device.get_logcat = mock.Mock(result_value=[])
layer(metadata)
andro.device.get_logcat.assert_called()
andro.device.clear_logcat.assert_called()
@mock.patch("mozperftest.system.android.AndroidDevice.setup", new=mock.MagicMock)
@mock.patch("mozperftest.system.android.Path")
@mock.patch("mozperftest.system.android.ADBLoggedDevice", new=FakeDevice)
def test_android_custom_apk(mozperftest_android_path):
args = {
"flavor": "mobile-browser",
"android": True,
}
with temp_file(name="user_upload.apk", content="") as sample_apk:
sample_apk = pathlib.Path(sample_apk)
mozperftest_android_path.return_value = sample_apk
mach_cmd, metadata, env = get_running_env(**args)
system = env.layers[SYSTEM]
android = system.layers[1]
with system as _, silence(system):
assert android._custom_apk_path is None
assert android.custom_apk_exists()
assert android.custom_apk_path == sample_apk
mozperftest_android_path.assert_called_once()
@mock.patch("mozperftest.system.android.AndroidDevice.setup", new=mock.MagicMock)
@mock.patch("mozperftest.system.android.Path.exists")
@mock.patch("mozperftest.system.android.ADBLoggedDevice", new=FakeDevice)
def test_android_custom_apk_nonexistent(path_exists):
args = {
"flavor": "mobile-browser",
"android": True,
}
path_exists.return_value = False
mach_cmd, metadata, env = get_running_env(**args)
system = env.layers[SYSTEM]
android = system.layers[1]
with system as _, silence(system):
assert android._custom_apk_path is None
assert not android.custom_apk_exists()
assert android.custom_apk_path is None
path_exists.assert_called()
@mock.patch("mozperftest.system.android.Path")
@mock.patch("mozperftest.system.android.ADBLoggedDevice", new=FakeDevice)
def test_android_setup_custom_apk(mozperftest_android_path):
args = {
"flavor": "mobile-browser",
"android": True,
}
with temp_file(name="user_upload.apk", content="") as sample_apk:
sample_apk = pathlib.Path(sample_apk)
mozperftest_android_path.return_value = sample_apk
mach_cmd, metadata, env = get_running_env(**args)
system = env.layers[SYSTEM]
android = system.layers[1]
with system as _, silence(system):
# The custom apk should be found immediately, and it
# should replace any --android-install-apk settings
assert android._custom_apk_path == sample_apk
assert env.get_arg("android-install-apk") == [sample_apk]
mozperftest_android_path.assert_called_once()
if __name__ == "__main__":
mozunit.main()