зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 20 changesets (bug 1486004, bug 1653094) for wrench bustages. CLOSED TREE
Backed out changeset 120c64ebdea3 (bug 1486004) Backed out changeset b10f105b1c36 (bug 1486004) Backed out changeset 7f186e6bcccc (bug 1486004) Backed out changeset cdda7b349cd8 (bug 1486004) Backed out changeset 650c47e81402 (bug 1486004) Backed out changeset 2bcca7cf3f1b (bug 1486004) Backed out changeset e1df276f8a8d (bug 1486004) Backed out changeset f6f5e7f2bd0a (bug 1486004) Backed out changeset 1c56cb03ce53 (bug 1486004) Backed out changeset 582cd190f174 (bug 1486004) Backed out changeset 7c162e1b3a79 (bug 1486004) Backed out changeset d1088e178216 (bug 1486004) Backed out changeset 40763f4afd26 (bug 1486004) Backed out changeset f20eb5b5a670 (bug 1486004) Backed out changeset 6349ee0bd63f (bug 1486004) Backed out changeset 7c23729053f6 (bug 1486004) Backed out changeset 49586014bd29 (bug 1486004) Backed out changeset 07971e82ae85 (bug 1653094) Backed out changeset 47e7295e9c19 (bug 1653094) Backed out changeset 57a25bbeec37 (bug 1653094)
This commit is contained in:
Родитель
e5880f1a26
Коммит
1eb115035d
|
@ -62,7 +62,7 @@ class RemoteAutomation(object):
|
|||
for |timeout| seconds.
|
||||
"""
|
||||
if self.device.is_file(self.remoteLog):
|
||||
self.device.rm(self.remoteLog)
|
||||
self.device.rm(self.remoteLog, root=True)
|
||||
self.log.info("remoteautomation.py | runApp deleted %s" % self.remoteLog)
|
||||
|
||||
if timeout == -1:
|
||||
|
@ -209,7 +209,7 @@ class RemoteAutomation(object):
|
|||
|
||||
if self.appName and self.device.process_exist(self.appName):
|
||||
print("remoteautomation.py %s is already running. Stopping..." % self.appName)
|
||||
self.device.stop_application(self.appName)
|
||||
self.device.stop_application(self.appName, root=True)
|
||||
|
||||
self.counts = counts
|
||||
if self.counts is not None:
|
||||
|
@ -268,7 +268,7 @@ class RemoteAutomation(object):
|
|||
except ADBTimeoutError:
|
||||
raise
|
||||
except Exception as e:
|
||||
self.log.exception("remoteautomation.py | exception reading log: %s" % str(e))
|
||||
self.log.info("remoteautomation.py | exception reading log: %s" % str(e))
|
||||
return False
|
||||
if not newLogContent:
|
||||
return False
|
||||
|
@ -354,12 +354,12 @@ class RemoteAutomation(object):
|
|||
endTime = datetime.datetime.now() + datetime.timedelta(seconds=timeout)
|
||||
# wait for log creation on startup
|
||||
retries = 0
|
||||
while retries < 20 and not self.device.is_file(self.remoteLog):
|
||||
while retries < 20 and not self.device.is_file(self.remoteLog, root=True):
|
||||
retries += 1
|
||||
time.sleep(1)
|
||||
if self.device.is_file(self.remoteLog):
|
||||
if self.device.is_file(self.remoteLog, root=True):
|
||||
# We must change the remote log's permissions so that the shell can read it.
|
||||
self.device.chmod(self.remoteLog, mask="666")
|
||||
self.device.chmod(self.remoteLog, mask="666", root=True)
|
||||
else:
|
||||
print("Failed wait for remote log: %s missing?" % self.remoteLog)
|
||||
while top == self.procName:
|
||||
|
@ -408,7 +408,7 @@ class RemoteAutomation(object):
|
|||
if stagedShutdown:
|
||||
# Trigger an ANR report with "kill -3" (SIGQUIT)
|
||||
try:
|
||||
self.device.pkill(self.procName, sig=3, attempts=1)
|
||||
self.device.pkill(self.procName, sig=3, attempts=1, root=True)
|
||||
except ADBTimeoutError:
|
||||
raise
|
||||
except: # NOQA: E722
|
||||
|
@ -416,7 +416,7 @@ class RemoteAutomation(object):
|
|||
time.sleep(3)
|
||||
# Trigger a breakpad dump with "kill -6" (SIGABRT)
|
||||
try:
|
||||
self.device.pkill(self.procName, sig=6, attempts=1)
|
||||
self.device.pkill(self.procName, sig=6, attempts=1, root=True)
|
||||
except ADBTimeoutError:
|
||||
raise
|
||||
except: # NOQA: E722
|
||||
|
@ -432,7 +432,7 @@ class RemoteAutomation(object):
|
|||
retries += 1
|
||||
if self.device.process_exist(self.procName):
|
||||
try:
|
||||
self.device.pkill(self.procName, sig=9, attempts=1)
|
||||
self.device.pkill(self.procName, sig=9, attempts=1, root=True)
|
||||
except ADBTimeoutError:
|
||||
raise
|
||||
except: # NOQA: E722
|
||||
|
@ -448,7 +448,7 @@ class RemoteAutomation(object):
|
|||
if self.device.process_exist(crashreporter):
|
||||
print("Warning: %s unexpectedly found running. Killing..." % crashreporter)
|
||||
try:
|
||||
self.device.pkill(crashreporter)
|
||||
self.device.pkill(crashreporter, root=True)
|
||||
except ADBTimeoutError:
|
||||
raise
|
||||
except: # NOQA: E722
|
||||
|
|
|
@ -169,7 +169,7 @@ def main(argv):
|
|||
type=str, dest='device_serial', default=None,
|
||||
help='ADB device serial number of remote device to test')
|
||||
op.add_argument('--remoteTestRoot', dest='remote_test_root', action='store',
|
||||
type=str, default='/data/local/tmp/test_root',
|
||||
type=str, default='/data/local/tests',
|
||||
help='The remote directory to use as test root'
|
||||
' (e.g. %(default)s)')
|
||||
op.add_argument('--localLib', dest='local_lib', action='store',
|
||||
|
|
|
@ -1 +1 @@
|
|||
|jit-test| skip-if: !this.hasOwnProperty('TypedObject')
|
||||
|jit-test| skip-if: !this.hasOwnProperty("TypedObject")
|
||||
|
|
|
@ -164,7 +164,7 @@ def parse_args():
|
|||
type=str, dest='device_serial', default=None,
|
||||
help='ADB device serial number of remote device to test')
|
||||
harness_og.add_argument('--remoteTestRoot', dest='remote_test_root', action='store',
|
||||
type=str, default='/data/local/tmp/test_root',
|
||||
type=str, default='/data/local/tests',
|
||||
help='The remote directory to use as test root'
|
||||
' (e.g. %(default)s)')
|
||||
harness_og.add_argument('--localLib', dest='local_lib', action='store',
|
||||
|
@ -608,7 +608,7 @@ def main():
|
|||
jtd_tests = posixpath.join(options.remote_test_root, 'tests', 'tests')
|
||||
init_remote_dir(device, jtd_tests)
|
||||
device.push(test_dir, jtd_tests, timeout=600)
|
||||
device.chmod(jtd_tests, recursive=True)
|
||||
device.chmod(jtd_tests, recursive=True, root=True)
|
||||
prefix[0] = options.js_shell
|
||||
for test in test_gen:
|
||||
out = run_test_remote(test, device, prefix, options)
|
||||
|
|
|
@ -361,7 +361,7 @@ class JitTest:
|
|||
for inc in self.other_script_includes:
|
||||
cmd += ['-f', scriptdir_var + inc]
|
||||
if self.skip_if_cond:
|
||||
cmd += ['-e', 'if ({}) quit({})'.format(self.skip_if_cond, self.SKIPPED_EXIT_STATUS)]
|
||||
cmd += ['-e', "if ({}) quit({})".format(self.skip_if_cond, self.SKIPPED_EXIT_STATUS)]
|
||||
cmd += ['--module-load-path', moduledir]
|
||||
if self.is_module:
|
||||
cmd += ['--module', path]
|
||||
|
@ -425,7 +425,6 @@ def run_test_remote(test, device, prefix, options):
|
|||
if test.tz_pacific:
|
||||
env['TZ'] = 'PST8PDT'
|
||||
|
||||
# replace with shlex.join when move to Python 3.8+
|
||||
cmd = ADBDevice._escape_command_line(cmd)
|
||||
start = datetime.now()
|
||||
try:
|
||||
|
@ -788,11 +787,11 @@ def run_tests_remote(tests, num_tests, prefix, options, slog):
|
|||
|
||||
init_remote_dir(device, jit_tests_dir)
|
||||
device.push(JS_TESTS_DIR, jtd_tests, timeout=600)
|
||||
device.chmod(jtd_tests, recursive=True)
|
||||
device.chmod(jtd_tests, recursive=True, root=True)
|
||||
|
||||
device.push(os.path.dirname(TEST_DIR), options.remote_test_root,
|
||||
timeout=600)
|
||||
device.chmod(options.remote_test_root, recursive=True)
|
||||
device.chmod(options.remote_test_root, recursive=True, root=True)
|
||||
except (ADBError, ADBTimeoutError):
|
||||
print("TEST-UNEXPECTED-FAIL | jit_test.py" +
|
||||
" : Device initialization failed")
|
||||
|
|
|
@ -19,7 +19,7 @@ def push_libs(options, device, dest_dir):
|
|||
if file in required_libs:
|
||||
remote_file = posixpath.join(dest_dir, file)
|
||||
device.push(os.path.join(options.local_lib, file), remote_file)
|
||||
device.chmod(remote_file)
|
||||
device.chmod(remote_file, root=True)
|
||||
|
||||
|
||||
def push_progs(options, device, progs, dest_dir):
|
||||
|
@ -28,12 +28,13 @@ def push_progs(options, device, progs, dest_dir):
|
|||
remote_file = posixpath.join(dest_dir,
|
||||
os.path.basename(local_file))
|
||||
device.push(local_file, remote_file)
|
||||
device.chmod(remote_file)
|
||||
device.chmod(remote_file, root=True)
|
||||
|
||||
|
||||
def init_remote_dir(device, path):
|
||||
device.rm(path, recursive=True, force=True)
|
||||
device.mkdir(path, parents=True)
|
||||
def init_remote_dir(device, path, root=True):
|
||||
device.rm(path, recursive=True, force=True, root=root)
|
||||
device.mkdir(path, parents=True, root=root)
|
||||
device.chmod(path, recursive=True, root=root)
|
||||
|
||||
|
||||
# We only have one device per test run.
|
||||
|
@ -49,15 +50,15 @@ def init_device(options):
|
|||
if DEVICE is not None:
|
||||
return DEVICE
|
||||
|
||||
from mozdevice import ADBDeviceFactory, ADBError, ADBTimeoutError
|
||||
from mozdevice import ADBDevice, ADBError, ADBTimeoutError
|
||||
try:
|
||||
if not options.local_lib:
|
||||
# if not specified, use the local directory containing
|
||||
# the js binary to find the necessary libraries.
|
||||
options.local_lib = posixpath.dirname(options.js_shell)
|
||||
|
||||
DEVICE = ADBDeviceFactory(device=options.device_serial,
|
||||
test_root=options.remote_test_root)
|
||||
DEVICE = ADBDevice(device=options.device_serial,
|
||||
test_root=options.remote_test_root)
|
||||
|
||||
init_remote_dir(DEVICE, options.remote_test_root)
|
||||
|
||||
|
|
|
@ -238,12 +238,7 @@ class MachCommands(MachCommandBase):
|
|||
if conditions.is_android(self):
|
||||
from mozrunner.devices.android_device import (verify_android_device, InstallIntent)
|
||||
install = InstallIntent.NO if kwargs.get('no_install') else InstallIntent.YES
|
||||
verbose = False
|
||||
if kwargs.get('log_mach_verbose') or kwargs.get('log_tbpl_level') == 'debug' or \
|
||||
kwargs.get('log_mach_level') == 'debug' or kwargs.get('log_raw_level') == 'debug':
|
||||
verbose = True
|
||||
verify_android_device(self, install=install, xre=True, network=True,
|
||||
app=kwargs["app"], device_serial=kwargs["deviceSerial"],
|
||||
verbose=verbose)
|
||||
app=kwargs["app"], device_serial=kwargs["deviceSerial"])
|
||||
return reftest.run_android_test(**kwargs)
|
||||
return reftest.run_desktop_test(**kwargs)
|
||||
|
|
|
@ -489,7 +489,7 @@ class RemoteArgumentsParser(ReftestArgumentsParser):
|
|||
type=str,
|
||||
dest="remoteTestRoot",
|
||||
help="Remote directory to use as test root "
|
||||
"(eg. /data/local/tmp/test_root).")
|
||||
"(eg. /mnt/sdcard/tests or /data/local/tests).")
|
||||
|
||||
self.add_argument("--httpd-path",
|
||||
action="store",
|
||||
|
|
|
@ -16,7 +16,7 @@ from contextlib import closing
|
|||
|
||||
from six.moves.urllib_request import urlopen
|
||||
|
||||
from mozdevice import ADBDeviceFactory, ADBTimeoutError
|
||||
from mozdevice import ADBDevice, ADBTimeoutError
|
||||
from remoteautomation import RemoteAutomation, fennecLogcatFilters
|
||||
|
||||
from output import OutputHandler
|
||||
|
@ -164,16 +164,13 @@ class RemoteReftest(RefTest):
|
|||
self.localLogName = options.localLogName
|
||||
|
||||
verbose = False
|
||||
if options.log_mach_verbose or options.log_tbpl_level == 'debug' or \
|
||||
options.log_mach_level == 'debug' or options.log_raw_level == 'debug':
|
||||
if options.log_tbpl_level == 'debug' or options.log_mach_level == 'debug':
|
||||
verbose = True
|
||||
print("set verbose!")
|
||||
expected = options.app.split('/')[-1]
|
||||
self.device = ADBDeviceFactory(adb=options.adb_path or 'adb',
|
||||
device=options.deviceSerial,
|
||||
test_root=options.remoteTestRoot,
|
||||
verbose=verbose,
|
||||
run_as_package=expected)
|
||||
self.device = ADBDevice(adb=options.adb_path or 'adb',
|
||||
device=options.deviceSerial,
|
||||
test_root=options.remoteTestRoot,
|
||||
verbose=verbose)
|
||||
if options.remoteTestRoot is None:
|
||||
options.remoteTestRoot = posixpath.join(self.device.test_root, "reftest")
|
||||
options.remoteProfile = posixpath.join(options.remoteTestRoot, "profile")
|
||||
|
@ -213,10 +210,10 @@ class RemoteReftest(RefTest):
|
|||
expected = options.app.split('/')[-1]
|
||||
if not self.device.is_app_installed(expected):
|
||||
raise Exception("%s is not installed on this device" % expected)
|
||||
self.device.run_as_package = expected
|
||||
|
||||
self.device.clear_logcat()
|
||||
|
||||
self.device.rm(self.remoteCache, force=True, recursive=True)
|
||||
self.device.rm(self.remoteCache, force=True, recursive=True, root=True)
|
||||
|
||||
procName = options.app.split('/')[-1]
|
||||
self.device.stop_application(procName)
|
||||
|
@ -330,7 +327,7 @@ class RemoteReftest(RefTest):
|
|||
# make sure the parent directories of the profile which
|
||||
# may have been created by the push, also have their
|
||||
# permissions set to allow access.
|
||||
self.device.chmod(options.remoteTestRoot, recursive=True)
|
||||
self.device.chmod(options.remoteTestRoot, recursive=True, root=True)
|
||||
except Exception:
|
||||
print("Automation Error: Failed to copy profiledir to device")
|
||||
raise
|
||||
|
@ -401,9 +398,9 @@ class RemoteReftest(RefTest):
|
|||
return status
|
||||
|
||||
def cleanup(self, profileDir):
|
||||
self.device.rm(self.remoteTestRoot, force=True, recursive=True)
|
||||
self.device.rm(self.remoteProfile, force=True, recursive=True)
|
||||
self.device.rm(self.remoteCache, force=True, recursive=True)
|
||||
self.device.rm(self.remoteTestRoot, force=True, recursive=True, root=True)
|
||||
self.device.rm(self.remoteProfile, force=True, recursive=True, root=True)
|
||||
self.device.rm(self.remoteCache, force=True, recursive=True, root=True)
|
||||
RefTest.cleanup(self, profileDir)
|
||||
|
||||
|
||||
|
|
|
@ -464,7 +464,7 @@ class GTestCommands(MachCommandBase):
|
|||
dest='remote_test_root',
|
||||
group='Android',
|
||||
help='Remote directory to use as test root '
|
||||
'(eg. /data/local/tmp/test_root).')
|
||||
'(eg. /mnt/sdcard/tests or /data/local/tests).')
|
||||
@CommandArgument('--libxul',
|
||||
dest='libxul_path',
|
||||
group='Android',
|
||||
|
|
|
@ -46,7 +46,7 @@ class ADBLoggedDevice(ADBDevice):
|
|||
self._provided_logger = kw.pop("logger")
|
||||
super(ADBLoggedDevice, self).__init__(*args, **kw)
|
||||
|
||||
def _get_logger(self, logger_name, verbose):
|
||||
def _get_logger(self, logger_name):
|
||||
return self._provided_logger
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class PerformanceTuner:
|
|||
def tune_performance(self):
|
||||
self.log.info("tuning android device performance")
|
||||
self.set_svc_power_stayon()
|
||||
if self.device.is_rooted:
|
||||
if self.device._have_su or self.device._have_android_su:
|
||||
device_name = self.device.shell_output(
|
||||
"getprop ro.product.model", timeout=self.timeout
|
||||
)
|
||||
|
@ -36,10 +36,12 @@ class PerformanceTuner:
|
|||
self.device.clear_logcat(timeout=self.timeout)
|
||||
self.log.info("android device performance tuning complete")
|
||||
|
||||
def _set_value_and_check_exitcode(self, file_name, value):
|
||||
def _set_value_and_check_exitcode(self, file_name, value, root=False):
|
||||
self.log.info("setting {} to {}".format(file_name, value))
|
||||
if self.device.shell_bool(
|
||||
" ".join(["echo", str(value), ">", str(file_name)]), timeout=self.timeout,
|
||||
" ".join(["echo", str(value), ">", str(file_name)]),
|
||||
root=root,
|
||||
timeout=self.timeout,
|
||||
):
|
||||
self.log.info("successfully set {} to {}".format(file_name, value))
|
||||
else:
|
||||
|
@ -63,7 +65,9 @@ class PerformanceTuner:
|
|||
]
|
||||
for service in services:
|
||||
self.log.info(" ".join(["turning off service:", service]))
|
||||
self.device.shell_bool(" ".join(["stop", service]), timeout=self.timeout)
|
||||
self.device.shell_bool(
|
||||
" ".join(["stop", service]), root=True, timeout=self.timeout
|
||||
)
|
||||
|
||||
services_list_output = self.device.shell_output(
|
||||
"service list", timeout=self.timeout
|
||||
|
@ -109,7 +113,7 @@ class PerformanceTuner:
|
|||
}
|
||||
|
||||
for key, value in commands.items():
|
||||
self._set_value_and_check_exitcode(key, value)
|
||||
self._set_value_and_check_exitcode(key, value, root=True)
|
||||
|
||||
def set_cpu_performance_parameters(self, device_name=None):
|
||||
self.log.info("setting cpu performance parameters")
|
||||
|
@ -154,7 +158,7 @@ class PerformanceTuner:
|
|||
)
|
||||
|
||||
for key, value in commands.items():
|
||||
self._set_value_and_check_exitcode(key, value)
|
||||
self._set_value_and_check_exitcode(key, value, root=True)
|
||||
|
||||
def set_gpu_performance_parameters(self, device_name=None):
|
||||
self.log.info("setting gpu performance parameters")
|
||||
|
@ -204,7 +208,7 @@ class PerformanceTuner:
|
|||
)
|
||||
|
||||
for key, value in commands.items():
|
||||
self._set_value_and_check_exitcode(key, value)
|
||||
self._set_value_and_check_exitcode(key, value, root=True)
|
||||
|
||||
def set_kernel_performance_parameters(self):
|
||||
self.log.info("setting kernel performance parameters")
|
||||
|
@ -215,4 +219,4 @@ class PerformanceTuner:
|
|||
"/sys/kernel/debug/msm-bus-dbg/shell-client/slv": "512",
|
||||
}
|
||||
for key, value in commands.items():
|
||||
self._set_value_and_check_exitcode(key, value)
|
||||
self._set_value_and_check_exitcode(key, value, root=True)
|
||||
|
|
|
@ -16,8 +16,6 @@ class FakeDevice:
|
|||
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
|
||||
|
@ -62,8 +60,6 @@ def test_android_perf_tuning_rooted(device):
|
|||
# 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:
|
||||
|
@ -78,8 +74,6 @@ def test_android_perf_tuning_nonrooted(device):
|
|||
# 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:
|
||||
|
|
|
@ -7,9 +7,9 @@ from __future__ import absolute_import
|
|||
from setuptools import setup
|
||||
|
||||
PACKAGE_NAME = "mozperftest"
|
||||
PACKAGE_VERSION = "0.2"
|
||||
PACKAGE_VERSION = "0.1"
|
||||
|
||||
deps = ["jsonschema", "mozlog >= 6.0", "mozdevice >= 4.0.0", "mozproxy", "mozinfo"]
|
||||
deps = ["jsonschema", "mozlog >= 6.0", "mozdevice >= 3.0.2,<4", "mozproxy", "mozinfo"]
|
||||
|
||||
setup(
|
||||
name=PACKAGE_NAME,
|
||||
|
|
|
@ -12,7 +12,7 @@ import logging
|
|||
|
||||
import attr
|
||||
from arsenic.services import Geckodriver, free_port, subprocess_based_service
|
||||
from mozdevice import ADBDeviceFactory, ADBError
|
||||
from mozdevice import ADBDevice, ADBError
|
||||
|
||||
from condprof.util import write_yml_file, logger, DEFAULT_PREFS, BaseEnv
|
||||
|
||||
|
@ -77,10 +77,10 @@ class AndroidDevice:
|
|||
self._set_adb_logger(logfile)
|
||||
try:
|
||||
# See android_emulator_pgo.py run_tests for more
|
||||
# details on why test_root must be /sdcard/test_root
|
||||
# details on why test_root must be /sdcard/tests
|
||||
# for android pgo due to Android 4.3.
|
||||
self.device = ADBDeviceFactory(
|
||||
verbose=self.verbose, logger_name="adb", test_root="/sdcard/test_root"
|
||||
self.device = ADBDevice(
|
||||
verbose=self.verbose, logger_name="adb", test_root="/sdcard/tests"
|
||||
)
|
||||
except Exception:
|
||||
logger.error("Cannot initialize device")
|
||||
|
@ -106,11 +106,12 @@ class AndroidDevice:
|
|||
logger.info("The profile on the phone will be at %s" % remote_profile)
|
||||
device.rm(remote_test_root, force=True, recursive=True)
|
||||
device.mkdir(remote_test_root)
|
||||
device.chmod(remote_test_root, recursive=True, root=True)
|
||||
|
||||
device.rm(remote_profile, force=True, recursive=True)
|
||||
logger.info("Pushing %s on the phone" % self.profile)
|
||||
device.push(profile, remote_profile)
|
||||
device.chmod(remote_profile, recursive=True)
|
||||
device.chmod(remote_profile, recursive=True, root=True)
|
||||
self.profile = profile
|
||||
self.remote_profile = remote_profile
|
||||
|
||||
|
@ -131,7 +132,7 @@ class AndroidDevice:
|
|||
try:
|
||||
device.rm(yml_on_device, force=True, recursive=True)
|
||||
device.push(yml_on_host, yml_on_device)
|
||||
device.chmod(yml_on_device, recursive=True)
|
||||
device.chmod(yml_on_device, recursive=True, root=True)
|
||||
except Exception:
|
||||
logger.info("could not create the yaml file on device. Permission issue?")
|
||||
raise
|
||||
|
@ -183,7 +184,7 @@ class AndroidDevice:
|
|||
def stop_browser(self):
|
||||
logger.info("Stopping %s" % self.app_name)
|
||||
try:
|
||||
self.device.stop_application(self.app_name)
|
||||
self.device.stop_application(self.app_name, root=True)
|
||||
except ADBError:
|
||||
logger.info("Could not stop the application using force-stop")
|
||||
|
||||
|
@ -193,7 +194,7 @@ class AndroidDevice:
|
|||
num_tries = 0
|
||||
while self.device.process_exist(self.app_name) and num_tries < 5:
|
||||
try:
|
||||
self.device.pkill(self.app_name)
|
||||
self.device.pkill(self.app_name, root=True)
|
||||
except ADBError:
|
||||
pass
|
||||
num_tries += 1
|
||||
|
|
|
@ -69,23 +69,23 @@ class RemoteGTests(object):
|
|||
Return False if a crash or other failure is detected, else True.
|
||||
"""
|
||||
update_mozinfo()
|
||||
self.device = mozdevice.ADBDeviceFactory(adb=adb_path,
|
||||
device=device_serial,
|
||||
test_root=remote_test_root,
|
||||
logger_name=LOGGER_NAME,
|
||||
verbose=True,
|
||||
run_as_package=package)
|
||||
self.device = mozdevice.ADBDevice(adb=adb_path,
|
||||
device=device_serial,
|
||||
test_root=remote_test_root,
|
||||
logger_name=LOGGER_NAME,
|
||||
verbose=True)
|
||||
root = self.device.test_root
|
||||
self.remote_profile = posixpath.join(root, 'gtest-profile')
|
||||
self.remote_minidumps = posixpath.join(root, 'gtest-minidumps')
|
||||
self.remote_log = posixpath.join(root, 'gtest.log')
|
||||
self.remote_libdir = posixpath.join(root, 'gtest')
|
||||
self.remote_libdir = posixpath.join('/data', 'local', 'gtest')
|
||||
|
||||
self.package = package
|
||||
self.cleanup()
|
||||
self.device.mkdir(self.remote_profile)
|
||||
self.device.mkdir(self.remote_minidumps)
|
||||
self.device.mkdir(self.remote_libdir)
|
||||
self.device.mkdir(self.remote_profile, parents=True)
|
||||
self.device.mkdir(self.remote_minidumps, parents=True)
|
||||
self.device.mkdir(self.remote_libdir, parents=True, root=True)
|
||||
self.device.chmod(self.remote_libdir, recursive=True, root=True)
|
||||
|
||||
log.info("Running Android gtest")
|
||||
if not self.device.is_app_installed(self.package):
|
||||
|
@ -134,7 +134,7 @@ class RemoteGTests(object):
|
|||
else:
|
||||
# Trigger an ANR report with "kill -3" (SIGQUIT)
|
||||
try:
|
||||
self.device.pkill(self.package, sig=3, attempts=1)
|
||||
self.device.pkill(self.package, sig=3, attempts=1, root=True)
|
||||
except mozdevice.ADBTimeoutError:
|
||||
raise
|
||||
except: # NOQA: E722
|
||||
|
@ -142,7 +142,7 @@ class RemoteGTests(object):
|
|||
time.sleep(3)
|
||||
# Trigger a breakpad dump with "kill -6" (SIGABRT)
|
||||
try:
|
||||
self.device.pkill(self.package, sig=6, attempts=1)
|
||||
self.device.pkill(self.package, sig=6, attempts=1, root=True)
|
||||
except mozdevice.ADBTimeoutError:
|
||||
raise
|
||||
except: # NOQA: E722
|
||||
|
@ -158,7 +158,7 @@ class RemoteGTests(object):
|
|||
retries += 1
|
||||
if self.device.process_exist(self.package):
|
||||
try:
|
||||
self.device.pkill(self.package, sig=9, attempts=1)
|
||||
self.device.pkill(self.package, sig=9, attempts=1, root=True)
|
||||
except mozdevice.ADBTimeoutError:
|
||||
raise
|
||||
except: # NOQA: E722
|
||||
|
@ -172,7 +172,7 @@ class RemoteGTests(object):
|
|||
if self.device.process_exist(crashreporter):
|
||||
log.warning("%s unexpectedly found running. Killing..." % crashreporter)
|
||||
try:
|
||||
self.device.pkill(crashreporter)
|
||||
self.device.pkill(crashreporter, root=True)
|
||||
except mozdevice.ADBTimeoutError:
|
||||
raise
|
||||
except: # NOQA: E722
|
||||
|
@ -205,10 +205,10 @@ class RemoteGTests(object):
|
|||
def cleanup(self):
|
||||
if self.device:
|
||||
self.device.stop_application(self.package)
|
||||
self.device.rm(self.remote_log, force=True)
|
||||
self.device.rm(self.remote_profile, recursive=True, force=True)
|
||||
self.device.rm(self.remote_minidumps, recursive=True, force=True)
|
||||
self.device.rm(self.remote_libdir, recursive=True, force=True)
|
||||
self.device.rm(self.remote_log, force=True, root=True)
|
||||
self.device.rm(self.remote_profile, recursive=True, force=True, root=True)
|
||||
self.device.rm(self.remote_minidumps, recursive=True, force=True, root=True)
|
||||
self.device.rm(self.remote_libdir, recursive=True, force=True, root=True)
|
||||
|
||||
|
||||
class AppWaiter(object):
|
||||
|
@ -343,7 +343,7 @@ class remoteGtestOptions(argparse.ArgumentParser):
|
|||
type=str,
|
||||
dest="remote_test_root",
|
||||
help="Remote directory to use as test root "
|
||||
"(eg. /data/local/tmp/test_root).")
|
||||
"(eg. /mnt/sdcard/tests or /data/local/tests).")
|
||||
self.add_argument("--libxul",
|
||||
action="store",
|
||||
type=str,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
from __future__ import absolute_import
|
||||
|
||||
__version__ = '5.0.2'
|
||||
__version__ = '5.0.1'
|
||||
|
||||
from .marionette_test import (
|
||||
CommonTestCase,
|
||||
|
|
|
@ -2,7 +2,7 @@ browsermob-proxy >= 0.8.0
|
|||
manifestparser >= 1.1
|
||||
marionette-driver >= 3.0.0
|
||||
mozcrash >= 2.0
|
||||
mozdevice >= 4.0.0,<5
|
||||
mozdevice >= 3.0.1,<4
|
||||
mozinfo >= 1.0.0
|
||||
mozlog >= 6.0
|
||||
moznetwork >= 0.27
|
||||
|
|
|
@ -930,7 +930,7 @@ class AndroidArguments(ArgumentContainer):
|
|||
{"dest": "remoteTestRoot",
|
||||
"default": None,
|
||||
"help": "Remote directory to use as test root "
|
||||
"(eg. /data/local/tmp/test_root).",
|
||||
"(eg. /mnt/sdcard/tests or /data/local/tests).",
|
||||
"suppress": True,
|
||||
}],
|
||||
[["--enable-coverage"],
|
||||
|
|
|
@ -17,7 +17,7 @@ import mozcrash
|
|||
import mozinfo
|
||||
import mozlog
|
||||
import moznetwork
|
||||
from mozdevice import ADBDeviceFactory, ADBError, ADBTimeoutError
|
||||
from mozdevice import ADBDevice, ADBError, ADBTimeoutError
|
||||
from mozprofile import Profile, DEFAULT_PORTS
|
||||
from mozprofile.cli import parse_preferences
|
||||
from mozprofile.permissions import ServerLocations
|
||||
|
@ -50,11 +50,10 @@ class JUnitTestRunner(MochitestDesktop):
|
|||
verbose = False
|
||||
if options.log_tbpl_level == 'debug' or options.log_mach_level == 'debug':
|
||||
verbose = True
|
||||
self.device = ADBDeviceFactory(adb=options.adbPath or 'adb',
|
||||
device=options.deviceSerial,
|
||||
test_root=options.remoteTestRoot,
|
||||
verbose=verbose,
|
||||
run_as_package=options.app)
|
||||
self.device = ADBDevice(adb=options.adbPath or 'adb',
|
||||
device=options.deviceSerial,
|
||||
test_root=options.remoteTestRoot,
|
||||
verbose=verbose)
|
||||
self.options = options
|
||||
self.log.debug("options=%s" % vars(options))
|
||||
update_mozinfo()
|
||||
|
@ -137,10 +136,10 @@ class JUnitTestRunner(MochitestDesktop):
|
|||
self.stopServers()
|
||||
self.log.debug("Servers stopped")
|
||||
self.device.stop_application(self.options.app)
|
||||
self.device.rm(self.remote_profile, force=True, recursive=True)
|
||||
self.device.rm(self.remote_profile, force=True, recursive=True, root=True)
|
||||
if hasattr(self, 'profile'):
|
||||
del self.profile
|
||||
self.device.rm(self.remote_filter_list, force=True)
|
||||
self.device.rm(self.remote_filter_list, force=True, root=True)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
self.log.info("Caught and ignored an exception during cleanup")
|
||||
|
@ -409,7 +408,7 @@ class JunitArgumentParser(argparse.ArgumentParser):
|
|||
type=str,
|
||||
dest="remoteTestRoot",
|
||||
help="Remote directory to use as test root "
|
||||
"(eg. /data/local/tmp/test_root).")
|
||||
"(eg. /mnt/sdcard/tests or /data/local/tests).")
|
||||
self.add_argument("--disable-e10s",
|
||||
action="store_false",
|
||||
dest="e10s",
|
||||
|
|
|
@ -16,7 +16,7 @@ sys.path.insert(
|
|||
from remoteautomation import RemoteAutomation, fennecLogcatFilters
|
||||
from runtests import MochitestDesktop, MessageLogger
|
||||
from mochitest_options import MochitestArgumentParser, build_obj
|
||||
from mozdevice import ADBDeviceFactory, ADBTimeoutError
|
||||
from mozdevice import ADBDevice, ADBTimeoutError
|
||||
from mozscreenshot import dump_screen, dump_device_screen
|
||||
import mozinfo
|
||||
|
||||
|
@ -31,8 +31,7 @@ class MochiRemote(MochitestDesktop):
|
|||
MochitestDesktop.__init__(self, options.flavor, vars(options))
|
||||
|
||||
verbose = False
|
||||
if options.log_mach_verbose or options.log_tbpl_level == 'debug' or \
|
||||
options.log_mach_level == 'debug' or options.log_raw_level == 'debug':
|
||||
if options.log_tbpl_level == 'debug' or options.log_mach_level == 'debug':
|
||||
verbose = True
|
||||
if hasattr(options, 'log'):
|
||||
delattr(options, 'log')
|
||||
|
@ -40,12 +39,10 @@ class MochiRemote(MochitestDesktop):
|
|||
self.certdbNew = True
|
||||
self.chromePushed = False
|
||||
|
||||
expected = options.app.split('/')[-1]
|
||||
self.device = ADBDeviceFactory(adb=options.adbPath or 'adb',
|
||||
device=options.deviceSerial,
|
||||
test_root=options.remoteTestRoot,
|
||||
verbose=verbose,
|
||||
run_as_package=expected)
|
||||
self.device = ADBDevice(adb=options.adbPath or 'adb',
|
||||
device=options.deviceSerial,
|
||||
test_root=options.remoteTestRoot,
|
||||
verbose=verbose)
|
||||
|
||||
if options.remoteTestRoot is None:
|
||||
options.remoteTestRoot = self.device.test_root
|
||||
|
@ -53,10 +50,10 @@ class MochiRemote(MochitestDesktop):
|
|||
self.remoteLogFile = posixpath.join(options.remoteTestRoot, "logs", "mochitest.log")
|
||||
logParent = posixpath.dirname(self.remoteLogFile)
|
||||
self.device.rm(logParent, force=True, recursive=True)
|
||||
self.device.mkdir(logParent, parents=True)
|
||||
self.device.mkdir(logParent)
|
||||
|
||||
self.remoteProfile = posixpath.join(options.remoteTestRoot, "profile")
|
||||
self.device.rm(self.remoteProfile, force=True, recursive=True)
|
||||
self.remoteProfile = posixpath.join(options.remoteTestRoot, "profile/")
|
||||
self.device.rm(self.remoteProfile, force=True, recursive=True, root=True)
|
||||
|
||||
self.counts = dict()
|
||||
self.message_logger = MessageLogger(logger=None)
|
||||
|
@ -76,20 +73,20 @@ class MochiRemote(MochitestDesktop):
|
|||
self.remoteModulesDir = posixpath.join(options.remoteTestRoot, "modules/")
|
||||
|
||||
self.remoteCache = posixpath.join(options.remoteTestRoot, "cache/")
|
||||
self.device.rm(self.remoteCache, force=True, recursive=True)
|
||||
self.device.rm(self.remoteCache, force=True, recursive=True, root=True)
|
||||
|
||||
# move necko cache to a location that can be cleaned up
|
||||
options.extraPrefs += ["browser.cache.disk.parent_directory=%s" % self.remoteCache]
|
||||
|
||||
self.remoteMozLog = posixpath.join(options.remoteTestRoot, "mozlog")
|
||||
self.device.rm(self.remoteMozLog, force=True, recursive=True)
|
||||
self.device.mkdir(self.remoteMozLog, parents=True)
|
||||
self.device.rm(self.remoteMozLog, force=True, recursive=True, root=True)
|
||||
self.device.mkdir(self.remoteMozLog)
|
||||
|
||||
self.remoteChromeTestDir = posixpath.join(
|
||||
options.remoteTestRoot,
|
||||
"chrome")
|
||||
self.device.rm(self.remoteChromeTestDir, force=True, recursive=True)
|
||||
self.device.mkdir(self.remoteChromeTestDir, parents=True)
|
||||
self.device.rm(self.remoteChromeTestDir, force=True, recursive=True, root=True)
|
||||
self.device.mkdir(self.remoteChromeTestDir)
|
||||
|
||||
procName = options.app.split('/')[-1]
|
||||
self.device.stop_application(procName)
|
||||
|
@ -107,14 +104,14 @@ class MochiRemote(MochitestDesktop):
|
|||
|
||||
def cleanup(self, options, final=False):
|
||||
if final:
|
||||
self.device.rm(self.remoteChromeTestDir, force=True, recursive=True)
|
||||
self.device.rm(self.remoteChromeTestDir, force=True, recursive=True, root=True)
|
||||
self.chromePushed = False
|
||||
uploadDir = os.environ.get('MOZ_UPLOAD_DIR', None)
|
||||
if uploadDir and self.device.is_dir(self.remoteMozLog):
|
||||
self.device.pull(self.remoteMozLog, uploadDir)
|
||||
self.device.rm(self.remoteLogFile, force=True)
|
||||
self.device.rm(self.remoteProfile, force=True, recursive=True)
|
||||
self.device.rm(self.remoteCache, force=True, recursive=True)
|
||||
self.device.rm(self.remoteLogFile, force=True, root=True)
|
||||
self.device.rm(self.remoteProfile, force=True, recursive=True, root=True)
|
||||
self.device.rm(self.remoteCache, force=True, recursive=True, root=True)
|
||||
MochitestDesktop.cleanup(self, options, final)
|
||||
self.localProfile = None
|
||||
|
||||
|
@ -211,7 +208,7 @@ class MochiRemote(MochitestDesktop):
|
|||
if options.testingModulesDir:
|
||||
try:
|
||||
self.device.push(options.testingModulesDir, self.remoteModulesDir)
|
||||
self.device.chmod(self.remoteModulesDir, recursive=True)
|
||||
self.device.chmod(self.remoteModulesDir, recursive=True, root=True)
|
||||
except Exception:
|
||||
self.log.error(
|
||||
"Automation Error: Unable to copy test modules to device.")
|
||||
|
@ -239,7 +236,7 @@ class MochiRemote(MochitestDesktop):
|
|||
# we really need testConfig.js (for browser chrome)
|
||||
try:
|
||||
self.device.push(options.profilePath, self.remoteProfile)
|
||||
self.device.chmod(self.remoteProfile, recursive=True)
|
||||
self.device.chmod(self.remoteProfile, recursive=True, root=True)
|
||||
except Exception:
|
||||
self.log.error("Automation Error: Unable to copy profile to device.")
|
||||
raise
|
||||
|
|
|
@ -2,8 +2,8 @@ Device management
|
|||
-----------------
|
||||
|
||||
Mozbase provides a module called `mozdevice` for the purposes of
|
||||
running automated tests or scripts on an Android phone, tablet, or
|
||||
emulator connected to a workstation.
|
||||
running automated tests or scripts on an Android or B2G device (e.g. a
|
||||
phone, tablet, or emulator) connected to a workstation.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
|
|
@ -1,8 +1,121 @@
|
|||
:mod:`mozdevice` --- Interact with Android devices
|
||||
==================================================
|
||||
|
||||
Mozdevice provides several interfaces to interact with an Android
|
||||
device such as a phone, tablet, or emulator. It allows you to push
|
||||
files to these types of devices, launch processes, and more. There are
|
||||
currently two available interfaces:
|
||||
|
||||
* :ref:`ADB`: Uses the Android Debugger Protocol explicitly
|
||||
|
||||
.. automodule:: mozdevice
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
:show-inheritance:
|
||||
|
||||
.. _ADB:
|
||||
|
||||
ADB Interface
|
||||
-------------
|
||||
|
||||
The following classes provide a basic interface to interact with the
|
||||
Android Debug Tool (adb) and Android-based devices. It has replaced
|
||||
the now defunct DeviceManager and DeviceManagerADB classes.
|
||||
|
||||
ADBCommand
|
||||
``````````
|
||||
|
||||
.. autoclass:: mozdevice.ADBCommand
|
||||
|
||||
.. automethod:: ADBCommand.command(self, cmds, timeout=None)
|
||||
.. automethod:: ADBCommand.command_output(self, cmds, timeout=None)
|
||||
|
||||
ADBHost
|
||||
```````
|
||||
.. autoclass:: mozdevice.ADBHost
|
||||
|
||||
.. automethod:: ADBHost.command(self, cmds, timeout=None)
|
||||
.. automethod:: ADBHost.command_output(self, cmds, timeout=None)
|
||||
.. automethod:: ADBHost.start_server(self, timeout=None)
|
||||
.. automethod:: ADBHost.kill_server(self, timeout=None)
|
||||
.. automethod:: ADBHost.devices(self, timeout=None)
|
||||
|
||||
ADBDevice
|
||||
`````````
|
||||
.. autoclass:: mozdevice.ADBDevice
|
||||
|
||||
Host Command methods
|
||||
++++++++++++++++++++
|
||||
.. automethod:: ADBDevice.command(self, cmds, timeout=None)
|
||||
.. automethod:: ADBDevice.command_output(self, cmds, timeout=None)
|
||||
|
||||
Device Shell methods
|
||||
++++++++++++++++++++
|
||||
.. automethod:: ADBDevice.shell(self, cmd, env=None, cwd=None, timeout=None, root=False)
|
||||
.. automethod:: ADBDevice.shell_bool(self, cmd, env=None, cwd=None, timeout=None, root=False)
|
||||
.. automethod:: ADBDevice.shell_output(self, cmd, env=None, cwd=None, timeout=None, root=False)
|
||||
|
||||
Informational methods
|
||||
+++++++++++++++++++++
|
||||
.. automethod:: ADBDevice.clear_logcat
|
||||
.. automethod:: ADBDevice.get_battery_percentage
|
||||
.. automethod:: ADBDevice.get_info
|
||||
.. automethod:: ADBDevice.get_logcat
|
||||
.. automethod:: ADBDevice.get_prop
|
||||
.. automethod:: ADBDevice.get_state
|
||||
.. automethod:: ADBDevice.get_top_activity
|
||||
|
||||
System control methods
|
||||
++++++++++++++++++++++
|
||||
.. automethod:: ADBDevice.is_device_ready
|
||||
.. automethod:: ADBDevice.power_on
|
||||
.. automethod:: ADBDevice.reboot
|
||||
|
||||
File management methods
|
||||
+++++++++++++++++++++++
|
||||
.. automethod:: ADBDevice.chmod
|
||||
.. automethod:: ADBDevice.cp
|
||||
.. automethod:: ADBDevice.exists
|
||||
.. automethod:: ADBDevice.get_file
|
||||
.. automethod:: ADBDevice.is_dir
|
||||
.. automethod:: ADBDevice.is_file
|
||||
.. automethod:: ADBDevice.list_files
|
||||
.. automethod:: ADBDevice.mkdir
|
||||
.. automethod:: ADBDevice.mv
|
||||
.. automethod:: ADBDevice.push
|
||||
.. automethod:: ADBDevice.pull
|
||||
.. automethod:: ADBDevice.rm
|
||||
.. automethod:: ADBDevice.rmdir
|
||||
.. autoattribute:: ADBDevice.test_root
|
||||
|
||||
Process management methods
|
||||
++++++++++++++++++++++++++
|
||||
.. automethod:: ADBDevice.get_process_list
|
||||
.. automethod:: ADBDevice.kill
|
||||
.. automethod:: ADBDevice.pkill
|
||||
.. automethod:: ADBDevice.process_exist
|
||||
|
||||
Application management methods
|
||||
++++++++++++++++++++++++++++++
|
||||
.. automethod:: ADBDevice.install_app
|
||||
.. automethod:: ADBDevice.is_app_installed
|
||||
.. automethod:: ADBDevice.launch_application
|
||||
.. automethod:: ADBDevice.launch_fennec
|
||||
.. automethod:: ADBDevice.launch_geckoview_example
|
||||
.. automethod:: ADBDevice.stop_application
|
||||
.. automethod:: ADBDevice.uninstall_app
|
||||
.. automethod:: ADBDevice.update_app
|
||||
|
||||
ADBProcess
|
||||
``````````
|
||||
.. autoclass:: mozdevice.ADBProcess
|
||||
|
||||
ADBError
|
||||
````````
|
||||
.. autoexception:: mozdevice.ADBError
|
||||
|
||||
ADBRootError
|
||||
````````````
|
||||
.. autoexception:: mozdevice.ADBRootError
|
||||
|
||||
ADBTimeoutError
|
||||
```````````````
|
||||
.. autoexception:: mozdevice.ADBTimeoutError
|
||||
|
||||
|
|
|
@ -2,163 +2,11 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
"""mozdevice provides a Python interface to the Android Debug Bridge (adb) for Android Devices.
|
||||
|
||||
mozdevice exports the following classes:
|
||||
|
||||
ADBProcess is a class which is used by ADBCommand to execute commands
|
||||
via subprocess.Popen.
|
||||
|
||||
ADBCommand is an internal only class which provides the basics of
|
||||
the interfaces for connecting to a device, and executing commands
|
||||
either on the host or device using ADBProcess.
|
||||
|
||||
ADBHost is a Python class used to execute commands which are not
|
||||
necessarily associated with a specific device. It is intended to be
|
||||
used directly.
|
||||
|
||||
ADBDevice is a Python class used to execute commands which will
|
||||
interact with a specific connected Android device.
|
||||
|
||||
ADBAndroid inherits directly from ADBDevice and is essentially a
|
||||
synonym for ADBDevice. It is included for backwards compatibility only
|
||||
and should not be used in new code.
|
||||
|
||||
ADBDeviceFactory is a Python function used to create instances of
|
||||
ADBDevice. ADBDeviceFactory is preferred over using ADBDevice to
|
||||
create new instances of ADBDevice since it will only create one
|
||||
instance of ADBDevice for each connected device.
|
||||
|
||||
mozdevice exports the following exceptions:
|
||||
|
||||
::
|
||||
|
||||
Exception -
|
||||
|- ADBTimeoutError
|
||||
|- ADBDeviceFactoryError
|
||||
|- ADBError
|
||||
|- ADBProcessError
|
||||
|- ADBListDevicesError
|
||||
|
||||
ADBTimeoutError is a special exception that is not part of the
|
||||
ADBError class hierarchy. It is raised when a command has failed to
|
||||
complete within the specified timeout period. Since this typically is
|
||||
due to a failure in the usb connection to the device and is not
|
||||
recoverable, it is implemented separately from ADBError so that it
|
||||
will not be caught by normal except clause handling of expected error
|
||||
conditions and is considered to be treated as a *fatal* error.
|
||||
|
||||
ADBDeviceFactoryError is also a special exception that is not part
|
||||
of the ADBError class hierarchy. It is raised by ADBDeviceFactory
|
||||
when the state of the internal ADBDevices object is in an
|
||||
inconsistent state and is considered to be a *fatal* error.
|
||||
|
||||
ADBListDevicesError is an instance of ADBError which is
|
||||
raised only by the ADBHost.devices() method to signify that
|
||||
``adb devices`` reports that the device state has no permissions and can
|
||||
not be contacted via adb.
|
||||
|
||||
ADBProcessError is an instance of ADBError which is raised when a
|
||||
process executed via ADBProcess has exited with a non-zero exit
|
||||
code. It is raised by the ADBCommand.command method and the methods
|
||||
that call it.
|
||||
|
||||
ADBError is a generic exception class to signify that some error
|
||||
condition has occured which may be handled depending on the semantics
|
||||
of the executing code.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
from mozdevice import ADBHost, ADBDeviceFactory, ADBError
|
||||
|
||||
adbhost = ADBHost()
|
||||
try:
|
||||
adbhost.kill_server()
|
||||
adbhost.start_server()
|
||||
except ADBError as e:
|
||||
print('Unable to restart the adb server: {}'.format(str(e)))
|
||||
|
||||
device = ADBDeviceFactory()
|
||||
try:
|
||||
sdcard_contents = device.ls('/sdcard/') # List the contents of the sdcard on the device.
|
||||
print('sdcard contains {}'.format(' '.join(sdcard_contents))
|
||||
except ADBError as e:
|
||||
print('Unable to list the sdcard: {}'.format(str(e)))
|
||||
|
||||
Android devices use a security model based upon user permissions much
|
||||
like that used in Linux upon which it is based. The adb shell executes
|
||||
commands on the device as the shell user whose access to the files and
|
||||
directories on the device are limited by the directory and file
|
||||
permissions set in the device's file system.
|
||||
|
||||
Android apps run under their own user accounts and are restricted by
|
||||
the app's requested permissions in terms of what commands and files
|
||||
and directories they may access.
|
||||
|
||||
Like Linux, Android supports a root user who has unrestricted access
|
||||
to the command and content stored on the device.
|
||||
|
||||
Most commercially released Android devices do not allow adb to run
|
||||
commands as the root user. Typically, only Android emulators running
|
||||
certain system images, devices which have AOSP debug or engineering
|
||||
Android builds or devices which have been *rooted* can run commands as
|
||||
the root user.
|
||||
|
||||
ADBDevice supports using both unrooted and rooted devices by laddering
|
||||
its capabilities depending on the specific circumstances where it is
|
||||
used.
|
||||
|
||||
ADBDevice uses a special location on the device, called the
|
||||
*test_root*, where it places content to be tested. This can include
|
||||
binary executables and libraries, configuration files and log
|
||||
files. Since the special location /data/local/tmp is usually
|
||||
accessible by the shell user, the test_root is located at
|
||||
/data/local/tmp/test_root by default. /data/local/tmp is used instead
|
||||
of the sdcard due to recent Scoped Storage restrictions on access to
|
||||
the sdcard in Android 10 and later.
|
||||
|
||||
If the device supports running adbd as root, or if the device has been
|
||||
rooted and supports the use of the su command to run commands as root,
|
||||
ADBDevice will default to running all shell commands under the root
|
||||
user and the test_root will remain set to /data/local/tmp/test_root
|
||||
unless changed.
|
||||
|
||||
If the device does not support running shell commands under the root
|
||||
user, and a *debuggable* app is set in ADBDevice property
|
||||
run_as_package, then ADBDevice will set the test_root to
|
||||
/data/data/<app-package-name>/test_root and will run shell commands as
|
||||
the app user when accessing content located in the app's data
|
||||
directory. Content can be pushed to the app's data directory or pulled
|
||||
from the app's data directory by using the command run-as to access
|
||||
the app's data.
|
||||
|
||||
If a device does not support running commands as root and a
|
||||
*debuggable* app is not being used, command line programs can still be
|
||||
executed by pushing them to the /data/local/tmp directory which is
|
||||
accessible to the shell user.
|
||||
|
||||
If for some reason, the device is not rooted and /data/local/tmp is
|
||||
not acccessible to the shell user, then ADBDevice will fail to
|
||||
initialize and will not be useable for that device.
|
||||
|
||||
NOTE: ADBFactory will clear the contents of the test_root when it
|
||||
first creates an instance of ADBDevice.
|
||||
|
||||
When the run_as_package property is set in an ADBDevice instance, it
|
||||
will clear the contents of the current test_root before changing the
|
||||
test_root to point to the new location
|
||||
/data/data/<app-package-name>/test_root which will then be cleared of
|
||||
any existing content.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from .adb import ADBError, ADBProcessError, ADBTimeoutError
|
||||
from .adb import ADBProcess, ADBCommand, ADBHost, ADBDevice, ADBDeviceFactory
|
||||
from .adb import ADBError, ADBProcessError, ADBRootError, ADBTimeoutError
|
||||
from .adb import ADBProcess, ADBCommand, ADBHost, ADBDevice
|
||||
from .adb_android import ADBAndroid
|
||||
|
||||
__all__ = ['ADBError', 'ADBProcessError', 'ADBTimeoutError',
|
||||
'ADBProcess', 'ADBCommand', 'ADBHost', 'ADBDevice', 'ADBAndroid', 'ADBDeviceFactory']
|
||||
__all__ = ['ADBError', 'ADBProcessError', 'ADBRootError', 'ADBTimeoutError',
|
||||
'ADBProcess', 'ADBCommand', 'ADBHost', 'ADBDevice', 'ADBAndroid']
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -8,7 +8,7 @@ from __future__ import absolute_import
|
|||
from setuptools import setup
|
||||
|
||||
PACKAGE_NAME = 'mozdevice'
|
||||
PACKAGE_VERSION = '4.0.0'
|
||||
PACKAGE_VERSION = '3.2.3'
|
||||
|
||||
deps = ['mozlog >= 6.0']
|
||||
|
||||
|
|
|
@ -57,8 +57,7 @@ def mock_shell_output(monkeypatch):
|
|||
:param object monkeypatch: pytest provided fixture for mocking.
|
||||
"""
|
||||
|
||||
def shell_output_wrapper(object, cmd, env=None, cwd=None, timeout=None,
|
||||
enable_run_as=False):
|
||||
def shell_output_wrapper(object, cmd, env=None, cwd=None, timeout=None, root=False):
|
||||
"""Actual monkeypatch implementation of the shell_output method call.
|
||||
|
||||
:param object object: placeholder object representing ADBDevice
|
||||
|
@ -68,7 +67,6 @@ def mock_shell_output(monkeypatch):
|
|||
:param cwd: The directory from which to execute.
|
||||
:type cwd: str or None
|
||||
:param timeout: unused parameter tp represent timeout threshold
|
||||
:param enable_run_as: bool determining if run_as <app> is to be used
|
||||
:returns: string - string representation of a simulated call to adb
|
||||
"""
|
||||
if 'pm list package error' in cmd:
|
||||
|
@ -117,27 +115,6 @@ def mock_is_path_internal_storage(monkeypatch):
|
|||
'is_path_internal_storage', is_path_internal_storage_wrapper)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_enable_run_as_for_path(monkeypatch):
|
||||
"""Monkeypatches the ADBDevice.enable_run_as_for_path(path) method.
|
||||
|
||||
Always return True
|
||||
|
||||
:param object monkeypatch: pytest provided fixture for mocking.
|
||||
"""
|
||||
|
||||
def enable_run_as_for_path_wrapper(object, path):
|
||||
"""Actual monkeypatch implementation of the enable_run_as_for_path() call.
|
||||
|
||||
:param str path: The path to test.
|
||||
:returns: boolean
|
||||
"""
|
||||
return True
|
||||
|
||||
monkeypatch.setattr(mozdevice.ADBDevice,
|
||||
'enable_run_as_for_path', enable_run_as_for_path_wrapper)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_shell_bool(monkeypatch):
|
||||
"""Monkeypatches the ADBDevice.shell_bool() method call.
|
||||
|
@ -149,8 +126,7 @@ def mock_shell_bool(monkeypatch):
|
|||
:param object monkeypatch: pytest provided fixture for mocking.
|
||||
"""
|
||||
|
||||
def shell_bool_wrapper(object, cmd, env=None, cwd=None, timeout=None,
|
||||
enable_run_as=False):
|
||||
def shell_bool_wrapper(object, cmd, env=None, cwd=None, timeout=None, root=False):
|
||||
"""Actual monkeypatch implementation of the shell_bool method call.
|
||||
|
||||
:param object object: placeholder object representing ADBDevice
|
||||
|
@ -160,7 +136,6 @@ def mock_shell_bool(monkeypatch):
|
|||
:param cwd: The directory from which to execute.
|
||||
:type cwd: str or None
|
||||
:param timeout: unused parameter tp represent timeout threshold
|
||||
:param enable_run_as: bool determining if run_as <app> is to be used
|
||||
:returns: string - string representation of a simulated call to adb
|
||||
"""
|
||||
print(cmd)
|
||||
|
|
|
@ -8,9 +8,9 @@ from __future__ import absolute_import
|
|||
from setuptools import setup
|
||||
|
||||
PACKAGE_NAME = 'mozpower'
|
||||
PACKAGE_VERSION = '1.1.2'
|
||||
PACKAGE_VERSION = '1.1.1'
|
||||
|
||||
deps = ['mozlog >= 6.0', 'mozdevice >= 4.0.0,<5']
|
||||
deps = ['mozlog >= 6.0', 'mozdevice >= 3.0.2,<4']
|
||||
|
||||
setup(name=PACKAGE_NAME,
|
||||
version=PACKAGE_VERSION,
|
||||
|
|
|
@ -9,7 +9,7 @@ from distutils.spawn import find_executable
|
|||
import os
|
||||
import posixpath
|
||||
|
||||
from mozdevice import ADBDeviceFactory
|
||||
from mozdevice import ADBDevice
|
||||
from mozprofile import (
|
||||
Profile,
|
||||
ChromeProfile,
|
||||
|
@ -117,7 +117,7 @@ class FennecContext(RemoteContext):
|
|||
if device_serial in devices:
|
||||
device = devices[device_serial]
|
||||
else:
|
||||
device = ADBDeviceFactory(adb=adb_path, device=device_serial)
|
||||
device = ADBDevice(adb=adb_path, device=device_serial)
|
||||
devices[device_serial] = device
|
||||
return device
|
||||
|
||||
|
|
|
@ -72,7 +72,6 @@ class DeviceRunner(BaseRunner):
|
|||
self.device.setup_profile(self.profile)
|
||||
|
||||
app = self.app_ctx.remote_process
|
||||
self.device.run_as_package = app
|
||||
args = ["-no-remote", "-profile", self.app_ctx.remote_profile]
|
||||
args.extend(self.cmdargs)
|
||||
env = self._device_env
|
||||
|
|
|
@ -19,7 +19,7 @@ from distutils.spawn import find_executable
|
|||
from enum import Enum
|
||||
|
||||
from mozbuild.base import MozbuildObject
|
||||
from mozdevice import ADBHost, ADBDeviceFactory
|
||||
from mozdevice import ADBHost, ADBDevice
|
||||
from six.moves import input, urllib
|
||||
|
||||
EMULATOR_HOME_DIR = os.path.join(os.path.expanduser('~'), '.mozbuild', 'android-device')
|
||||
|
@ -35,6 +35,7 @@ MANIFEST_PATH = 'testing/config/tooltool-manifests'
|
|||
SHORT_TIMEOUT = 10
|
||||
|
||||
verbose_logging = False
|
||||
devices = {}
|
||||
|
||||
|
||||
class InstallIntent(Enum):
|
||||
|
@ -85,11 +86,15 @@ AVD_DICT = {
|
|||
|
||||
|
||||
def _get_device(substs, device_serial=None):
|
||||
|
||||
adb_path = _find_sdk_exe(substs, 'adb', False)
|
||||
if not adb_path:
|
||||
adb_path = 'adb'
|
||||
device = ADBDeviceFactory(adb=adb_path, verbose=verbose_logging, device=device_serial)
|
||||
global devices
|
||||
if device_serial in devices:
|
||||
device = devices[device_serial]
|
||||
else:
|
||||
adb_path = _find_sdk_exe(substs, 'adb', False)
|
||||
if not adb_path:
|
||||
adb_path = 'adb'
|
||||
device = ADBDevice(adb=adb_path, verbose=verbose_logging, device=device_serial)
|
||||
devices[device_serial] = device
|
||||
return device
|
||||
|
||||
|
||||
|
@ -277,8 +282,6 @@ def verify_android_device(build_obj, install=InstallIntent.NO, xre=False, debugg
|
|||
"but I don't know how to install it.\n"
|
||||
"Install it now, then hit Enter " % app)
|
||||
|
||||
device.run_as_package = app
|
||||
|
||||
if device_verified and xre:
|
||||
# Check whether MOZ_HOST_BIN has been set to a valid xre; if not,
|
||||
# prompt to install one.
|
||||
|
@ -315,7 +318,6 @@ def verify_android_device(build_obj, install=InstallIntent.NO, xre=False, debugg
|
|||
serial = device_serial or os.environ.get('DEVICE_SERIAL')
|
||||
if not serial or ('emulator' not in serial):
|
||||
device = _get_device(build_obj.substs, serial)
|
||||
device.run_as_package = app
|
||||
try:
|
||||
addr = device.get_ip_address()
|
||||
if not addr:
|
||||
|
@ -347,7 +349,6 @@ def grant_runtime_permissions(build_obj, app, device_serial=None):
|
|||
(eg. org.mozilla.geckoview.test).
|
||||
"""
|
||||
device = _get_device(build_obj.substs, device_serial)
|
||||
device.run_as_package = app
|
||||
device.grant_runtime_permissions(app)
|
||||
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ class Device(object):
|
|||
print("WARNING: {}".format(e))
|
||||
if os.listdir(local_dump_dir):
|
||||
self.device.rm(remote_dump_dir, recursive=True)
|
||||
self.device.mkdir(remote_dump_dir, parents=True)
|
||||
self.device.mkdir(remote_dump_dir)
|
||||
return local_dump_dir
|
||||
|
||||
def setup_profile(self, profile):
|
||||
|
|
|
@ -7,12 +7,12 @@ from __future__ import absolute_import
|
|||
from setuptools import setup, find_packages
|
||||
|
||||
PACKAGE_NAME = 'mozrunner'
|
||||
PACKAGE_VERSION = '8.0.2'
|
||||
PACKAGE_VERSION = '8.0.1'
|
||||
|
||||
desc = """Reliable start/stop/configuration of Mozilla Applications (Firefox, Thunderbird, etc.)"""
|
||||
|
||||
deps = [
|
||||
'mozdevice>=4.0.0,<5',
|
||||
'mozdevice>=3.0.1,<4',
|
||||
'mozfile>=1.2',
|
||||
'mozinfo>=0.7,<2',
|
||||
'mozlog>=6.0',
|
||||
|
|
|
@ -40,9 +40,9 @@ config = {
|
|||
"default_actions": [
|
||||
'clobber',
|
||||
'setup-avds',
|
||||
'start-emulator',
|
||||
'download-and-extract',
|
||||
'create-virtualenv',
|
||||
'start-emulator',
|
||||
'verify-device',
|
||||
'install',
|
||||
'run-tests',
|
||||
|
|
|
@ -20,5 +20,5 @@ config = {
|
|||
"tooltool_cache": "/builds/tooltool_cache",
|
||||
# from android_common.py
|
||||
"download_tooltool": True,
|
||||
"xpcshell_extra": "--remoteTestRoot=/data/local/tmp/test_root",
|
||||
"xpcshell_extra": "--remoteTestRoot=/data/local/tests",
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
config = {
|
||||
"default_actions": [
|
||||
'setup-avds',
|
||||
'start-emulator',
|
||||
'download',
|
||||
'create-virtualenv',
|
||||
'start-emulator',
|
||||
'verify-device',
|
||||
'install',
|
||||
'run-tests',
|
||||
|
|
|
@ -1867,6 +1867,38 @@ class BaseScript(ScriptMixin, LogMixin, object):
|
|||
self._return_code = 0
|
||||
super(BaseScript, self).__init__()
|
||||
|
||||
# Collect decorated methods. We simply iterate over the attributes of
|
||||
# the current class instance and look for signatures deposited by
|
||||
# the decorators.
|
||||
self._listeners = dict(
|
||||
pre_run=[],
|
||||
pre_action=[],
|
||||
post_action=[],
|
||||
post_run=[],
|
||||
)
|
||||
for k in dir(self):
|
||||
item = getattr(self, k)
|
||||
|
||||
# We only decorate methods, so ignore other types.
|
||||
if not inspect.ismethod(item):
|
||||
continue
|
||||
|
||||
if hasattr(item, '_pre_run_listener'):
|
||||
self._listeners['pre_run'].append(k)
|
||||
|
||||
if hasattr(item, '_pre_action_listener'):
|
||||
self._listeners['pre_action'].append((
|
||||
k,
|
||||
item._pre_action_listener))
|
||||
|
||||
if hasattr(item, '_post_action_listener'):
|
||||
self._listeners['post_action'].append((
|
||||
k,
|
||||
item._post_action_listener))
|
||||
|
||||
if hasattr(item, '_post_run_listener'):
|
||||
self._listeners['post_run'].append(k)
|
||||
|
||||
self.log_obj = None
|
||||
self.abs_dirs = None
|
||||
if config_options is None:
|
||||
|
@ -1919,43 +1951,6 @@ class BaseScript(ScriptMixin, LogMixin, object):
|
|||
if self.config.get("dump_config"):
|
||||
self.dump_config(exit_on_finish=True)
|
||||
|
||||
# Collect decorated methods. We simply iterate over the attributes of
|
||||
# the current class instance and look for signatures deposited by
|
||||
# the decorators.
|
||||
self._listeners = dict(
|
||||
pre_run=[],
|
||||
pre_action=[],
|
||||
post_action=[],
|
||||
post_run=[],
|
||||
)
|
||||
for k in dir(self):
|
||||
try:
|
||||
item = getattr(self, k)
|
||||
except Exception as e:
|
||||
self.warning("BaseScript collecting decorated methods: "
|
||||
"failure to get attribute {}: {}".format(k, str(e)))
|
||||
continue
|
||||
|
||||
# We only decorate methods, so ignore other types.
|
||||
if not inspect.ismethod(item):
|
||||
continue
|
||||
|
||||
if hasattr(item, '_pre_run_listener'):
|
||||
self._listeners['pre_run'].append(k)
|
||||
|
||||
if hasattr(item, '_pre_action_listener'):
|
||||
self._listeners['pre_action'].append((
|
||||
k,
|
||||
item._pre_action_listener))
|
||||
|
||||
if hasattr(item, '_post_action_listener'):
|
||||
self._listeners['post_action'].append((
|
||||
k,
|
||||
item._post_action_listener))
|
||||
|
||||
if hasattr(item, '_post_run_listener'):
|
||||
self._listeners['post_run'].append(k)
|
||||
|
||||
def _dump_config_hierarchy(self, cfg_files):
|
||||
""" interpret each config file used.
|
||||
|
||||
|
|
|
@ -41,37 +41,55 @@ class AndroidMixin(object):
|
|||
@property
|
||||
def adb_path(self):
|
||||
'''Get the path to the adb executable.
|
||||
|
||||
Defer the use of query_exe() since it is defined by the
|
||||
BaseScript Mixin which hasn't finished initialing by the
|
||||
time the AndroidMixin is first initialized.
|
||||
'''
|
||||
self.activate_virtualenv()
|
||||
if not self._adb_path:
|
||||
self._adb_path = self.query_exe('adb')
|
||||
try:
|
||||
self._adb_path = self.query_exe('adb')
|
||||
except AttributeError:
|
||||
# Ignore attribute errors since BaseScript will
|
||||
# attempt to access properties before the other Mixins
|
||||
# have completed initialization. We recover afterwards
|
||||
# when additional attemps occur after initialization
|
||||
# is completed.
|
||||
pass
|
||||
return self._adb_path
|
||||
|
||||
@property
|
||||
def device(self):
|
||||
if not self._device:
|
||||
# We must access the adb_path property to activate the
|
||||
# virtualenv before importing mozdevice in order to
|
||||
# import the mozdevice installed into the virtualenv and
|
||||
# not any system-wide installation of mozdevice.
|
||||
adb = self.adb_path
|
||||
import mozdevice
|
||||
self._device = mozdevice.ADBDeviceFactory(adb=adb,
|
||||
device=self.device_serial,
|
||||
verbose=True)
|
||||
if not self._device and self.adb_path:
|
||||
try:
|
||||
import mozdevice
|
||||
self._device = mozdevice.ADBDevice(adb=self.adb_path,
|
||||
device=self.device_serial,
|
||||
verbose=True)
|
||||
self.info("New mozdevice with adb=%s, device=%s" %
|
||||
(self.adb_path, self.device_serial))
|
||||
except AttributeError:
|
||||
# As in adb_path, above.
|
||||
pass
|
||||
return self._device
|
||||
|
||||
@property
|
||||
def is_android(self):
|
||||
c = self.config
|
||||
installer_url = c.get('installer_url', None)
|
||||
return self.device_serial is not None or self.is_emulator or \
|
||||
(installer_url is not None and installer_url.endswith(".apk"))
|
||||
try:
|
||||
c = self.config
|
||||
installer_url = c.get('installer_url', None)
|
||||
return self.device_serial is not None or self.is_emulator or \
|
||||
(installer_url is not None and installer_url.endswith(".apk"))
|
||||
except AttributeError:
|
||||
return False
|
||||
|
||||
@property
|
||||
def is_emulator(self):
|
||||
c = self.config
|
||||
return True if c.get('emulator_avd_name') else False
|
||||
try:
|
||||
c = self.config
|
||||
return True if c.get('emulator_avd_name') else False
|
||||
except AttributeError:
|
||||
return False
|
||||
|
||||
def _get_repo_url(self, path):
|
||||
"""
|
||||
|
@ -324,7 +342,7 @@ class AndroidMixin(object):
|
|||
"""
|
||||
import mozdevice
|
||||
try:
|
||||
self.device.run_as_package = self.device.install_app(apk, replace=replace)
|
||||
self.device.install_app(apk, replace=replace)
|
||||
except (mozdevice.ADBError, mozdevice.ADBProcessError, mozdevice.ADBTimeoutError) as e:
|
||||
self.info('Failed to install %s on %s: %s %s' %
|
||||
(apk, self.device_name,
|
||||
|
@ -360,10 +378,10 @@ class AndroidMixin(object):
|
|||
pass
|
||||
return False
|
||||
|
||||
def shell_output(self, cmd, enable_run_as=False):
|
||||
def shell_output(self, cmd):
|
||||
import mozdevice
|
||||
try:
|
||||
return self.device.shell_output(cmd, timeout=30, enable_run_as=enable_run_as)
|
||||
return self.device.shell_output(cmd, timeout=30)
|
||||
except (mozdevice.ADBTimeoutError) as e:
|
||||
self.info('Failed to run shell command %s from %s: %s %s' %
|
||||
(cmd, self.device_name,
|
||||
|
@ -452,16 +470,16 @@ class AndroidMixin(object):
|
|||
def delete_ANRs(self):
|
||||
remote_dir = self.device.stack_trace_dir
|
||||
try:
|
||||
if not self.device.is_dir(remote_dir):
|
||||
self.device.mkdir(remote_dir)
|
||||
if not self.device.is_dir(remote_dir, root=True):
|
||||
self.mkdir(remote_dir, root=True)
|
||||
self.chmod(remote_dir, root=True)
|
||||
self.info("%s created" % remote_dir)
|
||||
return
|
||||
self.device.chmod(remote_dir, recursive=True)
|
||||
for trace_file in self.device.ls(remote_dir, recursive=True):
|
||||
for trace_file in self.device.ls(remote_dir, root=True):
|
||||
trace_path = posixpath.join(remote_dir, trace_file)
|
||||
if self.device.is_file(trace_path):
|
||||
self.device.rm(trace_path)
|
||||
self.info("%s deleted" % trace_path)
|
||||
self.device.chmod(trace_path, root=True)
|
||||
self.device.rm(trace_path, root=True)
|
||||
self.info("%s deleted" % trace_path)
|
||||
except Exception as e:
|
||||
self.info("failed to delete %s: %s %s" % (remote_dir, type(e).__name__, str(e)))
|
||||
|
||||
|
@ -475,7 +493,7 @@ class AndroidMixin(object):
|
|||
if not self.device.is_dir(remote_dir):
|
||||
self.info("%s not found; ANR check skipped" % remote_dir)
|
||||
return
|
||||
self.device.chmod(remote_dir, recursive=True)
|
||||
self.device.chmod(remote_dir, recursive=True, root=True)
|
||||
self.device.pull(remote_dir, dirs['abs_blob_upload_dir'])
|
||||
self.delete_ANRs()
|
||||
except Exception as e:
|
||||
|
@ -484,16 +502,16 @@ class AndroidMixin(object):
|
|||
def delete_tombstones(self):
|
||||
remote_dir = "/data/tombstones"
|
||||
try:
|
||||
if not self.device.is_dir(remote_dir):
|
||||
self.device.mkdir(remote_dir)
|
||||
if not self.device.is_dir(remote_dir, root=True):
|
||||
self.mkdir(remote_dir, root=True)
|
||||
self.chmod(remote_dir, root=True)
|
||||
self.info("%s created" % remote_dir)
|
||||
return
|
||||
self.device.chmod(remote_dir, recursive=True)
|
||||
for trace_file in self.device.ls(remote_dir, recursive=True):
|
||||
for trace_file in self.device.ls(remote_dir, root=True):
|
||||
trace_path = posixpath.join(remote_dir, trace_file)
|
||||
if self.device.is_file(trace_path):
|
||||
self.device.rm(trace_path)
|
||||
self.info("%s deleted" % trace_path)
|
||||
self.device.chmod(trace_path, root=True)
|
||||
self.device.rm(trace_path, root=True)
|
||||
self.info("%s deleted" % trace_path)
|
||||
except Exception as e:
|
||||
self.info("failed to delete %s: %s %s" % (remote_dir, type(e).__name__, str(e)))
|
||||
|
||||
|
@ -507,7 +525,7 @@ class AndroidMixin(object):
|
|||
if not self.device.is_dir(remote_dir):
|
||||
self.info("%s not found; tombstone check skipped" % remote_dir)
|
||||
return
|
||||
self.device.chmod(remote_dir, recursive=True)
|
||||
self.device.chmod(remote_dir, recursive=True, root=True)
|
||||
self.device.pull(remote_dir, dirs['abs_blob_upload_dir'])
|
||||
self.delete_tombstones()
|
||||
except Exception as e:
|
||||
|
|
|
@ -71,9 +71,9 @@ class AndroidProfileRun(TestingMixin, BaseScript, MozbaseMixin,
|
|||
super(AndroidProfileRun, self).__init__(
|
||||
config_options=self.config_options,
|
||||
all_actions=['setup-avds',
|
||||
'start-emulator',
|
||||
'download',
|
||||
'create-virtualenv',
|
||||
'start-emulator',
|
||||
'verify-device',
|
||||
'install',
|
||||
'run-tests',
|
||||
|
@ -150,7 +150,7 @@ class AndroidProfileRun(TestingMixin, BaseScript, MozbaseMixin,
|
|||
"""
|
||||
from mozhttpd import MozHttpd
|
||||
from mozprofile import Preferences
|
||||
from mozdevice import ADBDeviceFactory, ADBTimeoutError
|
||||
from mozdevice import ADBDevice, ADBTimeoutError
|
||||
from six import string_types
|
||||
from marionette_driver.marionette import Marionette
|
||||
|
||||
|
@ -215,26 +215,26 @@ class AndroidProfileRun(TestingMixin, BaseScript, MozbaseMixin,
|
|||
|
||||
# Force test_root to be on the sdcard for android pgo
|
||||
# builds which fail for Android 4.3 when profiles are located
|
||||
# in /data/local/tmp/test_root with
|
||||
# in /data/local/tmp/tests with
|
||||
# E AndroidRuntime: FATAL EXCEPTION: Gecko
|
||||
# E AndroidRuntime: java.lang.IllegalArgumentException: \
|
||||
# Profile directory must be writable if specified: /data/local/tmp/test_root/profile
|
||||
# Profile directory must be writable if specified: /data/local/tmp/tests/profile
|
||||
# This occurs when .can-write-sentinel is written to
|
||||
# the profile in
|
||||
# mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoProfile.java.
|
||||
# This is not a problem on later versions of Android. This
|
||||
# over-ride of test_root should be removed when Android 4.3 is no
|
||||
# longer supported.
|
||||
sdcard_test_root = '/sdcard/test_root'
|
||||
adbdevice = ADBDeviceFactory(adb=adb,
|
||||
device='emulator-5554',
|
||||
test_root=sdcard_test_root)
|
||||
sdcard_test_root = '/sdcard/tests'
|
||||
adbdevice = ADBDevice(adb=adb,
|
||||
device='emulator-5554',
|
||||
test_root=sdcard_test_root)
|
||||
if adbdevice.test_root != sdcard_test_root:
|
||||
# If the test_root was previously set and shared
|
||||
# the initializer will not have updated the shared
|
||||
# value. Force it to match the sdcard_test_root.
|
||||
adbdevice.test_root = sdcard_test_root
|
||||
adbdevice.mkdir(outputdir, parents=True)
|
||||
adbdevice.mkdir(outputdir)
|
||||
|
||||
try:
|
||||
# Run Fennec a first time to initialize its profile
|
||||
|
|
|
@ -120,9 +120,9 @@ class AndroidEmulatorTest(TestingMixin, BaseScript, MozbaseMixin, CodeCoverageMi
|
|||
config_options=self.config_options,
|
||||
all_actions=['clobber',
|
||||
'setup-avds',
|
||||
'start-emulator',
|
||||
'download-and-extract',
|
||||
'create-virtualenv',
|
||||
'start-emulator',
|
||||
'verify-device',
|
||||
'install',
|
||||
'run-tests',
|
||||
|
|
|
@ -128,11 +128,11 @@ class WebPlatformTest(TestingMixin, MercurialScript, CodeCoverageMixin, AndroidM
|
|||
all_actions=[
|
||||
'clobber',
|
||||
'setup-avds',
|
||||
'start-emulator',
|
||||
'download-and-extract',
|
||||
'download-and-process-manifest',
|
||||
'create-virtualenv',
|
||||
'pull',
|
||||
'start-emulator',
|
||||
'verify-device',
|
||||
'install',
|
||||
'run-tests',
|
||||
|
|
|
@ -234,13 +234,8 @@ class MachRaptor(MachCommandBase):
|
|||
from mozrunner.devices.android_device import (verify_android_device, InstallIntent)
|
||||
from mozdevice import ADBAndroid
|
||||
install = InstallIntent.NO if kwargs.pop('noinstall', False) else InstallIntent.YES
|
||||
verbose = False
|
||||
if kwargs.get('log_mach_verbose') or kwargs.get('log_tbpl_level') == 'debug' or \
|
||||
kwargs.get('log_mach_level') == 'debug' or kwargs.get('log_raw_level') == 'debug':
|
||||
verbose = True
|
||||
if not verify_android_device(build_obj, install=install,
|
||||
app=kwargs['binary'],
|
||||
verbose=verbose,
|
||||
xre=True): # Equivalent to 'run_local' = True.
|
||||
return 1
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ from __future__ import absolute_import
|
|||
|
||||
import os
|
||||
|
||||
from mozdevice import ADBDeviceFactory
|
||||
from mozdevice import ADBDevice
|
||||
|
||||
from logger.logger import RaptorLogger
|
||||
from performance_tuning import tune_performance
|
||||
|
@ -34,21 +34,16 @@ class BrowsertimeAndroid(PerftestAndroid, Browsertime):
|
|||
file ourselves. Also note when using playback, the nss certificate db is created as usual when
|
||||
mitmproxy is started (and saved in the profile) so it is already included in the profile that
|
||||
browsertime/geckodriver copies onto the device.
|
||||
XXX: bc: This doesn't work with scoped storage in Android 10 since the shell owns the profile
|
||||
directory that is pushed to the device and the profile can no longer be on the sdcard. But when
|
||||
geckodriver's android.rs defines the profile to be located on internal storage, it will be
|
||||
owned by shell but if we are attempting to eliminate root, then when we run shell commands
|
||||
as the app, they will fail due to the app being unable to write to the shell owned profile
|
||||
directory.
|
||||
"""
|
||||
|
||||
def __init__(self, app, binary, activity=None, intent=None, **kwargs):
|
||||
super(BrowsertimeAndroid, self).__init__(
|
||||
app, binary, profile_class="firefox", **kwargs
|
||||
)
|
||||
|
||||
self.config.update({"activity": activity, "intent": intent})
|
||||
self.remote_test_root = None
|
||||
self.remote_profile = None
|
||||
self.remote_test_root = "/data/local/tmp/tests/raptor"
|
||||
self.remote_profile = os.path.join(self.remote_test_root, "profile")
|
||||
|
||||
@property
|
||||
def browsertime_args(self):
|
||||
|
@ -122,15 +117,12 @@ class BrowsertimeAndroid(PerftestAndroid, Browsertime):
|
|||
|
||||
def setup_adb_device(self):
|
||||
if self.device is None:
|
||||
self.device = ADBDeviceFactory(verbose=True)
|
||||
self.device = ADBDevice(verbose=True)
|
||||
if not self.config.get("disable_perf_tuning", False):
|
||||
tune_performance(self.device, log=LOG)
|
||||
|
||||
self.clear_app_data()
|
||||
self.set_debug_app_flag()
|
||||
self.device.run_as_package = self.config['binary']
|
||||
self.remote_test_root = os.path.join(self.device.test_root, "raptor")
|
||||
self.remote_profile = os.path.join(self.remote_test_root, "profile")
|
||||
|
||||
def run_test_setup(self, test):
|
||||
super(BrowsertimeAndroid, self).run_test_setup(test)
|
||||
|
@ -146,7 +138,7 @@ class BrowsertimeAndroid(PerftestAndroid, Browsertime):
|
|||
|
||||
if self.config['app'] == "chrome-m":
|
||||
# Make sure that chrome is enabled on the device
|
||||
self.device.shell_output("pm enable com.android.chrome")
|
||||
self.device.shell_output("pm enable com.android.chrome", root=True)
|
||||
|
||||
return super(BrowsertimeAndroid, self).run_tests(tests, test_names)
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from mozdevice import ADBError
|
||||
|
||||
|
||||
def tune_performance(device, log=None, timeout=None):
|
||||
"""Set various performance-oriented parameters, to reduce jitter.
|
||||
|
@ -26,7 +24,7 @@ class PerformanceTuner(object):
|
|||
def tune_performance(self):
|
||||
self.log.info("tuning android device performance")
|
||||
self.set_svc_power_stayon()
|
||||
if self.device.is_rooted:
|
||||
if self.device._have_su or self.device._have_android_su:
|
||||
device_name = self.device.shell_output('getprop ro.product.model',
|
||||
timeout=self.timeout)
|
||||
# all commands require root shell from here on
|
||||
|
@ -39,15 +37,13 @@ class PerformanceTuner(object):
|
|||
self.device.clear_logcat(timeout=self.timeout)
|
||||
self.log.info("android device performance tuning complete")
|
||||
|
||||
def _set_value_and_check_exitcode(self, file_name, value):
|
||||
def _set_value_and_check_exitcode(self, file_name, value, root=False):
|
||||
self.log.info('setting {} to {}'.format(file_name, value))
|
||||
try:
|
||||
self.device.shell_output(' '.join(['echo', str(value), '>', str(file_name)]),
|
||||
timeout=self.timeout)
|
||||
if self.device.shell_bool(' '.join(['echo', str(value), '>', str(file_name)]),
|
||||
root=root, timeout=self.timeout):
|
||||
self.log.info('successfully set {} to {}'.format(file_name, value))
|
||||
except ADBError as e:
|
||||
self.log.info("Ignoring failure to set value {} to {}. {}".format(
|
||||
file_name, value, e))
|
||||
else:
|
||||
self.log.warning('command failed')
|
||||
|
||||
def set_svc_power_stayon(self):
|
||||
self.log.info('set device to stay awake on usb')
|
||||
|
@ -66,13 +62,8 @@ class PerformanceTuner(object):
|
|||
'thermald',
|
||||
]
|
||||
for service in services:
|
||||
try:
|
||||
self.log.info(' '.join(['turning off service:', service]))
|
||||
self.device.shell_bool(' '.join(['stop', service]),
|
||||
timeout=self.timeout)
|
||||
except ADBError as e:
|
||||
self.log.info("Ignoring failure to stop service {}. Error: {}: {}".format(
|
||||
service, e.__class__.__name__, e))
|
||||
self.log.info(' '.join(['turning off service:', service]))
|
||||
self.device.shell_bool(' '.join(['stop', service]), root=True, timeout=self.timeout)
|
||||
|
||||
services_list_output = self.device.shell_output('service list', timeout=self.timeout)
|
||||
for service in services:
|
||||
|
@ -116,7 +107,7 @@ class PerformanceTuner(object):
|
|||
}
|
||||
|
||||
for key, value in commands.items():
|
||||
self._set_value_and_check_exitcode(key, value)
|
||||
self._set_value_and_check_exitcode(key, value, root=True)
|
||||
|
||||
def set_cpu_performance_parameters(self, device_name=None):
|
||||
self.log.info('setting cpu performance parameters')
|
||||
|
@ -153,7 +144,7 @@ class PerformanceTuner(object):
|
|||
.format(device_name))
|
||||
|
||||
for key, value in commands.items():
|
||||
self._set_value_and_check_exitcode(key, value)
|
||||
self._set_value_and_check_exitcode(key, value, root=True)
|
||||
|
||||
def set_gpu_performance_parameters(self, device_name=None):
|
||||
self.log.info('setting gpu performance parameters')
|
||||
|
@ -195,7 +186,7 @@ class PerformanceTuner(object):
|
|||
.format(device_name))
|
||||
|
||||
for key, value in commands.items():
|
||||
self._set_value_and_check_exitcode(key, value)
|
||||
self._set_value_and_check_exitcode(key, value, root=True)
|
||||
|
||||
def set_kernel_performance_parameters(self):
|
||||
self.log.info('setting kernel performance parameters')
|
||||
|
@ -206,4 +197,4 @@ class PerformanceTuner(object):
|
|||
'/sys/kernel/debug/msm-bus-dbg/shell-client/slv': '512',
|
||||
}
|
||||
for key, value in commands.items():
|
||||
self._set_value_and_check_exitcode(key, value)
|
||||
self._set_value_and_check_exitcode(key, value, root=True)
|
||||
|
|
|
@ -577,8 +577,8 @@ class PerftestAndroid(Perftest):
|
|||
# We absolutely need to determine the chrome
|
||||
# version here so that we can select the correct
|
||||
# chromedriver for browsertime
|
||||
from mozdevice import ADBDeviceFactory
|
||||
device = ADBDeviceFactory(verbose=True)
|
||||
from mozdevice import ADBDevice
|
||||
device = ADBDevice(verbose=True)
|
||||
binary = "com.android.chrome"
|
||||
|
||||
pkg_info = device.shell_output("dumpsys package %s" % binary)
|
||||
|
@ -656,9 +656,12 @@ class PerftestAndroid(Perftest):
|
|||
|
||||
try:
|
||||
LOG.info("copying profile to device: %s" % self.remote_profile)
|
||||
self.device.rm(self.remote_profile, force=True, recursive=True)
|
||||
# We must use root=True since the remote profile has been
|
||||
# modified by gecko and has content which is only
|
||||
# accessible to the gecko user.
|
||||
self.device.rm(self.remote_profile, force=True, recursive=True, root=True)
|
||||
self.device.push(self.profile.profile, self.remote_profile)
|
||||
self.device.chmod(self.remote_profile, recursive=True)
|
||||
self.device.chmod(self.remote_profile, recursive=True, root=True)
|
||||
|
||||
except Exception:
|
||||
LOG.error("Unable to copy profile to device.")
|
||||
|
|
|
@ -41,12 +41,12 @@ def change_charging_state(device, device_type, enable=True, timeout=10):
|
|||
if device_type == "Pixel 2":
|
||||
status = 0 if enable else 1
|
||||
device.shell_bool(
|
||||
"echo %s > %s" % (status, P2_PATH), timeout=timeout
|
||||
"echo %s > %s" % (status, P2_PATH), root=True, timeout=timeout
|
||||
)
|
||||
elif device_type == "Moto G (5)":
|
||||
status = 1 if enable else 0
|
||||
device.shell_bool(
|
||||
"echo %s > %s" % (status, G5_PATH), timeout=timeout
|
||||
"echo %s > %s" % (status, G5_PATH), root=True, timeout=timeout
|
||||
)
|
||||
except (ADBTimeoutError, ADBError) as e:
|
||||
raise Exception(
|
||||
|
@ -360,9 +360,6 @@ def finish_android_power_test(raptor, test_name, os_baseline=False):
|
|||
LOG.info("Approximate power test time %s" % str(test_time))
|
||||
|
||||
def calculate_pc(power_measure, baseline_measure):
|
||||
if not baseline_measure:
|
||||
LOG.error("Power test baseline_measure is Zero.")
|
||||
return 0
|
||||
return (100 * (
|
||||
(power_measure + baseline_measure) /
|
||||
baseline_measure
|
||||
|
|
|
@ -15,7 +15,7 @@ import time
|
|||
import mozcrash
|
||||
from cpu import start_android_cpu_profiler
|
||||
from logger.logger import RaptorLogger
|
||||
from mozdevice import ADBDeviceFactory, ADBProcessError
|
||||
from mozdevice import ADBDevice, ADBProcessError
|
||||
from performance_tuning import tune_performance
|
||||
from perftest import PerftestAndroid
|
||||
from power import (
|
||||
|
@ -39,6 +39,8 @@ class WebExtensionAndroid(PerftestAndroid, WebExtension):
|
|||
|
||||
self.config.update({"activity": activity, "intent": intent})
|
||||
|
||||
self.remote_test_root = "/data/local/tmp/tests/raptor"
|
||||
self.remote_profile = os.path.join(self.remote_test_root, "profile")
|
||||
self.os_baseline_data = None
|
||||
self.power_test_time = None
|
||||
self.screen_off_timeout = 0
|
||||
|
@ -47,19 +49,17 @@ class WebExtensionAndroid(PerftestAndroid, WebExtension):
|
|||
|
||||
def setup_adb_device(self):
|
||||
if self.device is None:
|
||||
self.device = ADBDeviceFactory(verbose=True)
|
||||
self.device = ADBDevice(verbose=True)
|
||||
if not self.config.get("disable_perf_tuning", False):
|
||||
tune_performance(self.device, log=LOG)
|
||||
|
||||
self.device.run_as_package = self.config['binary']
|
||||
self.remote_test_root = os.path.join(self.device.test_root, "raptor")
|
||||
self.remote_profile = os.path.join(self.remote_test_root, "profile")
|
||||
if self.config['power_test']:
|
||||
disable_charging(self.device)
|
||||
|
||||
LOG.info("creating remote root folder for raptor: %s" % self.remote_test_root)
|
||||
self.device.rm(self.remote_test_root, force=True, recursive=True)
|
||||
self.device.mkdir(self.remote_test_root, parents=True)
|
||||
self.device.rm(self.remote_test_root, force=True, recursive=True, root=True)
|
||||
self.device.mkdir(self.remote_test_root, parents=True, root=True)
|
||||
self.device.chmod(self.remote_test_root, recursive=True, root=True)
|
||||
|
||||
self.clear_app_data()
|
||||
self.set_debug_app_flag()
|
||||
|
@ -415,7 +415,9 @@ class WebExtensionAndroid(PerftestAndroid, WebExtension):
|
|||
|
||||
def clean_up(self):
|
||||
LOG.info("removing test folder for raptor: %s" % self.remote_test_root)
|
||||
self.device.rm(self.remote_test_root, force=True, recursive=True)
|
||||
# We must use root=True since the browser will have created files in
|
||||
# the profile.
|
||||
self.device.rm(self.remote_test_root, force=True, recursive=True, root=True)
|
||||
|
||||
if self.config['power_test']:
|
||||
enable_charging(self.device)
|
||||
|
|
|
@ -3,7 +3,7 @@ mozrunner ~= 7.0
|
|||
mozprofile ~= 2.1
|
||||
manifestparser >= 1.1
|
||||
wptserve ~= 2.0
|
||||
mozdevice >= 4.0.0
|
||||
mozdevice >= 3.0.1,<4
|
||||
mozproxy >= 1.0
|
||||
pyyaml ~= 3.1
|
||||
mozpower >= 1.0.0
|
||||
|
|
|
@ -16,7 +16,7 @@ import mozcrash
|
|||
import mozfile
|
||||
import mozinfo
|
||||
import mozlog
|
||||
from mozdevice import ADBDeviceFactory, ADBProcessError, ADBTimeoutError
|
||||
from mozdevice import ADBDevice, ADBProcessError, ADBTimeoutError
|
||||
|
||||
try:
|
||||
from mozbuild.base import MozbuildObject
|
||||
|
@ -30,9 +30,9 @@ class RemoteCPPUnitTests(cppunittests.CPPUnitTests):
|
|||
def __init__(self, options, progs):
|
||||
cppunittests.CPPUnitTests.__init__(self)
|
||||
self.options = options
|
||||
self.device = ADBDeviceFactory(adb=options.adb_path or 'adb',
|
||||
device=options.device_serial,
|
||||
test_root=options.remote_test_root)
|
||||
self.device = ADBDevice(adb=options.adb_path or 'adb',
|
||||
device=options.device_serial,
|
||||
test_root=options.remote_test_root)
|
||||
self.remote_test_root = posixpath.join(self.device.test_root, "cppunittests")
|
||||
self.remote_bin_dir = posixpath.join(self.remote_test_root, "b")
|
||||
self.remote_tmp_dir = posixpath.join(self.remote_test_root, "tmp")
|
||||
|
@ -41,13 +41,13 @@ class RemoteCPPUnitTests(cppunittests.CPPUnitTests):
|
|||
self.setup_bin(progs)
|
||||
|
||||
def setup_bin(self, progs):
|
||||
self.device.rm(self.remote_test_root, force=True, recursive=True)
|
||||
self.device.rm(self.remote_test_root, force=True, recursive=True, root=True)
|
||||
self.device.mkdir(self.remote_home_dir, parents=True)
|
||||
self.device.mkdir(self.remote_tmp_dir)
|
||||
self.device.mkdir(self.remote_bin_dir)
|
||||
self.push_libs()
|
||||
self.push_progs(progs)
|
||||
self.device.chmod(self.remote_bin_dir, recursive=True)
|
||||
self.device.chmod(self.remote_bin_dir, recursive=True, root=True)
|
||||
|
||||
def push_libs(self):
|
||||
if self.options.local_apk:
|
||||
|
@ -209,13 +209,11 @@ class RemoteCPPUnittestOptions(cppunittests.CPPUnittestOptions):
|
|||
self.add_option("--remoteTestRoot", action="store",
|
||||
type="string", dest="remote_test_root",
|
||||
help="Remote directory to use as test root "
|
||||
"(eg. /data/local/tmp/test_root).")
|
||||
"(eg. /mnt/sdcard/tests or /data/local/tests).")
|
||||
|
||||
# /data/local/tmp/test_root is used because it is usually not
|
||||
# possible to set +x permissions on binaries on /mnt/sdcard
|
||||
# and since scope storage on Android 10 causes permission
|
||||
# errors on the sdcard.
|
||||
defaults["remote_test_root"] = "/data/local/tmp/test_root"
|
||||
# /data/local/tests is used because it is usually not possible to set +x permissions
|
||||
# on binaries on /mnt/sdcard
|
||||
defaults["remote_test_root"] = "/data/local/tests"
|
||||
|
||||
self.add_option("--addEnv", action="append",
|
||||
type="string", dest="add_env",
|
||||
|
|
|
@ -309,8 +309,8 @@ class FirefoxAndroid(BrowserSetup):
|
|||
os.environ["ADB_PATH"] = adb_path
|
||||
adb_path = os.environ["ADB_PATH"]
|
||||
|
||||
device = mozdevice.ADBDeviceFactory(adb=adb_path,
|
||||
device=kwargs["device_serial"])
|
||||
device = mozdevice.ADBDevice(adb=adb_path,
|
||||
device=kwargs["device_serial"])
|
||||
|
||||
if install:
|
||||
device.uninstall_app(app)
|
||||
|
|
|
@ -17,7 +17,7 @@ import tempfile
|
|||
from zipfile import ZipFile
|
||||
|
||||
import mozcrash
|
||||
from mozdevice import ADBDevice, ADBDeviceFactory, ADBTimeoutError
|
||||
from mozdevice import ADBDevice, ADBTimeoutError
|
||||
import mozfile
|
||||
import mozinfo
|
||||
from mozlog import commandline
|
||||
|
@ -37,11 +37,12 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
for key in mobileArgs:
|
||||
setattr(self, key, mobileArgs[key])
|
||||
|
||||
def initDir(self, path, mask="777", timeout=None):
|
||||
def initDir(self, path, mask="777", timeout=None, root=True):
|
||||
"""Initialize a directory by removing it if it exists, creating it
|
||||
and changing the permissions."""
|
||||
self.device.rm(path, recursive=True, force=True, timeout=timeout)
|
||||
self.device.mkdir(path, parents=True, timeout=timeout)
|
||||
self.device.rm(path, recursive=True, force=True, timeout=timeout, root=root)
|
||||
self.device.mkdir(path, parents=True, timeout=timeout, root=root)
|
||||
self.device.chmod(path, recursive=True, mask=mask, timeout=timeout, root=root)
|
||||
|
||||
def updateTestPrefsFile(self):
|
||||
testPrefsFile = xpcshell.XPCShellTestThread.updateTestPrefsFile(self)
|
||||
|
@ -53,7 +54,7 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
# Push the per-test prefs file in the remote temp dir.
|
||||
remoteTestPrefsFile = posixpath.join(self.remoteTmpDir, 'user.js')
|
||||
self.device.push(testPrefsFile, remoteTestPrefsFile)
|
||||
self.device.chmod(remoteTestPrefsFile)
|
||||
self.device.chmod(remoteTestPrefsFile, root=True)
|
||||
os.remove(testPrefsFile)
|
||||
return remoteTestPrefsFile
|
||||
|
||||
|
@ -87,7 +88,7 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
|
||||
pluginsDir = posixpath.join(self.remoteTmpDir, "plugins")
|
||||
self.device.push(self.pluginsPath, pluginsDir)
|
||||
self.device.chmod(pluginsDir)
|
||||
self.device.chmod(pluginsDir, root=True)
|
||||
if self.interactive:
|
||||
self.log.info("plugins dir is %s" % pluginsDir)
|
||||
return pluginsDir
|
||||
|
@ -103,7 +104,7 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
mozinfo.output_to_file(local)
|
||||
mozInfoJSPath = posixpath.join(self.profileDir, "mozinfo.json")
|
||||
self.device.push(local, mozInfoJSPath)
|
||||
self.device.chmod(mozInfoJSPath)
|
||||
self.device.chmod(mozInfoJSPath, root=True)
|
||||
os.remove(local)
|
||||
return mozInfoJSPath
|
||||
|
||||
|
@ -168,7 +169,7 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
try:
|
||||
# env is ignored here since the environment has already been
|
||||
# set for the command via the pushWrapper method.
|
||||
adb_process = self.device.shell(cmd, timeout=timeout+10)
|
||||
adb_process = self.device.shell(cmd, timeout=timeout+10, root=True)
|
||||
output_file = adb_process.stdout_file
|
||||
self.shellReturnCode = adb_process.exitcode
|
||||
except ADBTimeoutError:
|
||||
|
@ -185,7 +186,7 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
# Guard against an accumulation of hung processes by killing
|
||||
# them here. Note also that IPC tests may spawn new instances
|
||||
# of xpcshell.
|
||||
self.device.pkill("xpcshell")
|
||||
self.device.pkill("xpcshell", root=True)
|
||||
return output_file
|
||||
|
||||
def checkForCrashes(self,
|
||||
|
@ -214,7 +215,7 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
return None
|
||||
|
||||
def kill(self, proc):
|
||||
return self.device.pkill("xpcshell")
|
||||
return self.device.pkill("xpcshell", root=True)
|
||||
|
||||
def getReturnCode(self, proc):
|
||||
if self.shellReturnCode is not None:
|
||||
|
@ -224,7 +225,7 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
|
||||
def removeDir(self, dirname):
|
||||
try:
|
||||
self.device.rm(dirname, recursive=True)
|
||||
self.device.rm(dirname, recursive=True, root=True)
|
||||
except ADBTimeoutError:
|
||||
raise
|
||||
except Exception as e:
|
||||
|
@ -246,10 +247,10 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
verbose = False
|
||||
if options['log_tbpl_level'] == 'debug' or options['log_mach_level'] == 'debug':
|
||||
verbose = True
|
||||
self.device = ADBDeviceFactory(adb=options['adbPath'] or 'adb',
|
||||
device=options['deviceSerial'],
|
||||
test_root=options['remoteTestRoot'],
|
||||
verbose=verbose)
|
||||
self.device = ADBDevice(adb=options['adbPath'] or 'adb',
|
||||
device=options['deviceSerial'],
|
||||
test_root=options['remoteTestRoot'],
|
||||
verbose=verbose)
|
||||
self.remoteTestRoot = posixpath.join(self.device.test_root, "xpc")
|
||||
# Add Android version (SDK level) to mozinfo so that manifest entries
|
||||
# can be conditional on android_version.
|
||||
|
@ -262,7 +263,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
# be executable. Since +x permissions cannot usually be set on /mnt/sdcard,
|
||||
# and the test root may be on /mnt/sdcard, remoteBinDir is set to be on
|
||||
# /data/local, always.
|
||||
self.remoteBinDir = posixpath.join(self.device.test_root, "xpcb")
|
||||
self.remoteBinDir = posixpath.join("/data", "local", "xpcb")
|
||||
# Terse directory names are used here ("c" for the components directory)
|
||||
# to minimize the length of the command line used to execute
|
||||
# xpcshell on the remote device. adb has a limit to the number
|
||||
|
@ -319,11 +320,12 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
if self.remoteAPK:
|
||||
self.mobileArgs['remoteAPK'] = self.remoteAPK
|
||||
|
||||
def initDir(self, path, mask="777", timeout=None):
|
||||
def initDir(self, path, mask="777", timeout=None, root=True):
|
||||
"""Initialize a directory by removing it if it exists, creating it
|
||||
and changing the permissions."""
|
||||
self.device.rm(path, recursive=True, force=True, timeout=timeout)
|
||||
self.device.mkdir(path, parents=True, timeout=timeout)
|
||||
self.device.rm(path, recursive=True, force=True, timeout=timeout, root=root)
|
||||
self.device.mkdir(path, parents=True, timeout=timeout, root=root)
|
||||
self.device.chmod(path, recursive=True, mask=mask, timeout=timeout, root=root)
|
||||
|
||||
def setLD_LIBRARY_PATH(self):
|
||||
self.env["LD_LIBRARY_PATH"] = self.remoteBinDir
|
||||
|
@ -347,7 +349,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
"%s/xpcshell \"$@\"\n" % self.remoteBinDir])
|
||||
remoteWrapper = posixpath.join(self.remoteBinDir, "xpcw")
|
||||
self.device.push(localWrapper, remoteWrapper)
|
||||
self.device.chmod(remoteWrapper)
|
||||
self.device.chmod(remoteWrapper, root=True)
|
||||
os.remove(localWrapper)
|
||||
|
||||
def buildPrefsFile(self, extraPrefs):
|
||||
|
@ -355,7 +357,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
|
||||
remotePrefsFile = posixpath.join(self.remoteTestRoot, 'user.js')
|
||||
self.device.push(self.prefsFile, remotePrefsFile)
|
||||
self.device.chmod(remotePrefsFile)
|
||||
self.device.chmod(remotePrefsFile, root=True)
|
||||
os.remove(self.prefsFile)
|
||||
self.prefsFile = remotePrefsFile
|
||||
return prefs
|
||||
|
@ -418,7 +420,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
local = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'head.js')
|
||||
remoteFile = posixpath.join(self.remoteScriptsDir, "head.js")
|
||||
self.device.push(local, remoteFile)
|
||||
self.device.chmod(remoteFile)
|
||||
self.device.chmod(remoteFile, root=True)
|
||||
|
||||
# The xpcshell binary is required for all tests. Additional binaries
|
||||
# are required for some tests. This list should be similar to
|
||||
|
@ -438,7 +440,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
print("Pushing %s.." % fname, file=sys.stderr)
|
||||
remoteFile = posixpath.join(self.remoteBinDir, fname)
|
||||
self.device.push(local, remoteFile)
|
||||
self.device.chmod(remoteFile)
|
||||
self.device.chmod(remoteFile, root=True)
|
||||
else:
|
||||
print("*** Expected binary %s not found in %s!" %
|
||||
(fname, self.localBin), file=sys.stderr)
|
||||
|
@ -446,25 +448,25 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
local = os.path.join(self.localBin, "components/httpd.js")
|
||||
remoteFile = posixpath.join(self.remoteComponentsDir, "httpd.js")
|
||||
self.device.push(local, remoteFile)
|
||||
self.device.chmod(remoteFile)
|
||||
self.device.chmod(remoteFile, root=True)
|
||||
|
||||
local = os.path.join(self.localBin, "components/httpd.manifest")
|
||||
remoteFile = posixpath.join(self.remoteComponentsDir, "httpd.manifest")
|
||||
self.device.push(local, remoteFile)
|
||||
self.device.chmod(remoteFile)
|
||||
self.device.chmod(remoteFile, root=True)
|
||||
|
||||
if self.options['localAPK']:
|
||||
remoteFile = posixpath.join(self.remoteBinDir,
|
||||
os.path.basename(self.options['localAPK']))
|
||||
self.device.push(self.options['localAPK'], remoteFile)
|
||||
self.device.chmod(remoteFile)
|
||||
self.device.chmod(remoteFile, root=True)
|
||||
|
||||
self.pushLibs()
|
||||
else:
|
||||
localB2G = os.path.join(self.options['objdir'], "dist", "b2g")
|
||||
if os.path.exists(localB2G):
|
||||
self.device.push(localB2G, self.remoteBinDir)
|
||||
self.device.chmod(self.remoteBinDir)
|
||||
self.device.chmod(self.remoteBinDir, root=True)
|
||||
else:
|
||||
raise Exception("unable to install gre: no APK and not b2g")
|
||||
|
||||
|
@ -481,7 +483,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
localFile = os.path.join(dir, info.filename)
|
||||
self.device.push(localFile, remoteFile)
|
||||
pushed_libs_count += 1
|
||||
self.device.chmod(remoteFile)
|
||||
self.device.chmod(remoteFile, root=True)
|
||||
finally:
|
||||
shutil.rmtree(dir)
|
||||
return pushed_libs_count
|
||||
|
@ -489,26 +491,26 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
def setupModules(self):
|
||||
if self.testingModulesDir:
|
||||
self.device.push(self.testingModulesDir, self.remoteModulesDir)
|
||||
self.device.chmod(self.remoteModulesDir)
|
||||
self.device.chmod(self.remoteModulesDir, root=True)
|
||||
|
||||
def setupTestDir(self):
|
||||
print('pushing %s' % self.xpcDir)
|
||||
# The tests directory can be quite large: 5000 files and growing!
|
||||
# Sometimes - like on a low-end aws instance running an emulator - the push
|
||||
# may exceed the default 5 minute timeout, so we increase it here to 10 minutes.
|
||||
self.device.rm(self.remoteScriptsDir, recursive=True, force=True, timeout=None)
|
||||
self.device.rm(self.remoteScriptsDir, recursive=True, force=True, timeout=None, root=True)
|
||||
self.device.push(self.xpcDir, self.remoteScriptsDir, timeout=600)
|
||||
self.device.chmod(self.remoteScriptsDir, recursive=True)
|
||||
self.device.chmod(self.remoteScriptsDir, recursive=True, root=True)
|
||||
|
||||
def setupSocketConnections(self):
|
||||
# make node host ports visible to device
|
||||
if "MOZHTTP2_PORT" in self.env:
|
||||
port = "tcp:{}".format(self.env["MOZHTTP2_PORT"])
|
||||
self.device.create_socket_connection(ADBDevice.SOCKET_DIRECTION_REVERSE, port, port)
|
||||
self.device.create_socket_connection(ADBDevice.SOCKET_DIRECTON_REVERSE, port, port)
|
||||
self.log.info("reversed MOZHTTP2_PORT connection for port " + port)
|
||||
if "MOZNODE_EXEC_PORT" in self.env:
|
||||
port = "tcp:{}".format(self.env["MOZNODE_EXEC_PORT"])
|
||||
self.device.create_socket_connection(ADBDevice.SOCKET_DIRECTION_REVERSE, port, port)
|
||||
self.device.create_socket_connection(ADBDevice.SOCKET_DIRECTON_REVERSE, port, port)
|
||||
self.log.info("reversed MOZNODE_EXEC_PORT connection for port " + port)
|
||||
|
||||
def buildTestList(self, test_tags=None, test_paths=None, verify=False):
|
||||
|
|
|
@ -176,7 +176,7 @@ def add_remote_arguments(parser):
|
|||
|
||||
parser.add_argument("--remoteTestRoot", action="store", type=str, dest="remoteTestRoot",
|
||||
help="Remote directory to use as test root "
|
||||
"(eg. /data/local/tmp/test_root).")
|
||||
"(eg. /mnt/sdcard/tests or /data/local/tests).")
|
||||
|
||||
|
||||
def parser_desktop():
|
||||
|
|
Загрузка…
Ссылка в новой задаче